diff --git a/lib/editor/atto/plugins/table/yui/build/moodle-atto_table-button/moodle-atto_table-button-debug.js b/lib/editor/atto/plugins/table/yui/build/moodle-atto_table-button/moodle-atto_table-button-debug.js
index 8e9c9a5cc07..065fb55bbe7 100644
--- a/lib/editor/atto/plugins/table/yui/build/moodle-atto_table-button/moodle-atto_table-button-debug.js
+++ b/lib/editor/atto/plugins/table/yui/build/moodle-atto_table-button/moodle-atto_table-button-debug.js
@@ -149,30 +149,27 @@ Y.namespace('M.atto_table').Button = Y.Base.create('button', Y.M.editor_atto.Edi
* @private
*/
_displayTableEditor: function(e) {
- var selection = this.get('host').getSelectionParentNode(),
- cell;
-
- if (!selection) {
- // We don't have a current selection at all, so show the standard dialogue.
- return this._displayDialogue(e);
- }
-
- // Check all of the table cells found in the selection.
- Y.one(selection).ancestors('th, td', true).each(function(node) {
- if (this.editor.contains(node)) {
- cell = node;
- }
- }, this);
-
+ var cell = this._getSuitableTableCell();
if (cell) {
// Add the cell to the EventFacade to save duplication in when showing the menu.
e.tableCell = cell;
return this._showTableMenu(e);
}
-
return this._displayDialogue(e);
},
+ /**
+ * Returns whether or not the parameter node exists within the editor.
+ *
+ * @method _stopAtContentEditableFilter
+ * @param {Node} node
+ * @private
+ * @return {boolean} whether or not the parameter node exists within the editor.
+ */
+ _stopAtContentEditableFilter: function(node) {
+ this.editor.contains(node);
+ },
+
/**
* Return the dialogue content for the tool, attaching any required
* events.
@@ -195,6 +192,44 @@ Y.namespace('M.atto_table').Button = Y.Base.create('button', Y.M.editor_atto.Edi
return this._content;
},
+ /**
+ * Given the current selection, return a table cell suitable for table editing
+ * purposes, i.e. the first table cell selected, or the first cell in the table
+ * that the selection exists in, or null if not within a table.
+ *
+ * @method _getSuitableTableCell
+ * @private
+ * @return {Node} suitable target cell, or null if not within a table
+ */
+ _getSuitableTableCell: function() {
+ var targetcell = null,
+ host = this.get('host');
+
+ host.getSelectedNodes().some(function (node) {
+ if (node.ancestor('td, th, caption', true, this._stopAtContentEditableFilter)) {
+ targetcell = node;
+
+ var caption = node.ancestor('caption', true, this._stopAtContentEditableFilter);
+ if (caption) {
+ var table = caption.get('parentNode');
+ if (table) {
+ targetcell = table.one('td, th');
+ }
+ }
+
+ // Once we've found a cell to target, we shouldn't need to keep looking.
+ return true;
+ }
+ });
+
+ if (targetcell) {
+ var selection = host.getSelectionFromNode(targetcell);
+ host.setSelection(selection);
+ }
+
+ return targetcell;
+ },
+
/**
* Handle creation of a new table.
*
diff --git a/lib/editor/atto/plugins/table/yui/build/moodle-atto_table-button/moodle-atto_table-button-min.js b/lib/editor/atto/plugins/table/yui/build/moodle-atto_table-button/moodle-atto_table-button-min.js
index 5fd06f0e25d..b6957b5b2f2 100644
--- a/lib/editor/atto/plugins/table/yui/build/moodle-atto_table-button/moodle-atto_table-button-min.js
+++ b/lib/editor/atto/plugins/table/yui/build/moodle-atto_table-button/moodle-atto_table-button-min.js
@@ -1,2 +1,2 @@
-YUI.add("moodle-atto_table-button",function(e,t){var n="atto_table",r='
',i='';CSS={},e.namespace("M.atto_table").Button=e.Base.create("button",e.M.editor_atto.EditorPlugin,[],{_currentSelection:null,_contextMenu:null,_lastTarget:null,initializer:function(){this.addButton({icon:"e/table",callback:this._displayTableEditor,tags:"table"}),e.UA.gecko&&(document.execCommand("enableInlineTableEditing",!1,!1),document.execCommand("enableObjectResizing",!1,!1))},_displayDialogue:function(){this._currentSelection=this.get("host").getSelection();if(this._currentSelection!==!1&&!this._currentSelection.collapsed){var e=this.getDialogue({headerContent:M.util.get_string("createtable",n),focusAfterHide:!0});e.set("bodyContent",this._getDialogueContent()).show()}},_displayTableEditor:function(t){var n=this.get("host").getSelectionParentNode(),r;return n?(e.one(n).ancestors("th, td",!0).each(function(e){this.editor.contains(e)&&(r=e)},this),r?(t.tableCell=r,this._showTableMenu(t)):this._displayDialogue(t)):this._displayDialogue(t)},_getDialogueContent:function(){var t=e.Handlebars.compile(r);return this._content=e.Node.create(t({CSS:CSS,elementid:this.get("host").get("elementid"),component:n})),this._content.one(".submit").on("click",this._setTable,this),this._content},_setTable:function(t){var n,r,i,s,o,u,a;t.preventDefault(),this.getDialogue({focusAfterHide:null}).hide(),n=t.currentTarget.ancestor(".atto_form").one(".caption"),r=t.currentTarget.ancestor(".atto_form").one(".rows"),i=t.currentTarget.ancestor(".atto_form").one(".columns"),s=t.currentTarget.ancestor(".atto_form").one(".headers"),this.get("host").setSelection(this._currentSelection);var f="\n";o="
"+f+""+f,o+=""+e.Escape.html(n.get("value"))+""+f,u=0;if(s.get("value")==="columns"||s.get("value")==="both"){u=1,o+=""+f+""+f;for(a=0;a'+f;o+="
"+f+""+f}o+=""+f;for(;u"+f;for(a=0;a"+f:o+=' | '+f;o+=""+f}o+=""+f,o+="
"+f+"
",this.get("host").insertContentAtFocusPoint(o),this.markUpdated()},_showTableMenu:function(t){t.preventDefault();var r;if(!this._contextMenu){var s=e.Handlebars.compile(i),o=e.Node.create(s({elementid:this.get("host").get("elementid"),component:n}));this._contextMenu=new e.M.editor_atto.Menu({headerText:M.util.get_string("edittable","atto_table"),bodyContent:o}),r=this._contextMenu.get("boundingBox"),r.delegate("click",this._handleTableChange,"a",this),r.delegate("key",this._handleTableChange,"down:enter,space","a",this)}r=this._contextMenu.get("boundingBox"),this._lastTarget=t.tableCell.ancestor(".editor_atto_content td, .editor_atto_content th",!0),this._contextMenu.show(),this._contextMenu.align(this.buttons.table,[e.WidgetPositionAlign.TL,e.WidgetPositionAlign.BL]),r.one("a")&&r.one("a").focus()},_handleTableChange:function(e){e.preventDefault(),this._contextMenu.hide();switch(e.target.getData("change")){case"addcolumnafter":this._addColumnAfter();break;case"addrowafter":this._addRowAfter();break;case"deleterow":this._deleteRow();break;case"deletecolumn":this._deleteColumn();break;case"moverowdown":this._moveRowDown();break;case"moverowup":this._moveRowUp();break;case"movecolumnleft":this._moveColumnLeft();break;case"movecolumnright":this._moveColumnRight()}},_getRowIndex:function(e){var t=e.ancestor("table"),n=e.ancestor("tr");if(!t||!n)return;var r=t.all("tr");return r.indexOf(n)},_getColumnIndex:function(e){var t=e.ancestor("tr");if(!t)return;var n=t.all("td, th");return n.indexOf(e)},_deleteRow:function(){var e=this._lastTarget.ancestor("tr");e&&e.one("td")&&e.remove(!0),this.markUpdated()},_moveRowUp:function(){var e=this._lastTarget.ancestor("tr"),t=e.previous("tr");if(!e||!t)return;e.swap(t),this.markUpdated()},_moveColumnLeft:function(){var t=this._getColumnIndex(this._lastTarget),n=this._lastTarget.ancestor("table").all("tr"),r=new e.NodeList,i=new e.NodeList,s=!1;n.each(function(
-e){var n=e.all("td, th"),o=n.item(t),u=n.item(t-1);r.push(o),u&&(u.get("tagName")==="TD"&&(s=!0),i.push(u))});if(s&&i.size()>0){var o=0;for(o=0;o0){var o=0;for(o=0;o");t.replace(n),t=n}t.setHTML(" ")}),n.insert(newrow,t),this.markUpdated()},_addColumnAfter:function(){var t=this._getColumnIndex(this._lastTarget),n=this._lastTarget.ancestor("table"),r=n.all("tr");e.each(r,function(e){var n=e.one("td, th").cloneNode(!0);n.setHTML(" "),e.insert(n,t+1)},this),this.markUpdated()}})},"@VERSION@",{requires:["moodle-editor_atto-plugin","moodle-editor_atto-menu","event","event-valuechange"]});
+YUI.add("moodle-atto_table-button",function(e,t){var n="atto_table",r='',i='';CSS={},e.namespace("M.atto_table").Button=e.Base.create("button",e.M.editor_atto.EditorPlugin,[],{_currentSelection:null,_contextMenu:null,_lastTarget:null,initializer:function(){this.addButton({icon:"e/table",callback:this._displayTableEditor,tags:"table"}),e.UA.gecko&&(document.execCommand("enableInlineTableEditing",!1,!1),document.execCommand("enableObjectResizing",!1,!1))},_displayDialogue:function(){this._currentSelection=this.get("host").getSelection();if(this._currentSelection!==!1&&!this._currentSelection.collapsed){var e=this.getDialogue({headerContent:M.util.get_string("createtable",n),focusAfterHide:!0});e.set("bodyContent",this._getDialogueContent()).show()}},_displayTableEditor:function(e){var t=this._getSuitableTableCell();return t?(e.tableCell=t,this._showTableMenu(e)):this._displayDialogue(e)},_stopAtContentEditableFilter:function(e){this.editor.contains(e)},_getDialogueContent:function(){var t=e.Handlebars.compile(r);return this._content=e.Node.create(t({CSS:CSS,elementid:this.get("host").get("elementid"),component:n})),this._content.one(".submit").on("click",this._setTable,this),this._content},_getSuitableTableCell:function(){var e=null,t=this.get("host");t.getSelectedNodes().some(function(t){if(t.ancestor("td, th, caption",!0,this._stopAtContentEditableFilter)){e=t;var n=t.ancestor("caption",!0,this._stopAtContentEditableFilter);if(n){var r=n.get("parentNode");r&&(e=r.one("td, th"))}return!0}});if(e){var n=t.getSelectionFromNode(e);t.setSelection(n)}return e},_setTable:function(t){var n,r,i,s,o,u,a;t.preventDefault(),this.getDialogue({focusAfterHide:null}).hide(),n=t.currentTarget.ancestor(".atto_form").one(".caption"),r=t.currentTarget.ancestor(".atto_form").one(".rows"),i=t.currentTarget.ancestor(".atto_form").one(".columns"),s=t.currentTarget.ancestor(".atto_form").one(".headers"),this.get("host").setSelection(this._currentSelection);var f="\n";o="
"+f+""+f,o+=""+e.Escape.html(n.get("value"))+""+f,u=0;if(s.get("value")==="columns"||s.get("value")==="both"){u=1,o+=""+f+""+f;for(a=0;a'+f;o+="
"+f+""+f}o+=""+f;for(;u"+f;for(a=0;a"+f:o+=' | '+f;o+=""+f}o+=""+f,o+="
"+f+"
",this.get("host").insertContentAtFocusPoint(o),this.markUpdated()},_showTableMenu:function(t){t.preventDefault();var r;if(!this._contextMenu){var s=e.Handlebars.compile(i),o=e.Node.create(s({elementid:this.get("host").get("elementid"),component:n}));this._contextMenu=new e.M.editor_atto.Menu({headerText:M.util.get_string("edittable","atto_table"),bodyContent:o}),r=this._contextMenu.get("boundingBox"),r.delegate("click",this._handleTableChange,"a",this),r.delegate("key",this._handleTableChange,"down:enter,space","a",this)}r=this._contextMenu.get("boundingBox"),this._lastTarget=t.tableCell.ancestor(".editor_atto_content td, .editor_atto_content th",!0),this._contextMenu.show(),this._contextMenu.align(this.buttons.table,[e.WidgetPositionAlign.TL,e.WidgetPositionAlign.BL]),r.one("a")&&r.one("a").focus()},_handleTableChange:function(e){e.preventDefault(),this._contextMenu.hide();switch(e.target.getData("change")){case"addcolumnafter":this._addColumnAfter();break;case"addrowafter":this._addRowAfter();break;case"deleterow":this._deleteRow();break;case"deletecolumn":this._deleteColumn();break;case"moverowdown":this._moveRowDown();break;case"moverowup":this._moveRowUp();break;case"movecolumnleft":this._moveColumnLeft();break;case"movecolumnright":this._moveColumnRight()}},_getRowIndex:function(e){var t=e.ancestor("table"),n=e.ancestor("tr");if(!t||!n)return;var r=t.all("tr");return r.indexOf(n)},_getColumnIndex:function(e){var t=e.ancestor("tr");if(!t)return;var n=t.all("td, th");return n.indexOf(e)},_deleteRow:function(){var e=this._lastTarget.ancestor("tr");e&&e.one("td")&&e.remove(!0),this.markUpdated
+()},_moveRowUp:function(){var e=this._lastTarget.ancestor("tr"),t=e.previous("tr");if(!e||!t)return;e.swap(t),this.markUpdated()},_moveColumnLeft:function(){var t=this._getColumnIndex(this._lastTarget),n=this._lastTarget.ancestor("table").all("tr"),r=new e.NodeList,i=new e.NodeList,s=!1;n.each(function(e){var n=e.all("td, th"),o=n.item(t),u=n.item(t-1);r.push(o),u&&(u.get("tagName")==="TD"&&(s=!0),i.push(u))});if(s&&i.size()>0){var o=0;for(o=0;o0){var o=0;for(o=0;o");t.replace(n),t=n}t.setHTML(" ")}),n.insert(newrow,t),this.markUpdated()},_addColumnAfter:function(){var t=this._getColumnIndex(this._lastTarget),n=this._lastTarget.ancestor("table"),r=n.all("tr");e.each(r,function(e){var n=e.one("td, th").cloneNode(!0);n.setHTML(" "),e.insert(n,t+1)},this),this.markUpdated()}})},"@VERSION@",{requires:["moodle-editor_atto-plugin","moodle-editor_atto-menu","event","event-valuechange"]});
diff --git a/lib/editor/atto/plugins/table/yui/build/moodle-atto_table-button/moodle-atto_table-button.js b/lib/editor/atto/plugins/table/yui/build/moodle-atto_table-button/moodle-atto_table-button.js
index 8e9c9a5cc07..065fb55bbe7 100644
--- a/lib/editor/atto/plugins/table/yui/build/moodle-atto_table-button/moodle-atto_table-button.js
+++ b/lib/editor/atto/plugins/table/yui/build/moodle-atto_table-button/moodle-atto_table-button.js
@@ -149,30 +149,27 @@ Y.namespace('M.atto_table').Button = Y.Base.create('button', Y.M.editor_atto.Edi
* @private
*/
_displayTableEditor: function(e) {
- var selection = this.get('host').getSelectionParentNode(),
- cell;
-
- if (!selection) {
- // We don't have a current selection at all, so show the standard dialogue.
- return this._displayDialogue(e);
- }
-
- // Check all of the table cells found in the selection.
- Y.one(selection).ancestors('th, td', true).each(function(node) {
- if (this.editor.contains(node)) {
- cell = node;
- }
- }, this);
-
+ var cell = this._getSuitableTableCell();
if (cell) {
// Add the cell to the EventFacade to save duplication in when showing the menu.
e.tableCell = cell;
return this._showTableMenu(e);
}
-
return this._displayDialogue(e);
},
+ /**
+ * Returns whether or not the parameter node exists within the editor.
+ *
+ * @method _stopAtContentEditableFilter
+ * @param {Node} node
+ * @private
+ * @return {boolean} whether or not the parameter node exists within the editor.
+ */
+ _stopAtContentEditableFilter: function(node) {
+ this.editor.contains(node);
+ },
+
/**
* Return the dialogue content for the tool, attaching any required
* events.
@@ -195,6 +192,44 @@ Y.namespace('M.atto_table').Button = Y.Base.create('button', Y.M.editor_atto.Edi
return this._content;
},
+ /**
+ * Given the current selection, return a table cell suitable for table editing
+ * purposes, i.e. the first table cell selected, or the first cell in the table
+ * that the selection exists in, or null if not within a table.
+ *
+ * @method _getSuitableTableCell
+ * @private
+ * @return {Node} suitable target cell, or null if not within a table
+ */
+ _getSuitableTableCell: function() {
+ var targetcell = null,
+ host = this.get('host');
+
+ host.getSelectedNodes().some(function (node) {
+ if (node.ancestor('td, th, caption', true, this._stopAtContentEditableFilter)) {
+ targetcell = node;
+
+ var caption = node.ancestor('caption', true, this._stopAtContentEditableFilter);
+ if (caption) {
+ var table = caption.get('parentNode');
+ if (table) {
+ targetcell = table.one('td, th');
+ }
+ }
+
+ // Once we've found a cell to target, we shouldn't need to keep looking.
+ return true;
+ }
+ });
+
+ if (targetcell) {
+ var selection = host.getSelectionFromNode(targetcell);
+ host.setSelection(selection);
+ }
+
+ return targetcell;
+ },
+
/**
* Handle creation of a new table.
*
diff --git a/lib/editor/atto/plugins/table/yui/src/button/js/button.js b/lib/editor/atto/plugins/table/yui/src/button/js/button.js
index 5cc18aaa720..c3db11a7c31 100644
--- a/lib/editor/atto/plugins/table/yui/src/button/js/button.js
+++ b/lib/editor/atto/plugins/table/yui/src/button/js/button.js
@@ -147,30 +147,27 @@ Y.namespace('M.atto_table').Button = Y.Base.create('button', Y.M.editor_atto.Edi
* @private
*/
_displayTableEditor: function(e) {
- var selection = this.get('host').getSelectionParentNode(),
- cell;
-
- if (!selection) {
- // We don't have a current selection at all, so show the standard dialogue.
- return this._displayDialogue(e);
- }
-
- // Check all of the table cells found in the selection.
- Y.one(selection).ancestors('th, td', true).each(function(node) {
- if (this.editor.contains(node)) {
- cell = node;
- }
- }, this);
-
+ var cell = this._getSuitableTableCell();
if (cell) {
// Add the cell to the EventFacade to save duplication in when showing the menu.
e.tableCell = cell;
return this._showTableMenu(e);
}
-
return this._displayDialogue(e);
},
+ /**
+ * Returns whether or not the parameter node exists within the editor.
+ *
+ * @method _stopAtContentEditableFilter
+ * @param {Node} node
+ * @private
+ * @return {boolean} whether or not the parameter node exists within the editor.
+ */
+ _stopAtContentEditableFilter: function(node) {
+ this.editor.contains(node);
+ },
+
/**
* Return the dialogue content for the tool, attaching any required
* events.
@@ -193,6 +190,44 @@ Y.namespace('M.atto_table').Button = Y.Base.create('button', Y.M.editor_atto.Edi
return this._content;
},
+ /**
+ * Given the current selection, return a table cell suitable for table editing
+ * purposes, i.e. the first table cell selected, or the first cell in the table
+ * that the selection exists in, or null if not within a table.
+ *
+ * @method _getSuitableTableCell
+ * @private
+ * @return {Node} suitable target cell, or null if not within a table
+ */
+ _getSuitableTableCell: function() {
+ var targetcell = null,
+ host = this.get('host');
+
+ host.getSelectedNodes().some(function (node) {
+ if (node.ancestor('td, th, caption', true, this._stopAtContentEditableFilter)) {
+ targetcell = node;
+
+ var caption = node.ancestor('caption', true, this._stopAtContentEditableFilter);
+ if (caption) {
+ var table = caption.get('parentNode');
+ if (table) {
+ targetcell = table.one('td, th');
+ }
+ }
+
+ // Once we've found a cell to target, we shouldn't need to keep looking.
+ return true;
+ }
+ });
+
+ if (targetcell) {
+ var selection = host.getSelectionFromNode(targetcell);
+ host.setSelection(selection);
+ }
+
+ return targetcell;
+ },
+
/**
* Handle creation of a new table.
*