From 75fd42e70f5fc3ff0a92c53a4398fd6777550232 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niklas=20Laxstr=C3=B6m?= Date: Thu, 14 Jul 2016 07:46:01 +0200 Subject: [PATCH 01/71] Localisation updates from https://translatewiki.net. --- msg/json/es.json | 8 ++++---- msg/json/he.json | 3 ++- msg/json/ko.json | 6 +++--- msg/json/lb.json | 1 + msg/json/lt.json | 12 ++++++++++++ msg/json/pt.json | 2 +- msg/json/ta.json | 1 + 7 files changed, 24 insertions(+), 9 deletions(-) diff --git a/msg/json/es.json b/msg/json/es.json index d976c56f1..15266374f 100644 --- a/msg/json/es.json +++ b/msg/json/es.json @@ -244,15 +244,15 @@ "LISTS_GET_INDEX_RANDOM": "aleatorio", "LISTS_INDEX_FROM_START_TOOLTIP": "%1 es el primer elemento.", "LISTS_INDEX_FROM_END_TOOLTIP": "%1 es el último elemento.", - "LISTS_GET_INDEX_TOOLTIP_GET_FROM": "Devuelve el elemento en la posición especificada en la lista.", + "LISTS_GET_INDEX_TOOLTIP_GET_FROM": "Devuelve el elemento en la posición especificada en una lista.", "LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "Devuelve el primer elemento de una lista.", "LISTS_GET_INDEX_TOOLTIP_GET_LAST": "Devuelve el último elemento de una lista.", "LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "Devuelve un elemento aleatorio en una lista.", - "LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "Elimina y devuelve el elemento en la posición especificada en la lista.", + "LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM": "Elimina y devuelve el elemento en la posición especificada en una lista.", "LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST": "Elimina y devuelve el primer elemento de una lista.", "LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST": "Elimina y devuelve el último elemento de una lista.", "LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM": "Elimina y devuelve un elemento aleatorio en una lista.", - "LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "Elimina el elemento en la posición especificada en la lista.", + "LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM": "Elimina el elemento en la posición especificada en una lista.", "LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST": "Elimina el primer elemento de una lista.", "LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "Elimina el último elemento de una lista.", "LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "Elimina un elemento aleatorio en una lista.", @@ -263,7 +263,7 @@ "LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "Establece el primer elemento de una lista.", "LISTS_SET_INDEX_TOOLTIP_SET_LAST": "Establece el último elemento de una lista.", "LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "Establece un elemento aleatorio en una lista.", - "LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "Inserta el elemento en la posición especificada en la lista.", + "LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "Inserta el elemento en la posición especificada en una lista.", "LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "Inserta el elemento al inicio de una lista.", "LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "Añade el elemento al final de una lista.", "LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "Inserta el elemento aleatoriamente en una lista.", diff --git a/msg/json/he.json b/msg/json/he.json index fe2705e07..7eb0aaeb9 100644 --- a/msg/json/he.json +++ b/msg/json/he.json @@ -168,6 +168,7 @@ "TEXT_CREATE_JOIN_TITLE_JOIN": "צירוף", "TEXT_APPEND_TO": "אל", "TEXT_APPEND_APPENDTEXT": "הוספת טקסט", + "TEXT_INDEXOF_TOOLTIP": "מחזירה את האינדקס של המופע הראשון/האחרון בטקסט הראשון לתוך הטקסט השני. מחזירה %1 אם הטקסט אינו נמצא.", "TEXT_GET_SUBSTRING_END_FROM_START": "לאות #", "TEXT_GET_SUBSTRING_END_FROM_END": "לאות # מהסוף", "TEXT_CHANGECASE_OPERATOR_UPPERCASE": "לאותיות גדולות (עבור טקסט באנגלית)", @@ -199,7 +200,7 @@ "LISTS_INLIST": "ברשימה", "LISTS_INDEX_OF_FIRST": "מחזירה את המיקום הראשון של פריט ברשימה", "LISTS_INDEX_OF_LAST": "מחזירה את המיקום האחרון של פריט ברשימה", - "LISTS_INDEX_OF_TOOLTIP": "מחזירה את האינדקס של המופע ראשון/אחרון של הפריט ברשימה. מחזירה %1 אם הפריט אינו נמצא.", + "LISTS_INDEX_OF_TOOLTIP": "מחזירה את האינדקס של המופע הראשון/האחרון של הפריט ברשימה. מחזירה %1 אם הפריט אינו נמצא.", "LISTS_GET_INDEX_GET": "לקבל", "LISTS_GET_INDEX_GET_REMOVE": "קבל ומחק", "LISTS_GET_INDEX_REMOVE": "הסרה", diff --git a/msg/json/ko.json b/msg/json/ko.json index c0de5c003..ab12b36f0 100644 --- a/msg/json/ko.json +++ b/msg/json/ko.json @@ -214,7 +214,7 @@ "TEXT_ISEMPTY_TITLE": "%1이 비어 있습니다", "TEXT_ISEMPTY_TOOLTIP": "입력된 문장이, 빈 문장(\"\")이면 참(true) 값을 돌려줍니다.", "TEXT_INDEXOF_HELPURL": "https://github.com/google/blockly/wiki/Text#finding-text", - "TEXT_INDEXOF_TOOLTIP": "어떤 문장이 가장 처음 나타난 위치 또는, 가장 마지막으로 나타난 위치를 찾아 돌려줍니다. 찾는 문장이 없는 경우는 %1 값을 돌려줌.", + "TEXT_INDEXOF_TOOLTIP": "두 번째 텍스트에서 첫 번째 텍스트가 처음 또는 마지막으로 발생한 색인 위치를 반환합니다. 텍스트가 없으면 %1을 반환합니다.", "TEXT_INDEXOF_INPUT_INTEXT": "문장", "TEXT_INDEXOF_OPERATOR_FIRST": "에서 다음 문장이 처음으로 나타난 위치 찾기 :", "TEXT_INDEXOF_OPERATOR_LAST": "에서 다음 문장이 마지막으로 나타난 위치 찾기 :", @@ -278,7 +278,7 @@ "LISTS_INDEX_OF_HELPURL": "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list", "LISTS_INDEX_OF_FIRST": "처음으로 나타난 위치", "LISTS_INDEX_OF_LAST": "마지막으로 나타난 위치", - "LISTS_INDEX_OF_TOOLTIP": "아이템이 나타난 처음 또는 마지막 위치를 찾아 돌려줍니다. 아이템이 없으면 %1이 반환됩니다.", + "LISTS_INDEX_OF_TOOLTIP": "목록에서 항목이 처음 또는 마지막으로 발생한 색인 위치를 반환합니다. 항목이 없으면 %1을 반환합니다.", "LISTS_GET_INDEX_GET": "가져오기", "LISTS_GET_INDEX_GET_REMOVE": "잘라 내기", "LISTS_GET_INDEX_REMOVE": "삭제", @@ -310,7 +310,7 @@ "LISTS_SET_INDEX_TOOLTIP_SET_FIRST": "첫 번째 위치의 아이템으로 설정합니다.", "LISTS_SET_INDEX_TOOLTIP_SET_LAST": "마지막 아이템으로 설정합니다.", "LISTS_SET_INDEX_TOOLTIP_SET_RANDOM": "목록에서 임의 위치의 아이템을 설정합니다.", - "LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "아이템을 리스트의 특정 위치에 삽입합니다.", + "LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "목록의 특정 위치에 항목을 삽입합니다.", "LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST": "항목을 목록의 처음 위치에 삽입합니다.", "LISTS_SET_INDEX_TOOLTIP_INSERT_LAST": "리스트의 마지막에 아이템을 추가합니다.", "LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM": "목록에서 임의 위치에 아이템을 삽입합니다.", diff --git a/msg/json/lb.json b/msg/json/lb.json index ff82c489b..16c1fd068 100644 --- a/msg/json/lb.json +++ b/msg/json/lb.json @@ -106,6 +106,7 @@ "LISTS_GET_INDEX_FIRST": "éischt", "LISTS_GET_INDEX_LAST": "lescht", "LISTS_GET_INDEX_RANDOM": "Zoufall", + "LISTS_INDEX_FROM_START_TOOLTIP": "%1 ass dat éischt Element.", "LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "Schéckt en zoufällegt Element aus enger Lëscht zréck.", "LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "Hëlt dat lescht Element aus enger Lëscht eraus.", "LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "Hëlt en zoufällegt Element aus enger Lëscht eraus.", diff --git a/msg/json/lt.json b/msg/json/lt.json index 58ddf6f43..4b13cd71f 100644 --- a/msg/json/lt.json +++ b/msg/json/lt.json @@ -24,6 +24,8 @@ "DISABLE_BLOCK": "Išjungti bloką", "ENABLE_BLOCK": "Įjungti bloką", "HELP": "Pagalba", + "UNDO": "Anuliuoti", + "REDO": "Atkurti", "CHANGE_VALUE_TITLE": "Keisti reikšmę:", "NEW_VARIABLE": "Naujas kintamasis...", "NEW_VARIABLE_TITLE": "Naujo kintamojo pavadinimas:", @@ -70,6 +72,7 @@ "CONTROLS_IF_IF_TOOLTIP": "Galite pridėt/pašalinti/pertvarkyti sąlygų \"šakas\".", "CONTROLS_IF_ELSEIF_TOOLTIP": "Pridėti sąlygą „jei“ blokui.", "CONTROLS_IF_ELSE_TOOLTIP": "Pridėti veiksmų vykdymo variantą/\"šaką\", kai netenkinama nė viena sąlyga.", + "LOGIC_COMPARE_HELPURL": "https://en.wikipedia.org/wiki/Inequality_(mathematics)", "LOGIC_COMPARE_TOOLTIP_EQ": "Tenkinama, jei abu reiškiniai lygūs.", "LOGIC_OPERATION_TOOLTIP_AND": "Bus teisinga, kai abi sąlygos bus tenkinamos.", "LOGIC_OPERATION_AND": "ir", @@ -107,6 +110,7 @@ "MATH_TRIG_TOOLTIP_ASIN": "Grąžinti skaičiaus arksinusą.", "MATH_TRIG_TOOLTIP_ACOS": "Grąžinti skaičiaus arkkosinusą.", "MATH_TRIG_TOOLTIP_ATAN": "Grąžinti skaičiaus arktangentą.", + "MATH_CONSTANT_HELPURL": "https://lt.wikipedia.org/wiki/Matematin%C4%97_konstanta", "MATH_IS_EVEN": "yra lyginis", "MATH_IS_ODD": "yra nelyginis", "MATH_IS_PRIME": "yra pirminis", @@ -115,8 +119,11 @@ "MATH_IS_NEGATIVE": "yra neigiamas", "MATH_IS_DIVISIBLE_BY": "yra dalus iš", "MATH_IS_TOOLTIP": "Patikrina skaičiaus savybę: (ne)lyginis/pirminis/sveikasis/teigiamas/neigiamas/dalus iš x.", + "MATH_CHANGE_HELPURL": "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter", "MATH_CHANGE_TITLE": "padidink %1 (emptypage) %2", "MATH_CHANGE_TOOLTIP": "Prideda skaičių prie kintamojo '%1'. Kai skaičius neigiamas - gaunasi atimtis.", + "MATH_ROUND_HELPURL": "https://lt.wikipedia.org/wiki/Apvalinimas", + "MATH_ROUND_TOOLTIP": "Suapvalinti skaičių į žemesnę ar aukštesnę reikšmę.", "MATH_ROUND_OPERATOR_ROUND": "apvalink", "MATH_ROUND_OPERATOR_ROUNDUP": "apvalink aukštyn", "MATH_ROUND_OPERATOR_ROUNDDOWN": "apvalink žemyn", @@ -132,9 +139,12 @@ "MATH_ONLIST_OPERATOR_STD_DEV": "standartinis nuokrypis sąraše", "MATH_ONLIST_OPERATOR_RANDOM": "atsitiktinis elementas iš sąrašo", "MATH_ONLIST_TOOLTIP_RANDOM": "Grąžinti atsitiktinį elementą iš sąrašo.", + "MATH_MODULO_HELPURL": "https://en.wikipedia.org/wiki/Modulo_operation", "MATH_MODULO_TITLE": "dalybos liekana %1 ÷ %2", "MATH_CONSTRAIN_TITLE": "apribok %1 tarp %2 ir %3", + "MATH_RANDOM_INT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation", "MATH_RANDOM_INT_TITLE": "atsitiktinis sveikas sk. nuo %1 iki %2", + "MATH_RANDOM_FLOAT_HELPURL": "https://en.wikipedia.org/wiki/Random_number_generation", "MATH_RANDOM_FLOAT_TITLE_RANDOM": "atsitiktinė trupmena", "MATH_RANDOM_FLOAT_TOOLTIP": "Atsitiktinė trupmena nuo 0 (imtinai) iki 1 (neimtinai).", "TEXT_TEXT_TOOLTIP": "Tekstas (arba žodis, ar raidė)", @@ -219,7 +229,9 @@ "PROCEDURES_DEFRETURN_TOOLTIP": "Sukuria funkciją - komandą, kuri ne tik atlieka veiksmus bet ir pateikia (grąžina/duoda) rezultatą.", "PROCEDURES_ALLOW_STATEMENTS": "leisti vidinius veiksmus", "PROCEDURES_DEF_DUPLICATE_WARNING": "Ši komanda turi du vienodus gaunamų duomenų pavadinimus.", + "PROCEDURES_CALLNORETURN_HELPURL": "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29", "PROCEDURES_CALLNORETURN_TOOLTIP": "Vykdyti sukurtą komandą \"%1\".", + "PROCEDURES_CALLRETURN_HELPURL": "https://en.wikipedia.org/wiki/Procedure_%28computer_science%29", "PROCEDURES_CALLRETURN_TOOLTIP": "Įvykdyti komandą \"%1\" ir naudoti jos suskaičiuotą (atiduotą) reikšmę.", "PROCEDURES_MUTATORCONTAINER_TITLE": "gaunami duomenys (parametrai)", "PROCEDURES_MUTATORCONTAINER_TOOLTIP": "Tvarkyti komandos gaunamus duomenis (parametrus).", diff --git a/msg/json/pt.json b/msg/json/pt.json index 1098cf152..52c4ea31c 100644 --- a/msg/json/pt.json +++ b/msg/json/pt.json @@ -198,7 +198,7 @@ "TEXT_LENGTH_TOOLTIP": "Devolve o número de letras (incluindo espaços) do texto fornecido.", "TEXT_ISEMPTY_TITLE": "%1 está vazio", "TEXT_ISEMPTY_TOOLTIP": "Retorna verdadeiro se o texto fornecido estiver vazio.", - "TEXT_INDEXOF_TOOLTIP": "Retorna a posição da primeira/última ocorrência do primeiro texto no segundo texto. Retorna %1 se o texto não for encontrado.", + "TEXT_INDEXOF_TOOLTIP": "Retorna a posição da primeira/última ocorrência do primeiro texto no segundo texto. Retorna %1 se o texto não for encontrado.", "TEXT_INDEXOF_INPUT_INTEXT": "no texto", "TEXT_INDEXOF_OPERATOR_FIRST": "primeira ocorrência do texto", "TEXT_INDEXOF_OPERATOR_LAST": "última ocorrência do texto", diff --git a/msg/json/ta.json b/msg/json/ta.json index bddb09675..58b755a6d 100644 --- a/msg/json/ta.json +++ b/msg/json/ta.json @@ -176,6 +176,7 @@ "TEXT_LENGTH_TOOLTIP": "தொடரில் உள்ள எழுத்துக்களின் (இடைவெளிகளையும் சேர்த்து) எண்ணிகையை பின்கொடு.", "TEXT_ISEMPTY_TITLE": "%1 காலியானது", "TEXT_ISEMPTY_TOOLTIP": "காலியானது என்றால் மெய் மதிப்பை பின்கொடு", + "TEXT_INDEXOF_TOOLTIP": "இரண்டாவது உரையில் முதல் உரையின் முதல்/கடை இருக்கை குறிஎண்ணை பின்கொடு.", "TEXT_INDEXOF_INPUT_INTEXT": "உரையில்", "TEXT_INDEXOF_OPERATOR_FIRST": "உரையில் முதல் தோற்ற இடத்தை பின்கொடு", "TEXT_INDEXOF_OPERATOR_LAST": "உரையில் கடைசி தோற்ற இடத்தை பின்கொடு", From 74e905c611a71702aa2436305b3479ec595e8ea7 Mon Sep 17 00:00:00 2001 From: Rodrigo Queiro Date: Fri, 15 Jul 2016 10:35:45 +0200 Subject: [PATCH 02/71] Check flyout in isDragging() We also have to record startFlyout_ on background scrolls - before dragMode_ wasn't being reset by terminateDrag() for background scrolls, which would suppress clicks from that point on. Fixes #476. --- core/flyout.js | 1 + core/workspace_svg.js | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/core/flyout.js b/core/flyout.js index 0647b7219..0d1fa0407 100644 --- a/core/flyout.js +++ b/core/flyout.js @@ -774,6 +774,7 @@ Blockly.Flyout.prototype.onMouseDown_ = function(e) { this.dragMode_ = Blockly.DRAG_FREE; this.startDragMouseY_ = e.clientY; this.startDragMouseX_ = e.clientX; + Blockly.Flyout.startFlyout_ = this; Blockly.Flyout.onMouseMoveWrapper_ = Blockly.bindEvent_(document, 'mousemove', this, this.onMouseMove_); Blockly.Flyout.onMouseUpWrapper_ = Blockly.bindEvent_(document, 'mouseup', diff --git a/core/workspace_svg.js b/core/workspace_svg.js index b61c43742..bb04e15bf 100644 --- a/core/workspace_svg.js +++ b/core/workspace_svg.js @@ -715,11 +715,13 @@ Blockly.WorkspaceSvg.prototype.moveDrag = function(e) { }; /** - * Is the user currently dragging a block or scrolling the workspace? + * Is the user currently dragging a block or scrolling the flyout/workspace? * @return {boolean} True if currently dragging or scrolling. */ Blockly.WorkspaceSvg.prototype.isDragging = function() { return Blockly.dragMode_ == Blockly.DRAG_FREE || + (Blockly.Flyout.startFlyout_ && + Blockly.Flyout.startFlyout_.dragMode_ == Blockly.DRAG_FREE) || this.dragMode_ == Blockly.DRAG_FREE; }; From be98f29e18a0c3a5eb1071449165997f3aa8597b Mon Sep 17 00:00:00 2001 From: Sean Lip Date: Fri, 15 Jul 2016 14:43:43 -0700 Subject: [PATCH 03/71] Add support for Home and End keys for navigating the toolbox and workspace trees. --- accessible/tree.service.js | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/accessible/tree.service.js b/accessible/tree.service.js index e464bc788..2c7c54d1e 100644 --- a/accessible/tree.service.js +++ b/accessible/tree.service.js @@ -222,9 +222,21 @@ blocklyApp.TreeService = ng.core } e.preventDefault(); e.stopPropagation(); - } else if (e.keyCode >= 37 && e.keyCode <= 40) { - // Arrow keys. - if (e.keyCode == 37) { + } else if (e.keyCode >= 35 && e.keyCode <= 40) { + // End, home, and arrow keys. + if (e.keyCode == 35) { + // End key. Go to the last sibling in the subtree. + var finalSibling = this.getFinalSibling(activeDesc); + if (finalSibling) { + this.setActiveDesc(finalSibling.id, treeId); + } + } else if (e.keyCode == 36) { + // Home key. Go to the first sibling in the subtree. + var initialSibling = this.getInitialSibling(activeDesc); + if (initialSibling) { + this.setActiveDesc(initialSibling.id, treeId); + } + } else if (e.keyCode == 37) { // Left arrow key. Go up a level, if possible. var nextNode = activeDesc.parentNode; if (this.isButtonOrFieldNode_(activeDesc)) { @@ -278,6 +290,26 @@ blocklyApp.TreeService = ng.core return null; } }, + getFinalSibling: function(element) { + while (true) { + var nextSibling = this.getNextSibling(element); + if (nextSibling && nextSibling.id != element.id) { + element = nextSibling; + } else { + return element; + } + } + }, + getInitialSibling: function(element) { + while (true) { + var previousSibling = this.getPreviousSibling(element); + if (previousSibling && previousSibling.id != element.id) { + element = previousSibling; + } else { + return element; + } + } + }, getNextSibling: function(element) { if (element.nextElementSibling) { // If there is a sibling, find the list element child of the sibling. From 4f498dc99c13ac11b3d008e92875c1087dc2f198 Mon Sep 17 00:00:00 2001 From: Neil Fraser Date: Fri, 15 Jul 2016 14:55:00 -0700 Subject: [PATCH 04/71] Make tooltips reflect from-end indexing behaviour. --- blocks/lists.js | 10 ++-------- blocks/text.js | 12 +++++++++++- core/workspace_svg.js | 2 +- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/blocks/lists.js b/blocks/lists.js index 0d23db05f..55dfac025 100644 --- a/blocks/lists.js +++ b/blocks/lists.js @@ -389,12 +389,9 @@ Blockly.Blocks['lists_getIndex'] = { tooltip = Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM; break; } - if (where == 'FROM_START') { + if (where == 'FROM_START' || where == 'FROM_END') { tooltip += ' ' + Blockly.Msg.LISTS_INDEX_FROM_START_TOOLTIP .replace('%1', Blockly.Blocks.ONE_BASED_INDEXING ? '#1' : '#0'); - } else if (where == 'FROM_END') { - tooltip += ' ' + Blockly.Msg.LISTS_INDEX_FROM_END_TOOLTIP - .replace('%1', '#1'); // The end is always 1-indexed. } return tooltip; }); @@ -552,12 +549,9 @@ Blockly.Blocks['lists_setIndex'] = { tooltip = Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM; break; } - if (where == 'FROM_START') { + if (where == 'FROM_START' || where == 'FROM_END') { tooltip += ' ' + Blockly.Msg.LISTS_INDEX_FROM_START_TOOLTIP .replace('%1', Blockly.Blocks.ONE_BASED_INDEXING ? '#1' : '#0'); - } else if (where == 'FROM_END') { - tooltip += ' ' + Blockly.Msg.LISTS_INDEX_FROM_END_TOOLTIP - .replace('%1', '#1'); // The end is always 1-indexed. } return tooltip; }); diff --git a/blocks/text.js b/blocks/text.js index 23ff52b32..c26bb578b 100644 --- a/blocks/text.js +++ b/blocks/text.js @@ -349,7 +349,17 @@ Blockly.Blocks['text_charAt'] = { this.appendDummyInput('AT'); this.setInputsInline(true); this.updateAt_(true); - this.setTooltip(Blockly.Msg.TEXT_CHARAT_TOOLTIP); + // Assign 'this' to a variable for use in the tooltip closure below. + var thisBlock = this; + this.setTooltip(function() { + var where = thisBlock.getFieldValue('WHERE'); + var tooltip = Blockly.Msg.TEXT_CHARAT_TOOLTIP; + if (where == 'FROM_START' || where == 'FROM_END') { + tooltip += ' ' + Blockly.Msg.LISTS_INDEX_FROM_END_TOOLTIP + .replace('%1', Blockly.Blocks.ONE_BASED_INDEXING ? '#1' : '#0'); + } + return tooltip; + }); }, /** * Create XML to represent whether there is an 'AT' input. diff --git a/core/workspace_svg.js b/core/workspace_svg.js index b61c43742..73bd6afe1 100644 --- a/core/workspace_svg.js +++ b/core/workspace_svg.js @@ -984,7 +984,7 @@ Blockly.WorkspaceSvg.prototype.preloadAudio_ = function() { }; /** - * Play an audio file at specified value. If volume is not specified, + * Play a named sound at specified volume. If volume is not specified, * use full volume (1). * @param {string} name Name of sound. * @param {number=} opt_volume Volume of sound (0-1). From 311907cb6a339953891a19aa733a4eb10f404a3b Mon Sep 17 00:00:00 2001 From: Sean Lip Date: Fri, 15 Jul 2016 16:40:22 -0700 Subject: [PATCH 05/71] Disable input fields in the toolbox. --- accessible/field.component.js | 8 +++++--- accessible/toolbox-tree.component.js | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/accessible/field.component.js b/accessible/field.component.js index bb6b4cf07..9b1a35143 100644 --- a/accessible/field.component.js +++ b/accessible/field.component.js @@ -31,7 +31,8 @@ blocklyApp.FieldComponent = ng.core
  • - +
  • -
  • @@ -59,7 +61,7 @@ blocklyApp.FieldComponent = ng.core `, - inputs: ['field', 'level', 'index', 'parentId'], + inputs: ['field', 'level', 'index', 'parentId', 'disabled'], pipes: [blocklyApp.TranslatePipe] }) .Class({ diff --git a/accessible/toolbox-tree.component.js b/accessible/toolbox-tree.component.js index 64320458d..15dfa220a 100644 --- a/accessible/toolbox-tree.component.js +++ b/accessible/toolbox-tree.component.js @@ -72,8 +72,8 @@ blocklyApp.ToolboxTreeComponent = ng.core
    + [attr.aria-level]="level+1" [field]="field" + [level]="level+1" [disabled]="true"> Date: Fri, 15 Jul 2016 16:54:03 -0700 Subject: [PATCH 06/71] Implement correct keystroke handling for text input fields. --- accessible/tree.service.js | 154 +++++++++++++++++++++---------------- 1 file changed, 87 insertions(+), 67 deletions(-) diff --git a/accessible/tree.service.js b/accessible/tree.service.js index 2c7c54d1e..4bc9f4156 100644 --- a/accessible/tree.service.js +++ b/accessible/tree.service.js @@ -200,76 +200,96 @@ blocklyApp.TreeService = ng.core return; } - var isFocusingIntoField = false; + if (document.activeElement.tagName == 'INPUT') { + // For input fields, only Esc and Tab keystrokes are handled specially. + if (e.keyCode == 27 || e.keyCode == 9) { + // For Esc and Tab keys, the focus is removed from the input field. + this.focusOnCurrentTree_(treeId); - if (e.keyCode == 13) { - // Enter key. The user wants to interact with a child. - 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(); + // In addition, for Tab keys, the user tabs to the previous/next tree. + if (e.keyCode == 9) { + if (e.shiftKey) { + this.focusOnPreviousTree_(treeId); + } else { + this.focusOnNextTree_(treeId); + } } - } - } else if (e.keyCode == 9) { - // Tab key. - if (e.shiftKey) { - this.focusOnPreviousTree_(treeId); - } else { - this.focusOnNextTree_(treeId); - } - e.preventDefault(); - e.stopPropagation(); - } else if (e.keyCode >= 35 && e.keyCode <= 40) { - // End, home, and arrow keys. - if (e.keyCode == 35) { - // End key. Go to the last sibling in the subtree. - var finalSibling = this.getFinalSibling(activeDesc); - if (finalSibling) { - this.setActiveDesc(finalSibling.id, treeId); - } - } else if (e.keyCode == 36) { - // Home key. Go to the first sibling in the subtree. - var initialSibling = this.getInitialSibling(activeDesc); - if (initialSibling) { - this.setActiveDesc(initialSibling.id, treeId); - } - } else if (e.keyCode == 37) { - // Left arrow key. Go up a level, if possible. - 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) { - // Up arrow key. Go to the previous sibling, if possible. - var prevSibling = this.getPreviousSibling(activeDesc); - if (prevSibling) { - this.setActiveDesc(prevSibling.id, treeId); - } - } else if (e.keyCode == 39) { - // Right arrow key. Go down a level, if possible. - var firstChild = this.getFirstChild(activeDesc); - if (firstChild) { - this.setActiveDesc(firstChild.id, treeId); - } - } else if (e.keyCode == 40) { - // Down arrow key. Go to the next sibling, if possible. - var nextSibling = this.getNextSibling(activeDesc); - if (nextSibling) { - this.setActiveDesc(nextSibling.id, treeId); - } - } - e.preventDefault(); - e.stopPropagation(); + e.preventDefault(); + e.stopPropagation(); + } + } else { + // Outside an input field, Enter, Tab and navigation keys are all + // recognized. + if (e.keyCode == 13) { + // Enter key. The user wants to interact with a button or an input + // field. + if (activeDesc.children.length == 1) { + var child = activeDesc.children[0]; + if (child.tagName == 'BUTTON') { + child.click(); + } else if (child.tagName == 'INPUT') { + child.focus(); + } + } + } else if (e.keyCode == 9) { + // Tab key. + if (e.shiftKey) { + this.focusOnPreviousTree_(treeId); + } else { + this.focusOnNextTree_(treeId); + } + e.preventDefault(); + e.stopPropagation(); + } else if (e.keyCode >= 35 && e.keyCode <= 40) { + // End, home, and arrow keys. + if (e.keyCode == 35) { + // End key. Go to the last sibling in the subtree. + var finalSibling = this.getFinalSibling(activeDesc); + if (finalSibling) { + this.setActiveDesc(finalSibling.id, treeId); + } + } else if (e.keyCode == 36) { + // Home key. Go to the first sibling in the subtree. + var initialSibling = this.getInitialSibling(activeDesc); + if (initialSibling) { + this.setActiveDesc(initialSibling.id, treeId); + } + } else if (e.keyCode == 37) { + // Left arrow key. Go up a level, if possible. + 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) { + // Up arrow key. Go to the previous sibling, if possible. + var prevSibling = this.getPreviousSibling(activeDesc); + if (prevSibling) { + this.setActiveDesc(prevSibling.id, treeId); + } + } else if (e.keyCode == 39) { + // Right arrow key. Go down a level, if possible. + var firstChild = this.getFirstChild(activeDesc); + if (firstChild) { + this.setActiveDesc(firstChild.id, treeId); + } + } else if (e.keyCode == 40) { + // Down arrow key. Go to the next sibling, if possible. + var nextSibling = this.getNextSibling(activeDesc); + if (nextSibling) { + this.setActiveDesc(nextSibling.id, treeId); + } + } + + e.preventDefault(); + e.stopPropagation(); + } } }, getFirstChild: function(element) { From a76635d3525fda2b4c0267234167d75e164ec340 Mon Sep 17 00:00:00 2001 From: Neil Fraser Date: Fri, 15 Jul 2016 16:28:33 -0700 Subject: [PATCH 07/71] Fix line wrapping in Dart comments. --- generators/dart.js | 1 + 1 file changed, 1 insertion(+) diff --git a/generators/dart.js b/generators/dart.js index 6fb1236d4..feec82a2c 100644 --- a/generators/dart.js +++ b/generators/dart.js @@ -191,6 +191,7 @@ Blockly.Dart.scrub_ = function(block, code) { if (!block.outputConnection || !block.outputConnection.targetConnection) { // Collect comment for this block. var comment = block.getCommentText(); + comment = Blockly.utils.wrap(comment, Blockly.Dart.COMMENT_WRAP - 3); if (comment) { if (block.getProcedureDef) { // Use documentation comment for function comments. From 5852f8e7e134584217a2e9878e97b188bdaac743 Mon Sep 17 00:00:00 2001 From: Neil Fraser Date: Fri, 15 Jul 2016 16:28:39 -0700 Subject: [PATCH 08/71] Fix nested disabled blocks in disableOrphans. --- core/events.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/events.js b/core/events.js index f78222d03..ac78aa3a3 100644 --- a/core/events.js +++ b/core/events.js @@ -802,10 +802,10 @@ Blockly.Events.disableOrphans = function(event) { var block = workspace.getBlockById(event.blockId); if (block) { if (block.getParent() && !block.getParent().disabled) { - do { - block.setDisabled(false); - block = block.getNextBlock(); - } while (block); + var children = block.getDescendants(); + for (var i = 0, child; child = children[i]; i++) { + child.setDisabled(false); + } } else if ((block.outputConnection || block.previousConnection) && Blockly.dragMode_ == Blockly.DRAG_NONE) { do { From 8c48436c8f162171fe0572cb04a7ff181480bd61 Mon Sep 17 00:00:00 2001 From: Neil Fraser Date: Fri, 15 Jul 2016 20:05:45 -0700 Subject: [PATCH 09/71] Fix validation on number field. --- core/field_number.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/field_number.js b/core/field_number.js index cd773cb87..94cda5108 100644 --- a/core/field_number.js +++ b/core/field_number.js @@ -31,7 +31,7 @@ goog.require('goog.math'); /** * Class for an editable number field. - * @param {string} value The initial content of the field. + * @param {number|string} value The initial content of the field. * @param {number|string|undefined} opt_min Minimum value. * @param {number|string|undefined} opt_max Maximum value. * @param {number|string|undefined} opt_precision Precision for value. @@ -68,7 +68,7 @@ Blockly.FieldNumber.prototype.setConstraints = function(min, max, precision) { this.min_ = isNaN(min) ? -Infinity : min; max = parseFloat(max); this.max_ = isNaN(max) ? Infinity : max; - this.setValue(this.callValidator(this.getValue)); + this.setValue(this.callValidator(this.getValue())); }; /** From 5c2c4d8400e672636d33f910117683137a667a6b Mon Sep 17 00:00:00 2001 From: Neil Fraser Date: Fri, 15 Jul 2016 20:59:20 -0700 Subject: [PATCH 10/71] Refactor validators to survive aggressive Closure compression. --- core/events.js | 3 +-- core/field.js | 41 +++++++++++++++++++++++------------------ core/field_angle.js | 5 ++--- core/field_number.js | 3 +-- core/field_variable.js | 3 +-- 5 files changed, 28 insertions(+), 27 deletions(-) diff --git a/core/events.js b/core/events.js index ac78aa3a3..1d1e2b70e 100644 --- a/core/events.js +++ b/core/events.js @@ -554,8 +554,7 @@ Blockly.Events.Change.prototype.run = function(forward) { if (field) { // Run the validator for any side-effects it may have. // The validator's opinion on validity is ignored. - var validator = field.getValidator(); - validator && validator.call(field, value); + field.callValidator(value); field.setValue(value); } else { console.warn("Can't set non-existant field: " + this.name); diff --git a/core/field.js b/core/field.js index b6cff255b..00a717c27 100644 --- a/core/field.js +++ b/core/field.js @@ -236,6 +236,15 @@ Blockly.Field.prototype.getValidator = function() { return this.validator_; }; +/** + * Validates a change. Does nothing. Subclasses may override this. + * @param {string} text The user's text. + * @return {string} No change needed. + */ +Blockly.Field.prototype.classValidator = function(text) { + return text; +}; + /** * Calls the validation function for this field, as well as all the validation * function for the field's class and its parents. @@ -243,25 +252,21 @@ Blockly.Field.prototype.getValidator = function() { * @return {?string} Revised text, or null if invalid. */ Blockly.Field.prototype.callValidator = function(text) { - // Collect a list of validators, from Field, through to the subclass, ending - // with the user's validator. - var validators = [this.getValidator()]; - var fieldClass = this.constructor; - while (fieldClass) { - validators.unshift(fieldClass.classValidator); - fieldClass = fieldClass.superClass_; + var classResult = this.classValidator(text); + if (classResult === null) { + // Class validator rejects value. Game over. + return null; + } else if (classResult !== undefined) { + text = classResult; } - // Call each validator in turn, allowing each to rewrite or reject. - for (var i = 0; i < validators.length; i++) { - var validator = validators[i]; - if (validator) { - var result = validator.call(this, text); - if (result === null) { - // Validator rejects value. Game over. - return null; - } else if (result !== undefined) { - text = result; - } + var userValidator = this.getValidator(); + if (userValidator) { + var userResult = userValidator(text); + if (userResult === null) { + // User validator rejects value. Game over. + return null; + } else if (userResult !== undefined) { + text = userResult; } } return text; diff --git a/core/field_angle.js b/core/field_angle.js index 422191730..a294948e9 100644 --- a/core/field_angle.js +++ b/core/field_angle.js @@ -205,7 +205,7 @@ Blockly.FieldAngle.prototype.onMouseMove = function(e) { angle = Math.round(angle / Blockly.FieldAngle.ROUND) * Blockly.FieldAngle.ROUND; } - angle = Blockly.FieldAngle.classValidator(angle); + angle = this.callValidator(angle); Blockly.FieldTextInput.htmlInput_.value = angle; this.setValue(angle); this.validate_(); @@ -274,9 +274,8 @@ Blockly.FieldAngle.prototype.updateGraph_ = function() { * Ensure that only an angle may be entered. * @param {string} text The user's text. * @return {?string} A string representing a valid angle, or null if invalid. - * @this {!Blockly.FieldAngle} */ -Blockly.FieldAngle.classValidator = function(text) { +Blockly.FieldAngle.prototype.classValidator = function(text) { if (text === null) { return null; } diff --git a/core/field_number.js b/core/field_number.js index 94cda5108..3eb99d398 100644 --- a/core/field_number.js +++ b/core/field_number.js @@ -75,9 +75,8 @@ Blockly.FieldNumber.prototype.setConstraints = function(min, max, precision) { * Ensure that only a number in the correct range may be entered. * @param {string} text The user's text. * @return {?string} A string representing a valid number, or null if invalid. - * @this {!Blockly.FieldNumber} */ -Blockly.FieldNumber.classValidator = function(text) { +Blockly.FieldNumber.prototype.classValidator = function(text) { if (text === null) { return null; } diff --git a/core/field_variable.js b/core/field_variable.js index 3c6491794..f6cfd4ecb 100644 --- a/core/field_variable.js +++ b/core/field_variable.js @@ -127,9 +127,8 @@ Blockly.FieldVariable.dropdownCreate = function() { * @return {null|undefined|string} An acceptable new variable name, or null if * change is to be either aborted (cancel button) or has been already * handled (rename), or undefined if an existing variable was chosen. - * @this {!Blockly.FieldVariable} */ -Blockly.FieldVariable.classValidator = function(text) { +Blockly.FieldVariable.prototype.classValidator = function(text) { function promptName(promptText, defaultText) { Blockly.hideChaff(); var newVar = window.prompt(promptText, defaultText); From 08f55575725d8213d12041cfeed4668c719200f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niklas=20Laxstr=C3=B6m?= Date: Mon, 18 Jul 2016 08:23:29 +0200 Subject: [PATCH 11/71] Localisation updates from https://translatewiki.net. --- msg/json/hu.json | 2 +- msg/json/lb.json | 1 + msg/json/lt.json | 4 ++++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/msg/json/hu.json b/msg/json/hu.json index be22129d5..2ef04a974 100644 --- a/msg/json/hu.json +++ b/msg/json/hu.json @@ -238,7 +238,7 @@ "LISTS_INLIST": "A(z)", "LISTS_INDEX_OF_FIRST": "listában első előfordulásaː", "LISTS_INDEX_OF_LAST": "listában utolsó előfordulásaː", - "LISTS_INDEX_OF_TOOLTIP": "A megadott elem első vagy utolsó előfordulásával tér vissza. %1-val tér vissza, ha nem talál ilyen elemet.", + "LISTS_INDEX_OF_TOOLTIP": "A megadott elem első vagy utolsó előfordulásával tér vissza. Ha nem talál ilyen elemet, akkor %1 a visszatérési érték.", "LISTS_GET_INDEX_GET": "listából értéke", "LISTS_GET_INDEX_GET_REMOVE": "listából kivétele", "LISTS_GET_INDEX_REMOVE": "listából törlése", diff --git a/msg/json/lb.json b/msg/json/lb.json index 16c1fd068..129fba60c 100644 --- a/msg/json/lb.json +++ b/msg/json/lb.json @@ -107,6 +107,7 @@ "LISTS_GET_INDEX_LAST": "lescht", "LISTS_GET_INDEX_RANDOM": "Zoufall", "LISTS_INDEX_FROM_START_TOOLTIP": "%1 ass dat éischt Element.", + "LISTS_INDEX_FROM_END_TOOLTIP": "%1 ass dat éischt Element.", "LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "Schéckt en zoufällegt Element aus enger Lëscht zréck.", "LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST": "Hëlt dat lescht Element aus enger Lëscht eraus.", "LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM": "Hëlt en zoufällegt Element aus enger Lëscht eraus.", diff --git a/msg/json/lt.json b/msg/json/lt.json index 4b13cd71f..f8efcb73b 100644 --- a/msg/json/lt.json +++ b/msg/json/lt.json @@ -205,12 +205,16 @@ "LISTS_GET_INDEX_FIRST": "pirmas", "LISTS_GET_INDEX_LAST": "paskutinis", "LISTS_GET_INDEX_RANDOM": "atsitiktinis", + "LISTS_INDEX_FROM_START_TOOLTIP": "%1 yra pirmasis objektas.", + "LISTS_INDEX_FROM_END_TOOLTIP": "%1 yra paskutinis objektas.", + "LISTS_GET_INDEX_TOOLTIP_GET_FROM": "Gražina objektą į nurodyta poziciją sąraše.", "LISTS_GET_INDEX_TOOLTIP_GET_FIRST": "Grąžina pirmąjį sąrašo elementą.", "LISTS_GET_INDEX_TOOLTIP_GET_LAST": "Grąžina paskutinį elementą iš sąrašo.", "LISTS_GET_INDEX_TOOLTIP_GET_RANDOM": "Grąžina atsitiktinį elementą iš sąrašo.", "LISTS_SET_INDEX_SET": "priskirk elementui", "LISTS_SET_INDEX_INSERT": "įterpk į vietą", "LISTS_SET_INDEX_INPUT_TO": "kaip", + "LISTS_SET_INDEX_TOOLTIP_INSERT_FROM": "Įterpią objektą į nurodytą poziciją sąraše.", "LISTS_GET_SUBLIST_START_FROM_START": "sąrašo dalis nuo #", "LISTS_GET_SUBLIST_START_FROM_END": "sąrašo dalis nuo # nuo galo", "LISTS_GET_SUBLIST_START_FIRST": "sąrašo dalis nuo pradžios", From e03a4a9e30c12bc003735622cfb00b9f70d68e69 Mon Sep 17 00:00:00 2001 From: Neil Fraser Date: Mon, 18 Jul 2016 00:54:34 -0700 Subject: [PATCH 12/71] Fix creation of uneditable blocks. Issue #324. --- core/field.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/field.js b/core/field.js index 00a717c27..9060e8532 100644 --- a/core/field.js +++ b/core/field.js @@ -178,7 +178,7 @@ Blockly.Field.prototype.dispose = function() { * Add or remove the UI indicating if this field is editable or not. */ Blockly.Field.prototype.updateEditable = function() { - if (!this.EDITABLE || !this.sourceBlock_) { + if (!this.EDITABLE || !this.fieldGroup_) { return; } if (this.sourceBlock_.isEditable()) { @@ -261,7 +261,7 @@ Blockly.Field.prototype.callValidator = function(text) { } var userValidator = this.getValidator(); if (userValidator) { - var userResult = userValidator(text); + var userResult = userValidator.call(this, text); if (userResult === null) { // User validator rejects value. Game over. return null; From d9a3569706894b9fbb8dcbb41ef7f7e49d8782df Mon Sep 17 00:00:00 2001 From: Rodrigo Queiro Date: Mon, 18 Jul 2016 16:18:17 +0200 Subject: [PATCH 13/71] Convert createDom calls to createUntypedDom (#481) Unless they could be converted to use goog.dom.TagName, in which case do that. createDom is going to require goog.dom.TagName member as the tagName parameter. This change prepares for that. --- blocks/loops.js | 4 ++-- blocks/procedures.js | 16 ++++++++-------- blocks/variables.js | 4 ++-- core/events.js | 4 ++-- core/field_textinput.js | 4 +++- core/mutator.js | 5 +++-- core/procedures.js | 12 ++++++------ core/toolbox.js | 4 +++- core/tooltip.js | 4 +++- core/variables.js | 8 ++++---- core/widgetdiv.js | 4 +++- core/xml.js | 21 ++++++++++++--------- 12 files changed, 51 insertions(+), 39 deletions(-) diff --git a/blocks/loops.js b/blocks/loops.js index b9bae1e80..c06a7f2de 100644 --- a/blocks/loops.js +++ b/blocks/loops.js @@ -178,9 +178,9 @@ Blockly.Blocks['controls_for'] = { var option = {enabled: true}; var name = this.getFieldValue('VAR'); option.text = Blockly.Msg.VARIABLES_SET_CREATE_GET.replace('%1', name); - var xmlField = goog.dom.createDom('field', null, name); + var xmlField = goog.dom.createUntypedDom('field', null, name); xmlField.setAttribute('name', 'VAR'); - var xmlBlock = goog.dom.createDom('block', null, xmlField); + var xmlBlock = goog.dom.createUntypedDom('block', null, xmlField); xmlBlock.setAttribute('type', 'variables_get'); option.callback = Blockly.ContextMenu.callbackFactory(this, xmlBlock); options.push(option); diff --git a/blocks/procedures.js b/blocks/procedures.js index 82b383b51..17339b025 100644 --- a/blocks/procedures.js +++ b/blocks/procedures.js @@ -295,14 +295,14 @@ Blockly.Blocks['procedures_defnoreturn'] = { var option = {enabled: true}; var name = this.getFieldValue('NAME'); option.text = Blockly.Msg.PROCEDURES_CREATE_DO.replace('%1', name); - var xmlMutation = goog.dom.createDom('mutation'); + var xmlMutation = goog.dom.createUntypedDom('mutation'); xmlMutation.setAttribute('name', name); for (var i = 0; i < this.arguments_.length; i++) { - var xmlArg = goog.dom.createDom('arg'); + var xmlArg = goog.dom.createUntypedDom('arg'); xmlArg.setAttribute('name', this.arguments_[i]); xmlMutation.appendChild(xmlArg); } - var xmlBlock = goog.dom.createDom('block', null, xmlMutation); + var xmlBlock = goog.dom.createUntypedDom('block', null, xmlMutation); xmlBlock.setAttribute('type', this.callType_); option.callback = Blockly.ContextMenu.callbackFactory(this, xmlBlock); options.push(option); @@ -313,9 +313,9 @@ Blockly.Blocks['procedures_defnoreturn'] = { var option = {enabled: true}; var name = this.arguments_[i]; option.text = Blockly.Msg.VARIABLES_SET_CREATE_GET.replace('%1', name); - var xmlField = goog.dom.createDom('field', null, name); + var xmlField = goog.dom.createUntypedDom('field', null, name); xmlField.setAttribute('name', 'VAR'); - var xmlBlock = goog.dom.createDom('block', null, xmlField); + var xmlBlock = goog.dom.createUntypedDom('block', null, xmlField); xmlBlock.setAttribute('type', 'variables_get'); option.callback = Blockly.ContextMenu.callbackFactory(this, xmlBlock); options.push(option); @@ -687,8 +687,8 @@ Blockly.Blocks['procedures_callnoreturn'] = { * * */ - var xml = goog.dom.createDom('xml'); - var block = goog.dom.createDom('block'); + var xml = goog.dom.createUntypedDom('xml'); + var block = goog.dom.createUntypedDom('block'); block.setAttribute('type', this.defType_); var xy = this.getRelativeToSurfaceXY(); var x = xy.x + Blockly.SNAP_RADIUS * (this.RTL ? -1 : 1); @@ -697,7 +697,7 @@ Blockly.Blocks['procedures_callnoreturn'] = { block.setAttribute('y', y); var mutation = this.mutationToDom(); block.appendChild(mutation); - var field = goog.dom.createDom('field'); + var field = goog.dom.createUntypedDom('field'); field.setAttribute('name', 'NAME'); field.appendChild(document.createTextNode(this.getProcedureCall())); block.appendChild(field); diff --git a/blocks/variables.js b/blocks/variables.js index 3b7d99f92..fe8eae21f 100644 --- a/blocks/variables.js +++ b/blocks/variables.js @@ -59,9 +59,9 @@ Blockly.Blocks['variables_get'] = { var option = {enabled: true}; var name = this.getFieldValue('VAR'); option.text = this.contextMenuMsg_.replace('%1', name); - var xmlField = goog.dom.createDom('field', null, name); + var xmlField = goog.dom.createUntypedDom('field', null, name); xmlField.setAttribute('name', 'VAR'); - var xmlBlock = goog.dom.createDom('block', null, xmlField); + var xmlBlock = goog.dom.createUntypedDom('block', null, xmlField); xmlBlock.setAttribute('type', this.contextMenuType_); option.callback = Blockly.ContextMenu.callbackFactory(this, xmlBlock); options.push(option); diff --git a/core/events.js b/core/events.js index 1d1e2b70e..e3556ae4d 100644 --- a/core/events.js +++ b/core/events.js @@ -388,7 +388,7 @@ Blockly.Events.Create.prototype.fromJson = function(json) { Blockly.Events.Create.prototype.run = function(forward) { var workspace = Blockly.Workspace.getById(this.workspaceId); if (forward) { - var xml = goog.dom.createDom('xml'); + var xml = goog.dom.createUntypedDom('xml'); xml.appendChild(this.xml); Blockly.Xml.domToWorkspace(xml, workspace); } else { @@ -465,7 +465,7 @@ Blockly.Events.Delete.prototype.run = function(forward) { } } } else { - var xml = goog.dom.createDom('xml'); + var xml = goog.dom.createUntypedDom('xml'); xml.appendChild(this.oldXml); Blockly.Xml.domToWorkspace(xml, workspace); } diff --git a/core/field_textinput.js b/core/field_textinput.js index ba9375e4c..a1fe173b6 100644 --- a/core/field_textinput.js +++ b/core/field_textinput.js @@ -30,6 +30,7 @@ goog.require('Blockly.Field'); goog.require('Blockly.Msg'); goog.require('goog.asserts'); goog.require('goog.dom'); +goog.require('goog.dom.TagName'); goog.require('goog.userAgent'); @@ -124,7 +125,8 @@ Blockly.FieldTextInput.prototype.showEditor_ = function(opt_quietInput) { Blockly.WidgetDiv.show(this, this.sourceBlock_.RTL, this.widgetDispose_()); var div = Blockly.WidgetDiv.DIV; // Create the input. - var htmlInput = goog.dom.createDom('input', 'blocklyHtmlInput'); + var htmlInput = + goog.dom.createDom(goog.dom.TagName.INPUT, 'blocklyHtmlInput'); htmlInput.setAttribute('spellcheck', this.spellcheck_); var fontSize = (Blockly.FieldTextInput.FONTSIZE * this.workspace_.scale) + 'pt'; diff --git a/core/mutator.js b/core/mutator.js index a804b463f..d28beb49f 100644 --- a/core/mutator.js +++ b/core/mutator.js @@ -110,9 +110,10 @@ Blockly.Mutator.prototype.createEditor_ = function() { null); // Convert the list of names into a list of XML objects for the flyout. if (this.quarkNames_.length) { - var quarkXml = goog.dom.createDom('xml'); + var quarkXml = goog.dom.createUntypedDom('xml'); for (var i = 0, quarkName; quarkName = this.quarkNames_[i]; i++) { - quarkXml.appendChild(goog.dom.createDom('block', {'type': quarkName})); + quarkXml.appendChild( + goog.dom.createUntypedDom('block', {'type': quarkName})); } } else { var quarkXml = null; diff --git a/core/procedures.js b/core/procedures.js index beb4a17b8..aa3663319 100644 --- a/core/procedures.js +++ b/core/procedures.js @@ -162,21 +162,21 @@ Blockly.Procedures.flyoutCategory = function(workspace) { var xmlList = []; if (Blockly.Blocks['procedures_defnoreturn']) { // - var block = goog.dom.createDom('block'); + var block = goog.dom.createUntypedDom('block'); block.setAttribute('type', 'procedures_defnoreturn'); block.setAttribute('gap', 16); xmlList.push(block); } if (Blockly.Blocks['procedures_defreturn']) { // - var block = goog.dom.createDom('block'); + var block = goog.dom.createUntypedDom('block'); block.setAttribute('type', 'procedures_defreturn'); block.setAttribute('gap', 16); xmlList.push(block); } if (Blockly.Blocks['procedures_ifreturn']) { // - var block = goog.dom.createDom('block'); + var block = goog.dom.createUntypedDom('block'); block.setAttribute('type', 'procedures_ifreturn'); block.setAttribute('gap', 16); xmlList.push(block); @@ -195,14 +195,14 @@ Blockly.Procedures.flyoutCategory = function(workspace) { // // // - var block = goog.dom.createDom('block'); + var block = goog.dom.createUntypedDom('block'); block.setAttribute('type', templateName); block.setAttribute('gap', 16); - var mutation = goog.dom.createDom('mutation'); + var mutation = goog.dom.createUntypedDom('mutation'); mutation.setAttribute('name', name); block.appendChild(mutation); for (var j = 0; j < args.length; j++) { - var arg = goog.dom.createDom('arg'); + var arg = goog.dom.createUntypedDom('arg'); arg.setAttribute('name', args[j]); mutation.appendChild(arg); } diff --git a/core/toolbox.js b/core/toolbox.js index ac15ed128..3ff41df95 100644 --- a/core/toolbox.js +++ b/core/toolbox.js @@ -28,6 +28,7 @@ goog.provide('Blockly.Toolbox'); goog.require('Blockly.Flyout'); goog.require('goog.dom'); +goog.require('goog.dom.TagName'); goog.require('goog.events'); goog.require('goog.events.BrowserFeature'); goog.require('goog.html.SafeHtml'); @@ -146,7 +147,8 @@ Blockly.Toolbox.prototype.init = function() { var workspace = this.workspace_; // Create an HTML container for the Toolbox menu. - this.HtmlDiv = goog.dom.createDom('div', 'blocklyToolboxDiv'); + this.HtmlDiv = + goog.dom.createDom(goog.dom.TagName.DIV, 'blocklyToolboxDiv'); this.HtmlDiv.setAttribute('dir', workspace.RTL ? 'RTL' : 'LTR'); document.body.appendChild(this.HtmlDiv); diff --git a/core/tooltip.js b/core/tooltip.js index 3aa828812..2ff612b7b 100644 --- a/core/tooltip.js +++ b/core/tooltip.js @@ -32,6 +32,7 @@ goog.provide('Blockly.Tooltip'); goog.require('goog.dom'); +goog.require('goog.dom.TagName'); /** @@ -120,7 +121,8 @@ Blockly.Tooltip.createDom = function() { return; // Already created. } // Create an HTML container for popup overlays (e.g. editor widgets). - Blockly.Tooltip.DIV = goog.dom.createDom('div', 'blocklyTooltipDiv'); + Blockly.Tooltip.DIV = + goog.dom.createDom(goog.dom.TagName.DIV, 'blocklyTooltipDiv'); document.body.appendChild(Blockly.Tooltip.DIV); }; diff --git a/core/variables.js b/core/variables.js index 450d33fcf..b6df4d123 100644 --- a/core/variables.js +++ b/core/variables.js @@ -108,12 +108,12 @@ Blockly.Variables.flyoutCategory = function(workspace) { // // item // - var block = goog.dom.createDom('block'); + var block = goog.dom.createUntypedDom('block'); block.setAttribute('type', 'variables_set'); if (Blockly.Blocks['variables_get']) { block.setAttribute('gap', 8); } - var field = goog.dom.createDom('field', null, variableList[i]); + var field = goog.dom.createUntypedDom('field', null, variableList[i]); field.setAttribute('name', 'VAR'); block.appendChild(field); xmlList.push(block); @@ -122,12 +122,12 @@ Blockly.Variables.flyoutCategory = function(workspace) { // // item // - var block = goog.dom.createDom('block'); + var block = goog.dom.createUntypedDom('block'); block.setAttribute('type', 'variables_get'); if (Blockly.Blocks['variables_set']) { block.setAttribute('gap', 24); } - var field = goog.dom.createDom('field', null, variableList[i]); + var field = goog.dom.createUntypedDom('field', null, variableList[i]); field.setAttribute('name', 'VAR'); block.appendChild(field); xmlList.push(block); diff --git a/core/widgetdiv.js b/core/widgetdiv.js index 817d15bac..ac776d0ea 100644 --- a/core/widgetdiv.js +++ b/core/widgetdiv.js @@ -30,6 +30,7 @@ goog.provide('Blockly.WidgetDiv'); goog.require('Blockly.Css'); goog.require('goog.dom'); +goog.require('goog.dom.TagName'); goog.require('goog.style'); @@ -61,7 +62,8 @@ Blockly.WidgetDiv.createDom = function() { return; // Already created. } // Create an HTML container for popup overlays (e.g. editor widgets). - Blockly.WidgetDiv.DIV = goog.dom.createDom('div', 'blocklyWidgetDiv'); + Blockly.WidgetDiv.DIV = + goog.dom.createDom(goog.dom.TagName.DIV, 'blocklyWidgetDiv'); document.body.appendChild(Blockly.WidgetDiv.DIV); }; diff --git a/core/xml.js b/core/xml.js index 95e6471c2..002d21f01 100644 --- a/core/xml.js +++ b/core/xml.js @@ -36,7 +36,7 @@ goog.require('goog.dom'); * @return {!Element} XML document. */ Blockly.Xml.workspaceToDom = function(workspace) { - var xml = goog.dom.createDom('xml'); + var xml = goog.dom.createUntypedDom('xml'); var blocks = workspace.getTopBlocks(true); for (var i = 0, block; block = blocks[i]; i++) { xml.appendChild(Blockly.Xml.blockToDomWithXY(block)); @@ -68,7 +68,8 @@ Blockly.Xml.blockToDomWithXY = function(block) { * @return {!Element} Tree of XML elements. */ Blockly.Xml.blockToDom = function(block) { - var element = goog.dom.createDom(block.isShadow() ? 'shadow' : 'block'); + var element = goog.dom.createUntypedDom( + block.isShadow() ? 'shadow' : 'block'); element.setAttribute('type', block.type); element.setAttribute('id', block.id); if (block.mutationToDom) { @@ -80,7 +81,8 @@ Blockly.Xml.blockToDom = function(block) { } function fieldToDom(field) { if (field.name && field.EDITABLE) { - var container = goog.dom.createDom('field', null, field.getValue()); + var container = + goog.dom.createUntypedDom('field', null, field.getValue()); container.setAttribute('name', field.name); element.appendChild(container); } @@ -93,7 +95,8 @@ Blockly.Xml.blockToDom = function(block) { var commentText = block.getCommentText(); if (commentText) { - var commentElement = goog.dom.createDom('comment', null, commentText); + var commentElement = + goog.dom.createUntypedDom('comment', null, commentText); if (typeof block.comment == 'object') { commentElement.setAttribute('pinned', block.comment.isVisible()); var hw = block.comment.getBubbleSize(); @@ -104,7 +107,7 @@ Blockly.Xml.blockToDom = function(block) { } if (block.data) { - var dataElement = goog.dom.createDom('data', null, block.data); + var dataElement = goog.dom.createUntypedDom('data', null, block.data); element.appendChild(dataElement); } @@ -116,9 +119,9 @@ Blockly.Xml.blockToDom = function(block) { } else { var childBlock = input.connection.targetBlock(); if (input.type == Blockly.INPUT_VALUE) { - container = goog.dom.createDom('value'); + container = goog.dom.createUntypedDom('value'); } else if (input.type == Blockly.NEXT_STATEMENT) { - container = goog.dom.createDom('statement'); + container = goog.dom.createUntypedDom('statement'); } var shadow = input.connection.getShadowDom(); if (shadow && (!childBlock || !childBlock.isShadow())) { @@ -155,8 +158,8 @@ Blockly.Xml.blockToDom = function(block) { var nextBlock = block.getNextBlock(); if (nextBlock) { - var container = goog.dom.createDom('next', null, - Blockly.Xml.blockToDom(nextBlock)); + var container = goog.dom.createUntypedDom( + 'next', null, Blockly.Xml.blockToDom(nextBlock)); element.appendChild(container); } var shadow = block.nextConnection && block.nextConnection.getShadowDom(); From 0de625caf40e9262d848f842f94a558574a22813 Mon Sep 17 00:00:00 2001 From: Sean Lip Date: Mon, 18 Jul 2016 16:11:29 -0700 Subject: [PATCH 14/71] Tidy up usage and formatting of aria-level (fixing an off-by-one error in the process). --- accessible/field.component.js | 12 ++++++------ accessible/toolbox-tree.component.js | 20 +++++++++----------- accessible/toolbox.component.js | 6 +++--- accessible/workspace-tree.component.js | 16 ++++++++-------- 4 files changed, 26 insertions(+), 28 deletions(-) diff --git a/accessible/field.component.js b/accessible/field.component.js index 9b1a35143..6bc400af9 100644 --- a/accessible/field.component.js +++ b/accessible/field.component.js @@ -30,18 +30,18 @@ blocklyApp.FieldComponent = ng.core template: `
  • + [attr.aria-level]="level" aria-selected="false">
  • + [attr.aria-level]="level" aria-selected="false"> -
      +
      1. + [attr.aria-level]="level + 1" aria-selected="false">
    1. + [attr.aria-level]="level" aria-selected="false"> // Checkboxes are not currently supported.
    2. + [attr.aria-level]="level" aria-selected="false"> diff --git a/accessible/toolbox-tree.component.js b/accessible/toolbox-tree.component.js index 15dfa220a..c6cc803b8 100644 --- a/accessible/toolbox-tree.component.js +++ b/accessible/toolbox-tree.component.js @@ -34,17 +34,16 @@ blocklyApp.ToolboxTreeComponent = ng.core [attr.aria-selected]="index == 0 && tree.getAttribute('aria-activedescendant') == 'blockly-toolbox-tree-node0'" [attr.aria-level]="level"> -
        +
        1. + aria-selected="false" [attr.aria-level]="level + 1"> -
            +
            1. + [attr.aria-level]="level + 2" aria-selected="false">
            2. + [attr.aria-level]="level + 2" aria-selected="false">
            3. + [attr.aria-level]="level + 2" aria-selected="false">
            4. + [attr.aria-level]="level + 2" aria-selected="false">
            +