a:91:{s:9:"#provides";s:33:"dojox.editor.plugins.TablePlugins";s:9:"#resource";s:30:"editor/plugins/TablePlugins.js";s:9:"#requires";a:9:{i:0;a:3:{i:0;s:6:"common";i:1;s:21:"dijit._editor._Plugin";i:2;s:5:"dijit";}i:1;a:3:{i:0;s:6:"common";i:1;s:23:"dijit._editor.selection";i:2;s:5:"dijit";}i:2;a:3:{i:0;s:6:"common";i:1;s:10:"dijit.Menu";i:2;s:5:"dijit";}i:3;a:3:{i:0;s:6:"common";i:1;s:9:"dojo.i18n";i:2;s:4:"dojo";}i:4;a:3:{i:0;s:6:"common";i:1;s:12:"dijit.Dialog";i:2;s:5:"dijit";}i:5;a:3:{i:0;s:6:"common";i:1;s:18:"dijit.form.TextBox";i:2;s:5:"dijit";}i:6;a:3:{i:0;s:6:"common";i:1;s:26:"dijit.form.FilteringSelect";i:2;s:5:"dijit";}i:7;a:3:{i:0;s:6:"common";i:1;s:17:"dijit.form.Button";i:2;s:5:"dijit";}i:8;a:3:{i:0;s:6:"common";i:1;s:18:"dijit.ColorPalette";i:2;s:5:"dijit";}}s:39:"dojox.editor.plugins.GlobalTableHandler";a:4:{s:4:"type";s:8:"Function";s:6:"chains";a:2:{s:9:"prototype";a:1:{i:0;s:21:"dijit._editor._Plugin";}s:4:"call";a:1:{i:0;s:21:"dijit._editor._Plugin";}}s:7:"summary";s:277:"A global object that handles common tasks for all the plugins. Since there are several plugins that are all calling common methods, it's preferable that they call a centralized location that either has a set variable or a timeout to only repeat code-heavy calls when necessary.";s:9:"classlike";b:1;}s:55:"dojox.editor.plugins.GlobalTableHandler.tablesConnected";a:3:{s:9:"prototype";s:39:"dojox.editor.plugins.GlobalTableHandler";s:8:"instance";s:39:"dojox.editor.plugins.GlobalTableHandler";s:7:"summary";s:0:"";}s:58:"dojox.editor.plugins.GlobalTableHandler.currentlyAvailable";a:3:{s:9:"prototype";s:39:"dojox.editor.plugins.GlobalTableHandler";s:8:"instance";s:39:"dojox.editor.plugins.GlobalTableHandler";s:7:"summary";s:0:"";}s:55:"dojox.editor.plugins.GlobalTableHandler.alwaysAvailable";a:2:{s:9:"prototype";s:39:"dojox.editor.plugins.GlobalTableHandler";s:7:"summary";s:0:"";}s:61:"dojox.editor.plugins.GlobalTableHandler.availableCurrentlySet";a:3:{s:9:"prototype";s:39:"dojox.editor.plugins.GlobalTableHandler";s:8:"instance";s:39:"dojox.editor.plugins.GlobalTableHandler";s:7:"summary";s:0:"";}s:51:"dojox.editor.plugins.GlobalTableHandler.initialized";a:3:{s:9:"prototype";s:39:"dojox.editor.plugins.GlobalTableHandler";s:8:"instance";s:39:"dojox.editor.plugins.GlobalTableHandler";s:7:"summary";s:0:"";}s:49:"dojox.editor.plugins.GlobalTableHandler.tableData";a:3:{s:9:"prototype";s:39:"dojox.editor.plugins.GlobalTableHandler";s:8:"instance";s:39:"dojox.editor.plugins.GlobalTableHandler";s:7:"summary";s:0:"";}s:52:"dojox.editor.plugins.GlobalTableHandler.shiftKeyDown";a:3:{s:9:"prototype";s:39:"dojox.editor.plugins.GlobalTableHandler";s:8:"instance";s:39:"dojox.editor.plugins.GlobalTableHandler";s:7:"summary";s:0:"";}s:53:"dojox.editor.plugins.GlobalTableHandler.editorDomNode";a:3:{s:9:"prototype";s:39:"dojox.editor.plugins.GlobalTableHandler";s:8:"instance";s:39:"dojox.editor.plugins.GlobalTableHandler";s:7:"summary";s:0:"";}s:51:"dojox.editor.plugins.GlobalTableHandler.undoEnabled";a:2:{s:9:"prototype";s:39:"dojox.editor.plugins.GlobalTableHandler";s:7:"summary";s:0:"";}s:48:"dojox.editor.plugins.GlobalTableHandler.doMixins";a:4:{s:9:"prototype";s:39:"dojox.editor.plugins.GlobalTableHandler";s:4:"type";s:8:"Function";s:6:"source";s:786:" dojo.mixin(this.editor,{ getAncestorElement: function(tagName){ return dojo.withGlobal(this.window, "getAncestorElement",dijit._editor.selection, [tagName]); }, hasAncestorElement: function(tagName){ return true return dojo.withGlobal(this.window, "hasAncestorElement",dijit._editor.selection, [tagName]); }, selectElement: function(elem){ dojo.withGlobal(this.window, "selectElement",dijit._editor.selection, [elem]); }, byId: function(id){ return dojo.withGlobal(this.window, "byId", dojo, [id]); }, query: function(arg, scope, returnFirstOnly){ // this shortcut is dubious - not sure scoping is necessary var ar = dojo.withGlobal(this.window, "query", dojo, [arg, scope]); return (returnFirstOnly) ? ar[0] : ar; } });";s:7:"summary";s:0:"";}s:50:"dojox.editor.plugins.GlobalTableHandler.initialize";a:5:{s:9:"prototype";s:39:"dojox.editor.plugins.GlobalTableHandler";s:4:"type";s:8:"Function";s:10:"parameters";a:1:{s:6:"editor";a:1:{s:4:"type";s:0:"";}}s:6:"source";s:517:" if(this.initialized){ return; } this.initialized = true; this.editor = editor; this.editorDomNode = this.editor.editNode || this.editor.iframe.document.body.firstChild; // RichText should have a mouseup connection to recognize drag-selections // Example would be selecting multiple table cells dojo.connect(this.editorDomNode , "mouseup", this.editor, "onClick"); dojo.connect(this.editor, "onDisplayChanged", this, "checkAvailable"); this.doMixins(); this.connectDraggable();";s:7:"summary";s:144:"Initialize the global handler upon a plugin's first instance of setEditor All plugins will attempt initialization. We only need to do so once.";}s:52:"dojox.editor.plugins.GlobalTableHandler.getTableInfo";a:5:{s:9:"prototype";s:39:"dojox.editor.plugins.GlobalTableHandler";s:4:"type";s:8:"Function";s:10:"parameters";a:1:{s:12:"forceNewData";a:1:{s:4:"type";s:0:"";}}s:6:"source";s:4774:"dojo.provide("dojox.editor.plugins.TablePlugins"); dojo.require("dijit._editor._Plugin"); dojo.require("dijit._editor.selection"); dojo.require("dijit.Menu"); dojo.require("dojo.i18n"); dojo.requireLocalization("dojox.editor.plugins", "TableDialog"); dojo.experimental("dojox.editor.plugins.TablePlugins"); // summary: // A series of plugins that give the Editor the ability to create and edit // HTML tables. See the end of this document for all avaiable plugins // and dojox/editorPlugins/tests/editorTablePlugs.html for an example // // example: // |
// | Editor text is here // |
// // TODO: // Currently not supporting merging or splitting cells // // FIXME: Undo is very buggy, and therefore unimeplented in all browsers // except IE - which itself has only been lightly tested. // // FIXME: Selecting multiple table cells in Firefox looks to be impossible. // This affect the 'colorTableCell' plugin. Cells can still be // colored individually or in rows. dojo.declare("dojox.editor.plugins.GlobalTableHandler", dijit._editor._Plugin,{ // summary: // A global object that handles common tasks for all the plugins. Since // there are several plugins that are all calling common methods, it's preferable // that they call a centralized location that either has a set variable or a // timeout to only repeat code-heavy calls when necessary. // tablesConnected:false, currentlyAvailable: false, alwaysAvailable:false, availableCurrentlySet:false, initialized:false, tableData: null, shiftKeyDown:false, editorDomNode: null, undoEnabled: dojo.isIE, //FIXME: doMixins: function(){ dojo.mixin(this.editor,{ getAncestorElement: function(tagName){ return dojo.withGlobal(this.window, "getAncestorElement",dijit._editor.selection, [tagName]); }, hasAncestorElement: function(tagName){ return true return dojo.withGlobal(this.window, "hasAncestorElement",dijit._editor.selection, [tagName]); }, selectElement: function(elem){ dojo.withGlobal(this.window, "selectElement",dijit._editor.selection, [elem]); }, byId: function(id){ return dojo.withGlobal(this.window, "byId", dojo, [id]); }, query: function(arg, scope, returnFirstOnly){ // this shortcut is dubious - not sure scoping is necessary var ar = dojo.withGlobal(this.window, "query", dojo, [arg, scope]); return (returnFirstOnly) ? ar[0] : ar; } }); }, initialize: function(editor){ // summary: // Initialize the global handler upon a plugin's first instance of setEditor // // All plugins will attempt initialization. We only need to do so once. if(this.initialized){ return; } this.initialized = true; this.editor = editor; this.editorDomNode = this.editor.editNode || this.editor.iframe.document.body.firstChild; // RichText should have a mouseup connection to recognize drag-selections // Example would be selecting multiple table cells dojo.connect(this.editorDomNode , "mouseup", this.editor, "onClick"); dojo.connect(this.editor, "onDisplayChanged", this, "checkAvailable"); this.doMixins(); this.connectDraggable(); }, getTableInfo: function(forceNewData){ // summary // Gets the table in focus // Collects info on the table - see return params // if(forceNewData){ this._tempStoreTableData(false); } if(this.tableData){ // tableData is set for a short amount of time, so that all // plugins get the same return without doing the method over console.log("returning current tableData:", this.tableData); return this.tableData; } var tr, trs, td, tds, tbl, cols, tdIndex, trIndex; td = this.editor.getAncestorElement("td"); if(td){ tr = td.parentNode; } tbl = this.editor.getAncestorElement("table"); //console.log("td:", td);console.log("tr:", tr);console.log("tbl:", tbl) tds = dojo.query("td", tbl); tds.forEach(function(d, i){ if(td==d){tdIndex = i} }); trs = dojo.query("tr", tbl); trs.forEach(function(r, i){ if(tr==r){trIndex = i} }); cols = tds.length/trs.length; var o = { tbl:tbl, // focused table td:td, // focused TD tr:tr, // focused TR trs:trs, // rows tds:tds, // cells rows:trs.length,// row amount cols:cols, // column amount tdIndex:tdIndex,// index of focused cell trIndex:trIndex, // index of focused row colIndex:tdIndex%cols }; console.log("NEW tableData:",o); this.tableData = o; this._tempStoreTableData(500); return this.tableData;";s:7:"summary";s:0:"";}s:56:"dojox.editor.plugins.GlobalTableHandler.connectDraggable";a:4:{s:9:"prototype";s:39:"dojox.editor.plugins.GlobalTableHandler";s:4:"type";s:8:"Function";s:6:"source";s:6177:"dojo.provide("dojox.editor.plugins.TablePlugins"); dojo.require("dijit._editor._Plugin"); dojo.require("dijit._editor.selection"); dojo.require("dijit.Menu"); dojo.require("dojo.i18n"); dojo.requireLocalization("dojox.editor.plugins", "TableDialog"); dojo.experimental("dojox.editor.plugins.TablePlugins"); // summary: // A series of plugins that give the Editor the ability to create and edit // HTML tables. See the end of this document for all avaiable plugins // and dojox/editorPlugins/tests/editorTablePlugs.html for an example // // example: // |
// | Editor text is here // |
// // TODO: // Currently not supporting merging or splitting cells // // FIXME: Undo is very buggy, and therefore unimeplented in all browsers // except IE - which itself has only been lightly tested. // // FIXME: Selecting multiple table cells in Firefox looks to be impossible. // This affect the 'colorTableCell' plugin. Cells can still be // colored individually or in rows. dojo.declare("dojox.editor.plugins.GlobalTableHandler", dijit._editor._Plugin,{ // summary: // A global object that handles common tasks for all the plugins. Since // there are several plugins that are all calling common methods, it's preferable // that they call a centralized location that either has a set variable or a // timeout to only repeat code-heavy calls when necessary. // tablesConnected:false, currentlyAvailable: false, alwaysAvailable:false, availableCurrentlySet:false, initialized:false, tableData: null, shiftKeyDown:false, editorDomNode: null, undoEnabled: dojo.isIE, //FIXME: doMixins: function(){ dojo.mixin(this.editor,{ getAncestorElement: function(tagName){ return dojo.withGlobal(this.window, "getAncestorElement",dijit._editor.selection, [tagName]); }, hasAncestorElement: function(tagName){ return true return dojo.withGlobal(this.window, "hasAncestorElement",dijit._editor.selection, [tagName]); }, selectElement: function(elem){ dojo.withGlobal(this.window, "selectElement",dijit._editor.selection, [elem]); }, byId: function(id){ return dojo.withGlobal(this.window, "byId", dojo, [id]); }, query: function(arg, scope, returnFirstOnly){ // this shortcut is dubious - not sure scoping is necessary var ar = dojo.withGlobal(this.window, "query", dojo, [arg, scope]); return (returnFirstOnly) ? ar[0] : ar; } }); }, initialize: function(editor){ // summary: // Initialize the global handler upon a plugin's first instance of setEditor // // All plugins will attempt initialization. We only need to do so once. if(this.initialized){ return; } this.initialized = true; this.editor = editor; this.editorDomNode = this.editor.editNode || this.editor.iframe.document.body.firstChild; // RichText should have a mouseup connection to recognize drag-selections // Example would be selecting multiple table cells dojo.connect(this.editorDomNode , "mouseup", this.editor, "onClick"); dojo.connect(this.editor, "onDisplayChanged", this, "checkAvailable"); this.doMixins(); this.connectDraggable(); }, getTableInfo: function(forceNewData){ // summary // Gets the table in focus // Collects info on the table - see return params // if(forceNewData){ this._tempStoreTableData(false); } if(this.tableData){ // tableData is set for a short amount of time, so that all // plugins get the same return without doing the method over console.log("returning current tableData:", this.tableData); return this.tableData; } var tr, trs, td, tds, tbl, cols, tdIndex, trIndex; td = this.editor.getAncestorElement("td"); if(td){ tr = td.parentNode; } tbl = this.editor.getAncestorElement("table"); //console.log("td:", td);console.log("tr:", tr);console.log("tbl:", tbl) tds = dojo.query("td", tbl); tds.forEach(function(d, i){ if(td==d){tdIndex = i} }); trs = dojo.query("tr", tbl); trs.forEach(function(r, i){ if(tr==r){trIndex = i} }); cols = tds.length/trs.length; var o = { tbl:tbl, // focused table td:td, // focused TD tr:tr, // focused TR trs:trs, // rows tds:tds, // cells rows:trs.length,// row amount cols:cols, // column amount tdIndex:tdIndex,// index of focused cell trIndex:trIndex, // index of focused row colIndex:tdIndex%cols }; console.log("NEW tableData:",o); this.tableData = o; this._tempStoreTableData(500); return this.tableData; }, connectDraggable: function(){ // summary // Detects drag-n-drop in the editor (could probably be moved to there) // Currently only checks if item dragged was a TABLE, and removes its align attr // DOES NOT WORK IN FF - it could - but FF's drag detection is a monster // if(!dojo.isIE){ //console.warn("Drag and Drop is currently only detectable in IE."); return } // IE ONLY this.editorDomNode.ondragstart = dojo.hitch(this, "onDragStart"); this.editorDomNode.ondragend = dojo.hitch(this, "onDragEnd"); //NOTES: // FF _ Able to detect the drag-over object (the editor.domNode) // Not able to detect an item's ondrag() event // Don't know why - I actually got it working when there was an error // Something to do with different documents or windows I'm sure // //console.log("connectDraggable", tbl); /*tbl.ondragstart=dojo.hitch(this, "onDragStart"); tbl.addEventListener("dragstart", dojo.hitch(this, "onDragStart"), false); tbl.addEventListener("drag", dojo.hitch(this, "onDragStart2"), false); tbl.addEventListener("dragend", dojo.hitch(this, "onDragStart3"), false); dojo.withGlobal(this.editor.window, "selectElement",dijit._editor.selection, [tbl]); tbl.ondragstart = function(){ console.log ("ondragstart"); }; tbl.ondrag = function(){ alert("drag") //console.log ("ondrag"); */";s:7:"summary";s:0:"";}s:51:"dojox.editor.plugins.GlobalTableHandler.onDragStart";a:4:{s:9:"prototype";s:39:"dojox.editor.plugins.GlobalTableHandler";s:4:"type";s:8:"Function";s:6:"source";s:153:" var e = window.event; if(!e.srcElement.id){ e.srcElement.id = "tbl_"+(new Date().getTime()); } //console.log("onDragStart", e.srcElement.id);";s:7:"summary";s:0:"";}s:49:"dojox.editor.plugins.GlobalTableHandler.onDragEnd";a:4:{s:9:"prototype";s:39:"dojox.editor.plugins.GlobalTableHandler";s:4:"type";s:8:"Function";s:6:"source";s:7438:"dojo.provide("dojox.editor.plugins.TablePlugins"); dojo.require("dijit._editor._Plugin"); dojo.require("dijit._editor.selection"); dojo.require("dijit.Menu"); dojo.require("dojo.i18n"); dojo.requireLocalization("dojox.editor.plugins", "TableDialog"); dojo.experimental("dojox.editor.plugins.TablePlugins"); // summary: // A series of plugins that give the Editor the ability to create and edit // HTML tables. See the end of this document for all avaiable plugins // and dojox/editorPlugins/tests/editorTablePlugs.html for an example // // example: // |
// | Editor text is here // |
// // TODO: // Currently not supporting merging or splitting cells // // FIXME: Undo is very buggy, and therefore unimeplented in all browsers // except IE - which itself has only been lightly tested. // // FIXME: Selecting multiple table cells in Firefox looks to be impossible. // This affect the 'colorTableCell' plugin. Cells can still be // colored individually or in rows. dojo.declare("dojox.editor.plugins.GlobalTableHandler", dijit._editor._Plugin,{ // summary: // A global object that handles common tasks for all the plugins. Since // there are several plugins that are all calling common methods, it's preferable // that they call a centralized location that either has a set variable or a // timeout to only repeat code-heavy calls when necessary. // tablesConnected:false, currentlyAvailable: false, alwaysAvailable:false, availableCurrentlySet:false, initialized:false, tableData: null, shiftKeyDown:false, editorDomNode: null, undoEnabled: dojo.isIE, //FIXME: doMixins: function(){ dojo.mixin(this.editor,{ getAncestorElement: function(tagName){ return dojo.withGlobal(this.window, "getAncestorElement",dijit._editor.selection, [tagName]); }, hasAncestorElement: function(tagName){ return true return dojo.withGlobal(this.window, "hasAncestorElement",dijit._editor.selection, [tagName]); }, selectElement: function(elem){ dojo.withGlobal(this.window, "selectElement",dijit._editor.selection, [elem]); }, byId: function(id){ return dojo.withGlobal(this.window, "byId", dojo, [id]); }, query: function(arg, scope, returnFirstOnly){ // this shortcut is dubious - not sure scoping is necessary var ar = dojo.withGlobal(this.window, "query", dojo, [arg, scope]); return (returnFirstOnly) ? ar[0] : ar; } }); }, initialize: function(editor){ // summary: // Initialize the global handler upon a plugin's first instance of setEditor // // All plugins will attempt initialization. We only need to do so once. if(this.initialized){ return; } this.initialized = true; this.editor = editor; this.editorDomNode = this.editor.editNode || this.editor.iframe.document.body.firstChild; // RichText should have a mouseup connection to recognize drag-selections // Example would be selecting multiple table cells dojo.connect(this.editorDomNode , "mouseup", this.editor, "onClick"); dojo.connect(this.editor, "onDisplayChanged", this, "checkAvailable"); this.doMixins(); this.connectDraggable(); }, getTableInfo: function(forceNewData){ // summary // Gets the table in focus // Collects info on the table - see return params // if(forceNewData){ this._tempStoreTableData(false); } if(this.tableData){ // tableData is set for a short amount of time, so that all // plugins get the same return without doing the method over console.log("returning current tableData:", this.tableData); return this.tableData; } var tr, trs, td, tds, tbl, cols, tdIndex, trIndex; td = this.editor.getAncestorElement("td"); if(td){ tr = td.parentNode; } tbl = this.editor.getAncestorElement("table"); //console.log("td:", td);console.log("tr:", tr);console.log("tbl:", tbl) tds = dojo.query("td", tbl); tds.forEach(function(d, i){ if(td==d){tdIndex = i} }); trs = dojo.query("tr", tbl); trs.forEach(function(r, i){ if(tr==r){trIndex = i} }); cols = tds.length/trs.length; var o = { tbl:tbl, // focused table td:td, // focused TD tr:tr, // focused TR trs:trs, // rows tds:tds, // cells rows:trs.length,// row amount cols:cols, // column amount tdIndex:tdIndex,// index of focused cell trIndex:trIndex, // index of focused row colIndex:tdIndex%cols }; console.log("NEW tableData:",o); this.tableData = o; this._tempStoreTableData(500); return this.tableData; }, connectDraggable: function(){ // summary // Detects drag-n-drop in the editor (could probably be moved to there) // Currently only checks if item dragged was a TABLE, and removes its align attr // DOES NOT WORK IN FF - it could - but FF's drag detection is a monster // if(!dojo.isIE){ //console.warn("Drag and Drop is currently only detectable in IE."); return } // IE ONLY this.editorDomNode.ondragstart = dojo.hitch(this, "onDragStart"); this.editorDomNode.ondragend = dojo.hitch(this, "onDragEnd"); //NOTES: // FF _ Able to detect the drag-over object (the editor.domNode) // Not able to detect an item's ondrag() event // Don't know why - I actually got it working when there was an error // Something to do with different documents or windows I'm sure // //console.log("connectDraggable", tbl); /*tbl.ondragstart=dojo.hitch(this, "onDragStart"); tbl.addEventListener("dragstart", dojo.hitch(this, "onDragStart"), false); tbl.addEventListener("drag", dojo.hitch(this, "onDragStart2"), false); tbl.addEventListener("dragend", dojo.hitch(this, "onDragStart3"), false); dojo.withGlobal(this.editor.window, "selectElement",dijit._editor.selection, [tbl]); tbl.ondragstart = function(){ console.log ("ondragstart"); }; tbl.ondrag = function(){ alert("drag") //console.log ("ondrag"); */ }, onDragStart: function(){ var e = window.event; if(!e.srcElement.id){ e.srcElement.id = "tbl_"+(new Date().getTime()); } //console.log("onDragStart", e.srcElement.id); }, onDragEnd: function(){ // summary // Detects that an object has been dragged into place // Currently, this code is only used for when a table is dragged // and clears the "align" attribute, so that the table will look // to be more in the place that the user expected. // TODO: This code can be used for other things, most // notably UNDO, which currently is not quite usable. // This code could also find itself in the Editor code when it is // complete. //console.log("onDragEnd"); var e = window.event var node = e.srcElement; var id = node.id; var win = this.editor.window //console.log("NODE:", node.tagName, node.id, dojo.attr(node, "align")); // clearing a table's align attr // TODO: when ondrag becomes more robust, this code block // should move to its own method if(node.tagName.toLowerCase()=="table"){ setTimeout(function(){ var node = dojo.withGlobal(win, "byId", dojo, [id]); dojo.removeAttr(node, "align"); //console.log("set", node.tagName, dojo.attr(node, "align")) }, 100); }";s:7:"summary";s:0:"";}s:54:"dojox.editor.plugins.GlobalTableHandler.checkAvailable";a:4:{s:9:"prototype";s:39:"dojox.editor.plugins.GlobalTableHandler";s:4:"type";s:8:"Function";s:6:"source";s:8470:"dojo.provide("dojox.editor.plugins.TablePlugins"); dojo.require("dijit._editor._Plugin"); dojo.require("dijit._editor.selection"); dojo.require("dijit.Menu"); dojo.require("dojo.i18n"); dojo.requireLocalization("dojox.editor.plugins", "TableDialog"); dojo.experimental("dojox.editor.plugins.TablePlugins"); // summary: // A series of plugins that give the Editor the ability to create and edit // HTML tables. See the end of this document for all avaiable plugins // and dojox/editorPlugins/tests/editorTablePlugs.html for an example // // example: // |
// | Editor text is here // |
// // TODO: // Currently not supporting merging or splitting cells // // FIXME: Undo is very buggy, and therefore unimeplented in all browsers // except IE - which itself has only been lightly tested. // // FIXME: Selecting multiple table cells in Firefox looks to be impossible. // This affect the 'colorTableCell' plugin. Cells can still be // colored individually or in rows. dojo.declare("dojox.editor.plugins.GlobalTableHandler", dijit._editor._Plugin,{ // summary: // A global object that handles common tasks for all the plugins. Since // there are several plugins that are all calling common methods, it's preferable // that they call a centralized location that either has a set variable or a // timeout to only repeat code-heavy calls when necessary. // tablesConnected:false, currentlyAvailable: false, alwaysAvailable:false, availableCurrentlySet:false, initialized:false, tableData: null, shiftKeyDown:false, editorDomNode: null, undoEnabled: dojo.isIE, //FIXME: doMixins: function(){ dojo.mixin(this.editor,{ getAncestorElement: function(tagName){ return dojo.withGlobal(this.window, "getAncestorElement",dijit._editor.selection, [tagName]); }, hasAncestorElement: function(tagName){ return true return dojo.withGlobal(this.window, "hasAncestorElement",dijit._editor.selection, [tagName]); }, selectElement: function(elem){ dojo.withGlobal(this.window, "selectElement",dijit._editor.selection, [elem]); }, byId: function(id){ return dojo.withGlobal(this.window, "byId", dojo, [id]); }, query: function(arg, scope, returnFirstOnly){ // this shortcut is dubious - not sure scoping is necessary var ar = dojo.withGlobal(this.window, "query", dojo, [arg, scope]); return (returnFirstOnly) ? ar[0] : ar; } }); }, initialize: function(editor){ // summary: // Initialize the global handler upon a plugin's first instance of setEditor // // All plugins will attempt initialization. We only need to do so once. if(this.initialized){ return; } this.initialized = true; this.editor = editor; this.editorDomNode = this.editor.editNode || this.editor.iframe.document.body.firstChild; // RichText should have a mouseup connection to recognize drag-selections // Example would be selecting multiple table cells dojo.connect(this.editorDomNode , "mouseup", this.editor, "onClick"); dojo.connect(this.editor, "onDisplayChanged", this, "checkAvailable"); this.doMixins(); this.connectDraggable(); }, getTableInfo: function(forceNewData){ // summary // Gets the table in focus // Collects info on the table - see return params // if(forceNewData){ this._tempStoreTableData(false); } if(this.tableData){ // tableData is set for a short amount of time, so that all // plugins get the same return without doing the method over console.log("returning current tableData:", this.tableData); return this.tableData; } var tr, trs, td, tds, tbl, cols, tdIndex, trIndex; td = this.editor.getAncestorElement("td"); if(td){ tr = td.parentNode; } tbl = this.editor.getAncestorElement("table"); //console.log("td:", td);console.log("tr:", tr);console.log("tbl:", tbl) tds = dojo.query("td", tbl); tds.forEach(function(d, i){ if(td==d){tdIndex = i} }); trs = dojo.query("tr", tbl); trs.forEach(function(r, i){ if(tr==r){trIndex = i} }); cols = tds.length/trs.length; var o = { tbl:tbl, // focused table td:td, // focused TD tr:tr, // focused TR trs:trs, // rows tds:tds, // cells rows:trs.length,// row amount cols:cols, // column amount tdIndex:tdIndex,// index of focused cell trIndex:trIndex, // index of focused row colIndex:tdIndex%cols }; console.log("NEW tableData:",o); this.tableData = o; this._tempStoreTableData(500); return this.tableData; }, connectDraggable: function(){ // summary // Detects drag-n-drop in the editor (could probably be moved to there) // Currently only checks if item dragged was a TABLE, and removes its align attr // DOES NOT WORK IN FF - it could - but FF's drag detection is a monster // if(!dojo.isIE){ //console.warn("Drag and Drop is currently only detectable in IE."); return } // IE ONLY this.editorDomNode.ondragstart = dojo.hitch(this, "onDragStart"); this.editorDomNode.ondragend = dojo.hitch(this, "onDragEnd"); //NOTES: // FF _ Able to detect the drag-over object (the editor.domNode) // Not able to detect an item's ondrag() event // Don't know why - I actually got it working when there was an error // Something to do with different documents or windows I'm sure // //console.log("connectDraggable", tbl); /*tbl.ondragstart=dojo.hitch(this, "onDragStart"); tbl.addEventListener("dragstart", dojo.hitch(this, "onDragStart"), false); tbl.addEventListener("drag", dojo.hitch(this, "onDragStart2"), false); tbl.addEventListener("dragend", dojo.hitch(this, "onDragStart3"), false); dojo.withGlobal(this.editor.window, "selectElement",dijit._editor.selection, [tbl]); tbl.ondragstart = function(){ console.log ("ondragstart"); }; tbl.ondrag = function(){ alert("drag") //console.log ("ondrag"); */ }, onDragStart: function(){ var e = window.event; if(!e.srcElement.id){ e.srcElement.id = "tbl_"+(new Date().getTime()); } //console.log("onDragStart", e.srcElement.id); }, onDragEnd: function(){ // summary // Detects that an object has been dragged into place // Currently, this code is only used for when a table is dragged // and clears the "align" attribute, so that the table will look // to be more in the place that the user expected. // TODO: This code can be used for other things, most // notably UNDO, which currently is not quite usable. // This code could also find itself in the Editor code when it is // complete. //console.log("onDragEnd"); var e = window.event var node = e.srcElement; var id = node.id; var win = this.editor.window //console.log("NODE:", node.tagName, node.id, dojo.attr(node, "align")); // clearing a table's align attr // TODO: when ondrag becomes more robust, this code block // should move to its own method if(node.tagName.toLowerCase()=="table"){ setTimeout(function(){ var node = dojo.withGlobal(win, "byId", dojo, [id]); dojo.removeAttr(node, "align"); //console.log("set", node.tagName, dojo.attr(node, "align")) }, 100); } }, checkAvailable: function(){ // summary // For table plugs // Checking if a table or part of a table has focus so that // Plugs can change their status // if(this.availableCurrentlySet){ // availableCurrentlySet is set for a short amount of time, so that all // plugins get the same return without doing the method over //console.log("availableCurrentlySet:", this.availableCurrentlySet, "currentlyAvailable:", this.currentlyAvailable) return this.currentlyAvailable; } //console.log("G - checkAvailable..."); if(!this.editor) { //console.log("editor not ready") return false; } if(this.alwaysAvailable) { //console.log(" return always available") return true; } this.currentlyAvailable = this.editor.hasAncestorElement("table"); if(this.currentlyAvailable){ this.connectTableKeys(); }else{ this.disconnectTableKeys(); } this._tempAvailability(500); dojo.publish("available", [ this.currentlyAvailable ]); return this.currentlyAvailable;";s:7:"summary";s:0:"";}s:53:"dojox.editor.plugins.GlobalTableHandler._prepareTable";a:6:{s:9:"prototype";s:39:"dojox.editor.plugins.GlobalTableHandler";s:4:"type";s:8:"Function";s:10:"parameters";a:1:{s:3:"tbl";a:1:{s:4:"type";s:0:"";}}s:6:"source";s:8861:"dojo.provide("dojox.editor.plugins.TablePlugins"); dojo.require("dijit._editor._Plugin"); dojo.require("dijit._editor.selection"); dojo.require("dijit.Menu"); dojo.require("dojo.i18n"); dojo.requireLocalization("dojox.editor.plugins", "TableDialog"); dojo.experimental("dojox.editor.plugins.TablePlugins"); // summary: // A series of plugins that give the Editor the ability to create and edit // HTML tables. See the end of this document for all avaiable plugins // and dojox/editorPlugins/tests/editorTablePlugs.html for an example // // example: // |
// | Editor text is here // |
// // TODO: // Currently not supporting merging or splitting cells // // FIXME: Undo is very buggy, and therefore unimeplented in all browsers // except IE - which itself has only been lightly tested. // // FIXME: Selecting multiple table cells in Firefox looks to be impossible. // This affect the 'colorTableCell' plugin. Cells can still be // colored individually or in rows. dojo.declare("dojox.editor.plugins.GlobalTableHandler", dijit._editor._Plugin,{ // summary: // A global object that handles common tasks for all the plugins. Since // there are several plugins that are all calling common methods, it's preferable // that they call a centralized location that either has a set variable or a // timeout to only repeat code-heavy calls when necessary. // tablesConnected:false, currentlyAvailable: false, alwaysAvailable:false, availableCurrentlySet:false, initialized:false, tableData: null, shiftKeyDown:false, editorDomNode: null, undoEnabled: dojo.isIE, //FIXME: doMixins: function(){ dojo.mixin(this.editor,{ getAncestorElement: function(tagName){ return dojo.withGlobal(this.window, "getAncestorElement",dijit._editor.selection, [tagName]); }, hasAncestorElement: function(tagName){ return true return dojo.withGlobal(this.window, "hasAncestorElement",dijit._editor.selection, [tagName]); }, selectElement: function(elem){ dojo.withGlobal(this.window, "selectElement",dijit._editor.selection, [elem]); }, byId: function(id){ return dojo.withGlobal(this.window, "byId", dojo, [id]); }, query: function(arg, scope, returnFirstOnly){ // this shortcut is dubious - not sure scoping is necessary var ar = dojo.withGlobal(this.window, "query", dojo, [arg, scope]); return (returnFirstOnly) ? ar[0] : ar; } }); }, initialize: function(editor){ // summary: // Initialize the global handler upon a plugin's first instance of setEditor // // All plugins will attempt initialization. We only need to do so once. if(this.initialized){ return; } this.initialized = true; this.editor = editor; this.editorDomNode = this.editor.editNode || this.editor.iframe.document.body.firstChild; // RichText should have a mouseup connection to recognize drag-selections // Example would be selecting multiple table cells dojo.connect(this.editorDomNode , "mouseup", this.editor, "onClick"); dojo.connect(this.editor, "onDisplayChanged", this, "checkAvailable"); this.doMixins(); this.connectDraggable(); }, getTableInfo: function(forceNewData){ // summary // Gets the table in focus // Collects info on the table - see return params // if(forceNewData){ this._tempStoreTableData(false); } if(this.tableData){ // tableData is set for a short amount of time, so that all // plugins get the same return without doing the method over console.log("returning current tableData:", this.tableData); return this.tableData; } var tr, trs, td, tds, tbl, cols, tdIndex, trIndex; td = this.editor.getAncestorElement("td"); if(td){ tr = td.parentNode; } tbl = this.editor.getAncestorElement("table"); //console.log("td:", td);console.log("tr:", tr);console.log("tbl:", tbl) tds = dojo.query("td", tbl); tds.forEach(function(d, i){ if(td==d){tdIndex = i} }); trs = dojo.query("tr", tbl); trs.forEach(function(r, i){ if(tr==r){trIndex = i} }); cols = tds.length/trs.length; var o = { tbl:tbl, // focused table td:td, // focused TD tr:tr, // focused TR trs:trs, // rows tds:tds, // cells rows:trs.length,// row amount cols:cols, // column amount tdIndex:tdIndex,// index of focused cell trIndex:trIndex, // index of focused row colIndex:tdIndex%cols }; console.log("NEW tableData:",o); this.tableData = o; this._tempStoreTableData(500); return this.tableData; }, connectDraggable: function(){ // summary // Detects drag-n-drop in the editor (could probably be moved to there) // Currently only checks if item dragged was a TABLE, and removes its align attr // DOES NOT WORK IN FF - it could - but FF's drag detection is a monster // if(!dojo.isIE){ //console.warn("Drag and Drop is currently only detectable in IE."); return } // IE ONLY this.editorDomNode.ondragstart = dojo.hitch(this, "onDragStart"); this.editorDomNode.ondragend = dojo.hitch(this, "onDragEnd"); //NOTES: // FF _ Able to detect the drag-over object (the editor.domNode) // Not able to detect an item's ondrag() event // Don't know why - I actually got it working when there was an error // Something to do with different documents or windows I'm sure // //console.log("connectDraggable", tbl); /*tbl.ondragstart=dojo.hitch(this, "onDragStart"); tbl.addEventListener("dragstart", dojo.hitch(this, "onDragStart"), false); tbl.addEventListener("drag", dojo.hitch(this, "onDragStart2"), false); tbl.addEventListener("dragend", dojo.hitch(this, "onDragStart3"), false); dojo.withGlobal(this.editor.window, "selectElement",dijit._editor.selection, [tbl]); tbl.ondragstart = function(){ console.log ("ondragstart"); }; tbl.ondrag = function(){ alert("drag") //console.log ("ondrag"); */ }, onDragStart: function(){ var e = window.event; if(!e.srcElement.id){ e.srcElement.id = "tbl_"+(new Date().getTime()); } //console.log("onDragStart", e.srcElement.id); }, onDragEnd: function(){ // summary // Detects that an object has been dragged into place // Currently, this code is only used for when a table is dragged // and clears the "align" attribute, so that the table will look // to be more in the place that the user expected. // TODO: This code can be used for other things, most // notably UNDO, which currently is not quite usable. // This code could also find itself in the Editor code when it is // complete. //console.log("onDragEnd"); var e = window.event var node = e.srcElement; var id = node.id; var win = this.editor.window //console.log("NODE:", node.tagName, node.id, dojo.attr(node, "align")); // clearing a table's align attr // TODO: when ondrag becomes more robust, this code block // should move to its own method if(node.tagName.toLowerCase()=="table"){ setTimeout(function(){ var node = dojo.withGlobal(win, "byId", dojo, [id]); dojo.removeAttr(node, "align"); //console.log("set", node.tagName, dojo.attr(node, "align")) }, 100); } }, checkAvailable: function(){ // summary // For table plugs // Checking if a table or part of a table has focus so that // Plugs can change their status // if(this.availableCurrentlySet){ // availableCurrentlySet is set for a short amount of time, so that all // plugins get the same return without doing the method over //console.log("availableCurrentlySet:", this.availableCurrentlySet, "currentlyAvailable:", this.currentlyAvailable) return this.currentlyAvailable; } //console.log("G - checkAvailable..."); if(!this.editor) { //console.log("editor not ready") return false; } if(this.alwaysAvailable) { //console.log(" return always available") return true; } this.currentlyAvailable = this.editor.hasAncestorElement("table"); if(this.currentlyAvailable){ this.connectTableKeys(); }else{ this.disconnectTableKeys(); } this._tempAvailability(500); dojo.publish("available", [ this.currentlyAvailable ]); return this.currentlyAvailable; }, _prepareTable: function(tbl){ // For IE's sake, we are adding IDs to the TDs if none is there // We go ahead and use it for other code for convenience // var tds = this.editor.query("td", tbl); console.log("prep:", tds, tbl) if(!tds[0].id){ tds.forEach(function(td, i){ if(!td.id){ td.id = "tdid"+i+this.getTimeStamp(); } }, this); } return tds;";s:7:"private";b:1;s:7:"summary";s:0:"";}s:52:"dojox.editor.plugins.GlobalTableHandler.getTimeStamp";a:4:{s:9:"prototype";s:39:"dojox.editor.plugins.GlobalTableHandler";s:4:"type";s:8:"Function";s:6:"source";s:55:" return Math.floor(new Date().getTime() * 0.00000001);";s:7:"summary";s:0:"";}s:59:"dojox.editor.plugins.GlobalTableHandler._tempStoreTableData";a:6:{s:9:"prototype";s:39:"dojox.editor.plugins.GlobalTableHandler";s:4:"type";s:8:"Function";s:10:"parameters";a:1:{s:4:"type";a:1:{s:4:"type";s:0:"";}}s:6:"source";s:9408:"dojo.provide("dojox.editor.plugins.TablePlugins"); dojo.require("dijit._editor._Plugin"); dojo.require("dijit._editor.selection"); dojo.require("dijit.Menu"); dojo.require("dojo.i18n"); dojo.requireLocalization("dojox.editor.plugins", "TableDialog"); dojo.experimental("dojox.editor.plugins.TablePlugins"); // summary: // A series of plugins that give the Editor the ability to create and edit // HTML tables. See the end of this document for all avaiable plugins // and dojox/editorPlugins/tests/editorTablePlugs.html for an example // // example: // |
// | Editor text is here // |
// // TODO: // Currently not supporting merging or splitting cells // // FIXME: Undo is very buggy, and therefore unimeplented in all browsers // except IE - which itself has only been lightly tested. // // FIXME: Selecting multiple table cells in Firefox looks to be impossible. // This affect the 'colorTableCell' plugin. Cells can still be // colored individually or in rows. dojo.declare("dojox.editor.plugins.GlobalTableHandler", dijit._editor._Plugin,{ // summary: // A global object that handles common tasks for all the plugins. Since // there are several plugins that are all calling common methods, it's preferable // that they call a centralized location that either has a set variable or a // timeout to only repeat code-heavy calls when necessary. // tablesConnected:false, currentlyAvailable: false, alwaysAvailable:false, availableCurrentlySet:false, initialized:false, tableData: null, shiftKeyDown:false, editorDomNode: null, undoEnabled: dojo.isIE, //FIXME: doMixins: function(){ dojo.mixin(this.editor,{ getAncestorElement: function(tagName){ return dojo.withGlobal(this.window, "getAncestorElement",dijit._editor.selection, [tagName]); }, hasAncestorElement: function(tagName){ return true return dojo.withGlobal(this.window, "hasAncestorElement",dijit._editor.selection, [tagName]); }, selectElement: function(elem){ dojo.withGlobal(this.window, "selectElement",dijit._editor.selection, [elem]); }, byId: function(id){ return dojo.withGlobal(this.window, "byId", dojo, [id]); }, query: function(arg, scope, returnFirstOnly){ // this shortcut is dubious - not sure scoping is necessary var ar = dojo.withGlobal(this.window, "query", dojo, [arg, scope]); return (returnFirstOnly) ? ar[0] : ar; } }); }, initialize: function(editor){ // summary: // Initialize the global handler upon a plugin's first instance of setEditor // // All plugins will attempt initialization. We only need to do so once. if(this.initialized){ return; } this.initialized = true; this.editor = editor; this.editorDomNode = this.editor.editNode || this.editor.iframe.document.body.firstChild; // RichText should have a mouseup connection to recognize drag-selections // Example would be selecting multiple table cells dojo.connect(this.editorDomNode , "mouseup", this.editor, "onClick"); dojo.connect(this.editor, "onDisplayChanged", this, "checkAvailable"); this.doMixins(); this.connectDraggable(); }, getTableInfo: function(forceNewData){ // summary // Gets the table in focus // Collects info on the table - see return params // if(forceNewData){ this._tempStoreTableData(false); } if(this.tableData){ // tableData is set for a short amount of time, so that all // plugins get the same return without doing the method over console.log("returning current tableData:", this.tableData); return this.tableData; } var tr, trs, td, tds, tbl, cols, tdIndex, trIndex; td = this.editor.getAncestorElement("td"); if(td){ tr = td.parentNode; } tbl = this.editor.getAncestorElement("table"); //console.log("td:", td);console.log("tr:", tr);console.log("tbl:", tbl) tds = dojo.query("td", tbl); tds.forEach(function(d, i){ if(td==d){tdIndex = i} }); trs = dojo.query("tr", tbl); trs.forEach(function(r, i){ if(tr==r){trIndex = i} }); cols = tds.length/trs.length; var o = { tbl:tbl, // focused table td:td, // focused TD tr:tr, // focused TR trs:trs, // rows tds:tds, // cells rows:trs.length,// row amount cols:cols, // column amount tdIndex:tdIndex,// index of focused cell trIndex:trIndex, // index of focused row colIndex:tdIndex%cols }; console.log("NEW tableData:",o); this.tableData = o; this._tempStoreTableData(500); return this.tableData; }, connectDraggable: function(){ // summary // Detects drag-n-drop in the editor (could probably be moved to there) // Currently only checks if item dragged was a TABLE, and removes its align attr // DOES NOT WORK IN FF - it could - but FF's drag detection is a monster // if(!dojo.isIE){ //console.warn("Drag and Drop is currently only detectable in IE."); return } // IE ONLY this.editorDomNode.ondragstart = dojo.hitch(this, "onDragStart"); this.editorDomNode.ondragend = dojo.hitch(this, "onDragEnd"); //NOTES: // FF _ Able to detect the drag-over object (the editor.domNode) // Not able to detect an item's ondrag() event // Don't know why - I actually got it working when there was an error // Something to do with different documents or windows I'm sure // //console.log("connectDraggable", tbl); /*tbl.ondragstart=dojo.hitch(this, "onDragStart"); tbl.addEventListener("dragstart", dojo.hitch(this, "onDragStart"), false); tbl.addEventListener("drag", dojo.hitch(this, "onDragStart2"), false); tbl.addEventListener("dragend", dojo.hitch(this, "onDragStart3"), false); dojo.withGlobal(this.editor.window, "selectElement",dijit._editor.selection, [tbl]); tbl.ondragstart = function(){ console.log ("ondragstart"); }; tbl.ondrag = function(){ alert("drag") //console.log ("ondrag"); */ }, onDragStart: function(){ var e = window.event; if(!e.srcElement.id){ e.srcElement.id = "tbl_"+(new Date().getTime()); } //console.log("onDragStart", e.srcElement.id); }, onDragEnd: function(){ // summary // Detects that an object has been dragged into place // Currently, this code is only used for when a table is dragged // and clears the "align" attribute, so that the table will look // to be more in the place that the user expected. // TODO: This code can be used for other things, most // notably UNDO, which currently is not quite usable. // This code could also find itself in the Editor code when it is // complete. //console.log("onDragEnd"); var e = window.event var node = e.srcElement; var id = node.id; var win = this.editor.window //console.log("NODE:", node.tagName, node.id, dojo.attr(node, "align")); // clearing a table's align attr // TODO: when ondrag becomes more robust, this code block // should move to its own method if(node.tagName.toLowerCase()=="table"){ setTimeout(function(){ var node = dojo.withGlobal(win, "byId", dojo, [id]); dojo.removeAttr(node, "align"); //console.log("set", node.tagName, dojo.attr(node, "align")) }, 100); } }, checkAvailable: function(){ // summary // For table plugs // Checking if a table or part of a table has focus so that // Plugs can change their status // if(this.availableCurrentlySet){ // availableCurrentlySet is set for a short amount of time, so that all // plugins get the same return without doing the method over //console.log("availableCurrentlySet:", this.availableCurrentlySet, "currentlyAvailable:", this.currentlyAvailable) return this.currentlyAvailable; } //console.log("G - checkAvailable..."); if(!this.editor) { //console.log("editor not ready") return false; } if(this.alwaysAvailable) { //console.log(" return always available") return true; } this.currentlyAvailable = this.editor.hasAncestorElement("table"); if(this.currentlyAvailable){ this.connectTableKeys(); }else{ this.disconnectTableKeys(); } this._tempAvailability(500); dojo.publish("available", [ this.currentlyAvailable ]); return this.currentlyAvailable; }, _prepareTable: function(tbl){ // For IE's sake, we are adding IDs to the TDs if none is there // We go ahead and use it for other code for convenience // var tds = this.editor.query("td", tbl); console.log("prep:", tds, tbl) if(!tds[0].id){ tds.forEach(function(td, i){ if(!td.id){ td.id = "tdid"+i+this.getTimeStamp(); } }, this); } return tds; }, getTimeStamp: function(){ return Math.floor(new Date().getTime() * 0.00000001); }, _tempStoreTableData: function(type){ // caching or clearing table data, depending on the arg // if(type===true){ //store indefinitely }else if(type===false){ // clear object this.tableData = null; }else if(type===undefined){ console.warn("_tempStoreTableData must be passed an argument") }else{ // type is a number/ms setTimeout(dojo.hitch(this, function(){ this.tableData = null; }), type); }";s:7:"private";b:1;s:7:"summary";s:0:"";}s:57:"dojox.editor.plugins.GlobalTableHandler._tempAvailability";a:6:{s:9:"prototype";s:39:"dojox.editor.plugins.GlobalTableHandler";s:4:"type";s:8:"Function";s:10:"parameters";a:1:{s:4:"type";a:1:{s:4:"type";s:0:"";}}s:6:"source";s:9960:"dojo.provide("dojox.editor.plugins.TablePlugins"); dojo.require("dijit._editor._Plugin"); dojo.require("dijit._editor.selection"); dojo.require("dijit.Menu"); dojo.require("dojo.i18n"); dojo.requireLocalization("dojox.editor.plugins", "TableDialog"); dojo.experimental("dojox.editor.plugins.TablePlugins"); // summary: // A series of plugins that give the Editor the ability to create and edit // HTML tables. See the end of this document for all avaiable plugins // and dojox/editorPlugins/tests/editorTablePlugs.html for an example // // example: // |
// | Editor text is here // |
// // TODO: // Currently not supporting merging or splitting cells // // FIXME: Undo is very buggy, and therefore unimeplented in all browsers // except IE - which itself has only been lightly tested. // // FIXME: Selecting multiple table cells in Firefox looks to be impossible. // This affect the 'colorTableCell' plugin. Cells can still be // colored individually or in rows. dojo.declare("dojox.editor.plugins.GlobalTableHandler", dijit._editor._Plugin,{ // summary: // A global object that handles common tasks for all the plugins. Since // there are several plugins that are all calling common methods, it's preferable // that they call a centralized location that either has a set variable or a // timeout to only repeat code-heavy calls when necessary. // tablesConnected:false, currentlyAvailable: false, alwaysAvailable:false, availableCurrentlySet:false, initialized:false, tableData: null, shiftKeyDown:false, editorDomNode: null, undoEnabled: dojo.isIE, //FIXME: doMixins: function(){ dojo.mixin(this.editor,{ getAncestorElement: function(tagName){ return dojo.withGlobal(this.window, "getAncestorElement",dijit._editor.selection, [tagName]); }, hasAncestorElement: function(tagName){ return true return dojo.withGlobal(this.window, "hasAncestorElement",dijit._editor.selection, [tagName]); }, selectElement: function(elem){ dojo.withGlobal(this.window, "selectElement",dijit._editor.selection, [elem]); }, byId: function(id){ return dojo.withGlobal(this.window, "byId", dojo, [id]); }, query: function(arg, scope, returnFirstOnly){ // this shortcut is dubious - not sure scoping is necessary var ar = dojo.withGlobal(this.window, "query", dojo, [arg, scope]); return (returnFirstOnly) ? ar[0] : ar; } }); }, initialize: function(editor){ // summary: // Initialize the global handler upon a plugin's first instance of setEditor // // All plugins will attempt initialization. We only need to do so once. if(this.initialized){ return; } this.initialized = true; this.editor = editor; this.editorDomNode = this.editor.editNode || this.editor.iframe.document.body.firstChild; // RichText should have a mouseup connection to recognize drag-selections // Example would be selecting multiple table cells dojo.connect(this.editorDomNode , "mouseup", this.editor, "onClick"); dojo.connect(this.editor, "onDisplayChanged", this, "checkAvailable"); this.doMixins(); this.connectDraggable(); }, getTableInfo: function(forceNewData){ // summary // Gets the table in focus // Collects info on the table - see return params // if(forceNewData){ this._tempStoreTableData(false); } if(this.tableData){ // tableData is set for a short amount of time, so that all // plugins get the same return without doing the method over console.log("returning current tableData:", this.tableData); return this.tableData; } var tr, trs, td, tds, tbl, cols, tdIndex, trIndex; td = this.editor.getAncestorElement("td"); if(td){ tr = td.parentNode; } tbl = this.editor.getAncestorElement("table"); //console.log("td:", td);console.log("tr:", tr);console.log("tbl:", tbl) tds = dojo.query("td", tbl); tds.forEach(function(d, i){ if(td==d){tdIndex = i} }); trs = dojo.query("tr", tbl); trs.forEach(function(r, i){ if(tr==r){trIndex = i} }); cols = tds.length/trs.length; var o = { tbl:tbl, // focused table td:td, // focused TD tr:tr, // focused TR trs:trs, // rows tds:tds, // cells rows:trs.length,// row amount cols:cols, // column amount tdIndex:tdIndex,// index of focused cell trIndex:trIndex, // index of focused row colIndex:tdIndex%cols }; console.log("NEW tableData:",o); this.tableData = o; this._tempStoreTableData(500); return this.tableData; }, connectDraggable: function(){ // summary // Detects drag-n-drop in the editor (could probably be moved to there) // Currently only checks if item dragged was a TABLE, and removes its align attr // DOES NOT WORK IN FF - it could - but FF's drag detection is a monster // if(!dojo.isIE){ //console.warn("Drag and Drop is currently only detectable in IE."); return } // IE ONLY this.editorDomNode.ondragstart = dojo.hitch(this, "onDragStart"); this.editorDomNode.ondragend = dojo.hitch(this, "onDragEnd"); //NOTES: // FF _ Able to detect the drag-over object (the editor.domNode) // Not able to detect an item's ondrag() event // Don't know why - I actually got it working when there was an error // Something to do with different documents or windows I'm sure // //console.log("connectDraggable", tbl); /*tbl.ondragstart=dojo.hitch(this, "onDragStart"); tbl.addEventListener("dragstart", dojo.hitch(this, "onDragStart"), false); tbl.addEventListener("drag", dojo.hitch(this, "onDragStart2"), false); tbl.addEventListener("dragend", dojo.hitch(this, "onDragStart3"), false); dojo.withGlobal(this.editor.window, "selectElement",dijit._editor.selection, [tbl]); tbl.ondragstart = function(){ console.log ("ondragstart"); }; tbl.ondrag = function(){ alert("drag") //console.log ("ondrag"); */ }, onDragStart: function(){ var e = window.event; if(!e.srcElement.id){ e.srcElement.id = "tbl_"+(new Date().getTime()); } //console.log("onDragStart", e.srcElement.id); }, onDragEnd: function(){ // summary // Detects that an object has been dragged into place // Currently, this code is only used for when a table is dragged // and clears the "align" attribute, so that the table will look // to be more in the place that the user expected. // TODO: This code can be used for other things, most // notably UNDO, which currently is not quite usable. // This code could also find itself in the Editor code when it is // complete. //console.log("onDragEnd"); var e = window.event var node = e.srcElement; var id = node.id; var win = this.editor.window //console.log("NODE:", node.tagName, node.id, dojo.attr(node, "align")); // clearing a table's align attr // TODO: when ondrag becomes more robust, this code block // should move to its own method if(node.tagName.toLowerCase()=="table"){ setTimeout(function(){ var node = dojo.withGlobal(win, "byId", dojo, [id]); dojo.removeAttr(node, "align"); //console.log("set", node.tagName, dojo.attr(node, "align")) }, 100); } }, checkAvailable: function(){ // summary // For table plugs // Checking if a table or part of a table has focus so that // Plugs can change their status // if(this.availableCurrentlySet){ // availableCurrentlySet is set for a short amount of time, so that all // plugins get the same return without doing the method over //console.log("availableCurrentlySet:", this.availableCurrentlySet, "currentlyAvailable:", this.currentlyAvailable) return this.currentlyAvailable; } //console.log("G - checkAvailable..."); if(!this.editor) { //console.log("editor not ready") return false; } if(this.alwaysAvailable) { //console.log(" return always available") return true; } this.currentlyAvailable = this.editor.hasAncestorElement("table"); if(this.currentlyAvailable){ this.connectTableKeys(); }else{ this.disconnectTableKeys(); } this._tempAvailability(500); dojo.publish("available", [ this.currentlyAvailable ]); return this.currentlyAvailable; }, _prepareTable: function(tbl){ // For IE's sake, we are adding IDs to the TDs if none is there // We go ahead and use it for other code for convenience // var tds = this.editor.query("td", tbl); console.log("prep:", tds, tbl) if(!tds[0].id){ tds.forEach(function(td, i){ if(!td.id){ td.id = "tdid"+i+this.getTimeStamp(); } }, this); } return tds; }, getTimeStamp: function(){ return Math.floor(new Date().getTime() * 0.00000001); }, _tempStoreTableData: function(type){ // caching or clearing table data, depending on the arg // if(type===true){ //store indefinitely }else if(type===false){ // clear object this.tableData = null; }else if(type===undefined){ console.warn("_tempStoreTableData must be passed an argument") }else{ // type is a number/ms setTimeout(dojo.hitch(this, function(){ this.tableData = null; }), type); } }, _tempAvailability: function(type){ // caching or clearing availability, depending on the arg if(type===true){ //store indefinitely this.availableCurrentlySet = true; }else if(type===false){ // clear object this.availableCurrentlySet = false; }else if(type===undefined){ console.warn("_tempAvailability must be passed an argument") }else{ // type is a number/ms this.availableCurrentlySet = true; setTimeout(dojo.hitch(this, function(){ this.availableCurrentlySet = false; }), type); }";s:7:"private";b:1;s:7:"summary";s:0:"";}s:56:"dojox.editor.plugins.GlobalTableHandler.connectTableKeys";a:4:{s:9:"prototype";s:39:"dojox.editor.plugins.GlobalTableHandler";s:4:"type";s:8:"Function";s:6:"source";s:10557:"dojo.provide("dojox.editor.plugins.TablePlugins"); dojo.require("dijit._editor._Plugin"); dojo.require("dijit._editor.selection"); dojo.require("dijit.Menu"); dojo.require("dojo.i18n"); dojo.requireLocalization("dojox.editor.plugins", "TableDialog"); dojo.experimental("dojox.editor.plugins.TablePlugins"); // summary: // A series of plugins that give the Editor the ability to create and edit // HTML tables. See the end of this document for all avaiable plugins // and dojox/editorPlugins/tests/editorTablePlugs.html for an example // // example: // |
// | Editor text is here // |
// // TODO: // Currently not supporting merging or splitting cells // // FIXME: Undo is very buggy, and therefore unimeplented in all browsers // except IE - which itself has only been lightly tested. // // FIXME: Selecting multiple table cells in Firefox looks to be impossible. // This affect the 'colorTableCell' plugin. Cells can still be // colored individually or in rows. dojo.declare("dojox.editor.plugins.GlobalTableHandler", dijit._editor._Plugin,{ // summary: // A global object that handles common tasks for all the plugins. Since // there are several plugins that are all calling common methods, it's preferable // that they call a centralized location that either has a set variable or a // timeout to only repeat code-heavy calls when necessary. // tablesConnected:false, currentlyAvailable: false, alwaysAvailable:false, availableCurrentlySet:false, initialized:false, tableData: null, shiftKeyDown:false, editorDomNode: null, undoEnabled: dojo.isIE, //FIXME: doMixins: function(){ dojo.mixin(this.editor,{ getAncestorElement: function(tagName){ return dojo.withGlobal(this.window, "getAncestorElement",dijit._editor.selection, [tagName]); }, hasAncestorElement: function(tagName){ return true return dojo.withGlobal(this.window, "hasAncestorElement",dijit._editor.selection, [tagName]); }, selectElement: function(elem){ dojo.withGlobal(this.window, "selectElement",dijit._editor.selection, [elem]); }, byId: function(id){ return dojo.withGlobal(this.window, "byId", dojo, [id]); }, query: function(arg, scope, returnFirstOnly){ // this shortcut is dubious - not sure scoping is necessary var ar = dojo.withGlobal(this.window, "query", dojo, [arg, scope]); return (returnFirstOnly) ? ar[0] : ar; } }); }, initialize: function(editor){ // summary: // Initialize the global handler upon a plugin's first instance of setEditor // // All plugins will attempt initialization. We only need to do so once. if(this.initialized){ return; } this.initialized = true; this.editor = editor; this.editorDomNode = this.editor.editNode || this.editor.iframe.document.body.firstChild; // RichText should have a mouseup connection to recognize drag-selections // Example would be selecting multiple table cells dojo.connect(this.editorDomNode , "mouseup", this.editor, "onClick"); dojo.connect(this.editor, "onDisplayChanged", this, "checkAvailable"); this.doMixins(); this.connectDraggable(); }, getTableInfo: function(forceNewData){ // summary // Gets the table in focus // Collects info on the table - see return params // if(forceNewData){ this._tempStoreTableData(false); } if(this.tableData){ // tableData is set for a short amount of time, so that all // plugins get the same return without doing the method over console.log("returning current tableData:", this.tableData); return this.tableData; } var tr, trs, td, tds, tbl, cols, tdIndex, trIndex; td = this.editor.getAncestorElement("td"); if(td){ tr = td.parentNode; } tbl = this.editor.getAncestorElement("table"); //console.log("td:", td);console.log("tr:", tr);console.log("tbl:", tbl) tds = dojo.query("td", tbl); tds.forEach(function(d, i){ if(td==d){tdIndex = i} }); trs = dojo.query("tr", tbl); trs.forEach(function(r, i){ if(tr==r){trIndex = i} }); cols = tds.length/trs.length; var o = { tbl:tbl, // focused table td:td, // focused TD tr:tr, // focused TR trs:trs, // rows tds:tds, // cells rows:trs.length,// row amount cols:cols, // column amount tdIndex:tdIndex,// index of focused cell trIndex:trIndex, // index of focused row colIndex:tdIndex%cols }; console.log("NEW tableData:",o); this.tableData = o; this._tempStoreTableData(500); return this.tableData; }, connectDraggable: function(){ // summary // Detects drag-n-drop in the editor (could probably be moved to there) // Currently only checks if item dragged was a TABLE, and removes its align attr // DOES NOT WORK IN FF - it could - but FF's drag detection is a monster // if(!dojo.isIE){ //console.warn("Drag and Drop is currently only detectable in IE."); return } // IE ONLY this.editorDomNode.ondragstart = dojo.hitch(this, "onDragStart"); this.editorDomNode.ondragend = dojo.hitch(this, "onDragEnd"); //NOTES: // FF _ Able to detect the drag-over object (the editor.domNode) // Not able to detect an item's ondrag() event // Don't know why - I actually got it working when there was an error // Something to do with different documents or windows I'm sure // //console.log("connectDraggable", tbl); /*tbl.ondragstart=dojo.hitch(this, "onDragStart"); tbl.addEventListener("dragstart", dojo.hitch(this, "onDragStart"), false); tbl.addEventListener("drag", dojo.hitch(this, "onDragStart2"), false); tbl.addEventListener("dragend", dojo.hitch(this, "onDragStart3"), false); dojo.withGlobal(this.editor.window, "selectElement",dijit._editor.selection, [tbl]); tbl.ondragstart = function(){ console.log ("ondragstart"); }; tbl.ondrag = function(){ alert("drag") //console.log ("ondrag"); */ }, onDragStart: function(){ var e = window.event; if(!e.srcElement.id){ e.srcElement.id = "tbl_"+(new Date().getTime()); } //console.log("onDragStart", e.srcElement.id); }, onDragEnd: function(){ // summary // Detects that an object has been dragged into place // Currently, this code is only used for when a table is dragged // and clears the "align" attribute, so that the table will look // to be more in the place that the user expected. // TODO: This code can be used for other things, most // notably UNDO, which currently is not quite usable. // This code could also find itself in the Editor code when it is // complete. //console.log("onDragEnd"); var e = window.event var node = e.srcElement; var id = node.id; var win = this.editor.window //console.log("NODE:", node.tagName, node.id, dojo.attr(node, "align")); // clearing a table's align attr // TODO: when ondrag becomes more robust, this code block // should move to its own method if(node.tagName.toLowerCase()=="table"){ setTimeout(function(){ var node = dojo.withGlobal(win, "byId", dojo, [id]); dojo.removeAttr(node, "align"); //console.log("set", node.tagName, dojo.attr(node, "align")) }, 100); } }, checkAvailable: function(){ // summary // For table plugs // Checking if a table or part of a table has focus so that // Plugs can change their status // if(this.availableCurrentlySet){ // availableCurrentlySet is set for a short amount of time, so that all // plugins get the same return without doing the method over //console.log("availableCurrentlySet:", this.availableCurrentlySet, "currentlyAvailable:", this.currentlyAvailable) return this.currentlyAvailable; } //console.log("G - checkAvailable..."); if(!this.editor) { //console.log("editor not ready") return false; } if(this.alwaysAvailable) { //console.log(" return always available") return true; } this.currentlyAvailable = this.editor.hasAncestorElement("table"); if(this.currentlyAvailable){ this.connectTableKeys(); }else{ this.disconnectTableKeys(); } this._tempAvailability(500); dojo.publish("available", [ this.currentlyAvailable ]); return this.currentlyAvailable; }, _prepareTable: function(tbl){ // For IE's sake, we are adding IDs to the TDs if none is there // We go ahead and use it for other code for convenience // var tds = this.editor.query("td", tbl); console.log("prep:", tds, tbl) if(!tds[0].id){ tds.forEach(function(td, i){ if(!td.id){ td.id = "tdid"+i+this.getTimeStamp(); } }, this); } return tds; }, getTimeStamp: function(){ return Math.floor(new Date().getTime() * 0.00000001); }, _tempStoreTableData: function(type){ // caching or clearing table data, depending on the arg // if(type===true){ //store indefinitely }else if(type===false){ // clear object this.tableData = null; }else if(type===undefined){ console.warn("_tempStoreTableData must be passed an argument") }else{ // type is a number/ms setTimeout(dojo.hitch(this, function(){ this.tableData = null; }), type); } }, _tempAvailability: function(type){ // caching or clearing availability, depending on the arg if(type===true){ //store indefinitely this.availableCurrentlySet = true; }else if(type===false){ // clear object this.availableCurrentlySet = false; }else if(type===undefined){ console.warn("_tempAvailability must be passed an argument") }else{ // type is a number/ms this.availableCurrentlySet = true; setTimeout(dojo.hitch(this, function(){ this.availableCurrentlySet = false; }), type); } }, connectTableKeys: function(){ // summary // When a table is in focus, start detecting keys // Mainly checking for the TAB key so user can tab // through a table (blocking the browser's desire to // tab away from teh editor completely) if(this.tablesConnected){ return; } this.tablesConnected = true; var node = (this.editor.iframe) ? this.editor.document : this.editor.editNode; this.cnKeyDn = dojo.connect(node, "onkeydown", this, "onKeyDown"); this.cnKeyUp = dojo.connect(node, "onkeyup", this, "onKeyUp"); dojo.connect(node, "onkeypress", this, "onKeyUp");";s:7:"summary";s:0:"";}s:59:"dojox.editor.plugins.GlobalTableHandler.disconnectTableKeys";a:4:{s:9:"prototype";s:39:"dojox.editor.plugins.GlobalTableHandler";s:4:"type";s:8:"Function";s:6:"source";s:10727:"dojo.provide("dojox.editor.plugins.TablePlugins"); dojo.require("dijit._editor._Plugin"); dojo.require("dijit._editor.selection"); dojo.require("dijit.Menu"); dojo.require("dojo.i18n"); dojo.requireLocalization("dojox.editor.plugins", "TableDialog"); dojo.experimental("dojox.editor.plugins.TablePlugins"); // summary: // A series of plugins that give the Editor the ability to create and edit // HTML tables. See the end of this document for all avaiable plugins // and dojox/editorPlugins/tests/editorTablePlugs.html for an example // // example: // |
// | Editor text is here // |
// // TODO: // Currently not supporting merging or splitting cells // // FIXME: Undo is very buggy, and therefore unimeplented in all browsers // except IE - which itself has only been lightly tested. // // FIXME: Selecting multiple table cells in Firefox looks to be impossible. // This affect the 'colorTableCell' plugin. Cells can still be // colored individually or in rows. dojo.declare("dojox.editor.plugins.GlobalTableHandler", dijit._editor._Plugin,{ // summary: // A global object that handles common tasks for all the plugins. Since // there are several plugins that are all calling common methods, it's preferable // that they call a centralized location that either has a set variable or a // timeout to only repeat code-heavy calls when necessary. // tablesConnected:false, currentlyAvailable: false, alwaysAvailable:false, availableCurrentlySet:false, initialized:false, tableData: null, shiftKeyDown:false, editorDomNode: null, undoEnabled: dojo.isIE, //FIXME: doMixins: function(){ dojo.mixin(this.editor,{ getAncestorElement: function(tagName){ return dojo.withGlobal(this.window, "getAncestorElement",dijit._editor.selection, [tagName]); }, hasAncestorElement: function(tagName){ return true return dojo.withGlobal(this.window, "hasAncestorElement",dijit._editor.selection, [tagName]); }, selectElement: function(elem){ dojo.withGlobal(this.window, "selectElement",dijit._editor.selection, [elem]); }, byId: function(id){ return dojo.withGlobal(this.window, "byId", dojo, [id]); }, query: function(arg, scope, returnFirstOnly){ // this shortcut is dubious - not sure scoping is necessary var ar = dojo.withGlobal(this.window, "query", dojo, [arg, scope]); return (returnFirstOnly) ? ar[0] : ar; } }); }, initialize: function(editor){ // summary: // Initialize the global handler upon a plugin's first instance of setEditor // // All plugins will attempt initialization. We only need to do so once. if(this.initialized){ return; } this.initialized = true; this.editor = editor; this.editorDomNode = this.editor.editNode || this.editor.iframe.document.body.firstChild; // RichText should have a mouseup connection to recognize drag-selections // Example would be selecting multiple table cells dojo.connect(this.editorDomNode , "mouseup", this.editor, "onClick"); dojo.connect(this.editor, "onDisplayChanged", this, "checkAvailable"); this.doMixins(); this.connectDraggable(); }, getTableInfo: function(forceNewData){ // summary // Gets the table in focus // Collects info on the table - see return params // if(forceNewData){ this._tempStoreTableData(false); } if(this.tableData){ // tableData is set for a short amount of time, so that all // plugins get the same return without doing the method over console.log("returning current tableData:", this.tableData); return this.tableData; } var tr, trs, td, tds, tbl, cols, tdIndex, trIndex; td = this.editor.getAncestorElement("td"); if(td){ tr = td.parentNode; } tbl = this.editor.getAncestorElement("table"); //console.log("td:", td);console.log("tr:", tr);console.log("tbl:", tbl) tds = dojo.query("td", tbl); tds.forEach(function(d, i){ if(td==d){tdIndex = i} }); trs = dojo.query("tr", tbl); trs.forEach(function(r, i){ if(tr==r){trIndex = i} }); cols = tds.length/trs.length; var o = { tbl:tbl, // focused table td:td, // focused TD tr:tr, // focused TR trs:trs, // rows tds:tds, // cells rows:trs.length,// row amount cols:cols, // column amount tdIndex:tdIndex,// index of focused cell trIndex:trIndex, // index of focused row colIndex:tdIndex%cols }; console.log("NEW tableData:",o); this.tableData = o; this._tempStoreTableData(500); return this.tableData; }, connectDraggable: function(){ // summary // Detects drag-n-drop in the editor (could probably be moved to there) // Currently only checks if item dragged was a TABLE, and removes its align attr // DOES NOT WORK IN FF - it could - but FF's drag detection is a monster // if(!dojo.isIE){ //console.warn("Drag and Drop is currently only detectable in IE."); return } // IE ONLY this.editorDomNode.ondragstart = dojo.hitch(this, "onDragStart"); this.editorDomNode.ondragend = dojo.hitch(this, "onDragEnd"); //NOTES: // FF _ Able to detect the drag-over object (the editor.domNode) // Not able to detect an item's ondrag() event // Don't know why - I actually got it working when there was an error // Something to do with different documents or windows I'm sure // //console.log("connectDraggable", tbl); /*tbl.ondragstart=dojo.hitch(this, "onDragStart"); tbl.addEventListener("dragstart", dojo.hitch(this, "onDragStart"), false); tbl.addEventListener("drag", dojo.hitch(this, "onDragStart2"), false); tbl.addEventListener("dragend", dojo.hitch(this, "onDragStart3"), false); dojo.withGlobal(this.editor.window, "selectElement",dijit._editor.selection, [tbl]); tbl.ondragstart = function(){ console.log ("ondragstart"); }; tbl.ondrag = function(){ alert("drag") //console.log ("ondrag"); */ }, onDragStart: function(){ var e = window.event; if(!e.srcElement.id){ e.srcElement.id = "tbl_"+(new Date().getTime()); } //console.log("onDragStart", e.srcElement.id); }, onDragEnd: function(){ // summary // Detects that an object has been dragged into place // Currently, this code is only used for when a table is dragged // and clears the "align" attribute, so that the table will look // to be more in the place that the user expected. // TODO: This code can be used for other things, most // notably UNDO, which currently is not quite usable. // This code could also find itself in the Editor code when it is // complete. //console.log("onDragEnd"); var e = window.event var node = e.srcElement; var id = node.id; var win = this.editor.window //console.log("NODE:", node.tagName, node.id, dojo.attr(node, "align")); // clearing a table's align attr // TODO: when ondrag becomes more robust, this code block // should move to its own method if(node.tagName.toLowerCase()=="table"){ setTimeout(function(){ var node = dojo.withGlobal(win, "byId", dojo, [id]); dojo.removeAttr(node, "align"); //console.log("set", node.tagName, dojo.attr(node, "align")) }, 100); } }, checkAvailable: function(){ // summary // For table plugs // Checking if a table or part of a table has focus so that // Plugs can change their status // if(this.availableCurrentlySet){ // availableCurrentlySet is set for a short amount of time, so that all // plugins get the same return without doing the method over //console.log("availableCurrentlySet:", this.availableCurrentlySet, "currentlyAvailable:", this.currentlyAvailable) return this.currentlyAvailable; } //console.log("G - checkAvailable..."); if(!this.editor) { //console.log("editor not ready") return false; } if(this.alwaysAvailable) { //console.log(" return always available") return true; } this.currentlyAvailable = this.editor.hasAncestorElement("table"); if(this.currentlyAvailable){ this.connectTableKeys(); }else{ this.disconnectTableKeys(); } this._tempAvailability(500); dojo.publish("available", [ this.currentlyAvailable ]); return this.currentlyAvailable; }, _prepareTable: function(tbl){ // For IE's sake, we are adding IDs to the TDs if none is there // We go ahead and use it for other code for convenience // var tds = this.editor.query("td", tbl); console.log("prep:", tds, tbl) if(!tds[0].id){ tds.forEach(function(td, i){ if(!td.id){ td.id = "tdid"+i+this.getTimeStamp(); } }, this); } return tds; }, getTimeStamp: function(){ return Math.floor(new Date().getTime() * 0.00000001); }, _tempStoreTableData: function(type){ // caching or clearing table data, depending on the arg // if(type===true){ //store indefinitely }else if(type===false){ // clear object this.tableData = null; }else if(type===undefined){ console.warn("_tempStoreTableData must be passed an argument") }else{ // type is a number/ms setTimeout(dojo.hitch(this, function(){ this.tableData = null; }), type); } }, _tempAvailability: function(type){ // caching or clearing availability, depending on the arg if(type===true){ //store indefinitely this.availableCurrentlySet = true; }else if(type===false){ // clear object this.availableCurrentlySet = false; }else if(type===undefined){ console.warn("_tempAvailability must be passed an argument") }else{ // type is a number/ms this.availableCurrentlySet = true; setTimeout(dojo.hitch(this, function(){ this.availableCurrentlySet = false; }), type); } }, connectTableKeys: function(){ // summary // When a table is in focus, start detecting keys // Mainly checking for the TAB key so user can tab // through a table (blocking the browser's desire to // tab away from teh editor completely) if(this.tablesConnected){ return; } this.tablesConnected = true; var node = (this.editor.iframe) ? this.editor.document : this.editor.editNode; this.cnKeyDn = dojo.connect(node, "onkeydown", this, "onKeyDown"); this.cnKeyUp = dojo.connect(node, "onkeyup", this, "onKeyUp"); dojo.connect(node, "onkeypress", this, "onKeyUp"); }, disconnectTableKeys: function(){ //console.log("disconnect") dojo.disconnect(this.cnKeyDn); dojo.disconnect(this.cnKeyUp); this.tablesConnected = false;";s:7:"summary";s:0:"";}s:49:"dojox.editor.plugins.GlobalTableHandler.onKeyDown";a:5:{s:9:"prototype";s:39:"dojox.editor.plugins.GlobalTableHandler";s:4:"type";s:8:"Function";s:10:"parameters";a:1:{s:3:"evt";a:1:{s:4:"type";s:0:"";}}s:6:"source";s:886:" var key = evt.keyCode; //console.log(" -> DOWN:", key); if(key == 16) this.shiftKeyDown = true; if(key == 9) {console.log("TAB!:"); var o = this.getTableInfo(); //console.log("TAB ", o.tdIndex, o); // modifying the o.tdIndex in the tableData directly, because we may save it // FIXME: tabTo is a global o.tdIndex = (this.shiftKeyDown) ? o.tdIndex-1 : tabTo = o.tdIndex+1; if(o.tdIndex>=0 && o.tdIndex UP:", key) if(key == 16) this.shiftKeyDown = false; if(key == 37 || key == 38 || key == 39 || key == 40 ){ // user can arrow or tab out of table - need to recheck this.onDisplayChanged(); } if(key == 9 && this.stopEvent) dojo.stopEvent(evt);";s:7:"summary";s:0:"";}s:56:"dojox.editor.plugins.GlobalTableHandler.onDisplayChanged";a:4:{s:9:"prototype";s:39:"dojox.editor.plugins.GlobalTableHandler";s:4:"type";s:8:"Function";s:6:"source";s:12186:"dojo.provide("dojox.editor.plugins.TablePlugins"); dojo.require("dijit._editor._Plugin"); dojo.require("dijit._editor.selection"); dojo.require("dijit.Menu"); dojo.require("dojo.i18n"); dojo.requireLocalization("dojox.editor.plugins", "TableDialog"); dojo.experimental("dojox.editor.plugins.TablePlugins"); // summary: // A series of plugins that give the Editor the ability to create and edit // HTML tables. See the end of this document for all avaiable plugins // and dojox/editorPlugins/tests/editorTablePlugs.html for an example // // example: // |
// | Editor text is here // |
// // TODO: // Currently not supporting merging or splitting cells // // FIXME: Undo is very buggy, and therefore unimeplented in all browsers // except IE - which itself has only been lightly tested. // // FIXME: Selecting multiple table cells in Firefox looks to be impossible. // This affect the 'colorTableCell' plugin. Cells can still be // colored individually or in rows. dojo.declare("dojox.editor.plugins.GlobalTableHandler", dijit._editor._Plugin,{ // summary: // A global object that handles common tasks for all the plugins. Since // there are several plugins that are all calling common methods, it's preferable // that they call a centralized location that either has a set variable or a // timeout to only repeat code-heavy calls when necessary. // tablesConnected:false, currentlyAvailable: false, alwaysAvailable:false, availableCurrentlySet:false, initialized:false, tableData: null, shiftKeyDown:false, editorDomNode: null, undoEnabled: dojo.isIE, //FIXME: doMixins: function(){ dojo.mixin(this.editor,{ getAncestorElement: function(tagName){ return dojo.withGlobal(this.window, "getAncestorElement",dijit._editor.selection, [tagName]); }, hasAncestorElement: function(tagName){ return true return dojo.withGlobal(this.window, "hasAncestorElement",dijit._editor.selection, [tagName]); }, selectElement: function(elem){ dojo.withGlobal(this.window, "selectElement",dijit._editor.selection, [elem]); }, byId: function(id){ return dojo.withGlobal(this.window, "byId", dojo, [id]); }, query: function(arg, scope, returnFirstOnly){ // this shortcut is dubious - not sure scoping is necessary var ar = dojo.withGlobal(this.window, "query", dojo, [arg, scope]); return (returnFirstOnly) ? ar[0] : ar; } }); }, initialize: function(editor){ // summary: // Initialize the global handler upon a plugin's first instance of setEditor // // All plugins will attempt initialization. We only need to do so once. if(this.initialized){ return; } this.initialized = true; this.editor = editor; this.editorDomNode = this.editor.editNode || this.editor.iframe.document.body.firstChild; // RichText should have a mouseup connection to recognize drag-selections // Example would be selecting multiple table cells dojo.connect(this.editorDomNode , "mouseup", this.editor, "onClick"); dojo.connect(this.editor, "onDisplayChanged", this, "checkAvailable"); this.doMixins(); this.connectDraggable(); }, getTableInfo: function(forceNewData){ // summary // Gets the table in focus // Collects info on the table - see return params // if(forceNewData){ this._tempStoreTableData(false); } if(this.tableData){ // tableData is set for a short amount of time, so that all // plugins get the same return without doing the method over console.log("returning current tableData:", this.tableData); return this.tableData; } var tr, trs, td, tds, tbl, cols, tdIndex, trIndex; td = this.editor.getAncestorElement("td"); if(td){ tr = td.parentNode; } tbl = this.editor.getAncestorElement("table"); //console.log("td:", td);console.log("tr:", tr);console.log("tbl:", tbl) tds = dojo.query("td", tbl); tds.forEach(function(d, i){ if(td==d){tdIndex = i} }); trs = dojo.query("tr", tbl); trs.forEach(function(r, i){ if(tr==r){trIndex = i} }); cols = tds.length/trs.length; var o = { tbl:tbl, // focused table td:td, // focused TD tr:tr, // focused TR trs:trs, // rows tds:tds, // cells rows:trs.length,// row amount cols:cols, // column amount tdIndex:tdIndex,// index of focused cell trIndex:trIndex, // index of focused row colIndex:tdIndex%cols }; console.log("NEW tableData:",o); this.tableData = o; this._tempStoreTableData(500); return this.tableData; }, connectDraggable: function(){ // summary // Detects drag-n-drop in the editor (could probably be moved to there) // Currently only checks if item dragged was a TABLE, and removes its align attr // DOES NOT WORK IN FF - it could - but FF's drag detection is a monster // if(!dojo.isIE){ //console.warn("Drag and Drop is currently only detectable in IE."); return } // IE ONLY this.editorDomNode.ondragstart = dojo.hitch(this, "onDragStart"); this.editorDomNode.ondragend = dojo.hitch(this, "onDragEnd"); //NOTES: // FF _ Able to detect the drag-over object (the editor.domNode) // Not able to detect an item's ondrag() event // Don't know why - I actually got it working when there was an error // Something to do with different documents or windows I'm sure // //console.log("connectDraggable", tbl); /*tbl.ondragstart=dojo.hitch(this, "onDragStart"); tbl.addEventListener("dragstart", dojo.hitch(this, "onDragStart"), false); tbl.addEventListener("drag", dojo.hitch(this, "onDragStart2"), false); tbl.addEventListener("dragend", dojo.hitch(this, "onDragStart3"), false); dojo.withGlobal(this.editor.window, "selectElement",dijit._editor.selection, [tbl]); tbl.ondragstart = function(){ console.log ("ondragstart"); }; tbl.ondrag = function(){ alert("drag") //console.log ("ondrag"); */ }, onDragStart: function(){ var e = window.event; if(!e.srcElement.id){ e.srcElement.id = "tbl_"+(new Date().getTime()); } //console.log("onDragStart", e.srcElement.id); }, onDragEnd: function(){ // summary // Detects that an object has been dragged into place // Currently, this code is only used for when a table is dragged // and clears the "align" attribute, so that the table will look // to be more in the place that the user expected. // TODO: This code can be used for other things, most // notably UNDO, which currently is not quite usable. // This code could also find itself in the Editor code when it is // complete. //console.log("onDragEnd"); var e = window.event var node = e.srcElement; var id = node.id; var win = this.editor.window //console.log("NODE:", node.tagName, node.id, dojo.attr(node, "align")); // clearing a table's align attr // TODO: when ondrag becomes more robust, this code block // should move to its own method if(node.tagName.toLowerCase()=="table"){ setTimeout(function(){ var node = dojo.withGlobal(win, "byId", dojo, [id]); dojo.removeAttr(node, "align"); //console.log("set", node.tagName, dojo.attr(node, "align")) }, 100); } }, checkAvailable: function(){ // summary // For table plugs // Checking if a table or part of a table has focus so that // Plugs can change their status // if(this.availableCurrentlySet){ // availableCurrentlySet is set for a short amount of time, so that all // plugins get the same return without doing the method over //console.log("availableCurrentlySet:", this.availableCurrentlySet, "currentlyAvailable:", this.currentlyAvailable) return this.currentlyAvailable; } //console.log("G - checkAvailable..."); if(!this.editor) { //console.log("editor not ready") return false; } if(this.alwaysAvailable) { //console.log(" return always available") return true; } this.currentlyAvailable = this.editor.hasAncestorElement("table"); if(this.currentlyAvailable){ this.connectTableKeys(); }else{ this.disconnectTableKeys(); } this._tempAvailability(500); dojo.publish("available", [ this.currentlyAvailable ]); return this.currentlyAvailable; }, _prepareTable: function(tbl){ // For IE's sake, we are adding IDs to the TDs if none is there // We go ahead and use it for other code for convenience // var tds = this.editor.query("td", tbl); console.log("prep:", tds, tbl) if(!tds[0].id){ tds.forEach(function(td, i){ if(!td.id){ td.id = "tdid"+i+this.getTimeStamp(); } }, this); } return tds; }, getTimeStamp: function(){ return Math.floor(new Date().getTime() * 0.00000001); }, _tempStoreTableData: function(type){ // caching or clearing table data, depending on the arg // if(type===true){ //store indefinitely }else if(type===false){ // clear object this.tableData = null; }else if(type===undefined){ console.warn("_tempStoreTableData must be passed an argument") }else{ // type is a number/ms setTimeout(dojo.hitch(this, function(){ this.tableData = null; }), type); } }, _tempAvailability: function(type){ // caching or clearing availability, depending on the arg if(type===true){ //store indefinitely this.availableCurrentlySet = true; }else if(type===false){ // clear object this.availableCurrentlySet = false; }else if(type===undefined){ console.warn("_tempAvailability must be passed an argument") }else{ // type is a number/ms this.availableCurrentlySet = true; setTimeout(dojo.hitch(this, function(){ this.availableCurrentlySet = false; }), type); } }, connectTableKeys: function(){ // summary // When a table is in focus, start detecting keys // Mainly checking for the TAB key so user can tab // through a table (blocking the browser's desire to // tab away from teh editor completely) if(this.tablesConnected){ return; } this.tablesConnected = true; var node = (this.editor.iframe) ? this.editor.document : this.editor.editNode; this.cnKeyDn = dojo.connect(node, "onkeydown", this, "onKeyDown"); this.cnKeyUp = dojo.connect(node, "onkeyup", this, "onKeyUp"); dojo.connect(node, "onkeypress", this, "onKeyUp"); }, disconnectTableKeys: function(){ //console.log("disconnect") dojo.disconnect(this.cnKeyDn); dojo.disconnect(this.cnKeyUp); this.tablesConnected = false; }, onKeyDown: function(evt){ var key = evt.keyCode; //console.log(" -> DOWN:", key); if(key == 16) this.shiftKeyDown = true; if(key == 9) {console.log("TAB!:"); var o = this.getTableInfo(); //console.log("TAB ", o.tdIndex, o); // modifying the o.tdIndex in the tableData directly, because we may save it // FIXME: tabTo is a global o.tdIndex = (this.shiftKeyDown) ? o.tdIndex-1 : tabTo = o.tdIndex+1; if(o.tdIndex>=0 && o.tdIndex UP:", key) if(key == 16) this.shiftKeyDown = false; if(key == 37 || key == 38 || key == 39 || key == 40 ){ // user can arrow or tab out of table - need to recheck this.onDisplayChanged(); } if(key == 9 && this.stopEvent) dojo.stopEvent(evt); }, onDisplayChanged: function(){ //console.log("onDisplayChanged") this.currentlyAvailable = false; this._tempStoreTableData(false); this._tempAvailability(false); this.checkAvailable();";s:7:"summary";s:0:"";}s:46:"dojox.editor.plugins.GlobalTableHandler.editor";a:2:{s:8:"instance";s:39:"dojox.editor.plugins.GlobalTableHandler";s:7:"summary";s:0:"";}s:65:"dojox.editor.plugins.GlobalTableHandler.editorDomNode.ondragstart";a:2:{s:8:"instance";s:39:"dojox.editor.plugins.GlobalTableHandler";s:7:"summary";s:0:"";}s:63:"dojox.editor.plugins.GlobalTableHandler.editorDomNode.ondragend";a:2:{s:8:"instance";s:39:"dojox.editor.plugins.GlobalTableHandler";s:7:"summary";s:0:"";}s:47:"dojox.editor.plugins.GlobalTableHandler.cnKeyDn";a:2:{s:8:"instance";s:39:"dojox.editor.plugins.GlobalTableHandler";s:7:"summary";s:0:"";}s:47:"dojox.editor.plugins.GlobalTableHandler.cnKeyUp";a:2:{s:8:"instance";s:39:"dojox.editor.plugins.GlobalTableHandler";s:7:"summary";s:0:"";}s:49:"dojox.editor.plugins.GlobalTableHandler.stopEvent";a:2:{s:8:"instance";s:39:"dojox.editor.plugins.GlobalTableHandler";s:7:"summary";s:0:"";}s:33:"dojox.editor.plugins.TablePlugins";a:5:{s:4:"type";s:8:"Function";s:6:"chains";a:2:{s:9:"prototype";a:1:{i:0;s:21:"dijit._editor._Plugin";}s:4:"call";a:1:{i:0;s:21:"dijit._editor._Plugin";}}s:7:"summary";s:244:"A collection of Plugins for inserting and modifying tables in the Editor See end of this document for all avaiable plugs and dojox/editorPlugins/tests/editorTablePlugs.html for an example NOT IMPLEMENTED: Not handling cell merge, span or split";s:6:"source";s:13766:"dojo.provide("dojox.editor.plugins.TablePlugins"); dojo.require("dijit._editor._Plugin"); dojo.require("dijit._editor.selection"); dojo.require("dijit.Menu"); dojo.require("dojo.i18n"); dojo.requireLocalization("dojox.editor.plugins", "TableDialog"); dojo.experimental("dojox.editor.plugins.TablePlugins"); // summary: // A series of plugins that give the Editor the ability to create and edit // HTML tables. See the end of this document for all avaiable plugins // and dojox/editorPlugins/tests/editorTablePlugs.html for an example // // example: // |
// | Editor text is here // |
// // TODO: // Currently not supporting merging or splitting cells // // FIXME: Undo is very buggy, and therefore unimeplented in all browsers // except IE - which itself has only been lightly tested. // // FIXME: Selecting multiple table cells in Firefox looks to be impossible. // This affect the 'colorTableCell' plugin. Cells can still be // colored individually or in rows. dojo.declare("dojox.editor.plugins.GlobalTableHandler", dijit._editor._Plugin,{ // summary: // A global object that handles common tasks for all the plugins. Since // there are several plugins that are all calling common methods, it's preferable // that they call a centralized location that either has a set variable or a // timeout to only repeat code-heavy calls when necessary. // tablesConnected:false, currentlyAvailable: false, alwaysAvailable:false, availableCurrentlySet:false, initialized:false, tableData: null, shiftKeyDown:false, editorDomNode: null, undoEnabled: dojo.isIE, //FIXME: doMixins: function(){ dojo.mixin(this.editor,{ getAncestorElement: function(tagName){ return dojo.withGlobal(this.window, "getAncestorElement",dijit._editor.selection, [tagName]); }, hasAncestorElement: function(tagName){ return true return dojo.withGlobal(this.window, "hasAncestorElement",dijit._editor.selection, [tagName]); }, selectElement: function(elem){ dojo.withGlobal(this.window, "selectElement",dijit._editor.selection, [elem]); }, byId: function(id){ return dojo.withGlobal(this.window, "byId", dojo, [id]); }, query: function(arg, scope, returnFirstOnly){ // this shortcut is dubious - not sure scoping is necessary var ar = dojo.withGlobal(this.window, "query", dojo, [arg, scope]); return (returnFirstOnly) ? ar[0] : ar; } }); }, initialize: function(editor){ // summary: // Initialize the global handler upon a plugin's first instance of setEditor // // All plugins will attempt initialization. We only need to do so once. if(this.initialized){ return; } this.initialized = true; this.editor = editor; this.editorDomNode = this.editor.editNode || this.editor.iframe.document.body.firstChild; // RichText should have a mouseup connection to recognize drag-selections // Example would be selecting multiple table cells dojo.connect(this.editorDomNode , "mouseup", this.editor, "onClick"); dojo.connect(this.editor, "onDisplayChanged", this, "checkAvailable"); this.doMixins(); this.connectDraggable(); }, getTableInfo: function(forceNewData){ // summary // Gets the table in focus // Collects info on the table - see return params // if(forceNewData){ this._tempStoreTableData(false); } if(this.tableData){ // tableData is set for a short amount of time, so that all // plugins get the same return without doing the method over console.log("returning current tableData:", this.tableData); return this.tableData; } var tr, trs, td, tds, tbl, cols, tdIndex, trIndex; td = this.editor.getAncestorElement("td"); if(td){ tr = td.parentNode; } tbl = this.editor.getAncestorElement("table"); //console.log("td:", td);console.log("tr:", tr);console.log("tbl:", tbl) tds = dojo.query("td", tbl); tds.forEach(function(d, i){ if(td==d){tdIndex = i} }); trs = dojo.query("tr", tbl); trs.forEach(function(r, i){ if(tr==r){trIndex = i} }); cols = tds.length/trs.length; var o = { tbl:tbl, // focused table td:td, // focused TD tr:tr, // focused TR trs:trs, // rows tds:tds, // cells rows:trs.length,// row amount cols:cols, // column amount tdIndex:tdIndex,// index of focused cell trIndex:trIndex, // index of focused row colIndex:tdIndex%cols }; console.log("NEW tableData:",o); this.tableData = o; this._tempStoreTableData(500); return this.tableData; }, connectDraggable: function(){ // summary // Detects drag-n-drop in the editor (could probably be moved to there) // Currently only checks if item dragged was a TABLE, and removes its align attr // DOES NOT WORK IN FF - it could - but FF's drag detection is a monster // if(!dojo.isIE){ //console.warn("Drag and Drop is currently only detectable in IE."); return } // IE ONLY this.editorDomNode.ondragstart = dojo.hitch(this, "onDragStart"); this.editorDomNode.ondragend = dojo.hitch(this, "onDragEnd"); //NOTES: // FF _ Able to detect the drag-over object (the editor.domNode) // Not able to detect an item's ondrag() event // Don't know why - I actually got it working when there was an error // Something to do with different documents or windows I'm sure // //console.log("connectDraggable", tbl); /*tbl.ondragstart=dojo.hitch(this, "onDragStart"); tbl.addEventListener("dragstart", dojo.hitch(this, "onDragStart"), false); tbl.addEventListener("drag", dojo.hitch(this, "onDragStart2"), false); tbl.addEventListener("dragend", dojo.hitch(this, "onDragStart3"), false); dojo.withGlobal(this.editor.window, "selectElement",dijit._editor.selection, [tbl]); tbl.ondragstart = function(){ console.log ("ondragstart"); }; tbl.ondrag = function(){ alert("drag") //console.log ("ondrag"); */ }, onDragStart: function(){ var e = window.event; if(!e.srcElement.id){ e.srcElement.id = "tbl_"+(new Date().getTime()); } //console.log("onDragStart", e.srcElement.id); }, onDragEnd: function(){ // summary // Detects that an object has been dragged into place // Currently, this code is only used for when a table is dragged // and clears the "align" attribute, so that the table will look // to be more in the place that the user expected. // TODO: This code can be used for other things, most // notably UNDO, which currently is not quite usable. // This code could also find itself in the Editor code when it is // complete. //console.log("onDragEnd"); var e = window.event var node = e.srcElement; var id = node.id; var win = this.editor.window //console.log("NODE:", node.tagName, node.id, dojo.attr(node, "align")); // clearing a table's align attr // TODO: when ondrag becomes more robust, this code block // should move to its own method if(node.tagName.toLowerCase()=="table"){ setTimeout(function(){ var node = dojo.withGlobal(win, "byId", dojo, [id]); dojo.removeAttr(node, "align"); //console.log("set", node.tagName, dojo.attr(node, "align")) }, 100); } }, checkAvailable: function(){ // summary // For table plugs // Checking if a table or part of a table has focus so that // Plugs can change their status // if(this.availableCurrentlySet){ // availableCurrentlySet is set for a short amount of time, so that all // plugins get the same return without doing the method over //console.log("availableCurrentlySet:", this.availableCurrentlySet, "currentlyAvailable:", this.currentlyAvailable) return this.currentlyAvailable; } //console.log("G - checkAvailable..."); if(!this.editor) { //console.log("editor not ready") return false; } if(this.alwaysAvailable) { //console.log(" return always available") return true; } this.currentlyAvailable = this.editor.hasAncestorElement("table"); if(this.currentlyAvailable){ this.connectTableKeys(); }else{ this.disconnectTableKeys(); } this._tempAvailability(500); dojo.publish("available", [ this.currentlyAvailable ]); return this.currentlyAvailable; }, _prepareTable: function(tbl){ // For IE's sake, we are adding IDs to the TDs if none is there // We go ahead and use it for other code for convenience // var tds = this.editor.query("td", tbl); console.log("prep:", tds, tbl) if(!tds[0].id){ tds.forEach(function(td, i){ if(!td.id){ td.id = "tdid"+i+this.getTimeStamp(); } }, this); } return tds; }, getTimeStamp: function(){ return Math.floor(new Date().getTime() * 0.00000001); }, _tempStoreTableData: function(type){ // caching or clearing table data, depending on the arg // if(type===true){ //store indefinitely }else if(type===false){ // clear object this.tableData = null; }else if(type===undefined){ console.warn("_tempStoreTableData must be passed an argument") }else{ // type is a number/ms setTimeout(dojo.hitch(this, function(){ this.tableData = null; }), type); } }, _tempAvailability: function(type){ // caching or clearing availability, depending on the arg if(type===true){ //store indefinitely this.availableCurrentlySet = true; }else if(type===false){ // clear object this.availableCurrentlySet = false; }else if(type===undefined){ console.warn("_tempAvailability must be passed an argument") }else{ // type is a number/ms this.availableCurrentlySet = true; setTimeout(dojo.hitch(this, function(){ this.availableCurrentlySet = false; }), type); } }, connectTableKeys: function(){ // summary // When a table is in focus, start detecting keys // Mainly checking for the TAB key so user can tab // through a table (blocking the browser's desire to // tab away from teh editor completely) if(this.tablesConnected){ return; } this.tablesConnected = true; var node = (this.editor.iframe) ? this.editor.document : this.editor.editNode; this.cnKeyDn = dojo.connect(node, "onkeydown", this, "onKeyDown"); this.cnKeyUp = dojo.connect(node, "onkeyup", this, "onKeyUp"); dojo.connect(node, "onkeypress", this, "onKeyUp"); }, disconnectTableKeys: function(){ //console.log("disconnect") dojo.disconnect(this.cnKeyDn); dojo.disconnect(this.cnKeyUp); this.tablesConnected = false; }, onKeyDown: function(evt){ var key = evt.keyCode; //console.log(" -> DOWN:", key); if(key == 16) this.shiftKeyDown = true; if(key == 9) {console.log("TAB!:"); var o = this.getTableInfo(); //console.log("TAB ", o.tdIndex, o); // modifying the o.tdIndex in the tableData directly, because we may save it // FIXME: tabTo is a global o.tdIndex = (this.shiftKeyDown) ? o.tdIndex-1 : tabTo = o.tdIndex+1; if(o.tdIndex>=0 && o.tdIndex UP:", key) if(key == 16) this.shiftKeyDown = false; if(key == 37 || key == 38 || key == 39 || key == 40 ){ // user can arrow or tab out of table - need to recheck this.onDisplayChanged(); } if(key == 9 && this.stopEvent) dojo.stopEvent(evt); }, onDisplayChanged: function(){ //console.log("onDisplayChanged") this.currentlyAvailable = false; this._tempStoreTableData(false); this._tempAvailability(false); this.checkAvailable(); } }); // global: tablePluginHandler = new dojox.editor.plugins.GlobalTableHandler(); //FIXME: no globals. dojo.declare("dojox.editor.plugins.TablePlugins", dijit._editor._Plugin, { //summary: // A collection of Plugins for inserting and modifying tables in the Editor // See end of this document for all avaiable plugs // and dojox/editorPlugins/tests/editorTablePlugs.html for an example // // NOT IMPLEMENTED: Not handling cell merge, span or split // iconClassPrefix: "editorIcon", useDefaultCommand: false, buttonClass: dijit.form.Button, commandName:"", label:"", alwaysAvailable:false, undoEnabled:false, constructor: function(){ // summary // Initialize certain plugins // switch(this.commandName){ case "colorTableCell": this.buttonClass = dijit.form.DropDownButton; this.dropDown = new dijit.ColorPalette(); this.connect(this.dropDown, "onChange", function(color){ this.modTable(null, color); }); break; case "modifyTable": this.buttonClass = dijit.form.DropDownButton; this.modTable = this.launchModifyDialog; break; case "insertTable": this.alwaysAvailable = true; this.buttonClass = dijit.form.DropDownButton; this.modTable = this.launchInsertDialog; break; case "tableContextMenu": this.connect(this, "setEditor", function(){ this._createContextMenu(); this.button.domNode.style.display = "none"; }); break; } dojo.subscribe("available", this, "onDisplayChanged");";s:9:"classlike";b:1;}s:49:"dojox.editor.plugins.TablePlugins.iconClassPrefix";a:2:{s:9:"prototype";s:33:"dojox.editor.plugins.TablePlugins";s:7:"summary";s:0:"";}s:51:"dojox.editor.plugins.TablePlugins.useDefaultCommand";a:2:{s:9:"prototype";s:33:"dojox.editor.plugins.TablePlugins";s:7:"summary";s:0:"";}s:45:"dojox.editor.plugins.TablePlugins.buttonClass";a:3:{s:9:"prototype";s:33:"dojox.editor.plugins.TablePlugins";s:8:"instance";s:33:"dojox.editor.plugins.TablePlugins";s:7:"summary";s:0:"";}s:45:"dojox.editor.plugins.TablePlugins.commandName";a:3:{s:9:"prototype";s:33:"dojox.editor.plugins.TablePlugins";s:8:"instance";s:33:"dojox.editor.plugins.TablePlugins";s:7:"summary";s:0:"";}s:39:"dojox.editor.plugins.TablePlugins.label";a:3:{s:9:"prototype";s:33:"dojox.editor.plugins.TablePlugins";s:8:"instance";s:33:"dojox.editor.plugins.TablePlugins";s:7:"summary";s:0:"";}s:49:"dojox.editor.plugins.TablePlugins.alwaysAvailable";a:3:{s:9:"prototype";s:33:"dojox.editor.plugins.TablePlugins";s:8:"instance";s:33:"dojox.editor.plugins.TablePlugins";s:7:"summary";s:0:"";}s:45:"dojox.editor.plugins.TablePlugins.undoEnabled";a:2:{s:9:"prototype";s:33:"dojox.editor.plugins.TablePlugins";s:7:"summary";s:0:"";}s:50:"dojox.editor.plugins.TablePlugins.onDisplayChanged";a:5:{s:9:"prototype";s:33:"dojox.editor.plugins.TablePlugins";s:4:"type";s:8:"Function";s:10:"parameters";a:1:{s:11:"withinTable";a:1:{s:4:"type";s:0:"";}}s:6:"source";s:14061:"dojo.provide("dojox.editor.plugins.TablePlugins"); dojo.require("dijit._editor._Plugin"); dojo.require("dijit._editor.selection"); dojo.require("dijit.Menu"); dojo.require("dojo.i18n"); dojo.requireLocalization("dojox.editor.plugins", "TableDialog"); dojo.experimental("dojox.editor.plugins.TablePlugins"); // summary: // A series of plugins that give the Editor the ability to create and edit // HTML tables. See the end of this document for all avaiable plugins // and dojox/editorPlugins/tests/editorTablePlugs.html for an example // // example: // |
// | Editor text is here // |
// // TODO: // Currently not supporting merging or splitting cells // // FIXME: Undo is very buggy, and therefore unimeplented in all browsers // except IE - which itself has only been lightly tested. // // FIXME: Selecting multiple table cells in Firefox looks to be impossible. // This affect the 'colorTableCell' plugin. Cells can still be // colored individually or in rows. dojo.declare("dojox.editor.plugins.GlobalTableHandler", dijit._editor._Plugin,{ // summary: // A global object that handles common tasks for all the plugins. Since // there are several plugins that are all calling common methods, it's preferable // that they call a centralized location that either has a set variable or a // timeout to only repeat code-heavy calls when necessary. // tablesConnected:false, currentlyAvailable: false, alwaysAvailable:false, availableCurrentlySet:false, initialized:false, tableData: null, shiftKeyDown:false, editorDomNode: null, undoEnabled: dojo.isIE, //FIXME: doMixins: function(){ dojo.mixin(this.editor,{ getAncestorElement: function(tagName){ return dojo.withGlobal(this.window, "getAncestorElement",dijit._editor.selection, [tagName]); }, hasAncestorElement: function(tagName){ return true return dojo.withGlobal(this.window, "hasAncestorElement",dijit._editor.selection, [tagName]); }, selectElement: function(elem){ dojo.withGlobal(this.window, "selectElement",dijit._editor.selection, [elem]); }, byId: function(id){ return dojo.withGlobal(this.window, "byId", dojo, [id]); }, query: function(arg, scope, returnFirstOnly){ // this shortcut is dubious - not sure scoping is necessary var ar = dojo.withGlobal(this.window, "query", dojo, [arg, scope]); return (returnFirstOnly) ? ar[0] : ar; } }); }, initialize: function(editor){ // summary: // Initialize the global handler upon a plugin's first instance of setEditor // // All plugins will attempt initialization. We only need to do so once. if(this.initialized){ return; } this.initialized = true; this.editor = editor; this.editorDomNode = this.editor.editNode || this.editor.iframe.document.body.firstChild; // RichText should have a mouseup connection to recognize drag-selections // Example would be selecting multiple table cells dojo.connect(this.editorDomNode , "mouseup", this.editor, "onClick"); dojo.connect(this.editor, "onDisplayChanged", this, "checkAvailable"); this.doMixins(); this.connectDraggable(); }, getTableInfo: function(forceNewData){ // summary // Gets the table in focus // Collects info on the table - see return params // if(forceNewData){ this._tempStoreTableData(false); } if(this.tableData){ // tableData is set for a short amount of time, so that all // plugins get the same return without doing the method over console.log("returning current tableData:", this.tableData); return this.tableData; } var tr, trs, td, tds, tbl, cols, tdIndex, trIndex; td = this.editor.getAncestorElement("td"); if(td){ tr = td.parentNode; } tbl = this.editor.getAncestorElement("table"); //console.log("td:", td);console.log("tr:", tr);console.log("tbl:", tbl) tds = dojo.query("td", tbl); tds.forEach(function(d, i){ if(td==d){tdIndex = i} }); trs = dojo.query("tr", tbl); trs.forEach(function(r, i){ if(tr==r){trIndex = i} }); cols = tds.length/trs.length; var o = { tbl:tbl, // focused table td:td, // focused TD tr:tr, // focused TR trs:trs, // rows tds:tds, // cells rows:trs.length,// row amount cols:cols, // column amount tdIndex:tdIndex,// index of focused cell trIndex:trIndex, // index of focused row colIndex:tdIndex%cols }; console.log("NEW tableData:",o); this.tableData = o; this._tempStoreTableData(500); return this.tableData; }, connectDraggable: function(){ // summary // Detects drag-n-drop in the editor (could probably be moved to there) // Currently only checks if item dragged was a TABLE, and removes its align attr // DOES NOT WORK IN FF - it could - but FF's drag detection is a monster // if(!dojo.isIE){ //console.warn("Drag and Drop is currently only detectable in IE."); return } // IE ONLY this.editorDomNode.ondragstart = dojo.hitch(this, "onDragStart"); this.editorDomNode.ondragend = dojo.hitch(this, "onDragEnd"); //NOTES: // FF _ Able to detect the drag-over object (the editor.domNode) // Not able to detect an item's ondrag() event // Don't know why - I actually got it working when there was an error // Something to do with different documents or windows I'm sure // //console.log("connectDraggable", tbl); /*tbl.ondragstart=dojo.hitch(this, "onDragStart"); tbl.addEventListener("dragstart", dojo.hitch(this, "onDragStart"), false); tbl.addEventListener("drag", dojo.hitch(this, "onDragStart2"), false); tbl.addEventListener("dragend", dojo.hitch(this, "onDragStart3"), false); dojo.withGlobal(this.editor.window, "selectElement",dijit._editor.selection, [tbl]); tbl.ondragstart = function(){ console.log ("ondragstart"); }; tbl.ondrag = function(){ alert("drag") //console.log ("ondrag"); */ }, onDragStart: function(){ var e = window.event; if(!e.srcElement.id){ e.srcElement.id = "tbl_"+(new Date().getTime()); } //console.log("onDragStart", e.srcElement.id); }, onDragEnd: function(){ // summary // Detects that an object has been dragged into place // Currently, this code is only used for when a table is dragged // and clears the "align" attribute, so that the table will look // to be more in the place that the user expected. // TODO: This code can be used for other things, most // notably UNDO, which currently is not quite usable. // This code could also find itself in the Editor code when it is // complete. //console.log("onDragEnd"); var e = window.event var node = e.srcElement; var id = node.id; var win = this.editor.window //console.log("NODE:", node.tagName, node.id, dojo.attr(node, "align")); // clearing a table's align attr // TODO: when ondrag becomes more robust, this code block // should move to its own method if(node.tagName.toLowerCase()=="table"){ setTimeout(function(){ var node = dojo.withGlobal(win, "byId", dojo, [id]); dojo.removeAttr(node, "align"); //console.log("set", node.tagName, dojo.attr(node, "align")) }, 100); } }, checkAvailable: function(){ // summary // For table plugs // Checking if a table or part of a table has focus so that // Plugs can change their status // if(this.availableCurrentlySet){ // availableCurrentlySet is set for a short amount of time, so that all // plugins get the same return without doing the method over //console.log("availableCurrentlySet:", this.availableCurrentlySet, "currentlyAvailable:", this.currentlyAvailable) return this.currentlyAvailable; } //console.log("G - checkAvailable..."); if(!this.editor) { //console.log("editor not ready") return false; } if(this.alwaysAvailable) { //console.log(" return always available") return true; } this.currentlyAvailable = this.editor.hasAncestorElement("table"); if(this.currentlyAvailable){ this.connectTableKeys(); }else{ this.disconnectTableKeys(); } this._tempAvailability(500); dojo.publish("available", [ this.currentlyAvailable ]); return this.currentlyAvailable; }, _prepareTable: function(tbl){ // For IE's sake, we are adding IDs to the TDs if none is there // We go ahead and use it for other code for convenience // var tds = this.editor.query("td", tbl); console.log("prep:", tds, tbl) if(!tds[0].id){ tds.forEach(function(td, i){ if(!td.id){ td.id = "tdid"+i+this.getTimeStamp(); } }, this); } return tds; }, getTimeStamp: function(){ return Math.floor(new Date().getTime() * 0.00000001); }, _tempStoreTableData: function(type){ // caching or clearing table data, depending on the arg // if(type===true){ //store indefinitely }else if(type===false){ // clear object this.tableData = null; }else if(type===undefined){ console.warn("_tempStoreTableData must be passed an argument") }else{ // type is a number/ms setTimeout(dojo.hitch(this, function(){ this.tableData = null; }), type); } }, _tempAvailability: function(type){ // caching or clearing availability, depending on the arg if(type===true){ //store indefinitely this.availableCurrentlySet = true; }else if(type===false){ // clear object this.availableCurrentlySet = false; }else if(type===undefined){ console.warn("_tempAvailability must be passed an argument") }else{ // type is a number/ms this.availableCurrentlySet = true; setTimeout(dojo.hitch(this, function(){ this.availableCurrentlySet = false; }), type); } }, connectTableKeys: function(){ // summary // When a table is in focus, start detecting keys // Mainly checking for the TAB key so user can tab // through a table (blocking the browser's desire to // tab away from teh editor completely) if(this.tablesConnected){ return; } this.tablesConnected = true; var node = (this.editor.iframe) ? this.editor.document : this.editor.editNode; this.cnKeyDn = dojo.connect(node, "onkeydown", this, "onKeyDown"); this.cnKeyUp = dojo.connect(node, "onkeyup", this, "onKeyUp"); dojo.connect(node, "onkeypress", this, "onKeyUp"); }, disconnectTableKeys: function(){ //console.log("disconnect") dojo.disconnect(this.cnKeyDn); dojo.disconnect(this.cnKeyUp); this.tablesConnected = false; }, onKeyDown: function(evt){ var key = evt.keyCode; //console.log(" -> DOWN:", key); if(key == 16) this.shiftKeyDown = true; if(key == 9) {console.log("TAB!:"); var o = this.getTableInfo(); //console.log("TAB ", o.tdIndex, o); // modifying the o.tdIndex in the tableData directly, because we may save it // FIXME: tabTo is a global o.tdIndex = (this.shiftKeyDown) ? o.tdIndex-1 : tabTo = o.tdIndex+1; if(o.tdIndex>=0 && o.tdIndex UP:", key) if(key == 16) this.shiftKeyDown = false; if(key == 37 || key == 38 || key == 39 || key == 40 ){ // user can arrow or tab out of table - need to recheck this.onDisplayChanged(); } if(key == 9 && this.stopEvent) dojo.stopEvent(evt); }, onDisplayChanged: function(){ //console.log("onDisplayChanged") this.currentlyAvailable = false; this._tempStoreTableData(false); this._tempAvailability(false); this.checkAvailable(); } }); // global: tablePluginHandler = new dojox.editor.plugins.GlobalTableHandler(); //FIXME: no globals. dojo.declare("dojox.editor.plugins.TablePlugins", dijit._editor._Plugin, { //summary: // A collection of Plugins for inserting and modifying tables in the Editor // See end of this document for all avaiable plugs // and dojox/editorPlugins/tests/editorTablePlugs.html for an example // // NOT IMPLEMENTED: Not handling cell merge, span or split // iconClassPrefix: "editorIcon", useDefaultCommand: false, buttonClass: dijit.form.Button, commandName:"", label:"", alwaysAvailable:false, undoEnabled:false, constructor: function(){ // summary // Initialize certain plugins // switch(this.commandName){ case "colorTableCell": this.buttonClass = dijit.form.DropDownButton; this.dropDown = new dijit.ColorPalette(); this.connect(this.dropDown, "onChange", function(color){ this.modTable(null, color); }); break; case "modifyTable": this.buttonClass = dijit.form.DropDownButton; this.modTable = this.launchModifyDialog; break; case "insertTable": this.alwaysAvailable = true; this.buttonClass = dijit.form.DropDownButton; this.modTable = this.launchInsertDialog; break; case "tableContextMenu": this.connect(this, "setEditor", function(){ this._createContextMenu(); this.button.domNode.style.display = "none"; }); break; } dojo.subscribe("available", this, "onDisplayChanged"); }, onDisplayChanged: function(withinTable){ // subscribed to from the global object's publish method // //console.log("onDisplayChanged", this.commandName); if(!this.alwaysAvailable){ this.available = withinTable; this.button.attr('disabled', !this.available); }";s:7:"summary";s:0:"";}s:43:"dojox.editor.plugins.TablePlugins.setEditor";a:4:{s:9:"prototype";s:33:"dojox.editor.plugins.TablePlugins";s:4:"type";s:8:"Function";s:6:"source";s:55:" this.inherited(arguments); this.onEditorLoaded();";s:7:"summary";s:0:"";}s:48:"dojox.editor.plugins.TablePlugins.onEditorLoaded";a:4:{s:9:"prototype";s:33:"dojox.editor.plugins.TablePlugins";s:4:"type";s:8:"Function";s:6:"source";s:14285:"dojo.provide("dojox.editor.plugins.TablePlugins"); dojo.require("dijit._editor._Plugin"); dojo.require("dijit._editor.selection"); dojo.require("dijit.Menu"); dojo.require("dojo.i18n"); dojo.requireLocalization("dojox.editor.plugins", "TableDialog"); dojo.experimental("dojox.editor.plugins.TablePlugins"); // summary: // A series of plugins that give the Editor the ability to create and edit // HTML tables. See the end of this document for all avaiable plugins // and dojox/editorPlugins/tests/editorTablePlugs.html for an example // // example: // |
// | Editor text is here // |
// // TODO: // Currently not supporting merging or splitting cells // // FIXME: Undo is very buggy, and therefore unimeplented in all browsers // except IE - which itself has only been lightly tested. // // FIXME: Selecting multiple table cells in Firefox looks to be impossible. // This affect the 'colorTableCell' plugin. Cells can still be // colored individually or in rows. dojo.declare("dojox.editor.plugins.GlobalTableHandler", dijit._editor._Plugin,{ // summary: // A global object that handles common tasks for all the plugins. Since // there are several plugins that are all calling common methods, it's preferable // that they call a centralized location that either has a set variable or a // timeout to only repeat code-heavy calls when necessary. // tablesConnected:false, currentlyAvailable: false, alwaysAvailable:false, availableCurrentlySet:false, initialized:false, tableData: null, shiftKeyDown:false, editorDomNode: null, undoEnabled: dojo.isIE, //FIXME: doMixins: function(){ dojo.mixin(this.editor,{ getAncestorElement: function(tagName){ return dojo.withGlobal(this.window, "getAncestorElement",dijit._editor.selection, [tagName]); }, hasAncestorElement: function(tagName){ return true return dojo.withGlobal(this.window, "hasAncestorElement",dijit._editor.selection, [tagName]); }, selectElement: function(elem){ dojo.withGlobal(this.window, "selectElement",dijit._editor.selection, [elem]); }, byId: function(id){ return dojo.withGlobal(this.window, "byId", dojo, [id]); }, query: function(arg, scope, returnFirstOnly){ // this shortcut is dubious - not sure scoping is necessary var ar = dojo.withGlobal(this.window, "query", dojo, [arg, scope]); return (returnFirstOnly) ? ar[0] : ar; } }); }, initialize: function(editor){ // summary: // Initialize the global handler upon a plugin's first instance of setEditor // // All plugins will attempt initialization. We only need to do so once. if(this.initialized){ return; } this.initialized = true; this.editor = editor; this.editorDomNode = this.editor.editNode || this.editor.iframe.document.body.firstChild; // RichText should have a mouseup connection to recognize drag-selections // Example would be selecting multiple table cells dojo.connect(this.editorDomNode , "mouseup", this.editor, "onClick"); dojo.connect(this.editor, "onDisplayChanged", this, "checkAvailable"); this.doMixins(); this.connectDraggable(); }, getTableInfo: function(forceNewData){ // summary // Gets the table in focus // Collects info on the table - see return params // if(forceNewData){ this._tempStoreTableData(false); } if(this.tableData){ // tableData is set for a short amount of time, so that all // plugins get the same return without doing the method over console.log("returning current tableData:", this.tableData); return this.tableData; } var tr, trs, td, tds, tbl, cols, tdIndex, trIndex; td = this.editor.getAncestorElement("td"); if(td){ tr = td.parentNode; } tbl = this.editor.getAncestorElement("table"); //console.log("td:", td);console.log("tr:", tr);console.log("tbl:", tbl) tds = dojo.query("td", tbl); tds.forEach(function(d, i){ if(td==d){tdIndex = i} }); trs = dojo.query("tr", tbl); trs.forEach(function(r, i){ if(tr==r){trIndex = i} }); cols = tds.length/trs.length; var o = { tbl:tbl, // focused table td:td, // focused TD tr:tr, // focused TR trs:trs, // rows tds:tds, // cells rows:trs.length,// row amount cols:cols, // column amount tdIndex:tdIndex,// index of focused cell trIndex:trIndex, // index of focused row colIndex:tdIndex%cols }; console.log("NEW tableData:",o); this.tableData = o; this._tempStoreTableData(500); return this.tableData; }, connectDraggable: function(){ // summary // Detects drag-n-drop in the editor (could probably be moved to there) // Currently only checks if item dragged was a TABLE, and removes its align attr // DOES NOT WORK IN FF - it could - but FF's drag detection is a monster // if(!dojo.isIE){ //console.warn("Drag and Drop is currently only detectable in IE."); return } // IE ONLY this.editorDomNode.ondragstart = dojo.hitch(this, "onDragStart"); this.editorDomNode.ondragend = dojo.hitch(this, "onDragEnd"); //NOTES: // FF _ Able to detect the drag-over object (the editor.domNode) // Not able to detect an item's ondrag() event // Don't know why - I actually got it working when there was an error // Something to do with different documents or windows I'm sure // //console.log("connectDraggable", tbl); /*tbl.ondragstart=dojo.hitch(this, "onDragStart"); tbl.addEventListener("dragstart", dojo.hitch(this, "onDragStart"), false); tbl.addEventListener("drag", dojo.hitch(this, "onDragStart2"), false); tbl.addEventListener("dragend", dojo.hitch(this, "onDragStart3"), false); dojo.withGlobal(this.editor.window, "selectElement",dijit._editor.selection, [tbl]); tbl.ondragstart = function(){ console.log ("ondragstart"); }; tbl.ondrag = function(){ alert("drag") //console.log ("ondrag"); */ }, onDragStart: function(){ var e = window.event; if(!e.srcElement.id){ e.srcElement.id = "tbl_"+(new Date().getTime()); } //console.log("onDragStart", e.srcElement.id); }, onDragEnd: function(){ // summary // Detects that an object has been dragged into place // Currently, this code is only used for when a table is dragged // and clears the "align" attribute, so that the table will look // to be more in the place that the user expected. // TODO: This code can be used for other things, most // notably UNDO, which currently is not quite usable. // This code could also find itself in the Editor code when it is // complete. //console.log("onDragEnd"); var e = window.event var node = e.srcElement; var id = node.id; var win = this.editor.window //console.log("NODE:", node.tagName, node.id, dojo.attr(node, "align")); // clearing a table's align attr // TODO: when ondrag becomes more robust, this code block // should move to its own method if(node.tagName.toLowerCase()=="table"){ setTimeout(function(){ var node = dojo.withGlobal(win, "byId", dojo, [id]); dojo.removeAttr(node, "align"); //console.log("set", node.tagName, dojo.attr(node, "align")) }, 100); } }, checkAvailable: function(){ // summary // For table plugs // Checking if a table or part of a table has focus so that // Plugs can change their status // if(this.availableCurrentlySet){ // availableCurrentlySet is set for a short amount of time, so that all // plugins get the same return without doing the method over //console.log("availableCurrentlySet:", this.availableCurrentlySet, "currentlyAvailable:", this.currentlyAvailable) return this.currentlyAvailable; } //console.log("G - checkAvailable..."); if(!this.editor) { //console.log("editor not ready") return false; } if(this.alwaysAvailable) { //console.log(" return always available") return true; } this.currentlyAvailable = this.editor.hasAncestorElement("table"); if(this.currentlyAvailable){ this.connectTableKeys(); }else{ this.disconnectTableKeys(); } this._tempAvailability(500); dojo.publish("available", [ this.currentlyAvailable ]); return this.currentlyAvailable; }, _prepareTable: function(tbl){ // For IE's sake, we are adding IDs to the TDs if none is there // We go ahead and use it for other code for convenience // var tds = this.editor.query("td", tbl); console.log("prep:", tds, tbl) if(!tds[0].id){ tds.forEach(function(td, i){ if(!td.id){ td.id = "tdid"+i+this.getTimeStamp(); } }, this); } return tds; }, getTimeStamp: function(){ return Math.floor(new Date().getTime() * 0.00000001); }, _tempStoreTableData: function(type){ // caching or clearing table data, depending on the arg // if(type===true){ //store indefinitely }else if(type===false){ // clear object this.tableData = null; }else if(type===undefined){ console.warn("_tempStoreTableData must be passed an argument") }else{ // type is a number/ms setTimeout(dojo.hitch(this, function(){ this.tableData = null; }), type); } }, _tempAvailability: function(type){ // caching or clearing availability, depending on the arg if(type===true){ //store indefinitely this.availableCurrentlySet = true; }else if(type===false){ // clear object this.availableCurrentlySet = false; }else if(type===undefined){ console.warn("_tempAvailability must be passed an argument") }else{ // type is a number/ms this.availableCurrentlySet = true; setTimeout(dojo.hitch(this, function(){ this.availableCurrentlySet = false; }), type); } }, connectTableKeys: function(){ // summary // When a table is in focus, start detecting keys // Mainly checking for the TAB key so user can tab // through a table (blocking the browser's desire to // tab away from teh editor completely) if(this.tablesConnected){ return; } this.tablesConnected = true; var node = (this.editor.iframe) ? this.editor.document : this.editor.editNode; this.cnKeyDn = dojo.connect(node, "onkeydown", this, "onKeyDown"); this.cnKeyUp = dojo.connect(node, "onkeyup", this, "onKeyUp"); dojo.connect(node, "onkeypress", this, "onKeyUp"); }, disconnectTableKeys: function(){ //console.log("disconnect") dojo.disconnect(this.cnKeyDn); dojo.disconnect(this.cnKeyUp); this.tablesConnected = false; }, onKeyDown: function(evt){ var key = evt.keyCode; //console.log(" -> DOWN:", key); if(key == 16) this.shiftKeyDown = true; if(key == 9) {console.log("TAB!:"); var o = this.getTableInfo(); //console.log("TAB ", o.tdIndex, o); // modifying the o.tdIndex in the tableData directly, because we may save it // FIXME: tabTo is a global o.tdIndex = (this.shiftKeyDown) ? o.tdIndex-1 : tabTo = o.tdIndex+1; if(o.tdIndex>=0 && o.tdIndex UP:", key) if(key == 16) this.shiftKeyDown = false; if(key == 37 || key == 38 || key == 39 || key == 40 ){ // user can arrow or tab out of table - need to recheck this.onDisplayChanged(); } if(key == 9 && this.stopEvent) dojo.stopEvent(evt); }, onDisplayChanged: function(){ //console.log("onDisplayChanged") this.currentlyAvailable = false; this._tempStoreTableData(false); this._tempAvailability(false); this.checkAvailable(); } }); // global: tablePluginHandler = new dojox.editor.plugins.GlobalTableHandler(); //FIXME: no globals. dojo.declare("dojox.editor.plugins.TablePlugins", dijit._editor._Plugin, { //summary: // A collection of Plugins for inserting and modifying tables in the Editor // See end of this document for all avaiable plugs // and dojox/editorPlugins/tests/editorTablePlugs.html for an example // // NOT IMPLEMENTED: Not handling cell merge, span or split // iconClassPrefix: "editorIcon", useDefaultCommand: false, buttonClass: dijit.form.Button, commandName:"", label:"", alwaysAvailable:false, undoEnabled:false, constructor: function(){ // summary // Initialize certain plugins // switch(this.commandName){ case "colorTableCell": this.buttonClass = dijit.form.DropDownButton; this.dropDown = new dijit.ColorPalette(); this.connect(this.dropDown, "onChange", function(color){ this.modTable(null, color); }); break; case "modifyTable": this.buttonClass = dijit.form.DropDownButton; this.modTable = this.launchModifyDialog; break; case "insertTable": this.alwaysAvailable = true; this.buttonClass = dijit.form.DropDownButton; this.modTable = this.launchInsertDialog; break; case "tableContextMenu": this.connect(this, "setEditor", function(){ this._createContextMenu(); this.button.domNode.style.display = "none"; }); break; } dojo.subscribe("available", this, "onDisplayChanged"); }, onDisplayChanged: function(withinTable){ // subscribed to from the global object's publish method // //console.log("onDisplayChanged", this.commandName); if(!this.alwaysAvailable){ this.available = withinTable; this.button.attr('disabled', !this.available); } }, setEditor: function(){ this.inherited(arguments); this.onEditorLoaded(); }, onEditorLoaded: function(){ //stub // call global object to initialize it tablePluginHandler.initialize(this.editor);";s:7:"summary";s:0:"";}s:52:"dojox.editor.plugins.TablePlugins._createContextMenu";a:6:{s:9:"prototype";s:33:"dojox.editor.plugins.TablePlugins";s:4:"type";s:8:"Function";s:6:"source";s:17303:"dojo.provide("dojox.editor.plugins.TablePlugins"); dojo.require("dijit._editor._Plugin"); dojo.require("dijit._editor.selection"); dojo.require("dijit.Menu"); dojo.require("dojo.i18n"); dojo.requireLocalization("dojox.editor.plugins", "TableDialog"); dojo.experimental("dojox.editor.plugins.TablePlugins"); // summary: // A series of plugins that give the Editor the ability to create and edit // HTML tables. See the end of this document for all avaiable plugins // and dojox/editorPlugins/tests/editorTablePlugs.html for an example // // example: // |
// | Editor text is here // |
// // TODO: // Currently not supporting merging or splitting cells // // FIXME: Undo is very buggy, and therefore unimeplented in all browsers // except IE - which itself has only been lightly tested. // // FIXME: Selecting multiple table cells in Firefox looks to be impossible. // This affect the 'colorTableCell' plugin. Cells can still be // colored individually or in rows. dojo.declare("dojox.editor.plugins.GlobalTableHandler", dijit._editor._Plugin,{ // summary: // A global object that handles common tasks for all the plugins. Since // there are several plugins that are all calling common methods, it's preferable // that they call a centralized location that either has a set variable or a // timeout to only repeat code-heavy calls when necessary. // tablesConnected:false, currentlyAvailable: false, alwaysAvailable:false, availableCurrentlySet:false, initialized:false, tableData: null, shiftKeyDown:false, editorDomNode: null, undoEnabled: dojo.isIE, //FIXME: doMixins: function(){ dojo.mixin(this.editor,{ getAncestorElement: function(tagName){ return dojo.withGlobal(this.window, "getAncestorElement",dijit._editor.selection, [tagName]); }, hasAncestorElement: function(tagName){ return true return dojo.withGlobal(this.window, "hasAncestorElement",dijit._editor.selection, [tagName]); }, selectElement: function(elem){ dojo.withGlobal(this.window, "selectElement",dijit._editor.selection, [elem]); }, byId: function(id){ return dojo.withGlobal(this.window, "byId", dojo, [id]); }, query: function(arg, scope, returnFirstOnly){ // this shortcut is dubious - not sure scoping is necessary var ar = dojo.withGlobal(this.window, "query", dojo, [arg, scope]); return (returnFirstOnly) ? ar[0] : ar; } }); }, initialize: function(editor){ // summary: // Initialize the global handler upon a plugin's first instance of setEditor // // All plugins will attempt initialization. We only need to do so once. if(this.initialized){ return; } this.initialized = true; this.editor = editor; this.editorDomNode = this.editor.editNode || this.editor.iframe.document.body.firstChild; // RichText should have a mouseup connection to recognize drag-selections // Example would be selecting multiple table cells dojo.connect(this.editorDomNode , "mouseup", this.editor, "onClick"); dojo.connect(this.editor, "onDisplayChanged", this, "checkAvailable"); this.doMixins(); this.connectDraggable(); }, getTableInfo: function(forceNewData){ // summary // Gets the table in focus // Collects info on the table - see return params // if(forceNewData){ this._tempStoreTableData(false); } if(this.tableData){ // tableData is set for a short amount of time, so that all // plugins get the same return without doing the method over console.log("returning current tableData:", this.tableData); return this.tableData; } var tr, trs, td, tds, tbl, cols, tdIndex, trIndex; td = this.editor.getAncestorElement("td"); if(td){ tr = td.parentNode; } tbl = this.editor.getAncestorElement("table"); //console.log("td:", td);console.log("tr:", tr);console.log("tbl:", tbl) tds = dojo.query("td", tbl); tds.forEach(function(d, i){ if(td==d){tdIndex = i} }); trs = dojo.query("tr", tbl); trs.forEach(function(r, i){ if(tr==r){trIndex = i} }); cols = tds.length/trs.length; var o = { tbl:tbl, // focused table td:td, // focused TD tr:tr, // focused TR trs:trs, // rows tds:tds, // cells rows:trs.length,// row amount cols:cols, // column amount tdIndex:tdIndex,// index of focused cell trIndex:trIndex, // index of focused row colIndex:tdIndex%cols }; console.log("NEW tableData:",o); this.tableData = o; this._tempStoreTableData(500); return this.tableData; }, connectDraggable: function(){ // summary // Detects drag-n-drop in the editor (could probably be moved to there) // Currently only checks if item dragged was a TABLE, and removes its align attr // DOES NOT WORK IN FF - it could - but FF's drag detection is a monster // if(!dojo.isIE){ //console.warn("Drag and Drop is currently only detectable in IE."); return } // IE ONLY this.editorDomNode.ondragstart = dojo.hitch(this, "onDragStart"); this.editorDomNode.ondragend = dojo.hitch(this, "onDragEnd"); //NOTES: // FF _ Able to detect the drag-over object (the editor.domNode) // Not able to detect an item's ondrag() event // Don't know why - I actually got it working when there was an error // Something to do with different documents or windows I'm sure // //console.log("connectDraggable", tbl); /*tbl.ondragstart=dojo.hitch(this, "onDragStart"); tbl.addEventListener("dragstart", dojo.hitch(this, "onDragStart"), false); tbl.addEventListener("drag", dojo.hitch(this, "onDragStart2"), false); tbl.addEventListener("dragend", dojo.hitch(this, "onDragStart3"), false); dojo.withGlobal(this.editor.window, "selectElement",dijit._editor.selection, [tbl]); tbl.ondragstart = function(){ console.log ("ondragstart"); }; tbl.ondrag = function(){ alert("drag") //console.log ("ondrag"); */ }, onDragStart: function(){ var e = window.event; if(!e.srcElement.id){ e.srcElement.id = "tbl_"+(new Date().getTime()); } //console.log("onDragStart", e.srcElement.id); }, onDragEnd: function(){ // summary // Detects that an object has been dragged into place // Currently, this code is only used for when a table is dragged // and clears the "align" attribute, so that the table will look // to be more in the place that the user expected. // TODO: This code can be used for other things, most // notably UNDO, which currently is not quite usable. // This code could also find itself in the Editor code when it is // complete. //console.log("onDragEnd"); var e = window.event var node = e.srcElement; var id = node.id; var win = this.editor.window //console.log("NODE:", node.tagName, node.id, dojo.attr(node, "align")); // clearing a table's align attr // TODO: when ondrag becomes more robust, this code block // should move to its own method if(node.tagName.toLowerCase()=="table"){ setTimeout(function(){ var node = dojo.withGlobal(win, "byId", dojo, [id]); dojo.removeAttr(node, "align"); //console.log("set", node.tagName, dojo.attr(node, "align")) }, 100); } }, checkAvailable: function(){ // summary // For table plugs // Checking if a table or part of a table has focus so that // Plugs can change their status // if(this.availableCurrentlySet){ // availableCurrentlySet is set for a short amount of time, so that all // plugins get the same return without doing the method over //console.log("availableCurrentlySet:", this.availableCurrentlySet, "currentlyAvailable:", this.currentlyAvailable) return this.currentlyAvailable; } //console.log("G - checkAvailable..."); if(!this.editor) { //console.log("editor not ready") return false; } if(this.alwaysAvailable) { //console.log(" return always available") return true; } this.currentlyAvailable = this.editor.hasAncestorElement("table"); if(this.currentlyAvailable){ this.connectTableKeys(); }else{ this.disconnectTableKeys(); } this._tempAvailability(500); dojo.publish("available", [ this.currentlyAvailable ]); return this.currentlyAvailable; }, _prepareTable: function(tbl){ // For IE's sake, we are adding IDs to the TDs if none is there // We go ahead and use it for other code for convenience // var tds = this.editor.query("td", tbl); console.log("prep:", tds, tbl) if(!tds[0].id){ tds.forEach(function(td, i){ if(!td.id){ td.id = "tdid"+i+this.getTimeStamp(); } }, this); } return tds; }, getTimeStamp: function(){ return Math.floor(new Date().getTime() * 0.00000001); }, _tempStoreTableData: function(type){ // caching or clearing table data, depending on the arg // if(type===true){ //store indefinitely }else if(type===false){ // clear object this.tableData = null; }else if(type===undefined){ console.warn("_tempStoreTableData must be passed an argument") }else{ // type is a number/ms setTimeout(dojo.hitch(this, function(){ this.tableData = null; }), type); } }, _tempAvailability: function(type){ // caching or clearing availability, depending on the arg if(type===true){ //store indefinitely this.availableCurrentlySet = true; }else if(type===false){ // clear object this.availableCurrentlySet = false; }else if(type===undefined){ console.warn("_tempAvailability must be passed an argument") }else{ // type is a number/ms this.availableCurrentlySet = true; setTimeout(dojo.hitch(this, function(){ this.availableCurrentlySet = false; }), type); } }, connectTableKeys: function(){ // summary // When a table is in focus, start detecting keys // Mainly checking for the TAB key so user can tab // through a table (blocking the browser's desire to // tab away from teh editor completely) if(this.tablesConnected){ return; } this.tablesConnected = true; var node = (this.editor.iframe) ? this.editor.document : this.editor.editNode; this.cnKeyDn = dojo.connect(node, "onkeydown", this, "onKeyDown"); this.cnKeyUp = dojo.connect(node, "onkeyup", this, "onKeyUp"); dojo.connect(node, "onkeypress", this, "onKeyUp"); }, disconnectTableKeys: function(){ //console.log("disconnect") dojo.disconnect(this.cnKeyDn); dojo.disconnect(this.cnKeyUp); this.tablesConnected = false; }, onKeyDown: function(evt){ var key = evt.keyCode; //console.log(" -> DOWN:", key); if(key == 16) this.shiftKeyDown = true; if(key == 9) {console.log("TAB!:"); var o = this.getTableInfo(); //console.log("TAB ", o.tdIndex, o); // modifying the o.tdIndex in the tableData directly, because we may save it // FIXME: tabTo is a global o.tdIndex = (this.shiftKeyDown) ? o.tdIndex-1 : tabTo = o.tdIndex+1; if(o.tdIndex>=0 && o.tdIndex UP:", key) if(key == 16) this.shiftKeyDown = false; if(key == 37 || key == 38 || key == 39 || key == 40 ){ // user can arrow or tab out of table - need to recheck this.onDisplayChanged(); } if(key == 9 && this.stopEvent) dojo.stopEvent(evt); }, onDisplayChanged: function(){ //console.log("onDisplayChanged") this.currentlyAvailable = false; this._tempStoreTableData(false); this._tempAvailability(false); this.checkAvailable(); } }); // global: tablePluginHandler = new dojox.editor.plugins.GlobalTableHandler(); //FIXME: no globals. dojo.declare("dojox.editor.plugins.TablePlugins", dijit._editor._Plugin, { //summary: // A collection of Plugins for inserting and modifying tables in the Editor // See end of this document for all avaiable plugs // and dojox/editorPlugins/tests/editorTablePlugs.html for an example // // NOT IMPLEMENTED: Not handling cell merge, span or split // iconClassPrefix: "editorIcon", useDefaultCommand: false, buttonClass: dijit.form.Button, commandName:"", label:"", alwaysAvailable:false, undoEnabled:false, constructor: function(){ // summary // Initialize certain plugins // switch(this.commandName){ case "colorTableCell": this.buttonClass = dijit.form.DropDownButton; this.dropDown = new dijit.ColorPalette(); this.connect(this.dropDown, "onChange", function(color){ this.modTable(null, color); }); break; case "modifyTable": this.buttonClass = dijit.form.DropDownButton; this.modTable = this.launchModifyDialog; break; case "insertTable": this.alwaysAvailable = true; this.buttonClass = dijit.form.DropDownButton; this.modTable = this.launchInsertDialog; break; case "tableContextMenu": this.connect(this, "setEditor", function(){ this._createContextMenu(); this.button.domNode.style.display = "none"; }); break; } dojo.subscribe("available", this, "onDisplayChanged"); }, onDisplayChanged: function(withinTable){ // subscribed to from the global object's publish method // //console.log("onDisplayChanged", this.commandName); if(!this.alwaysAvailable){ this.available = withinTable; this.button.attr('disabled', !this.available); } }, setEditor: function(){ this.inherited(arguments); this.onEditorLoaded(); }, onEditorLoaded: function(){ //stub // call global object to initialize it tablePluginHandler.initialize(this.editor); }, _createContextMenu: function(){ // summary // Building context menu for right-click shortcuts within a table // var node = dojo.isFF ? this.editor.editNode : this.editorDomNode; var pMenu = new dijit.Menu({targetNodeIds:[node], id:"progMenu", contextMenuForWindow:dojo.isIE}); var _M = dijit.MenuItem; var messages = dojo.i18n.getLocalization("dojox.editor.plugins", "TableDialog", this.lang); pMenu.addChild(new _M({label: messages.selectTableLabel, onClick: dojo.hitch(this, "selectTable")})); pMenu.addChild(new dijit.MenuSeparator()); pMenu.addChild(new _M({label: messages.insertTableRowBeforeLabel, onClick: dojo.hitch(this, "modTable", "insertTableRowBefore" )})); pMenu.addChild(new _M({label: messages.insertTableRowAfterLabel, onClick: dojo.hitch(this, "modTable", "insertTableRowAfter" )})); pMenu.addChild(new _M({label: messages.insertTableColumnBeforeLabel, onClick: dojo.hitch(this, "modTable", "insertTableColumnBefore" )})); pMenu.addChild(new _M({label: messages.insertTableColumnAfterLabel, onClick: dojo.hitch(this, "modTable", "insertTableColumnAfter" )})); pMenu.addChild(new dijit.MenuSeparator()); pMenu.addChild(new _M({label: messages.deleteTableRowLabel, onClick: dojo.hitch(this, "modTable", "deleteTableRow" )})); pMenu.addChild(new _M({label: messages.deleteTableColumnLabel, onClick: dojo.hitch(this, "modTable", "deleteTableColumn" )})); // overwriting this method, as the menu's coordinates // are not accurate in the editor's iframe // FIXME: Works well in IE - all others, sometimes inaccurate. pMenu._openMyself = function(e){ if(!tablePluginHandler.checkAvailable()){ return; } if(this.leftClickToOpen && e.button>0){ return; } dojo.stopEvent(e); var x,y; if(dojo.isIE){ x = e.x; y = e.y; }else{ x = e.screenX; y = e.screenY + 25; } var self=this; var savedFocus = dijit.getFocus(this); function closeAndRestoreFocus(){ // user has clicked on a menu or popup dijit.focus(savedFocus); dijit.popup.close(self); } var res = dijit.popup.open({ popup: this, x: x, y: y, onExecute: closeAndRestoreFocus, onCancel: closeAndRestoreFocus, orient: this.isLeftToRight() ? 'L' : 'R' }); var v = dijit.getViewport(); if(res.y+res.h>v.h){ if(e.screenY-res.h>=0){ y = e.screenY - res.h; }else{ y = 0; } dijit.popup.close(this); // FIXME: Not very DRY here. // Reopening popup if the location was not good. res = dijit.popup.open({ popup: this, x: x, y: y, onExecute: closeAndRestoreFocus, onCancel: closeAndRestoreFocus, orient: this.isLeftToRight() ? 'L' : 'R' }); } console.log(dijit.getViewport()); this.focus(); this._onBlur = function(){ this.inherited('_onBlur', arguments); dijit.popup.close(this); } } this.menu = pMenu;";s:7:"private";b:1;s:7:"summary";s:0:"";s:9:"classlike";b:1;}s:45:"dojox.editor.plugins.TablePlugins.selectTable";a:4:{s:9:"prototype";s:33:"dojox.editor.plugins.TablePlugins";s:4:"type";s:8:"Function";s:6:"source";s:17503:"dojo.provide("dojox.editor.plugins.TablePlugins"); dojo.require("dijit._editor._Plugin"); dojo.require("dijit._editor.selection"); dojo.require("dijit.Menu"); dojo.require("dojo.i18n"); dojo.requireLocalization("dojox.editor.plugins", "TableDialog"); dojo.experimental("dojox.editor.plugins.TablePlugins"); // summary: // A series of plugins that give the Editor the ability to create and edit // HTML tables. See the end of this document for all avaiable plugins // and dojox/editorPlugins/tests/editorTablePlugs.html for an example // // example: // |
// | Editor text is here // |
// // TODO: // Currently not supporting merging or splitting cells // // FIXME: Undo is very buggy, and therefore unimeplented in all browsers // except IE - which itself has only been lightly tested. // // FIXME: Selecting multiple table cells in Firefox looks to be impossible. // This affect the 'colorTableCell' plugin. Cells can still be // colored individually or in rows. dojo.declare("dojox.editor.plugins.GlobalTableHandler", dijit._editor._Plugin,{ // summary: // A global object that handles common tasks for all the plugins. Since // there are several plugins that are all calling common methods, it's preferable // that they call a centralized location that either has a set variable or a // timeout to only repeat code-heavy calls when necessary. // tablesConnected:false, currentlyAvailable: false, alwaysAvailable:false, availableCurrentlySet:false, initialized:false, tableData: null, shiftKeyDown:false, editorDomNode: null, undoEnabled: dojo.isIE, //FIXME: doMixins: function(){ dojo.mixin(this.editor,{ getAncestorElement: function(tagName){ return dojo.withGlobal(this.window, "getAncestorElement",dijit._editor.selection, [tagName]); }, hasAncestorElement: function(tagName){ return true return dojo.withGlobal(this.window, "hasAncestorElement",dijit._editor.selection, [tagName]); }, selectElement: function(elem){ dojo.withGlobal(this.window, "selectElement",dijit._editor.selection, [elem]); }, byId: function(id){ return dojo.withGlobal(this.window, "byId", dojo, [id]); }, query: function(arg, scope, returnFirstOnly){ // this shortcut is dubious - not sure scoping is necessary var ar = dojo.withGlobal(this.window, "query", dojo, [arg, scope]); return (returnFirstOnly) ? ar[0] : ar; } }); }, initialize: function(editor){ // summary: // Initialize the global handler upon a plugin's first instance of setEditor // // All plugins will attempt initialization. We only need to do so once. if(this.initialized){ return; } this.initialized = true; this.editor = editor; this.editorDomNode = this.editor.editNode || this.editor.iframe.document.body.firstChild; // RichText should have a mouseup connection to recognize drag-selections // Example would be selecting multiple table cells dojo.connect(this.editorDomNode , "mouseup", this.editor, "onClick"); dojo.connect(this.editor, "onDisplayChanged", this, "checkAvailable"); this.doMixins(); this.connectDraggable(); }, getTableInfo: function(forceNewData){ // summary // Gets the table in focus // Collects info on the table - see return params // if(forceNewData){ this._tempStoreTableData(false); } if(this.tableData){ // tableData is set for a short amount of time, so that all // plugins get the same return without doing the method over console.log("returning current tableData:", this.tableData); return this.tableData; } var tr, trs, td, tds, tbl, cols, tdIndex, trIndex; td = this.editor.getAncestorElement("td"); if(td){ tr = td.parentNode; } tbl = this.editor.getAncestorElement("table"); //console.log("td:", td);console.log("tr:", tr);console.log("tbl:", tbl) tds = dojo.query("td", tbl); tds.forEach(function(d, i){ if(td==d){tdIndex = i} }); trs = dojo.query("tr", tbl); trs.forEach(function(r, i){ if(tr==r){trIndex = i} }); cols = tds.length/trs.length; var o = { tbl:tbl, // focused table td:td, // focused TD tr:tr, // focused TR trs:trs, // rows tds:tds, // cells rows:trs.length,// row amount cols:cols, // column amount tdIndex:tdIndex,// index of focused cell trIndex:trIndex, // index of focused row colIndex:tdIndex%cols }; console.log("NEW tableData:",o); this.tableData = o; this._tempStoreTableData(500); return this.tableData; }, connectDraggable: function(){ // summary // Detects drag-n-drop in the editor (could probably be moved to there) // Currently only checks if item dragged was a TABLE, and removes its align attr // DOES NOT WORK IN FF - it could - but FF's drag detection is a monster // if(!dojo.isIE){ //console.warn("Drag and Drop is currently only detectable in IE."); return } // IE ONLY this.editorDomNode.ondragstart = dojo.hitch(this, "onDragStart"); this.editorDomNode.ondragend = dojo.hitch(this, "onDragEnd"); //NOTES: // FF _ Able to detect the drag-over object (the editor.domNode) // Not able to detect an item's ondrag() event // Don't know why - I actually got it working when there was an error // Something to do with different documents or windows I'm sure // //console.log("connectDraggable", tbl); /*tbl.ondragstart=dojo.hitch(this, "onDragStart"); tbl.addEventListener("dragstart", dojo.hitch(this, "onDragStart"), false); tbl.addEventListener("drag", dojo.hitch(this, "onDragStart2"), false); tbl.addEventListener("dragend", dojo.hitch(this, "onDragStart3"), false); dojo.withGlobal(this.editor.window, "selectElement",dijit._editor.selection, [tbl]); tbl.ondragstart = function(){ console.log ("ondragstart"); }; tbl.ondrag = function(){ alert("drag") //console.log ("ondrag"); */ }, onDragStart: function(){ var e = window.event; if(!e.srcElement.id){ e.srcElement.id = "tbl_"+(new Date().getTime()); } //console.log("onDragStart", e.srcElement.id); }, onDragEnd: function(){ // summary // Detects that an object has been dragged into place // Currently, this code is only used for when a table is dragged // and clears the "align" attribute, so that the table will look // to be more in the place that the user expected. // TODO: This code can be used for other things, most // notably UNDO, which currently is not quite usable. // This code could also find itself in the Editor code when it is // complete. //console.log("onDragEnd"); var e = window.event var node = e.srcElement; var id = node.id; var win = this.editor.window //console.log("NODE:", node.tagName, node.id, dojo.attr(node, "align")); // clearing a table's align attr // TODO: when ondrag becomes more robust, this code block // should move to its own method if(node.tagName.toLowerCase()=="table"){ setTimeout(function(){ var node = dojo.withGlobal(win, "byId", dojo, [id]); dojo.removeAttr(node, "align"); //console.log("set", node.tagName, dojo.attr(node, "align")) }, 100); } }, checkAvailable: function(){ // summary // For table plugs // Checking if a table or part of a table has focus so that // Plugs can change their status // if(this.availableCurrentlySet){ // availableCurrentlySet is set for a short amount of time, so that all // plugins get the same return without doing the method over //console.log("availableCurrentlySet:", this.availableCurrentlySet, "currentlyAvailable:", this.currentlyAvailable) return this.currentlyAvailable; } //console.log("G - checkAvailable..."); if(!this.editor) { //console.log("editor not ready") return false; } if(this.alwaysAvailable) { //console.log(" return always available") return true; } this.currentlyAvailable = this.editor.hasAncestorElement("table"); if(this.currentlyAvailable){ this.connectTableKeys(); }else{ this.disconnectTableKeys(); } this._tempAvailability(500); dojo.publish("available", [ this.currentlyAvailable ]); return this.currentlyAvailable; }, _prepareTable: function(tbl){ // For IE's sake, we are adding IDs to the TDs if none is there // We go ahead and use it for other code for convenience // var tds = this.editor.query("td", tbl); console.log("prep:", tds, tbl) if(!tds[0].id){ tds.forEach(function(td, i){ if(!td.id){ td.id = "tdid"+i+this.getTimeStamp(); } }, this); } return tds; }, getTimeStamp: function(){ return Math.floor(new Date().getTime() * 0.00000001); }, _tempStoreTableData: function(type){ // caching or clearing table data, depending on the arg // if(type===true){ //store indefinitely }else if(type===false){ // clear object this.tableData = null; }else if(type===undefined){ console.warn("_tempStoreTableData must be passed an argument") }else{ // type is a number/ms setTimeout(dojo.hitch(this, function(){ this.tableData = null; }), type); } }, _tempAvailability: function(type){ // caching or clearing availability, depending on the arg if(type===true){ //store indefinitely this.availableCurrentlySet = true; }else if(type===false){ // clear object this.availableCurrentlySet = false; }else if(type===undefined){ console.warn("_tempAvailability must be passed an argument") }else{ // type is a number/ms this.availableCurrentlySet = true; setTimeout(dojo.hitch(this, function(){ this.availableCurrentlySet = false; }), type); } }, connectTableKeys: function(){ // summary // When a table is in focus, start detecting keys // Mainly checking for the TAB key so user can tab // through a table (blocking the browser's desire to // tab away from teh editor completely) if(this.tablesConnected){ return; } this.tablesConnected = true; var node = (this.editor.iframe) ? this.editor.document : this.editor.editNode; this.cnKeyDn = dojo.connect(node, "onkeydown", this, "onKeyDown"); this.cnKeyUp = dojo.connect(node, "onkeyup", this, "onKeyUp"); dojo.connect(node, "onkeypress", this, "onKeyUp"); }, disconnectTableKeys: function(){ //console.log("disconnect") dojo.disconnect(this.cnKeyDn); dojo.disconnect(this.cnKeyUp); this.tablesConnected = false; }, onKeyDown: function(evt){ var key = evt.keyCode; //console.log(" -> DOWN:", key); if(key == 16) this.shiftKeyDown = true; if(key == 9) {console.log("TAB!:"); var o = this.getTableInfo(); //console.log("TAB ", o.tdIndex, o); // modifying the o.tdIndex in the tableData directly, because we may save it // FIXME: tabTo is a global o.tdIndex = (this.shiftKeyDown) ? o.tdIndex-1 : tabTo = o.tdIndex+1; if(o.tdIndex>=0 && o.tdIndex UP:", key) if(key == 16) this.shiftKeyDown = false; if(key == 37 || key == 38 || key == 39 || key == 40 ){ // user can arrow or tab out of table - need to recheck this.onDisplayChanged(); } if(key == 9 && this.stopEvent) dojo.stopEvent(evt); }, onDisplayChanged: function(){ //console.log("onDisplayChanged") this.currentlyAvailable = false; this._tempStoreTableData(false); this._tempAvailability(false); this.checkAvailable(); } }); // global: tablePluginHandler = new dojox.editor.plugins.GlobalTableHandler(); //FIXME: no globals. dojo.declare("dojox.editor.plugins.TablePlugins", dijit._editor._Plugin, { //summary: // A collection of Plugins for inserting and modifying tables in the Editor // See end of this document for all avaiable plugs // and dojox/editorPlugins/tests/editorTablePlugs.html for an example // // NOT IMPLEMENTED: Not handling cell merge, span or split // iconClassPrefix: "editorIcon", useDefaultCommand: false, buttonClass: dijit.form.Button, commandName:"", label:"", alwaysAvailable:false, undoEnabled:false, constructor: function(){ // summary // Initialize certain plugins // switch(this.commandName){ case "colorTableCell": this.buttonClass = dijit.form.DropDownButton; this.dropDown = new dijit.ColorPalette(); this.connect(this.dropDown, "onChange", function(color){ this.modTable(null, color); }); break; case "modifyTable": this.buttonClass = dijit.form.DropDownButton; this.modTable = this.launchModifyDialog; break; case "insertTable": this.alwaysAvailable = true; this.buttonClass = dijit.form.DropDownButton; this.modTable = this.launchInsertDialog; break; case "tableContextMenu": this.connect(this, "setEditor", function(){ this._createContextMenu(); this.button.domNode.style.display = "none"; }); break; } dojo.subscribe("available", this, "onDisplayChanged"); }, onDisplayChanged: function(withinTable){ // subscribed to from the global object's publish method // //console.log("onDisplayChanged", this.commandName); if(!this.alwaysAvailable){ this.available = withinTable; this.button.attr('disabled', !this.available); } }, setEditor: function(){ this.inherited(arguments); this.onEditorLoaded(); }, onEditorLoaded: function(){ //stub // call global object to initialize it tablePluginHandler.initialize(this.editor); }, _createContextMenu: function(){ // summary // Building context menu for right-click shortcuts within a table // var node = dojo.isFF ? this.editor.editNode : this.editorDomNode; var pMenu = new dijit.Menu({targetNodeIds:[node], id:"progMenu", contextMenuForWindow:dojo.isIE}); var _M = dijit.MenuItem; var messages = dojo.i18n.getLocalization("dojox.editor.plugins", "TableDialog", this.lang); pMenu.addChild(new _M({label: messages.selectTableLabel, onClick: dojo.hitch(this, "selectTable")})); pMenu.addChild(new dijit.MenuSeparator()); pMenu.addChild(new _M({label: messages.insertTableRowBeforeLabel, onClick: dojo.hitch(this, "modTable", "insertTableRowBefore" )})); pMenu.addChild(new _M({label: messages.insertTableRowAfterLabel, onClick: dojo.hitch(this, "modTable", "insertTableRowAfter" )})); pMenu.addChild(new _M({label: messages.insertTableColumnBeforeLabel, onClick: dojo.hitch(this, "modTable", "insertTableColumnBefore" )})); pMenu.addChild(new _M({label: messages.insertTableColumnAfterLabel, onClick: dojo.hitch(this, "modTable", "insertTableColumnAfter" )})); pMenu.addChild(new dijit.MenuSeparator()); pMenu.addChild(new _M({label: messages.deleteTableRowLabel, onClick: dojo.hitch(this, "modTable", "deleteTableRow" )})); pMenu.addChild(new _M({label: messages.deleteTableColumnLabel, onClick: dojo.hitch(this, "modTable", "deleteTableColumn" )})); // overwriting this method, as the menu's coordinates // are not accurate in the editor's iframe // FIXME: Works well in IE - all others, sometimes inaccurate. pMenu._openMyself = function(e){ if(!tablePluginHandler.checkAvailable()){ return; } if(this.leftClickToOpen && e.button>0){ return; } dojo.stopEvent(e); var x,y; if(dojo.isIE){ x = e.x; y = e.y; }else{ x = e.screenX; y = e.screenY + 25; } var self=this; var savedFocus = dijit.getFocus(this); function closeAndRestoreFocus(){ // user has clicked on a menu or popup dijit.focus(savedFocus); dijit.popup.close(self); } var res = dijit.popup.open({ popup: this, x: x, y: y, onExecute: closeAndRestoreFocus, onCancel: closeAndRestoreFocus, orient: this.isLeftToRight() ? 'L' : 'R' }); var v = dijit.getViewport(); if(res.y+res.h>v.h){ if(e.screenY-res.h>=0){ y = e.screenY - res.h; }else{ y = 0; } dijit.popup.close(this); // FIXME: Not very DRY here. // Reopening popup if the location was not good. res = dijit.popup.open({ popup: this, x: x, y: y, onExecute: closeAndRestoreFocus, onCancel: closeAndRestoreFocus, orient: this.isLeftToRight() ? 'L' : 'R' }); } console.log(dijit.getViewport()); this.focus(); this._onBlur = function(){ this.inherited('_onBlur', arguments); dijit.popup.close(this); } } this.menu = pMenu; }, selectTable: function(){ // selects table that is in focus var o = this.getTableInfo(); dojo.withGlobal(this.editor.window, "selectElement",dijit._editor.selection, [o.tbl]);";s:7:"summary";s:0:"";}s:52:"dojox.editor.plugins.TablePlugins.launchInsertDialog";a:4:{s:9:"prototype";s:33:"dojox.editor.plugins.TablePlugins";s:4:"type";s:8:"Function";s:6:"source";s:466:" var w = new dojox.editor.plugins.EditorTableDialog({}); w.show(); var c = dojo.connect(w, "onBuildTable", this, function(obj){ dojo.disconnect(c); var res = this.editor.execCommand('inserthtml', obj.htmlText); // commenting this line, due to msg below //var td = this.editor.query("td", this.editor.byId(obj.id)); //HMMMM.... This throws a security error now. didn't used to. //this.editor.selectElement(td); });";s:7:"summary";s:0:"";}s:52:"dojox.editor.plugins.TablePlugins.launchModifyDialog";a:4:{s:9:"prototype";s:33:"dojox.editor.plugins.TablePlugins";s:4:"type";s:8:"Function";s:6:"source";s:364:" var o = this.getTableInfo(); console.log("LAUNCH DIALOG") var w = new dojox.editor.plugins.EditorModifyTableDialog({table:o.tbl}); w.show(); this.connect(w, "onSetTable", function(color){ // uhm... not sure whats going on here... var o = this.getTableInfo(); console.log("set color:", color) dojo.attr(o.td, "bgcolor", color); });";s:7:"summary";s:0:"";}s:45:"dojox.editor.plugins.TablePlugins._initButton";a:5:{s:9:"prototype";s:33:"dojox.editor.plugins.TablePlugins";s:4:"type";s:8:"Function";s:6:"source";s:403:" this.command = this.commandName; this.label = this.editor.commands[this.command] = this._makeTitle(this.command); this.inherited(arguments); delete this.command; if(this.commandName != "colorTableCell") this.connect(this.button.domNode, "click", "modTable"); if(this.commandName=="tableContextMenu") this.button.domNode.display = "none"; this.onDisplayChanged(false);";s:7:"private";b:1;s:7:"summary";s:0:"";}s:42:"dojox.editor.plugins.TablePlugins.modTable";a:6:{s:9:"prototype";s:33:"dojox.editor.plugins.TablePlugins";s:4:"type";s:8:"Function";s:10:"parameters";a:2:{s:3:"cmd";a:1:{s:4:"type";s:0:"";}s:4:"args";a:1:{s:4:"type";s:0:"";}}s:6:"source";s:20878:"dojo.provide("dojox.editor.plugins.TablePlugins"); dojo.require("dijit._editor._Plugin"); dojo.require("dijit._editor.selection"); dojo.require("dijit.Menu"); dojo.require("dojo.i18n"); dojo.requireLocalization("dojox.editor.plugins", "TableDialog"); dojo.experimental("dojox.editor.plugins.TablePlugins"); // summary: // A series of plugins that give the Editor the ability to create and edit // HTML tables. See the end of this document for all avaiable plugins // and dojox/editorPlugins/tests/editorTablePlugs.html for an example // // example: // |
// | Editor text is here // |
// // TODO: // Currently not supporting merging or splitting cells // // FIXME: Undo is very buggy, and therefore unimeplented in all browsers // except IE - which itself has only been lightly tested. // // FIXME: Selecting multiple table cells in Firefox looks to be impossible. // This affect the 'colorTableCell' plugin. Cells can still be // colored individually or in rows. dojo.declare("dojox.editor.plugins.GlobalTableHandler", dijit._editor._Plugin,{ // summary: // A global object that handles common tasks for all the plugins. Since // there are several plugins that are all calling common methods, it's preferable // that they call a centralized location that either has a set variable or a // timeout to only repeat code-heavy calls when necessary. // tablesConnected:false, currentlyAvailable: false, alwaysAvailable:false, availableCurrentlySet:false, initialized:false, tableData: null, shiftKeyDown:false, editorDomNode: null, undoEnabled: dojo.isIE, //FIXME: doMixins: function(){ dojo.mixin(this.editor,{ getAncestorElement: function(tagName){ return dojo.withGlobal(this.window, "getAncestorElement",dijit._editor.selection, [tagName]); }, hasAncestorElement: function(tagName){ return true return dojo.withGlobal(this.window, "hasAncestorElement",dijit._editor.selection, [tagName]); }, selectElement: function(elem){ dojo.withGlobal(this.window, "selectElement",dijit._editor.selection, [elem]); }, byId: function(id){ return dojo.withGlobal(this.window, "byId", dojo, [id]); }, query: function(arg, scope, returnFirstOnly){ // this shortcut is dubious - not sure scoping is necessary var ar = dojo.withGlobal(this.window, "query", dojo, [arg, scope]); return (returnFirstOnly) ? ar[0] : ar; } }); }, initialize: function(editor){ // summary: // Initialize the global handler upon a plugin's first instance of setEditor // // All plugins will attempt initialization. We only need to do so once. if(this.initialized){ return; } this.initialized = true; this.editor = editor; this.editorDomNode = this.editor.editNode || this.editor.iframe.document.body.firstChild; // RichText should have a mouseup connection to recognize drag-selections // Example would be selecting multiple table cells dojo.connect(this.editorDomNode , "mouseup", this.editor, "onClick"); dojo.connect(this.editor, "onDisplayChanged", this, "checkAvailable"); this.doMixins(); this.connectDraggable(); }, getTableInfo: function(forceNewData){ // summary // Gets the table in focus // Collects info on the table - see return params // if(forceNewData){ this._tempStoreTableData(false); } if(this.tableData){ // tableData is set for a short amount of time, so that all // plugins get the same return without doing the method over console.log("returning current tableData:", this.tableData); return this.tableData; } var tr, trs, td, tds, tbl, cols, tdIndex, trIndex; td = this.editor.getAncestorElement("td"); if(td){ tr = td.parentNode; } tbl = this.editor.getAncestorElement("table"); //console.log("td:", td);console.log("tr:", tr);console.log("tbl:", tbl) tds = dojo.query("td", tbl); tds.forEach(function(d, i){ if(td==d){tdIndex = i} }); trs = dojo.query("tr", tbl); trs.forEach(function(r, i){ if(tr==r){trIndex = i} }); cols = tds.length/trs.length; var o = { tbl:tbl, // focused table td:td, // focused TD tr:tr, // focused TR trs:trs, // rows tds:tds, // cells rows:trs.length,// row amount cols:cols, // column amount tdIndex:tdIndex,// index of focused cell trIndex:trIndex, // index of focused row colIndex:tdIndex%cols }; console.log("NEW tableData:",o); this.tableData = o; this._tempStoreTableData(500); return this.tableData; }, connectDraggable: function(){ // summary // Detects drag-n-drop in the editor (could probably be moved to there) // Currently only checks if item dragged was a TABLE, and removes its align attr // DOES NOT WORK IN FF - it could - but FF's drag detection is a monster // if(!dojo.isIE){ //console.warn("Drag and Drop is currently only detectable in IE."); return } // IE ONLY this.editorDomNode.ondragstart = dojo.hitch(this, "onDragStart"); this.editorDomNode.ondragend = dojo.hitch(this, "onDragEnd"); //NOTES: // FF _ Able to detect the drag-over object (the editor.domNode) // Not able to detect an item's ondrag() event // Don't know why - I actually got it working when there was an error // Something to do with different documents or windows I'm sure // //console.log("connectDraggable", tbl); /*tbl.ondragstart=dojo.hitch(this, "onDragStart"); tbl.addEventListener("dragstart", dojo.hitch(this, "onDragStart"), false); tbl.addEventListener("drag", dojo.hitch(this, "onDragStart2"), false); tbl.addEventListener("dragend", dojo.hitch(this, "onDragStart3"), false); dojo.withGlobal(this.editor.window, "selectElement",dijit._editor.selection, [tbl]); tbl.ondragstart = function(){ console.log ("ondragstart"); }; tbl.ondrag = function(){ alert("drag") //console.log ("ondrag"); */ }, onDragStart: function(){ var e = window.event; if(!e.srcElement.id){ e.srcElement.id = "tbl_"+(new Date().getTime()); } //console.log("onDragStart", e.srcElement.id); }, onDragEnd: function(){ // summary // Detects that an object has been dragged into place // Currently, this code is only used for when a table is dragged // and clears the "align" attribute, so that the table will look // to be more in the place that the user expected. // TODO: This code can be used for other things, most // notably UNDO, which currently is not quite usable. // This code could also find itself in the Editor code when it is // complete. //console.log("onDragEnd"); var e = window.event var node = e.srcElement; var id = node.id; var win = this.editor.window //console.log("NODE:", node.tagName, node.id, dojo.attr(node, "align")); // clearing a table's align attr // TODO: when ondrag becomes more robust, this code block // should move to its own method if(node.tagName.toLowerCase()=="table"){ setTimeout(function(){ var node = dojo.withGlobal(win, "byId", dojo, [id]); dojo.removeAttr(node, "align"); //console.log("set", node.tagName, dojo.attr(node, "align")) }, 100); } }, checkAvailable: function(){ // summary // For table plugs // Checking if a table or part of a table has focus so that // Plugs can change their status // if(this.availableCurrentlySet){ // availableCurrentlySet is set for a short amount of time, so that all // plugins get the same return without doing the method over //console.log("availableCurrentlySet:", this.availableCurrentlySet, "currentlyAvailable:", this.currentlyAvailable) return this.currentlyAvailable; } //console.log("G - checkAvailable..."); if(!this.editor) { //console.log("editor not ready") return false; } if(this.alwaysAvailable) { //console.log(" return always available") return true; } this.currentlyAvailable = this.editor.hasAncestorElement("table"); if(this.currentlyAvailable){ this.connectTableKeys(); }else{ this.disconnectTableKeys(); } this._tempAvailability(500); dojo.publish("available", [ this.currentlyAvailable ]); return this.currentlyAvailable; }, _prepareTable: function(tbl){ // For IE's sake, we are adding IDs to the TDs if none is there // We go ahead and use it for other code for convenience // var tds = this.editor.query("td", tbl); console.log("prep:", tds, tbl) if(!tds[0].id){ tds.forEach(function(td, i){ if(!td.id){ td.id = "tdid"+i+this.getTimeStamp(); } }, this); } return tds; }, getTimeStamp: function(){ return Math.floor(new Date().getTime() * 0.00000001); }, _tempStoreTableData: function(type){ // caching or clearing table data, depending on the arg // if(type===true){ //store indefinitely }else if(type===false){ // clear object this.tableData = null; }else if(type===undefined){ console.warn("_tempStoreTableData must be passed an argument") }else{ // type is a number/ms setTimeout(dojo.hitch(this, function(){ this.tableData = null; }), type); } }, _tempAvailability: function(type){ // caching or clearing availability, depending on the arg if(type===true){ //store indefinitely this.availableCurrentlySet = true; }else if(type===false){ // clear object this.availableCurrentlySet = false; }else if(type===undefined){ console.warn("_tempAvailability must be passed an argument") }else{ // type is a number/ms this.availableCurrentlySet = true; setTimeout(dojo.hitch(this, function(){ this.availableCurrentlySet = false; }), type); } }, connectTableKeys: function(){ // summary // When a table is in focus, start detecting keys // Mainly checking for the TAB key so user can tab // through a table (blocking the browser's desire to // tab away from teh editor completely) if(this.tablesConnected){ return; } this.tablesConnected = true; var node = (this.editor.iframe) ? this.editor.document : this.editor.editNode; this.cnKeyDn = dojo.connect(node, "onkeydown", this, "onKeyDown"); this.cnKeyUp = dojo.connect(node, "onkeyup", this, "onKeyUp"); dojo.connect(node, "onkeypress", this, "onKeyUp"); }, disconnectTableKeys: function(){ //console.log("disconnect") dojo.disconnect(this.cnKeyDn); dojo.disconnect(this.cnKeyUp); this.tablesConnected = false; }, onKeyDown: function(evt){ var key = evt.keyCode; //console.log(" -> DOWN:", key); if(key == 16) this.shiftKeyDown = true; if(key == 9) {console.log("TAB!:"); var o = this.getTableInfo(); //console.log("TAB ", o.tdIndex, o); // modifying the o.tdIndex in the tableData directly, because we may save it // FIXME: tabTo is a global o.tdIndex = (this.shiftKeyDown) ? o.tdIndex-1 : tabTo = o.tdIndex+1; if(o.tdIndex>=0 && o.tdIndex UP:", key) if(key == 16) this.shiftKeyDown = false; if(key == 37 || key == 38 || key == 39 || key == 40 ){ // user can arrow or tab out of table - need to recheck this.onDisplayChanged(); } if(key == 9 && this.stopEvent) dojo.stopEvent(evt); }, onDisplayChanged: function(){ //console.log("onDisplayChanged") this.currentlyAvailable = false; this._tempStoreTableData(false); this._tempAvailability(false); this.checkAvailable(); } }); // global: tablePluginHandler = new dojox.editor.plugins.GlobalTableHandler(); //FIXME: no globals. dojo.declare("dojox.editor.plugins.TablePlugins", dijit._editor._Plugin, { //summary: // A collection of Plugins for inserting and modifying tables in the Editor // See end of this document for all avaiable plugs // and dojox/editorPlugins/tests/editorTablePlugs.html for an example // // NOT IMPLEMENTED: Not handling cell merge, span or split // iconClassPrefix: "editorIcon", useDefaultCommand: false, buttonClass: dijit.form.Button, commandName:"", label:"", alwaysAvailable:false, undoEnabled:false, constructor: function(){ // summary // Initialize certain plugins // switch(this.commandName){ case "colorTableCell": this.buttonClass = dijit.form.DropDownButton; this.dropDown = new dijit.ColorPalette(); this.connect(this.dropDown, "onChange", function(color){ this.modTable(null, color); }); break; case "modifyTable": this.buttonClass = dijit.form.DropDownButton; this.modTable = this.launchModifyDialog; break; case "insertTable": this.alwaysAvailable = true; this.buttonClass = dijit.form.DropDownButton; this.modTable = this.launchInsertDialog; break; case "tableContextMenu": this.connect(this, "setEditor", function(){ this._createContextMenu(); this.button.domNode.style.display = "none"; }); break; } dojo.subscribe("available", this, "onDisplayChanged"); }, onDisplayChanged: function(withinTable){ // subscribed to from the global object's publish method // //console.log("onDisplayChanged", this.commandName); if(!this.alwaysAvailable){ this.available = withinTable; this.button.attr('disabled', !this.available); } }, setEditor: function(){ this.inherited(arguments); this.onEditorLoaded(); }, onEditorLoaded: function(){ //stub // call global object to initialize it tablePluginHandler.initialize(this.editor); }, _createContextMenu: function(){ // summary // Building context menu for right-click shortcuts within a table // var node = dojo.isFF ? this.editor.editNode : this.editorDomNode; var pMenu = new dijit.Menu({targetNodeIds:[node], id:"progMenu", contextMenuForWindow:dojo.isIE}); var _M = dijit.MenuItem; var messages = dojo.i18n.getLocalization("dojox.editor.plugins", "TableDialog", this.lang); pMenu.addChild(new _M({label: messages.selectTableLabel, onClick: dojo.hitch(this, "selectTable")})); pMenu.addChild(new dijit.MenuSeparator()); pMenu.addChild(new _M({label: messages.insertTableRowBeforeLabel, onClick: dojo.hitch(this, "modTable", "insertTableRowBefore" )})); pMenu.addChild(new _M({label: messages.insertTableRowAfterLabel, onClick: dojo.hitch(this, "modTable", "insertTableRowAfter" )})); pMenu.addChild(new _M({label: messages.insertTableColumnBeforeLabel, onClick: dojo.hitch(this, "modTable", "insertTableColumnBefore" )})); pMenu.addChild(new _M({label: messages.insertTableColumnAfterLabel, onClick: dojo.hitch(this, "modTable", "insertTableColumnAfter" )})); pMenu.addChild(new dijit.MenuSeparator()); pMenu.addChild(new _M({label: messages.deleteTableRowLabel, onClick: dojo.hitch(this, "modTable", "deleteTableRow" )})); pMenu.addChild(new _M({label: messages.deleteTableColumnLabel, onClick: dojo.hitch(this, "modTable", "deleteTableColumn" )})); // overwriting this method, as the menu's coordinates // are not accurate in the editor's iframe // FIXME: Works well in IE - all others, sometimes inaccurate. pMenu._openMyself = function(e){ if(!tablePluginHandler.checkAvailable()){ return; } if(this.leftClickToOpen && e.button>0){ return; } dojo.stopEvent(e); var x,y; if(dojo.isIE){ x = e.x; y = e.y; }else{ x = e.screenX; y = e.screenY + 25; } var self=this; var savedFocus = dijit.getFocus(this); function closeAndRestoreFocus(){ // user has clicked on a menu or popup dijit.focus(savedFocus); dijit.popup.close(self); } var res = dijit.popup.open({ popup: this, x: x, y: y, onExecute: closeAndRestoreFocus, onCancel: closeAndRestoreFocus, orient: this.isLeftToRight() ? 'L' : 'R' }); var v = dijit.getViewport(); if(res.y+res.h>v.h){ if(e.screenY-res.h>=0){ y = e.screenY - res.h; }else{ y = 0; } dijit.popup.close(this); // FIXME: Not very DRY here. // Reopening popup if the location was not good. res = dijit.popup.open({ popup: this, x: x, y: y, onExecute: closeAndRestoreFocus, onCancel: closeAndRestoreFocus, orient: this.isLeftToRight() ? 'L' : 'R' }); } console.log(dijit.getViewport()); this.focus(); this._onBlur = function(){ this.inherited('_onBlur', arguments); dijit.popup.close(this); } } this.menu = pMenu; }, selectTable: function(){ // selects table that is in focus var o = this.getTableInfo(); dojo.withGlobal(this.editor.window, "selectElement",dijit._editor.selection, [o.tbl]); }, launchInsertDialog: function(){ var w = new dojox.editor.plugins.EditorTableDialog({}); w.show(); var c = dojo.connect(w, "onBuildTable", this, function(obj){ dojo.disconnect(c); var res = this.editor.execCommand('inserthtml', obj.htmlText); // commenting this line, due to msg below //var td = this.editor.query("td", this.editor.byId(obj.id)); //HMMMM.... This throws a security error now. didn't used to. //this.editor.selectElement(td); }); }, launchModifyDialog: function(){ var o = this.getTableInfo(); console.log("LAUNCH DIALOG") var w = new dojox.editor.plugins.EditorModifyTableDialog({table:o.tbl}); w.show(); this.connect(w, "onSetTable", function(color){ // uhm... not sure whats going on here... var o = this.getTableInfo(); console.log("set color:", color) dojo.attr(o.td, "bgcolor", color); }); }, _initButton: function(){ this.command = this.commandName; this.label = this.editor.commands[this.command] = this._makeTitle(this.command); this.inherited(arguments); delete this.command; if(this.commandName != "colorTableCell") this.connect(this.button.domNode, "click", "modTable"); if(this.commandName=="tableContextMenu") this.button.domNode.display = "none"; this.onDisplayChanged(false); }, modTable: function(cmd, args){ // summary // Where each plugin performs its action // Note: not using execCommand. In spite of their presence in the // Editor as query-able plugins, I was not able to find any evidence // that they are supported (especially in NOT IE). If they are // supported in other browsers, it may help with the undo problem. // this.begEdit(); var o = this.getTableInfo(); var sw = (dojo.isString(cmd))?cmd : this.commandName; var r, c, i; var adjustColWidth = false; //console.log("modTable:", sw) switch(sw){ case "insertTableRowBefore": r = o.tbl.insertRow(o.trIndex); for(i=0;imike

"); this.editor.setValue(this.valBeforeUndo); this.editor.replaceValue(afterUndo); } this.editor.onDisplayChanged(); }";s:7:"summary";s:0:"";}s:49:"dojox.editor.plugins.TablePlugins.makeColumnsEven";a:4:{s:9:"prototype";s:33:"dojox.editor.plugins.TablePlugins";s:4:"type";s:8:"Function";s:6:"source";s:22126:"dojo.provide("dojox.editor.plugins.TablePlugins"); dojo.require("dijit._editor._Plugin"); dojo.require("dijit._editor.selection"); dojo.require("dijit.Menu"); dojo.require("dojo.i18n"); dojo.requireLocalization("dojox.editor.plugins", "TableDialog"); dojo.experimental("dojox.editor.plugins.TablePlugins"); // summary: // A series of plugins that give the Editor the ability to create and edit // HTML tables. See the end of this document for all avaiable plugins // and dojox/editorPlugins/tests/editorTablePlugs.html for an example // // example: // |
// | Editor text is here // |
// // TODO: // Currently not supporting merging or splitting cells // // FIXME: Undo is very buggy, and therefore unimeplented in all browsers // except IE - which itself has only been lightly tested. // // FIXME: Selecting multiple table cells in Firefox looks to be impossible. // This affect the 'colorTableCell' plugin. Cells can still be // colored individually or in rows. dojo.declare("dojox.editor.plugins.GlobalTableHandler", dijit._editor._Plugin,{ // summary: // A global object that handles common tasks for all the plugins. Since // there are several plugins that are all calling common methods, it's preferable // that they call a centralized location that either has a set variable or a // timeout to only repeat code-heavy calls when necessary. // tablesConnected:false, currentlyAvailable: false, alwaysAvailable:false, availableCurrentlySet:false, initialized:false, tableData: null, shiftKeyDown:false, editorDomNode: null, undoEnabled: dojo.isIE, //FIXME: doMixins: function(){ dojo.mixin(this.editor,{ getAncestorElement: function(tagName){ return dojo.withGlobal(this.window, "getAncestorElement",dijit._editor.selection, [tagName]); }, hasAncestorElement: function(tagName){ return true return dojo.withGlobal(this.window, "hasAncestorElement",dijit._editor.selection, [tagName]); }, selectElement: function(elem){ dojo.withGlobal(this.window, "selectElement",dijit._editor.selection, [elem]); }, byId: function(id){ return dojo.withGlobal(this.window, "byId", dojo, [id]); }, query: function(arg, scope, returnFirstOnly){ // this shortcut is dubious - not sure scoping is necessary var ar = dojo.withGlobal(this.window, "query", dojo, [arg, scope]); return (returnFirstOnly) ? ar[0] : ar; } }); }, initialize: function(editor){ // summary: // Initialize the global handler upon a plugin's first instance of setEditor // // All plugins will attempt initialization. We only need to do so once. if(this.initialized){ return; } this.initialized = true; this.editor = editor; this.editorDomNode = this.editor.editNode || this.editor.iframe.document.body.firstChild; // RichText should have a mouseup connection to recognize drag-selections // Example would be selecting multiple table cells dojo.connect(this.editorDomNode , "mouseup", this.editor, "onClick"); dojo.connect(this.editor, "onDisplayChanged", this, "checkAvailable"); this.doMixins(); this.connectDraggable(); }, getTableInfo: function(forceNewData){ // summary // Gets the table in focus // Collects info on the table - see return params // if(forceNewData){ this._tempStoreTableData(false); } if(this.tableData){ // tableData is set for a short amount of time, so that all // plugins get the same return without doing the method over console.log("returning current tableData:", this.tableData); return this.tableData; } var tr, trs, td, tds, tbl, cols, tdIndex, trIndex; td = this.editor.getAncestorElement("td"); if(td){ tr = td.parentNode; } tbl = this.editor.getAncestorElement("table"); //console.log("td:", td);console.log("tr:", tr);console.log("tbl:", tbl) tds = dojo.query("td", tbl); tds.forEach(function(d, i){ if(td==d){tdIndex = i} }); trs = dojo.query("tr", tbl); trs.forEach(function(r, i){ if(tr==r){trIndex = i} }); cols = tds.length/trs.length; var o = { tbl:tbl, // focused table td:td, // focused TD tr:tr, // focused TR trs:trs, // rows tds:tds, // cells rows:trs.length,// row amount cols:cols, // column amount tdIndex:tdIndex,// index of focused cell trIndex:trIndex, // index of focused row colIndex:tdIndex%cols }; console.log("NEW tableData:",o); this.tableData = o; this._tempStoreTableData(500); return this.tableData; }, connectDraggable: function(){ // summary // Detects drag-n-drop in the editor (could probably be moved to there) // Currently only checks if item dragged was a TABLE, and removes its align attr // DOES NOT WORK IN FF - it could - but FF's drag detection is a monster // if(!dojo.isIE){ //console.warn("Drag and Drop is currently only detectable in IE."); return } // IE ONLY this.editorDomNode.ondragstart = dojo.hitch(this, "onDragStart"); this.editorDomNode.ondragend = dojo.hitch(this, "onDragEnd"); //NOTES: // FF _ Able to detect the drag-over object (the editor.domNode) // Not able to detect an item's ondrag() event // Don't know why - I actually got it working when there was an error // Something to do with different documents or windows I'm sure // //console.log("connectDraggable", tbl); /*tbl.ondragstart=dojo.hitch(this, "onDragStart"); tbl.addEventListener("dragstart", dojo.hitch(this, "onDragStart"), false); tbl.addEventListener("drag", dojo.hitch(this, "onDragStart2"), false); tbl.addEventListener("dragend", dojo.hitch(this, "onDragStart3"), false); dojo.withGlobal(this.editor.window, "selectElement",dijit._editor.selection, [tbl]); tbl.ondragstart = function(){ console.log ("ondragstart"); }; tbl.ondrag = function(){ alert("drag") //console.log ("ondrag"); */ }, onDragStart: function(){ var e = window.event; if(!e.srcElement.id){ e.srcElement.id = "tbl_"+(new Date().getTime()); } //console.log("onDragStart", e.srcElement.id); }, onDragEnd: function(){ // summary // Detects that an object has been dragged into place // Currently, this code is only used for when a table is dragged // and clears the "align" attribute, so that the table will look // to be more in the place that the user expected. // TODO: This code can be used for other things, most // notably UNDO, which currently is not quite usable. // This code could also find itself in the Editor code when it is // complete. //console.log("onDragEnd"); var e = window.event var node = e.srcElement; var id = node.id; var win = this.editor.window //console.log("NODE:", node.tagName, node.id, dojo.attr(node, "align")); // clearing a table's align attr // TODO: when ondrag becomes more robust, this code block // should move to its own method if(node.tagName.toLowerCase()=="table"){ setTimeout(function(){ var node = dojo.withGlobal(win, "byId", dojo, [id]); dojo.removeAttr(node, "align"); //console.log("set", node.tagName, dojo.attr(node, "align")) }, 100); } }, checkAvailable: function(){ // summary // For table plugs // Checking if a table or part of a table has focus so that // Plugs can change their status // if(this.availableCurrentlySet){ // availableCurrentlySet is set for a short amount of time, so that all // plugins get the same return without doing the method over //console.log("availableCurrentlySet:", this.availableCurrentlySet, "currentlyAvailable:", this.currentlyAvailable) return this.currentlyAvailable; } //console.log("G - checkAvailable..."); if(!this.editor) { //console.log("editor not ready") return false; } if(this.alwaysAvailable) { //console.log(" return always available") return true; } this.currentlyAvailable = this.editor.hasAncestorElement("table"); if(this.currentlyAvailable){ this.connectTableKeys(); }else{ this.disconnectTableKeys(); } this._tempAvailability(500); dojo.publish("available", [ this.currentlyAvailable ]); return this.currentlyAvailable; }, _prepareTable: function(tbl){ // For IE's sake, we are adding IDs to the TDs if none is there // We go ahead and use it for other code for convenience // var tds = this.editor.query("td", tbl); console.log("prep:", tds, tbl) if(!tds[0].id){ tds.forEach(function(td, i){ if(!td.id){ td.id = "tdid"+i+this.getTimeStamp(); } }, this); } return tds; }, getTimeStamp: function(){ return Math.floor(new Date().getTime() * 0.00000001); }, _tempStoreTableData: function(type){ // caching or clearing table data, depending on the arg // if(type===true){ //store indefinitely }else if(type===false){ // clear object this.tableData = null; }else if(type===undefined){ console.warn("_tempStoreTableData must be passed an argument") }else{ // type is a number/ms setTimeout(dojo.hitch(this, function(){ this.tableData = null; }), type); } }, _tempAvailability: function(type){ // caching or clearing availability, depending on the arg if(type===true){ //store indefinitely this.availableCurrentlySet = true; }else if(type===false){ // clear object this.availableCurrentlySet = false; }else if(type===undefined){ console.warn("_tempAvailability must be passed an argument") }else{ // type is a number/ms this.availableCurrentlySet = true; setTimeout(dojo.hitch(this, function(){ this.availableCurrentlySet = false; }), type); } }, connectTableKeys: function(){ // summary // When a table is in focus, start detecting keys // Mainly checking for the TAB key so user can tab // through a table (blocking the browser's desire to // tab away from teh editor completely) if(this.tablesConnected){ return; } this.tablesConnected = true; var node = (this.editor.iframe) ? this.editor.document : this.editor.editNode; this.cnKeyDn = dojo.connect(node, "onkeydown", this, "onKeyDown"); this.cnKeyUp = dojo.connect(node, "onkeyup", this, "onKeyUp"); dojo.connect(node, "onkeypress", this, "onKeyUp"); }, disconnectTableKeys: function(){ //console.log("disconnect") dojo.disconnect(this.cnKeyDn); dojo.disconnect(this.cnKeyUp); this.tablesConnected = false; }, onKeyDown: function(evt){ var key = evt.keyCode; //console.log(" -> DOWN:", key); if(key == 16) this.shiftKeyDown = true; if(key == 9) {console.log("TAB!:"); var o = this.getTableInfo(); //console.log("TAB ", o.tdIndex, o); // modifying the o.tdIndex in the tableData directly, because we may save it // FIXME: tabTo is a global o.tdIndex = (this.shiftKeyDown) ? o.tdIndex-1 : tabTo = o.tdIndex+1; if(o.tdIndex>=0 && o.tdIndex UP:", key) if(key == 16) this.shiftKeyDown = false; if(key == 37 || key == 38 || key == 39 || key == 40 ){ // user can arrow or tab out of table - need to recheck this.onDisplayChanged(); } if(key == 9 && this.stopEvent) dojo.stopEvent(evt); }, onDisplayChanged: function(){ //console.log("onDisplayChanged") this.currentlyAvailable = false; this._tempStoreTableData(false); this._tempAvailability(false); this.checkAvailable(); } }); // global: tablePluginHandler = new dojox.editor.plugins.GlobalTableHandler(); //FIXME: no globals. dojo.declare("dojox.editor.plugins.TablePlugins", dijit._editor._Plugin, { //summary: // A collection of Plugins for inserting and modifying tables in the Editor // See end of this document for all avaiable plugs // and dojox/editorPlugins/tests/editorTablePlugs.html for an example // // NOT IMPLEMENTED: Not handling cell merge, span or split // iconClassPrefix: "editorIcon", useDefaultCommand: false, buttonClass: dijit.form.Button, commandName:"", label:"", alwaysAvailable:false, undoEnabled:false, constructor: function(){ // summary // Initialize certain plugins // switch(this.commandName){ case "colorTableCell": this.buttonClass = dijit.form.DropDownButton; this.dropDown = new dijit.ColorPalette(); this.connect(this.dropDown, "onChange", function(color){ this.modTable(null, color); }); break; case "modifyTable": this.buttonClass = dijit.form.DropDownButton; this.modTable = this.launchModifyDialog; break; case "insertTable": this.alwaysAvailable = true; this.buttonClass = dijit.form.DropDownButton; this.modTable = this.launchInsertDialog; break; case "tableContextMenu": this.connect(this, "setEditor", function(){ this._createContextMenu(); this.button.domNode.style.display = "none"; }); break; } dojo.subscribe("available", this, "onDisplayChanged"); }, onDisplayChanged: function(withinTable){ // subscribed to from the global object's publish method // //console.log("onDisplayChanged", this.commandName); if(!this.alwaysAvailable){ this.available = withinTable; this.button.attr('disabled', !this.available); } }, setEditor: function(){ this.inherited(arguments); this.onEditorLoaded(); }, onEditorLoaded: function(){ //stub // call global object to initialize it tablePluginHandler.initialize(this.editor); }, _createContextMenu: function(){ // summary // Building context menu for right-click shortcuts within a table // var node = dojo.isFF ? this.editor.editNode : this.editorDomNode; var pMenu = new dijit.Menu({targetNodeIds:[node], id:"progMenu", contextMenuForWindow:dojo.isIE}); var _M = dijit.MenuItem; var messages = dojo.i18n.getLocalization("dojox.editor.plugins", "TableDialog", this.lang); pMenu.addChild(new _M({label: messages.selectTableLabel, onClick: dojo.hitch(this, "selectTable")})); pMenu.addChild(new dijit.MenuSeparator()); pMenu.addChild(new _M({label: messages.insertTableRowBeforeLabel, onClick: dojo.hitch(this, "modTable", "insertTableRowBefore" )})); pMenu.addChild(new _M({label: messages.insertTableRowAfterLabel, onClick: dojo.hitch(this, "modTable", "insertTableRowAfter" )})); pMenu.addChild(new _M({label: messages.insertTableColumnBeforeLabel, onClick: dojo.hitch(this, "modTable", "insertTableColumnBefore" )})); pMenu.addChild(new _M({label: messages.insertTableColumnAfterLabel, onClick: dojo.hitch(this, "modTable", "insertTableColumnAfter" )})); pMenu.addChild(new dijit.MenuSeparator()); pMenu.addChild(new _M({label: messages.deleteTableRowLabel, onClick: dojo.hitch(this, "modTable", "deleteTableRow" )})); pMenu.addChild(new _M({label: messages.deleteTableColumnLabel, onClick: dojo.hitch(this, "modTable", "deleteTableColumn" )})); // overwriting this method, as the menu's coordinates // are not accurate in the editor's iframe // FIXME: Works well in IE - all others, sometimes inaccurate. pMenu._openMyself = function(e){ if(!tablePluginHandler.checkAvailable()){ return; } if(this.leftClickToOpen && e.button>0){ return; } dojo.stopEvent(e); var x,y; if(dojo.isIE){ x = e.x; y = e.y; }else{ x = e.screenX; y = e.screenY + 25; } var self=this; var savedFocus = dijit.getFocus(this); function closeAndRestoreFocus(){ // user has clicked on a menu or popup dijit.focus(savedFocus); dijit.popup.close(self); } var res = dijit.popup.open({ popup: this, x: x, y: y, onExecute: closeAndRestoreFocus, onCancel: closeAndRestoreFocus, orient: this.isLeftToRight() ? 'L' : 'R' }); var v = dijit.getViewport(); if(res.y+res.h>v.h){ if(e.screenY-res.h>=0){ y = e.screenY - res.h; }else{ y = 0; } dijit.popup.close(this); // FIXME: Not very DRY here. // Reopening popup if the location was not good. res = dijit.popup.open({ popup: this, x: x, y: y, onExecute: closeAndRestoreFocus, onCancel: closeAndRestoreFocus, orient: this.isLeftToRight() ? 'L' : 'R' }); } console.log(dijit.getViewport()); this.focus(); this._onBlur = function(){ this.inherited('_onBlur', arguments); dijit.popup.close(this); } } this.menu = pMenu; }, selectTable: function(){ // selects table that is in focus var o = this.getTableInfo(); dojo.withGlobal(this.editor.window, "selectElement",dijit._editor.selection, [o.tbl]); }, launchInsertDialog: function(){ var w = new dojox.editor.plugins.EditorTableDialog({}); w.show(); var c = dojo.connect(w, "onBuildTable", this, function(obj){ dojo.disconnect(c); var res = this.editor.execCommand('inserthtml', obj.htmlText); // commenting this line, due to msg below //var td = this.editor.query("td", this.editor.byId(obj.id)); //HMMMM.... This throws a security error now. didn't used to. //this.editor.selectElement(td); }); }, launchModifyDialog: function(){ var o = this.getTableInfo(); console.log("LAUNCH DIALOG") var w = new dojox.editor.plugins.EditorModifyTableDialog({table:o.tbl}); w.show(); this.connect(w, "onSetTable", function(color){ // uhm... not sure whats going on here... var o = this.getTableInfo(); console.log("set color:", color) dojo.attr(o.td, "bgcolor", color); }); }, _initButton: function(){ this.command = this.commandName; this.label = this.editor.commands[this.command] = this._makeTitle(this.command); this.inherited(arguments); delete this.command; if(this.commandName != "colorTableCell") this.connect(this.button.domNode, "click", "modTable"); if(this.commandName=="tableContextMenu") this.button.domNode.display = "none"; this.onDisplayChanged(false); }, modTable: function(cmd, args){ // summary // Where each plugin performs its action // Note: not using execCommand. In spite of their presence in the // Editor as query-able plugins, I was not able to find any evidence // that they are supported (especially in NOT IE). If they are // supported in other browsers, it may help with the undo problem. // this.begEdit(); var o = this.getTableInfo(); var sw = (dojo.isString(cmd))?cmd : this.commandName; var r, c, i; var adjustColWidth = false; //console.log("modTable:", sw) switch(sw){ case "insertTableRowBefore": r = o.tbl.insertRow(o.trIndex); for(i=0;imike

"); this.editor.setValue(this.valBeforeUndo); this.editor.replaceValue(afterUndo); } this.editor.onDisplayChanged(); } }, makeColumnsEven: function(){ //summary // After changing column amount, change widths to // keep columns even // // the timeout helps prevent an occasional snafu setTimeout(dojo.hitch(this, function(){ var o = this.getTableInfo(true); var w = Math.floor(100/o.cols); o.tds.forEach(function(d){ dojo.attr(d, "width", w+"%"); }); }), 10);";s:7:"summary";s:0:"";}s:46:"dojox.editor.plugins.TablePlugins.getTableInfo";a:5:{s:9:"prototype";s:33:"dojox.editor.plugins.TablePlugins";s:4:"type";s:8:"Function";s:10:"parameters";a:1:{s:12:"forceNewData";a:1:{s:4:"type";s:0:"";}}s:6:"source";s:22335:"dojo.provide("dojox.editor.plugins.TablePlugins"); dojo.require("dijit._editor._Plugin"); dojo.require("dijit._editor.selection"); dojo.require("dijit.Menu"); dojo.require("dojo.i18n"); dojo.requireLocalization("dojox.editor.plugins", "TableDialog"); dojo.experimental("dojox.editor.plugins.TablePlugins"); // summary: // A series of plugins that give the Editor the ability to create and edit // HTML tables. See the end of this document for all avaiable plugins // and dojox/editorPlugins/tests/editorTablePlugs.html for an example // // example: // |
// | Editor text is here // |
// // TODO: // Currently not supporting merging or splitting cells // // FIXME: Undo is very buggy, and therefore unimeplented in all browsers // except IE - which itself has only been lightly tested. // // FIXME: Selecting multiple table cells in Firefox looks to be impossible. // This affect the 'colorTableCell' plugin. Cells can still be // colored individually or in rows. dojo.declare("dojox.editor.plugins.GlobalTableHandler", dijit._editor._Plugin,{ // summary: // A global object that handles common tasks for all the plugins. Since // there are several plugins that are all calling common methods, it's preferable // that they call a centralized location that either has a set variable or a // timeout to only repeat code-heavy calls when necessary. // tablesConnected:false, currentlyAvailable: false, alwaysAvailable:false, availableCurrentlySet:false, initialized:false, tableData: null, shiftKeyDown:false, editorDomNode: null, undoEnabled: dojo.isIE, //FIXME: doMixins: function(){ dojo.mixin(this.editor,{ getAncestorElement: function(tagName){ return dojo.withGlobal(this.window, "getAncestorElement",dijit._editor.selection, [tagName]); }, hasAncestorElement: function(tagName){ return true return dojo.withGlobal(this.window, "hasAncestorElement",dijit._editor.selection, [tagName]); }, selectElement: function(elem){ dojo.withGlobal(this.window, "selectElement",dijit._editor.selection, [elem]); }, byId: function(id){ return dojo.withGlobal(this.window, "byId", dojo, [id]); }, query: function(arg, scope, returnFirstOnly){ // this shortcut is dubious - not sure scoping is necessary var ar = dojo.withGlobal(this.window, "query", dojo, [arg, scope]); return (returnFirstOnly) ? ar[0] : ar; } }); }, initialize: function(editor){ // summary: // Initialize the global handler upon a plugin's first instance of setEditor // // All plugins will attempt initialization. We only need to do so once. if(this.initialized){ return; } this.initialized = true; this.editor = editor; this.editorDomNode = this.editor.editNode || this.editor.iframe.document.body.firstChild; // RichText should have a mouseup connection to recognize drag-selections // Example would be selecting multiple table cells dojo.connect(this.editorDomNode , "mouseup", this.editor, "onClick"); dojo.connect(this.editor, "onDisplayChanged", this, "checkAvailable"); this.doMixins(); this.connectDraggable(); }, getTableInfo: function(forceNewData){ // summary // Gets the table in focus // Collects info on the table - see return params // if(forceNewData){ this._tempStoreTableData(false); } if(this.tableData){ // tableData is set for a short amount of time, so that all // plugins get the same return without doing the method over console.log("returning current tableData:", this.tableData); return this.tableData; } var tr, trs, td, tds, tbl, cols, tdIndex, trIndex; td = this.editor.getAncestorElement("td"); if(td){ tr = td.parentNode; } tbl = this.editor.getAncestorElement("table"); //console.log("td:", td);console.log("tr:", tr);console.log("tbl:", tbl) tds = dojo.query("td", tbl); tds.forEach(function(d, i){ if(td==d){tdIndex = i} }); trs = dojo.query("tr", tbl); trs.forEach(function(r, i){ if(tr==r){trIndex = i} }); cols = tds.length/trs.length; var o = { tbl:tbl, // focused table td:td, // focused TD tr:tr, // focused TR trs:trs, // rows tds:tds, // cells rows:trs.length,// row amount cols:cols, // column amount tdIndex:tdIndex,// index of focused cell trIndex:trIndex, // index of focused row colIndex:tdIndex%cols }; console.log("NEW tableData:",o); this.tableData = o; this._tempStoreTableData(500); return this.tableData; }, connectDraggable: function(){ // summary // Detects drag-n-drop in the editor (could probably be moved to there) // Currently only checks if item dragged was a TABLE, and removes its align attr // DOES NOT WORK IN FF - it could - but FF's drag detection is a monster // if(!dojo.isIE){ //console.warn("Drag and Drop is currently only detectable in IE."); return } // IE ONLY this.editorDomNode.ondragstart = dojo.hitch(this, "onDragStart"); this.editorDomNode.ondragend = dojo.hitch(this, "onDragEnd"); //NOTES: // FF _ Able to detect the drag-over object (the editor.domNode) // Not able to detect an item's ondrag() event // Don't know why - I actually got it working when there was an error // Something to do with different documents or windows I'm sure // //console.log("connectDraggable", tbl); /*tbl.ondragstart=dojo.hitch(this, "onDragStart"); tbl.addEventListener("dragstart", dojo.hitch(this, "onDragStart"), false); tbl.addEventListener("drag", dojo.hitch(this, "onDragStart2"), false); tbl.addEventListener("dragend", dojo.hitch(this, "onDragStart3"), false); dojo.withGlobal(this.editor.window, "selectElement",dijit._editor.selection, [tbl]); tbl.ondragstart = function(){ console.log ("ondragstart"); }; tbl.ondrag = function(){ alert("drag") //console.log ("ondrag"); */ }, onDragStart: function(){ var e = window.event; if(!e.srcElement.id){ e.srcElement.id = "tbl_"+(new Date().getTime()); } //console.log("onDragStart", e.srcElement.id); }, onDragEnd: function(){ // summary // Detects that an object has been dragged into place // Currently, this code is only used for when a table is dragged // and clears the "align" attribute, so that the table will look // to be more in the place that the user expected. // TODO: This code can be used for other things, most // notably UNDO, which currently is not quite usable. // This code could also find itself in the Editor code when it is // complete. //console.log("onDragEnd"); var e = window.event var node = e.srcElement; var id = node.id; var win = this.editor.window //console.log("NODE:", node.tagName, node.id, dojo.attr(node, "align")); // clearing a table's align attr // TODO: when ondrag becomes more robust, this code block // should move to its own method if(node.tagName.toLowerCase()=="table"){ setTimeout(function(){ var node = dojo.withGlobal(win, "byId", dojo, [id]); dojo.removeAttr(node, "align"); //console.log("set", node.tagName, dojo.attr(node, "align")) }, 100); } }, checkAvailable: function(){ // summary // For table plugs // Checking if a table or part of a table has focus so that // Plugs can change their status // if(this.availableCurrentlySet){ // availableCurrentlySet is set for a short amount of time, so that all // plugins get the same return without doing the method over //console.log("availableCurrentlySet:", this.availableCurrentlySet, "currentlyAvailable:", this.currentlyAvailable) return this.currentlyAvailable; } //console.log("G - checkAvailable..."); if(!this.editor) { //console.log("editor not ready") return false; } if(this.alwaysAvailable) { //console.log(" return always available") return true; } this.currentlyAvailable = this.editor.hasAncestorElement("table"); if(this.currentlyAvailable){ this.connectTableKeys(); }else{ this.disconnectTableKeys(); } this._tempAvailability(500); dojo.publish("available", [ this.currentlyAvailable ]); return this.currentlyAvailable; }, _prepareTable: function(tbl){ // For IE's sake, we are adding IDs to the TDs if none is there // We go ahead and use it for other code for convenience // var tds = this.editor.query("td", tbl); console.log("prep:", tds, tbl) if(!tds[0].id){ tds.forEach(function(td, i){ if(!td.id){ td.id = "tdid"+i+this.getTimeStamp(); } }, this); } return tds; }, getTimeStamp: function(){ return Math.floor(new Date().getTime() * 0.00000001); }, _tempStoreTableData: function(type){ // caching or clearing table data, depending on the arg // if(type===true){ //store indefinitely }else if(type===false){ // clear object this.tableData = null; }else if(type===undefined){ console.warn("_tempStoreTableData must be passed an argument") }else{ // type is a number/ms setTimeout(dojo.hitch(this, function(){ this.tableData = null; }), type); } }, _tempAvailability: function(type){ // caching or clearing availability, depending on the arg if(type===true){ //store indefinitely this.availableCurrentlySet = true; }else if(type===false){ // clear object this.availableCurrentlySet = false; }else if(type===undefined){ console.warn("_tempAvailability must be passed an argument") }else{ // type is a number/ms this.availableCurrentlySet = true; setTimeout(dojo.hitch(this, function(){ this.availableCurrentlySet = false; }), type); } }, connectTableKeys: function(){ // summary // When a table is in focus, start detecting keys // Mainly checking for the TAB key so user can tab // through a table (blocking the browser's desire to // tab away from teh editor completely) if(this.tablesConnected){ return; } this.tablesConnected = true; var node = (this.editor.iframe) ? this.editor.document : this.editor.editNode; this.cnKeyDn = dojo.connect(node, "onkeydown", this, "onKeyDown"); this.cnKeyUp = dojo.connect(node, "onkeyup", this, "onKeyUp"); dojo.connect(node, "onkeypress", this, "onKeyUp"); }, disconnectTableKeys: function(){ //console.log("disconnect") dojo.disconnect(this.cnKeyDn); dojo.disconnect(this.cnKeyUp); this.tablesConnected = false; }, onKeyDown: function(evt){ var key = evt.keyCode; //console.log(" -> DOWN:", key); if(key == 16) this.shiftKeyDown = true; if(key == 9) {console.log("TAB!:"); var o = this.getTableInfo(); //console.log("TAB ", o.tdIndex, o); // modifying the o.tdIndex in the tableData directly, because we may save it // FIXME: tabTo is a global o.tdIndex = (this.shiftKeyDown) ? o.tdIndex-1 : tabTo = o.tdIndex+1; if(o.tdIndex>=0 && o.tdIndex UP:", key) if(key == 16) this.shiftKeyDown = false; if(key == 37 || key == 38 || key == 39 || key == 40 ){ // user can arrow or tab out of table - need to recheck this.onDisplayChanged(); } if(key == 9 && this.stopEvent) dojo.stopEvent(evt); }, onDisplayChanged: function(){ //console.log("onDisplayChanged") this.currentlyAvailable = false; this._tempStoreTableData(false); this._tempAvailability(false); this.checkAvailable(); } }); // global: tablePluginHandler = new dojox.editor.plugins.GlobalTableHandler(); //FIXME: no globals. dojo.declare("dojox.editor.plugins.TablePlugins", dijit._editor._Plugin, { //summary: // A collection of Plugins for inserting and modifying tables in the Editor // See end of this document for all avaiable plugs // and dojox/editorPlugins/tests/editorTablePlugs.html for an example // // NOT IMPLEMENTED: Not handling cell merge, span or split // iconClassPrefix: "editorIcon", useDefaultCommand: false, buttonClass: dijit.form.Button, commandName:"", label:"", alwaysAvailable:false, undoEnabled:false, constructor: function(){ // summary // Initialize certain plugins // switch(this.commandName){ case "colorTableCell": this.buttonClass = dijit.form.DropDownButton; this.dropDown = new dijit.ColorPalette(); this.connect(this.dropDown, "onChange", function(color){ this.modTable(null, color); }); break; case "modifyTable": this.buttonClass = dijit.form.DropDownButton; this.modTable = this.launchModifyDialog; break; case "insertTable": this.alwaysAvailable = true; this.buttonClass = dijit.form.DropDownButton; this.modTable = this.launchInsertDialog; break; case "tableContextMenu": this.connect(this, "setEditor", function(){ this._createContextMenu(); this.button.domNode.style.display = "none"; }); break; } dojo.subscribe("available", this, "onDisplayChanged"); }, onDisplayChanged: function(withinTable){ // subscribed to from the global object's publish method // //console.log("onDisplayChanged", this.commandName); if(!this.alwaysAvailable){ this.available = withinTable; this.button.attr('disabled', !this.available); } }, setEditor: function(){ this.inherited(arguments); this.onEditorLoaded(); }, onEditorLoaded: function(){ //stub // call global object to initialize it tablePluginHandler.initialize(this.editor); }, _createContextMenu: function(){ // summary // Building context menu for right-click shortcuts within a table // var node = dojo.isFF ? this.editor.editNode : this.editorDomNode; var pMenu = new dijit.Menu({targetNodeIds:[node], id:"progMenu", contextMenuForWindow:dojo.isIE}); var _M = dijit.MenuItem; var messages = dojo.i18n.getLocalization("dojox.editor.plugins", "TableDialog", this.lang); pMenu.addChild(new _M({label: messages.selectTableLabel, onClick: dojo.hitch(this, "selectTable")})); pMenu.addChild(new dijit.MenuSeparator()); pMenu.addChild(new _M({label: messages.insertTableRowBeforeLabel, onClick: dojo.hitch(this, "modTable", "insertTableRowBefore" )})); pMenu.addChild(new _M({label: messages.insertTableRowAfterLabel, onClick: dojo.hitch(this, "modTable", "insertTableRowAfter" )})); pMenu.addChild(new _M({label: messages.insertTableColumnBeforeLabel, onClick: dojo.hitch(this, "modTable", "insertTableColumnBefore" )})); pMenu.addChild(new _M({label: messages.insertTableColumnAfterLabel, onClick: dojo.hitch(this, "modTable", "insertTableColumnAfter" )})); pMenu.addChild(new dijit.MenuSeparator()); pMenu.addChild(new _M({label: messages.deleteTableRowLabel, onClick: dojo.hitch(this, "modTable", "deleteTableRow" )})); pMenu.addChild(new _M({label: messages.deleteTableColumnLabel, onClick: dojo.hitch(this, "modTable", "deleteTableColumn" )})); // overwriting this method, as the menu's coordinates // are not accurate in the editor's iframe // FIXME: Works well in IE - all others, sometimes inaccurate. pMenu._openMyself = function(e){ if(!tablePluginHandler.checkAvailable()){ return; } if(this.leftClickToOpen && e.button>0){ return; } dojo.stopEvent(e); var x,y; if(dojo.isIE){ x = e.x; y = e.y; }else{ x = e.screenX; y = e.screenY + 25; } var self=this; var savedFocus = dijit.getFocus(this); function closeAndRestoreFocus(){ // user has clicked on a menu or popup dijit.focus(savedFocus); dijit.popup.close(self); } var res = dijit.popup.open({ popup: this, x: x, y: y, onExecute: closeAndRestoreFocus, onCancel: closeAndRestoreFocus, orient: this.isLeftToRight() ? 'L' : 'R' }); var v = dijit.getViewport(); if(res.y+res.h>v.h){ if(e.screenY-res.h>=0){ y = e.screenY - res.h; }else{ y = 0; } dijit.popup.close(this); // FIXME: Not very DRY here. // Reopening popup if the location was not good. res = dijit.popup.open({ popup: this, x: x, y: y, onExecute: closeAndRestoreFocus, onCancel: closeAndRestoreFocus, orient: this.isLeftToRight() ? 'L' : 'R' }); } console.log(dijit.getViewport()); this.focus(); this._onBlur = function(){ this.inherited('_onBlur', arguments); dijit.popup.close(this); } } this.menu = pMenu; }, selectTable: function(){ // selects table that is in focus var o = this.getTableInfo(); dojo.withGlobal(this.editor.window, "selectElement",dijit._editor.selection, [o.tbl]); }, launchInsertDialog: function(){ var w = new dojox.editor.plugins.EditorTableDialog({}); w.show(); var c = dojo.connect(w, "onBuildTable", this, function(obj){ dojo.disconnect(c); var res = this.editor.execCommand('inserthtml', obj.htmlText); // commenting this line, due to msg below //var td = this.editor.query("td", this.editor.byId(obj.id)); //HMMMM.... This throws a security error now. didn't used to. //this.editor.selectElement(td); }); }, launchModifyDialog: function(){ var o = this.getTableInfo(); console.log("LAUNCH DIALOG") var w = new dojox.editor.plugins.EditorModifyTableDialog({table:o.tbl}); w.show(); this.connect(w, "onSetTable", function(color){ // uhm... not sure whats going on here... var o = this.getTableInfo(); console.log("set color:", color) dojo.attr(o.td, "bgcolor", color); }); }, _initButton: function(){ this.command = this.commandName; this.label = this.editor.commands[this.command] = this._makeTitle(this.command); this.inherited(arguments); delete this.command; if(this.commandName != "colorTableCell") this.connect(this.button.domNode, "click", "modTable"); if(this.commandName=="tableContextMenu") this.button.domNode.display = "none"; this.onDisplayChanged(false); }, modTable: function(cmd, args){ // summary // Where each plugin performs its action // Note: not using execCommand. In spite of their presence in the // Editor as query-able plugins, I was not able to find any evidence // that they are supported (especially in NOT IE). If they are // supported in other browsers, it may help with the undo problem. // this.begEdit(); var o = this.getTableInfo(); var sw = (dojo.isString(cmd))?cmd : this.commandName; var r, c, i; var adjustColWidth = false; //console.log("modTable:", sw) switch(sw){ case "insertTableRowBefore": r = o.tbl.insertRow(o.trIndex); for(i=0;imike

"); this.editor.setValue(this.valBeforeUndo); this.editor.replaceValue(afterUndo); } this.editor.onDisplayChanged(); } }, makeColumnsEven: function(){ //summary // After changing column amount, change widths to // keep columns even // // the timeout helps prevent an occasional snafu setTimeout(dojo.hitch(this, function(){ var o = this.getTableInfo(true); var w = Math.floor(100/o.cols); o.tds.forEach(function(d){ dojo.attr(d, "width", w+"%"); }); }), 10); }, getTableInfo: function(forceNewData){ // summary // Gets the table in focus // Collects info on the table - see return params // return tablePluginHandler.getTableInfo(forceNewData);";s:7:"summary";s:0:"";}s:44:"dojox.editor.plugins.TablePlugins._makeTitle";a:6:{s:9:"prototype";s:33:"dojox.editor.plugins.TablePlugins";s:4:"type";s:8:"Function";s:10:"parameters";a:1:{s:3:"str";a:1:{s:4:"type";s:0:"";}}s:6:"source";s:22678:"dojo.provide("dojox.editor.plugins.TablePlugins"); dojo.require("dijit._editor._Plugin"); dojo.require("dijit._editor.selection"); dojo.require("dijit.Menu"); dojo.require("dojo.i18n"); dojo.requireLocalization("dojox.editor.plugins", "TableDialog"); dojo.experimental("dojox.editor.plugins.TablePlugins"); // summary: // A series of plugins that give the Editor the ability to create and edit // HTML tables. See the end of this document for all avaiable plugins // and dojox/editorPlugins/tests/editorTablePlugs.html for an example // // example: // |
// | Editor text is here // |
// // TODO: // Currently not supporting merging or splitting cells // // FIXME: Undo is very buggy, and therefore unimeplented in all browsers // except IE - which itself has only been lightly tested. // // FIXME: Selecting multiple table cells in Firefox looks to be impossible. // This affect the 'colorTableCell' plugin. Cells can still be // colored individually or in rows. dojo.declare("dojox.editor.plugins.GlobalTableHandler", dijit._editor._Plugin,{ // summary: // A global object that handles common tasks for all the plugins. Since // there are several plugins that are all calling common methods, it's preferable // that they call a centralized location that either has a set variable or a // timeout to only repeat code-heavy calls when necessary. // tablesConnected:false, currentlyAvailable: false, alwaysAvailable:false, availableCurrentlySet:false, initialized:false, tableData: null, shiftKeyDown:false, editorDomNode: null, undoEnabled: dojo.isIE, //FIXME: doMixins: function(){ dojo.mixin(this.editor,{ getAncestorElement: function(tagName){ return dojo.withGlobal(this.window, "getAncestorElement",dijit._editor.selection, [tagName]); }, hasAncestorElement: function(tagName){ return true return dojo.withGlobal(this.window, "hasAncestorElement",dijit._editor.selection, [tagName]); }, selectElement: function(elem){ dojo.withGlobal(this.window, "selectElement",dijit._editor.selection, [elem]); }, byId: function(id){ return dojo.withGlobal(this.window, "byId", dojo, [id]); }, query: function(arg, scope, returnFirstOnly){ // this shortcut is dubious - not sure scoping is necessary var ar = dojo.withGlobal(this.window, "query", dojo, [arg, scope]); return (returnFirstOnly) ? ar[0] : ar; } }); }, initialize: function(editor){ // summary: // Initialize the global handler upon a plugin's first instance of setEditor // // All plugins will attempt initialization. We only need to do so once. if(this.initialized){ return; } this.initialized = true; this.editor = editor; this.editorDomNode = this.editor.editNode || this.editor.iframe.document.body.firstChild; // RichText should have a mouseup connection to recognize drag-selections // Example would be selecting multiple table cells dojo.connect(this.editorDomNode , "mouseup", this.editor, "onClick"); dojo.connect(this.editor, "onDisplayChanged", this, "checkAvailable"); this.doMixins(); this.connectDraggable(); }, getTableInfo: function(forceNewData){ // summary // Gets the table in focus // Collects info on the table - see return params // if(forceNewData){ this._tempStoreTableData(false); } if(this.tableData){ // tableData is set for a short amount of time, so that all // plugins get the same return without doing the method over console.log("returning current tableData:", this.tableData); return this.tableData; } var tr, trs, td, tds, tbl, cols, tdIndex, trIndex; td = this.editor.getAncestorElement("td"); if(td){ tr = td.parentNode; } tbl = this.editor.getAncestorElement("table"); //console.log("td:", td);console.log("tr:", tr);console.log("tbl:", tbl) tds = dojo.query("td", tbl); tds.forEach(function(d, i){ if(td==d){tdIndex = i} }); trs = dojo.query("tr", tbl); trs.forEach(function(r, i){ if(tr==r){trIndex = i} }); cols = tds.length/trs.length; var o = { tbl:tbl, // focused table td:td, // focused TD tr:tr, // focused TR trs:trs, // rows tds:tds, // cells rows:trs.length,// row amount cols:cols, // column amount tdIndex:tdIndex,// index of focused cell trIndex:trIndex, // index of focused row colIndex:tdIndex%cols }; console.log("NEW tableData:",o); this.tableData = o; this._tempStoreTableData(500); return this.tableData; }, connectDraggable: function(){ // summary // Detects drag-n-drop in the editor (could probably be moved to there) // Currently only checks if item dragged was a TABLE, and removes its align attr // DOES NOT WORK IN FF - it could - but FF's drag detection is a monster // if(!dojo.isIE){ //console.warn("Drag and Drop is currently only detectable in IE."); return } // IE ONLY this.editorDomNode.ondragstart = dojo.hitch(this, "onDragStart"); this.editorDomNode.ondragend = dojo.hitch(this, "onDragEnd"); //NOTES: // FF _ Able to detect the drag-over object (the editor.domNode) // Not able to detect an item's ondrag() event // Don't know why - I actually got it working when there was an error // Something to do with different documents or windows I'm sure // //console.log("connectDraggable", tbl); /*tbl.ondragstart=dojo.hitch(this, "onDragStart"); tbl.addEventListener("dragstart", dojo.hitch(this, "onDragStart"), false); tbl.addEventListener("drag", dojo.hitch(this, "onDragStart2"), false); tbl.addEventListener("dragend", dojo.hitch(this, "onDragStart3"), false); dojo.withGlobal(this.editor.window, "selectElement",dijit._editor.selection, [tbl]); tbl.ondragstart = function(){ console.log ("ondragstart"); }; tbl.ondrag = function(){ alert("drag") //console.log ("ondrag"); */ }, onDragStart: function(){ var e = window.event; if(!e.srcElement.id){ e.srcElement.id = "tbl_"+(new Date().getTime()); } //console.log("onDragStart", e.srcElement.id); }, onDragEnd: function(){ // summary // Detects that an object has been dragged into place // Currently, this code is only used for when a table is dragged // and clears the "align" attribute, so that the table will look // to be more in the place that the user expected. // TODO: This code can be used for other things, most // notably UNDO, which currently is not quite usable. // This code could also find itself in the Editor code when it is // complete. //console.log("onDragEnd"); var e = window.event var node = e.srcElement; var id = node.id; var win = this.editor.window //console.log("NODE:", node.tagName, node.id, dojo.attr(node, "align")); // clearing a table's align attr // TODO: when ondrag becomes more robust, this code block // should move to its own method if(node.tagName.toLowerCase()=="table"){ setTimeout(function(){ var node = dojo.withGlobal(win, "byId", dojo, [id]); dojo.removeAttr(node, "align"); //console.log("set", node.tagName, dojo.attr(node, "align")) }, 100); } }, checkAvailable: function(){ // summary // For table plugs // Checking if a table or part of a table has focus so that // Plugs can change their status // if(this.availableCurrentlySet){ // availableCurrentlySet is set for a short amount of time, so that all // plugins get the same return without doing the method over //console.log("availableCurrentlySet:", this.availableCurrentlySet, "currentlyAvailable:", this.currentlyAvailable) return this.currentlyAvailable; } //console.log("G - checkAvailable..."); if(!this.editor) { //console.log("editor not ready") return false; } if(this.alwaysAvailable) { //console.log(" return always available") return true; } this.currentlyAvailable = this.editor.hasAncestorElement("table"); if(this.currentlyAvailable){ this.connectTableKeys(); }else{ this.disconnectTableKeys(); } this._tempAvailability(500); dojo.publish("available", [ this.currentlyAvailable ]); return this.currentlyAvailable; }, _prepareTable: function(tbl){ // For IE's sake, we are adding IDs to the TDs if none is there // We go ahead and use it for other code for convenience // var tds = this.editor.query("td", tbl); console.log("prep:", tds, tbl) if(!tds[0].id){ tds.forEach(function(td, i){ if(!td.id){ td.id = "tdid"+i+this.getTimeStamp(); } }, this); } return tds; }, getTimeStamp: function(){ return Math.floor(new Date().getTime() * 0.00000001); }, _tempStoreTableData: function(type){ // caching or clearing table data, depending on the arg // if(type===true){ //store indefinitely }else if(type===false){ // clear object this.tableData = null; }else if(type===undefined){ console.warn("_tempStoreTableData must be passed an argument") }else{ // type is a number/ms setTimeout(dojo.hitch(this, function(){ this.tableData = null; }), type); } }, _tempAvailability: function(type){ // caching or clearing availability, depending on the arg if(type===true){ //store indefinitely this.availableCurrentlySet = true; }else if(type===false){ // clear object this.availableCurrentlySet = false; }else if(type===undefined){ console.warn("_tempAvailability must be passed an argument") }else{ // type is a number/ms this.availableCurrentlySet = true; setTimeout(dojo.hitch(this, function(){ this.availableCurrentlySet = false; }), type); } }, connectTableKeys: function(){ // summary // When a table is in focus, start detecting keys // Mainly checking for the TAB key so user can tab // through a table (blocking the browser's desire to // tab away from teh editor completely) if(this.tablesConnected){ return; } this.tablesConnected = true; var node = (this.editor.iframe) ? this.editor.document : this.editor.editNode; this.cnKeyDn = dojo.connect(node, "onkeydown", this, "onKeyDown"); this.cnKeyUp = dojo.connect(node, "onkeyup", this, "onKeyUp"); dojo.connect(node, "onkeypress", this, "onKeyUp"); }, disconnectTableKeys: function(){ //console.log("disconnect") dojo.disconnect(this.cnKeyDn); dojo.disconnect(this.cnKeyUp); this.tablesConnected = false; }, onKeyDown: function(evt){ var key = evt.keyCode; //console.log(" -> DOWN:", key); if(key == 16) this.shiftKeyDown = true; if(key == 9) {console.log("TAB!:"); var o = this.getTableInfo(); //console.log("TAB ", o.tdIndex, o); // modifying the o.tdIndex in the tableData directly, because we may save it // FIXME: tabTo is a global o.tdIndex = (this.shiftKeyDown) ? o.tdIndex-1 : tabTo = o.tdIndex+1; if(o.tdIndex>=0 && o.tdIndex UP:", key) if(key == 16) this.shiftKeyDown = false; if(key == 37 || key == 38 || key == 39 || key == 40 ){ // user can arrow or tab out of table - need to recheck this.onDisplayChanged(); } if(key == 9 && this.stopEvent) dojo.stopEvent(evt); }, onDisplayChanged: function(){ //console.log("onDisplayChanged") this.currentlyAvailable = false; this._tempStoreTableData(false); this._tempAvailability(false); this.checkAvailable(); } }); // global: tablePluginHandler = new dojox.editor.plugins.GlobalTableHandler(); //FIXME: no globals. dojo.declare("dojox.editor.plugins.TablePlugins", dijit._editor._Plugin, { //summary: // A collection of Plugins for inserting and modifying tables in the Editor // See end of this document for all avaiable plugs // and dojox/editorPlugins/tests/editorTablePlugs.html for an example // // NOT IMPLEMENTED: Not handling cell merge, span or split // iconClassPrefix: "editorIcon", useDefaultCommand: false, buttonClass: dijit.form.Button, commandName:"", label:"", alwaysAvailable:false, undoEnabled:false, constructor: function(){ // summary // Initialize certain plugins // switch(this.commandName){ case "colorTableCell": this.buttonClass = dijit.form.DropDownButton; this.dropDown = new dijit.ColorPalette(); this.connect(this.dropDown, "onChange", function(color){ this.modTable(null, color); }); break; case "modifyTable": this.buttonClass = dijit.form.DropDownButton; this.modTable = this.launchModifyDialog; break; case "insertTable": this.alwaysAvailable = true; this.buttonClass = dijit.form.DropDownButton; this.modTable = this.launchInsertDialog; break; case "tableContextMenu": this.connect(this, "setEditor", function(){ this._createContextMenu(); this.button.domNode.style.display = "none"; }); break; } dojo.subscribe("available", this, "onDisplayChanged"); }, onDisplayChanged: function(withinTable){ // subscribed to from the global object's publish method // //console.log("onDisplayChanged", this.commandName); if(!this.alwaysAvailable){ this.available = withinTable; this.button.attr('disabled', !this.available); } }, setEditor: function(){ this.inherited(arguments); this.onEditorLoaded(); }, onEditorLoaded: function(){ //stub // call global object to initialize it tablePluginHandler.initialize(this.editor); }, _createContextMenu: function(){ // summary // Building context menu for right-click shortcuts within a table // var node = dojo.isFF ? this.editor.editNode : this.editorDomNode; var pMenu = new dijit.Menu({targetNodeIds:[node], id:"progMenu", contextMenuForWindow:dojo.isIE}); var _M = dijit.MenuItem; var messages = dojo.i18n.getLocalization("dojox.editor.plugins", "TableDialog", this.lang); pMenu.addChild(new _M({label: messages.selectTableLabel, onClick: dojo.hitch(this, "selectTable")})); pMenu.addChild(new dijit.MenuSeparator()); pMenu.addChild(new _M({label: messages.insertTableRowBeforeLabel, onClick: dojo.hitch(this, "modTable", "insertTableRowBefore" )})); pMenu.addChild(new _M({label: messages.insertTableRowAfterLabel, onClick: dojo.hitch(this, "modTable", "insertTableRowAfter" )})); pMenu.addChild(new _M({label: messages.insertTableColumnBeforeLabel, onClick: dojo.hitch(this, "modTable", "insertTableColumnBefore" )})); pMenu.addChild(new _M({label: messages.insertTableColumnAfterLabel, onClick: dojo.hitch(this, "modTable", "insertTableColumnAfter" )})); pMenu.addChild(new dijit.MenuSeparator()); pMenu.addChild(new _M({label: messages.deleteTableRowLabel, onClick: dojo.hitch(this, "modTable", "deleteTableRow" )})); pMenu.addChild(new _M({label: messages.deleteTableColumnLabel, onClick: dojo.hitch(this, "modTable", "deleteTableColumn" )})); // overwriting this method, as the menu's coordinates // are not accurate in the editor's iframe // FIXME: Works well in IE - all others, sometimes inaccurate. pMenu._openMyself = function(e){ if(!tablePluginHandler.checkAvailable()){ return; } if(this.leftClickToOpen && e.button>0){ return; } dojo.stopEvent(e); var x,y; if(dojo.isIE){ x = e.x; y = e.y; }else{ x = e.screenX; y = e.screenY + 25; } var self=this; var savedFocus = dijit.getFocus(this); function closeAndRestoreFocus(){ // user has clicked on a menu or popup dijit.focus(savedFocus); dijit.popup.close(self); } var res = dijit.popup.open({ popup: this, x: x, y: y, onExecute: closeAndRestoreFocus, onCancel: closeAndRestoreFocus, orient: this.isLeftToRight() ? 'L' : 'R' }); var v = dijit.getViewport(); if(res.y+res.h>v.h){ if(e.screenY-res.h>=0){ y = e.screenY - res.h; }else{ y = 0; } dijit.popup.close(this); // FIXME: Not very DRY here. // Reopening popup if the location was not good. res = dijit.popup.open({ popup: this, x: x, y: y, onExecute: closeAndRestoreFocus, onCancel: closeAndRestoreFocus, orient: this.isLeftToRight() ? 'L' : 'R' }); } console.log(dijit.getViewport()); this.focus(); this._onBlur = function(){ this.inherited('_onBlur', arguments); dijit.popup.close(this); } } this.menu = pMenu; }, selectTable: function(){ // selects table that is in focus var o = this.getTableInfo(); dojo.withGlobal(this.editor.window, "selectElement",dijit._editor.selection, [o.tbl]); }, launchInsertDialog: function(){ var w = new dojox.editor.plugins.EditorTableDialog({}); w.show(); var c = dojo.connect(w, "onBuildTable", this, function(obj){ dojo.disconnect(c); var res = this.editor.execCommand('inserthtml', obj.htmlText); // commenting this line, due to msg below //var td = this.editor.query("td", this.editor.byId(obj.id)); //HMMMM.... This throws a security error now. didn't used to. //this.editor.selectElement(td); }); }, launchModifyDialog: function(){ var o = this.getTableInfo(); console.log("LAUNCH DIALOG") var w = new dojox.editor.plugins.EditorModifyTableDialog({table:o.tbl}); w.show(); this.connect(w, "onSetTable", function(color){ // uhm... not sure whats going on here... var o = this.getTableInfo(); console.log("set color:", color) dojo.attr(o.td, "bgcolor", color); }); }, _initButton: function(){ this.command = this.commandName; this.label = this.editor.commands[this.command] = this._makeTitle(this.command); this.inherited(arguments); delete this.command; if(this.commandName != "colorTableCell") this.connect(this.button.domNode, "click", "modTable"); if(this.commandName=="tableContextMenu") this.button.domNode.display = "none"; this.onDisplayChanged(false); }, modTable: function(cmd, args){ // summary // Where each plugin performs its action // Note: not using execCommand. In spite of their presence in the // Editor as query-able plugins, I was not able to find any evidence // that they are supported (especially in NOT IE). If they are // supported in other browsers, it may help with the undo problem. // this.begEdit(); var o = this.getTableInfo(); var sw = (dojo.isString(cmd))?cmd : this.commandName; var r, c, i; var adjustColWidth = false; //console.log("modTable:", sw) switch(sw){ case "insertTableRowBefore": r = o.tbl.insertRow(o.trIndex); for(i=0;imike

"); this.editor.setValue(this.valBeforeUndo); this.editor.replaceValue(afterUndo); } this.editor.onDisplayChanged(); } }, makeColumnsEven: function(){ //summary // After changing column amount, change widths to // keep columns even // // the timeout helps prevent an occasional snafu setTimeout(dojo.hitch(this, function(){ var o = this.getTableInfo(true); var w = Math.floor(100/o.cols); o.tds.forEach(function(d){ dojo.attr(d, "width", w+"%"); }); }), 10); }, getTableInfo: function(forceNewData){ // summary // Gets the table in focus // Collects info on the table - see return params // return tablePluginHandler.getTableInfo(forceNewData); }, _makeTitle: function(str){ // Parses the commandName into a Title // based on camelCase var s = str.split(""), ns = []; dojo.forEach(str, function(c, i){ if(c.charCodeAt(0)<91 && i>0 && ns[i-1].charCodeAt(0)!=32){ ns.push(" "); } if(i==0) c = c.toUpperCase(); ns.push(c); }); return ns.join(""); ";s:7:"private";b:1;s:7:"summary";s:0:"";}s:50:"dojox.editor.plugins.TablePlugins.getSelectedCells";a:4:{s:9:"prototype";s:33:"dojox.editor.plugins.TablePlugins";s:4:"type";s:8:"Function";s:6:"source";s:25292:"dojo.provide("dojox.editor.plugins.TablePlugins"); dojo.require("dijit._editor._Plugin"); dojo.require("dijit._editor.selection"); dojo.require("dijit.Menu"); dojo.require("dojo.i18n"); dojo.requireLocalization("dojox.editor.plugins", "TableDialog"); dojo.experimental("dojox.editor.plugins.TablePlugins"); // summary: // A series of plugins that give the Editor the ability to create and edit // HTML tables. See the end of this document for all avaiable plugins // and dojox/editorPlugins/tests/editorTablePlugs.html for an example // // example: // |
// | Editor text is here // |
// // TODO: // Currently not supporting merging or splitting cells // // FIXME: Undo is very buggy, and therefore unimeplented in all browsers // except IE - which itself has only been lightly tested. // // FIXME: Selecting multiple table cells in Firefox looks to be impossible. // This affect the 'colorTableCell' plugin. Cells can still be // colored individually or in rows. dojo.declare("dojox.editor.plugins.GlobalTableHandler", dijit._editor._Plugin,{ // summary: // A global object that handles common tasks for all the plugins. Since // there are several plugins that are all calling common methods, it's preferable // that they call a centralized location that either has a set variable or a // timeout to only repeat code-heavy calls when necessary. // tablesConnected:false, currentlyAvailable: false, alwaysAvailable:false, availableCurrentlySet:false, initialized:false, tableData: null, shiftKeyDown:false, editorDomNode: null, undoEnabled: dojo.isIE, //FIXME: doMixins: function(){ dojo.mixin(this.editor,{ getAncestorElement: function(tagName){ return dojo.withGlobal(this.window, "getAncestorElement",dijit._editor.selection, [tagName]); }, hasAncestorElement: function(tagName){ return true return dojo.withGlobal(this.window, "hasAncestorElement",dijit._editor.selection, [tagName]); }, selectElement: function(elem){ dojo.withGlobal(this.window, "selectElement",dijit._editor.selection, [elem]); }, byId: function(id){ return dojo.withGlobal(this.window, "byId", dojo, [id]); }, query: function(arg, scope, returnFirstOnly){ // this shortcut is dubious - not sure scoping is necessary var ar = dojo.withGlobal(this.window, "query", dojo, [arg, scope]); return (returnFirstOnly) ? ar[0] : ar; } }); }, initialize: function(editor){ // summary: // Initialize the global handler upon a plugin's first instance of setEditor // // All plugins will attempt initialization. We only need to do so once. if(this.initialized){ return; } this.initialized = true; this.editor = editor; this.editorDomNode = this.editor.editNode || this.editor.iframe.document.body.firstChild; // RichText should have a mouseup connection to recognize drag-selections // Example would be selecting multiple table cells dojo.connect(this.editorDomNode , "mouseup", this.editor, "onClick"); dojo.connect(this.editor, "onDisplayChanged", this, "checkAvailable"); this.doMixins(); this.connectDraggable(); }, getTableInfo: function(forceNewData){ // summary // Gets the table in focus // Collects info on the table - see return params // if(forceNewData){ this._tempStoreTableData(false); } if(this.tableData){ // tableData is set for a short amount of time, so that all // plugins get the same return without doing the method over console.log("returning current tableData:", this.tableData); return this.tableData; } var tr, trs, td, tds, tbl, cols, tdIndex, trIndex; td = this.editor.getAncestorElement("td"); if(td){ tr = td.parentNode; } tbl = this.editor.getAncestorElement("table"); //console.log("td:", td);console.log("tr:", tr);console.log("tbl:", tbl) tds = dojo.query("td", tbl); tds.forEach(function(d, i){ if(td==d){tdIndex = i} }); trs = dojo.query("tr", tbl); trs.forEach(function(r, i){ if(tr==r){trIndex = i} }); cols = tds.length/trs.length; var o = { tbl:tbl, // focused table td:td, // focused TD tr:tr, // focused TR trs:trs, // rows tds:tds, // cells rows:trs.length,// row amount cols:cols, // column amount tdIndex:tdIndex,// index of focused cell trIndex:trIndex, // index of focused row colIndex:tdIndex%cols }; console.log("NEW tableData:",o); this.tableData = o; this._tempStoreTableData(500); return this.tableData; }, connectDraggable: function(){ // summary // Detects drag-n-drop in the editor (could probably be moved to there) // Currently only checks if item dragged was a TABLE, and removes its align attr // DOES NOT WORK IN FF - it could - but FF's drag detection is a monster // if(!dojo.isIE){ //console.warn("Drag and Drop is currently only detectable in IE."); return } // IE ONLY this.editorDomNode.ondragstart = dojo.hitch(this, "onDragStart"); this.editorDomNode.ondragend = dojo.hitch(this, "onDragEnd"); //NOTES: // FF _ Able to detect the drag-over object (the editor.domNode) // Not able to detect an item's ondrag() event // Don't know why - I actually got it working when there was an error // Something to do with different documents or windows I'm sure // //console.log("connectDraggable", tbl); /*tbl.ondragstart=dojo.hitch(this, "onDragStart"); tbl.addEventListener("dragstart", dojo.hitch(this, "onDragStart"), false); tbl.addEventListener("drag", dojo.hitch(this, "onDragStart2"), false); tbl.addEventListener("dragend", dojo.hitch(this, "onDragStart3"), false); dojo.withGlobal(this.editor.window, "selectElement",dijit._editor.selection, [tbl]); tbl.ondragstart = function(){ console.log ("ondragstart"); }; tbl.ondrag = function(){ alert("drag") //console.log ("ondrag"); */ }, onDragStart: function(){ var e = window.event; if(!e.srcElement.id){ e.srcElement.id = "tbl_"+(new Date().getTime()); } //console.log("onDragStart", e.srcElement.id); }, onDragEnd: function(){ // summary // Detects that an object has been dragged into place // Currently, this code is only used for when a table is dragged // and clears the "align" attribute, so that the table will look // to be more in the place that the user expected. // TODO: This code can be used for other things, most // notably UNDO, which currently is not quite usable. // This code could also find itself in the Editor code when it is // complete. //console.log("onDragEnd"); var e = window.event var node = e.srcElement; var id = node.id; var win = this.editor.window //console.log("NODE:", node.tagName, node.id, dojo.attr(node, "align")); // clearing a table's align attr // TODO: when ondrag becomes more robust, this code block // should move to its own method if(node.tagName.toLowerCase()=="table"){ setTimeout(function(){ var node = dojo.withGlobal(win, "byId", dojo, [id]); dojo.removeAttr(node, "align"); //console.log("set", node.tagName, dojo.attr(node, "align")) }, 100); } }, checkAvailable: function(){ // summary // For table plugs // Checking if a table or part of a table has focus so that // Plugs can change their status // if(this.availableCurrentlySet){ // availableCurrentlySet is set for a short amount of time, so that all // plugins get the same return without doing the method over //console.log("availableCurrentlySet:", this.availableCurrentlySet, "currentlyAvailable:", this.currentlyAvailable) return this.currentlyAvailable; } //console.log("G - checkAvailable..."); if(!this.editor) { //console.log("editor not ready") return false; } if(this.alwaysAvailable) { //console.log(" return always available") return true; } this.currentlyAvailable = this.editor.hasAncestorElement("table"); if(this.currentlyAvailable){ this.connectTableKeys(); }else{ this.disconnectTableKeys(); } this._tempAvailability(500); dojo.publish("available", [ this.currentlyAvailable ]); return this.currentlyAvailable; }, _prepareTable: function(tbl){ // For IE's sake, we are adding IDs to the TDs if none is there // We go ahead and use it for other code for convenience // var tds = this.editor.query("td", tbl); console.log("prep:", tds, tbl) if(!tds[0].id){ tds.forEach(function(td, i){ if(!td.id){ td.id = "tdid"+i+this.getTimeStamp(); } }, this); } return tds; }, getTimeStamp: function(){ return Math.floor(new Date().getTime() * 0.00000001); }, _tempStoreTableData: function(type){ // caching or clearing table data, depending on the arg // if(type===true){ //store indefinitely }else if(type===false){ // clear object this.tableData = null; }else if(type===undefined){ console.warn("_tempStoreTableData must be passed an argument") }else{ // type is a number/ms setTimeout(dojo.hitch(this, function(){ this.tableData = null; }), type); } }, _tempAvailability: function(type){ // caching or clearing availability, depending on the arg if(type===true){ //store indefinitely this.availableCurrentlySet = true; }else if(type===false){ // clear object this.availableCurrentlySet = false; }else if(type===undefined){ console.warn("_tempAvailability must be passed an argument") }else{ // type is a number/ms this.availableCurrentlySet = true; setTimeout(dojo.hitch(this, function(){ this.availableCurrentlySet = false; }), type); } }, connectTableKeys: function(){ // summary // When a table is in focus, start detecting keys // Mainly checking for the TAB key so user can tab // through a table (blocking the browser's desire to // tab away from teh editor completely) if(this.tablesConnected){ return; } this.tablesConnected = true; var node = (this.editor.iframe) ? this.editor.document : this.editor.editNode; this.cnKeyDn = dojo.connect(node, "onkeydown", this, "onKeyDown"); this.cnKeyUp = dojo.connect(node, "onkeyup", this, "onKeyUp"); dojo.connect(node, "onkeypress", this, "onKeyUp"); }, disconnectTableKeys: function(){ //console.log("disconnect") dojo.disconnect(this.cnKeyDn); dojo.disconnect(this.cnKeyUp); this.tablesConnected = false; }, onKeyDown: function(evt){ var key = evt.keyCode; //console.log(" -> DOWN:", key); if(key == 16) this.shiftKeyDown = true; if(key == 9) {console.log("TAB!:"); var o = this.getTableInfo(); //console.log("TAB ", o.tdIndex, o); // modifying the o.tdIndex in the tableData directly, because we may save it // FIXME: tabTo is a global o.tdIndex = (this.shiftKeyDown) ? o.tdIndex-1 : tabTo = o.tdIndex+1; if(o.tdIndex>=0 && o.tdIndex UP:", key) if(key == 16) this.shiftKeyDown = false; if(key == 37 || key == 38 || key == 39 || key == 40 ){ // user can arrow or tab out of table - need to recheck this.onDisplayChanged(); } if(key == 9 && this.stopEvent) dojo.stopEvent(evt); }, onDisplayChanged: function(){ //console.log("onDisplayChanged") this.currentlyAvailable = false; this._tempStoreTableData(false); this._tempAvailability(false); this.checkAvailable(); } }); // global: tablePluginHandler = new dojox.editor.plugins.GlobalTableHandler(); //FIXME: no globals. dojo.declare("dojox.editor.plugins.TablePlugins", dijit._editor._Plugin, { //summary: // A collection of Plugins for inserting and modifying tables in the Editor // See end of this document for all avaiable plugs // and dojox/editorPlugins/tests/editorTablePlugs.html for an example // // NOT IMPLEMENTED: Not handling cell merge, span or split // iconClassPrefix: "editorIcon", useDefaultCommand: false, buttonClass: dijit.form.Button, commandName:"", label:"", alwaysAvailable:false, undoEnabled:false, constructor: function(){ // summary // Initialize certain plugins // switch(this.commandName){ case "colorTableCell": this.buttonClass = dijit.form.DropDownButton; this.dropDown = new dijit.ColorPalette(); this.connect(this.dropDown, "onChange", function(color){ this.modTable(null, color); }); break; case "modifyTable": this.buttonClass = dijit.form.DropDownButton; this.modTable = this.launchModifyDialog; break; case "insertTable": this.alwaysAvailable = true; this.buttonClass = dijit.form.DropDownButton; this.modTable = this.launchInsertDialog; break; case "tableContextMenu": this.connect(this, "setEditor", function(){ this._createContextMenu(); this.button.domNode.style.display = "none"; }); break; } dojo.subscribe("available", this, "onDisplayChanged"); }, onDisplayChanged: function(withinTable){ // subscribed to from the global object's publish method // //console.log("onDisplayChanged", this.commandName); if(!this.alwaysAvailable){ this.available = withinTable; this.button.attr('disabled', !this.available); } }, setEditor: function(){ this.inherited(arguments); this.onEditorLoaded(); }, onEditorLoaded: function(){ //stub // call global object to initialize it tablePluginHandler.initialize(this.editor); }, _createContextMenu: function(){ // summary // Building context menu for right-click shortcuts within a table // var node = dojo.isFF ? this.editor.editNode : this.editorDomNode; var pMenu = new dijit.Menu({targetNodeIds:[node], id:"progMenu", contextMenuForWindow:dojo.isIE}); var _M = dijit.MenuItem; var messages = dojo.i18n.getLocalization("dojox.editor.plugins", "TableDialog", this.lang); pMenu.addChild(new _M({label: messages.selectTableLabel, onClick: dojo.hitch(this, "selectTable")})); pMenu.addChild(new dijit.MenuSeparator()); pMenu.addChild(new _M({label: messages.insertTableRowBeforeLabel, onClick: dojo.hitch(this, "modTable", "insertTableRowBefore" )})); pMenu.addChild(new _M({label: messages.insertTableRowAfterLabel, onClick: dojo.hitch(this, "modTable", "insertTableRowAfter" )})); pMenu.addChild(new _M({label: messages.insertTableColumnBeforeLabel, onClick: dojo.hitch(this, "modTable", "insertTableColumnBefore" )})); pMenu.addChild(new _M({label: messages.insertTableColumnAfterLabel, onClick: dojo.hitch(this, "modTable", "insertTableColumnAfter" )})); pMenu.addChild(new dijit.MenuSeparator()); pMenu.addChild(new _M({label: messages.deleteTableRowLabel, onClick: dojo.hitch(this, "modTable", "deleteTableRow" )})); pMenu.addChild(new _M({label: messages.deleteTableColumnLabel, onClick: dojo.hitch(this, "modTable", "deleteTableColumn" )})); // overwriting this method, as the menu's coordinates // are not accurate in the editor's iframe // FIXME: Works well in IE - all others, sometimes inaccurate. pMenu._openMyself = function(e){ if(!tablePluginHandler.checkAvailable()){ return; } if(this.leftClickToOpen && e.button>0){ return; } dojo.stopEvent(e); var x,y; if(dojo.isIE){ x = e.x; y = e.y; }else{ x = e.screenX; y = e.screenY + 25; } var self=this; var savedFocus = dijit.getFocus(this); function closeAndRestoreFocus(){ // user has clicked on a menu or popup dijit.focus(savedFocus); dijit.popup.close(self); } var res = dijit.popup.open({ popup: this, x: x, y: y, onExecute: closeAndRestoreFocus, onCancel: closeAndRestoreFocus, orient: this.isLeftToRight() ? 'L' : 'R' }); var v = dijit.getViewport(); if(res.y+res.h>v.h){ if(e.screenY-res.h>=0){ y = e.screenY - res.h; }else{ y = 0; } dijit.popup.close(this); // FIXME: Not very DRY here. // Reopening popup if the location was not good. res = dijit.popup.open({ popup: this, x: x, y: y, onExecute: closeAndRestoreFocus, onCancel: closeAndRestoreFocus, orient: this.isLeftToRight() ? 'L' : 'R' }); } console.log(dijit.getViewport()); this.focus(); this._onBlur = function(){ this.inherited('_onBlur', arguments); dijit.popup.close(this); } } this.menu = pMenu; }, selectTable: function(){ // selects table that is in focus var o = this.getTableInfo(); dojo.withGlobal(this.editor.window, "selectElement",dijit._editor.selection, [o.tbl]); }, launchInsertDialog: function(){ var w = new dojox.editor.plugins.EditorTableDialog({}); w.show(); var c = dojo.connect(w, "onBuildTable", this, function(obj){ dojo.disconnect(c); var res = this.editor.execCommand('inserthtml', obj.htmlText); // commenting this line, due to msg below //var td = this.editor.query("td", this.editor.byId(obj.id)); //HMMMM.... This throws a security error now. didn't used to. //this.editor.selectElement(td); }); }, launchModifyDialog: function(){ var o = this.getTableInfo(); console.log("LAUNCH DIALOG") var w = new dojox.editor.plugins.EditorModifyTableDialog({table:o.tbl}); w.show(); this.connect(w, "onSetTable", function(color){ // uhm... not sure whats going on here... var o = this.getTableInfo(); console.log("set color:", color) dojo.attr(o.td, "bgcolor", color); }); }, _initButton: function(){ this.command = this.commandName; this.label = this.editor.commands[this.command] = this._makeTitle(this.command); this.inherited(arguments); delete this.command; if(this.commandName != "colorTableCell") this.connect(this.button.domNode, "click", "modTable"); if(this.commandName=="tableContextMenu") this.button.domNode.display = "none"; this.onDisplayChanged(false); }, modTable: function(cmd, args){ // summary // Where each plugin performs its action // Note: not using execCommand. In spite of their presence in the // Editor as query-able plugins, I was not able to find any evidence // that they are supported (especially in NOT IE). If they are // supported in other browsers, it may help with the undo problem. // this.begEdit(); var o = this.getTableInfo(); var sw = (dojo.isString(cmd))?cmd : this.commandName; var r, c, i; var adjustColWidth = false; //console.log("modTable:", sw) switch(sw){ case "insertTableRowBefore": r = o.tbl.insertRow(o.trIndex); for(i=0;imike

"); this.editor.setValue(this.valBeforeUndo); this.editor.replaceValue(afterUndo); } this.editor.onDisplayChanged(); } }, makeColumnsEven: function(){ //summary // After changing column amount, change widths to // keep columns even // // the timeout helps prevent an occasional snafu setTimeout(dojo.hitch(this, function(){ var o = this.getTableInfo(true); var w = Math.floor(100/o.cols); o.tds.forEach(function(d){ dojo.attr(d, "width", w+"%"); }); }), 10); }, getTableInfo: function(forceNewData){ // summary // Gets the table in focus // Collects info on the table - see return params // return tablePluginHandler.getTableInfo(forceNewData); }, _makeTitle: function(str){ // Parses the commandName into a Title // based on camelCase var s = str.split(""), ns = []; dojo.forEach(str, function(c, i){ if(c.charCodeAt(0)<91 && i>0 && ns[i-1].charCodeAt(0)!=32){ ns.push(" "); } if(i==0) c = c.toUpperCase(); ns.push(c); }); return ns.join(""); }, getSelectedCells: function(){ // summary // Gets the selected cells from the passed table // Returns: array of TDs or empty array // var cells = []; var tbl = this.getTableInfo().tbl; var tds = tablePluginHandler._prepareTable(tbl); var e = this.editor; var r; if(!dojo.isIE){ r = dijit.range.getSelection(e.window); var foundFirst=false; var foundLast=false; if(r.anchorNode && r.anchorNode.tagName && r.anchorNode.tagName.toLowerCase()=="tr"){ // Firefox // Geez - and I thought IE was hard.... // In the Editor, FF refuses to grab a multiple cell selection at the TD level // in spite of multiple selection techniques // Resorting to going ahead with its TR selection and selecting // the entire row // Has no problem with individual cell selection though // var trs = dojo.query("tr", tbl); var rows = []; trs.forEach(function(tr, i){ if(!foundFirst && (tr == r.anchorNode || tr == r.focusNode)){ rows.push(tr); foundFirst = true; if(r.anchorNode == r.focusNode){ foundLast = true; } }else if(foundFirst && !foundLast){ rows.push(tr); if(tr == r.anchorNode || tr == r.focusNode){ foundLast = true; } } }); dojo.forEach(rows, function(tr){ cells = cells.concat(dojo.query("td", tr)); }, this); }else{ // Safari // Yay! It works like expected // Getting the cells from anchorNode to focusNode // tds.forEach(function(td, i){ if(!foundFirst && (td.id == r.anchorNode.parentNode.id || td.id == r.focusNode.parentNode.id)){ cells.push(td); foundFirst = true; if(r.anchorNode.parentNode.id == r.focusNode.parentNode.id){ foundLast = true; } }else if(foundFirst && !foundLast){ cells.push(td) if(td.id == r.focusNode.parentNode.id || td.id == r.anchorNode.parentNode.id){ foundLast = true; } } }); console.log("SAF CELLS:", cells); } } if(dojo.isIE){ // IE // Although the code is tight - there's some funkiness here // Can only get the htmlText, so we add IDs to the cells (above) // And pull them from the htmlText, then search for those cells // r = document.selection.createRange() var str = r.htmlText.match(/id=\w*/g); dojo.forEach(str, function(a){ var id = a.substring(3, a.length); cells.push(e.byId(id)); }, this) } return cells;";s:7:"summary";s:0:"";}s:43:"dojox.editor.plugins.TablePlugins.available";a:2:{s:8:"instance";s:33:"dojox.editor.plugins.TablePlugins";s:7:"summary";s:0:"";}s:41:"dojox.editor.plugins.TablePlugins._onBlur";a:3:{s:8:"instance";s:33:"dojox.editor.plugins.TablePlugins";s:7:"private";b:1;s:7:"summary";s:0:"";}s:38:"dojox.editor.plugins.TablePlugins.menu";a:2:{s:8:"instance";s:33:"dojox.editor.plugins.TablePlugins";s:7:"summary";s:0:"";}s:60:"dojox.editor.plugins.TablePlugins._createContextMenu._onBlur";a:6:{s:4:"type";s:8:"Function";s:6:"source";s:72:" this.inherited('_onBlur', arguments); dijit.popup.close(this);";s:8:"instance";s:52:"dojox.editor.plugins.TablePlugins._createContextMenu";s:7:"private";b:1;s:14:"private_parent";b:1;s:7:"summary";s:0:"";}s:41:"dojox.editor.plugins.TablePlugins.command";a:2:{s:8:"instance";s:33:"dojox.editor.plugins.TablePlugins";s:7:"summary";s:0:"";}s:47:"dojox.editor.plugins.TablePlugins.valBeforeUndo";a:2:{s:8:"instance";s:33:"dojox.editor.plugins.TablePlugins";s:7:"summary";s:0:"";}s:42:"dojox.editor.plugins.TablePlugins.dropDown";a:2:{s:8:"instance";s:33:"dojox.editor.plugins.TablePlugins";s:7:"summary";s:0:"";}s:62:"dojox.editor.plugins.TablePlugins.button.domNode.style.display";a:2:{s:8:"instance";s:33:"dojox.editor.plugins.TablePlugins";s:7:"summary";s:0:"";}s:38:"dojox.editor.plugins.EditorTableDialog";a:4:{s:4:"type";s:8:"Function";s:6:"chains";a:2:{s:9:"prototype";a:1:{i:0;s:12:"dijit.Dialog";}s:4:"call";a:1:{i:0;s:12:"dijit.Dialog";}}s:9:"classlike";b:1;s:7:"summary";s:0:"";}s:48:"dojox.editor.plugins.EditorTableDialog.baseClass";a:2:{s:9:"prototype";s:38:"dojox.editor.plugins.EditorTableDialog";s:7:"summary";s:0:"";}s:56:"dojox.editor.plugins.EditorTableDialog.widgetsInTemplate";a:2:{s:9:"prototype";s:38:"dojox.editor.plugins.EditorTableDialog";s:7:"summary";s:0:"";}s:51:"dojox.editor.plugins.EditorTableDialog.templatePath";a:2:{s:9:"prototype";s:38:"dojox.editor.plugins.EditorTableDialog";s:7:"summary";s:0:"";}s:58:"dojox.editor.plugins.EditorTableDialog.postMixInProperties";a:4:{s:9:"prototype";s:38:"dojox.editor.plugins.EditorTableDialog";s:4:"type";s:8:"Function";s:6:"source";s:152:" var messages = dojo.i18n.getLocalization("dojox.editor.plugins", "TableDialog", this.lang); dojo.mixin(this, messages); this.inherited(arguments);";s:7:"summary";s:0:"";}s:49:"dojox.editor.plugins.EditorTableDialog.postCreate";a:4:{s:9:"prototype";s:38:"dojox.editor.plugins.EditorTableDialog";s:4:"type";s:8:"Function";s:6:"source";s:127:" dojo.addClass(this.domNode, this.baseClass); //FIXME - why isn't Dialog accepting the baseClass? this.inherited(arguments);";s:7:"summary";s:0:"";}s:47:"dojox.editor.plugins.EditorTableDialog.onInsert";a:4:{s:9:"prototype";s:38:"dojox.editor.plugins.EditorTableDialog";s:4:"type";s:8:"Function";s:6:"source";s:820:" console.log("insert"); var rows = this.selectRow.attr("value") || 1, cols = this.selectCol.attr("value") || 1, width = this.selectWidth.attr("value"), widthType = this.selectWidthType.attr("value"), border = this.selectBorder.attr("value"), pad = this.selectPad.attr("value"), space = this.selectSpace.attr("value"), _id = "tbl_"+(new Date().getTime()), t = '\n'; for(var r=0;r \n'; } t += '\t\n'; } t += '
'; //console.log(t); this.onBuildTable({htmlText:t, id:_id}); this.hide();";s:7:"summary";s:0:"";}s:51:"dojox.editor.plugins.EditorTableDialog.onBuildTable";a:5:{s:9:"prototype";s:38:"dojox.editor.plugins.EditorTableDialog";s:4:"type";s:8:"Function";s:10:"parameters";a:1:{s:9:"tableText";a:1:{s:4:"type";s:0:"";}}s:6:"source";s:27042:"dojo.provide("dojox.editor.plugins.TablePlugins"); dojo.require("dijit._editor._Plugin"); dojo.require("dijit._editor.selection"); dojo.require("dijit.Menu"); dojo.require("dojo.i18n"); dojo.requireLocalization("dojox.editor.plugins", "TableDialog"); dojo.experimental("dojox.editor.plugins.TablePlugins"); // summary: // A series of plugins that give the Editor the ability to create and edit // HTML tables. See the end of this document for all avaiable plugins // and dojox/editorPlugins/tests/editorTablePlugs.html for an example // // example: // |
// | Editor text is here // |
// // TODO: // Currently not supporting merging or splitting cells // // FIXME: Undo is very buggy, and therefore unimeplented in all browsers // except IE - which itself has only been lightly tested. // // FIXME: Selecting multiple table cells in Firefox looks to be impossible. // This affect the 'colorTableCell' plugin. Cells can still be // colored individually or in rows. dojo.declare("dojox.editor.plugins.GlobalTableHandler", dijit._editor._Plugin,{ // summary: // A global object that handles common tasks for all the plugins. Since // there are several plugins that are all calling common methods, it's preferable // that they call a centralized location that either has a set variable or a // timeout to only repeat code-heavy calls when necessary. // tablesConnected:false, currentlyAvailable: false, alwaysAvailable:false, availableCurrentlySet:false, initialized:false, tableData: null, shiftKeyDown:false, editorDomNode: null, undoEnabled: dojo.isIE, //FIXME: doMixins: function(){ dojo.mixin(this.editor,{ getAncestorElement: function(tagName){ return dojo.withGlobal(this.window, "getAncestorElement",dijit._editor.selection, [tagName]); }, hasAncestorElement: function(tagName){ return true return dojo.withGlobal(this.window, "hasAncestorElement",dijit._editor.selection, [tagName]); }, selectElement: function(elem){ dojo.withGlobal(this.window, "selectElement",dijit._editor.selection, [elem]); }, byId: function(id){ return dojo.withGlobal(this.window, "byId", dojo, [id]); }, query: function(arg, scope, returnFirstOnly){ // this shortcut is dubious - not sure scoping is necessary var ar = dojo.withGlobal(this.window, "query", dojo, [arg, scope]); return (returnFirstOnly) ? ar[0] : ar; } }); }, initialize: function(editor){ // summary: // Initialize the global handler upon a plugin's first instance of setEditor // // All plugins will attempt initialization. We only need to do so once. if(this.initialized){ return; } this.initialized = true; this.editor = editor; this.editorDomNode = this.editor.editNode || this.editor.iframe.document.body.firstChild; // RichText should have a mouseup connection to recognize drag-selections // Example would be selecting multiple table cells dojo.connect(this.editorDomNode , "mouseup", this.editor, "onClick"); dojo.connect(this.editor, "onDisplayChanged", this, "checkAvailable"); this.doMixins(); this.connectDraggable(); }, getTableInfo: function(forceNewData){ // summary // Gets the table in focus // Collects info on the table - see return params // if(forceNewData){ this._tempStoreTableData(false); } if(this.tableData){ // tableData is set for a short amount of time, so that all // plugins get the same return without doing the method over console.log("returning current tableData:", this.tableData); return this.tableData; } var tr, trs, td, tds, tbl, cols, tdIndex, trIndex; td = this.editor.getAncestorElement("td"); if(td){ tr = td.parentNode; } tbl = this.editor.getAncestorElement("table"); //console.log("td:", td);console.log("tr:", tr);console.log("tbl:", tbl) tds = dojo.query("td", tbl); tds.forEach(function(d, i){ if(td==d){tdIndex = i} }); trs = dojo.query("tr", tbl); trs.forEach(function(r, i){ if(tr==r){trIndex = i} }); cols = tds.length/trs.length; var o = { tbl:tbl, // focused table td:td, // focused TD tr:tr, // focused TR trs:trs, // rows tds:tds, // cells rows:trs.length,// row amount cols:cols, // column amount tdIndex:tdIndex,// index of focused cell trIndex:trIndex, // index of focused row colIndex:tdIndex%cols }; console.log("NEW tableData:",o); this.tableData = o; this._tempStoreTableData(500); return this.tableData; }, connectDraggable: function(){ // summary // Detects drag-n-drop in the editor (could probably be moved to there) // Currently only checks if item dragged was a TABLE, and removes its align attr // DOES NOT WORK IN FF - it could - but FF's drag detection is a monster // if(!dojo.isIE){ //console.warn("Drag and Drop is currently only detectable in IE."); return } // IE ONLY this.editorDomNode.ondragstart = dojo.hitch(this, "onDragStart"); this.editorDomNode.ondragend = dojo.hitch(this, "onDragEnd"); //NOTES: // FF _ Able to detect the drag-over object (the editor.domNode) // Not able to detect an item's ondrag() event // Don't know why - I actually got it working when there was an error // Something to do with different documents or windows I'm sure // //console.log("connectDraggable", tbl); /*tbl.ondragstart=dojo.hitch(this, "onDragStart"); tbl.addEventListener("dragstart", dojo.hitch(this, "onDragStart"), false); tbl.addEventListener("drag", dojo.hitch(this, "onDragStart2"), false); tbl.addEventListener("dragend", dojo.hitch(this, "onDragStart3"), false); dojo.withGlobal(this.editor.window, "selectElement",dijit._editor.selection, [tbl]); tbl.ondragstart = function(){ console.log ("ondragstart"); }; tbl.ondrag = function(){ alert("drag") //console.log ("ondrag"); */ }, onDragStart: function(){ var e = window.event; if(!e.srcElement.id){ e.srcElement.id = "tbl_"+(new Date().getTime()); } //console.log("onDragStart", e.srcElement.id); }, onDragEnd: function(){ // summary // Detects that an object has been dragged into place // Currently, this code is only used for when a table is dragged // and clears the "align" attribute, so that the table will look // to be more in the place that the user expected. // TODO: This code can be used for other things, most // notably UNDO, which currently is not quite usable. // This code could also find itself in the Editor code when it is // complete. //console.log("onDragEnd"); var e = window.event var node = e.srcElement; var id = node.id; var win = this.editor.window //console.log("NODE:", node.tagName, node.id, dojo.attr(node, "align")); // clearing a table's align attr // TODO: when ondrag becomes more robust, this code block // should move to its own method if(node.tagName.toLowerCase()=="table"){ setTimeout(function(){ var node = dojo.withGlobal(win, "byId", dojo, [id]); dojo.removeAttr(node, "align"); //console.log("set", node.tagName, dojo.attr(node, "align")) }, 100); } }, checkAvailable: function(){ // summary // For table plugs // Checking if a table or part of a table has focus so that // Plugs can change their status // if(this.availableCurrentlySet){ // availableCurrentlySet is set for a short amount of time, so that all // plugins get the same return without doing the method over //console.log("availableCurrentlySet:", this.availableCurrentlySet, "currentlyAvailable:", this.currentlyAvailable) return this.currentlyAvailable; } //console.log("G - checkAvailable..."); if(!this.editor) { //console.log("editor not ready") return false; } if(this.alwaysAvailable) { //console.log(" return always available") return true; } this.currentlyAvailable = this.editor.hasAncestorElement("table"); if(this.currentlyAvailable){ this.connectTableKeys(); }else{ this.disconnectTableKeys(); } this._tempAvailability(500); dojo.publish("available", [ this.currentlyAvailable ]); return this.currentlyAvailable; }, _prepareTable: function(tbl){ // For IE's sake, we are adding IDs to the TDs if none is there // We go ahead and use it for other code for convenience // var tds = this.editor.query("td", tbl); console.log("prep:", tds, tbl) if(!tds[0].id){ tds.forEach(function(td, i){ if(!td.id){ td.id = "tdid"+i+this.getTimeStamp(); } }, this); } return tds; }, getTimeStamp: function(){ return Math.floor(new Date().getTime() * 0.00000001); }, _tempStoreTableData: function(type){ // caching or clearing table data, depending on the arg // if(type===true){ //store indefinitely }else if(type===false){ // clear object this.tableData = null; }else if(type===undefined){ console.warn("_tempStoreTableData must be passed an argument") }else{ // type is a number/ms setTimeout(dojo.hitch(this, function(){ this.tableData = null; }), type); } }, _tempAvailability: function(type){ // caching or clearing availability, depending on the arg if(type===true){ //store indefinitely this.availableCurrentlySet = true; }else if(type===false){ // clear object this.availableCurrentlySet = false; }else if(type===undefined){ console.warn("_tempAvailability must be passed an argument") }else{ // type is a number/ms this.availableCurrentlySet = true; setTimeout(dojo.hitch(this, function(){ this.availableCurrentlySet = false; }), type); } }, connectTableKeys: function(){ // summary // When a table is in focus, start detecting keys // Mainly checking for the TAB key so user can tab // through a table (blocking the browser's desire to // tab away from teh editor completely) if(this.tablesConnected){ return; } this.tablesConnected = true; var node = (this.editor.iframe) ? this.editor.document : this.editor.editNode; this.cnKeyDn = dojo.connect(node, "onkeydown", this, "onKeyDown"); this.cnKeyUp = dojo.connect(node, "onkeyup", this, "onKeyUp"); dojo.connect(node, "onkeypress", this, "onKeyUp"); }, disconnectTableKeys: function(){ //console.log("disconnect") dojo.disconnect(this.cnKeyDn); dojo.disconnect(this.cnKeyUp); this.tablesConnected = false; }, onKeyDown: function(evt){ var key = evt.keyCode; //console.log(" -> DOWN:", key); if(key == 16) this.shiftKeyDown = true; if(key == 9) {console.log("TAB!:"); var o = this.getTableInfo(); //console.log("TAB ", o.tdIndex, o); // modifying the o.tdIndex in the tableData directly, because we may save it // FIXME: tabTo is a global o.tdIndex = (this.shiftKeyDown) ? o.tdIndex-1 : tabTo = o.tdIndex+1; if(o.tdIndex>=0 && o.tdIndex UP:", key) if(key == 16) this.shiftKeyDown = false; if(key == 37 || key == 38 || key == 39 || key == 40 ){ // user can arrow or tab out of table - need to recheck this.onDisplayChanged(); } if(key == 9 && this.stopEvent) dojo.stopEvent(evt); }, onDisplayChanged: function(){ //console.log("onDisplayChanged") this.currentlyAvailable = false; this._tempStoreTableData(false); this._tempAvailability(false); this.checkAvailable(); } }); // global: tablePluginHandler = new dojox.editor.plugins.GlobalTableHandler(); //FIXME: no globals. dojo.declare("dojox.editor.plugins.TablePlugins", dijit._editor._Plugin, { //summary: // A collection of Plugins for inserting and modifying tables in the Editor // See end of this document for all avaiable plugs // and dojox/editorPlugins/tests/editorTablePlugs.html for an example // // NOT IMPLEMENTED: Not handling cell merge, span or split // iconClassPrefix: "editorIcon", useDefaultCommand: false, buttonClass: dijit.form.Button, commandName:"", label:"", alwaysAvailable:false, undoEnabled:false, constructor: function(){ // summary // Initialize certain plugins // switch(this.commandName){ case "colorTableCell": this.buttonClass = dijit.form.DropDownButton; this.dropDown = new dijit.ColorPalette(); this.connect(this.dropDown, "onChange", function(color){ this.modTable(null, color); }); break; case "modifyTable": this.buttonClass = dijit.form.DropDownButton; this.modTable = this.launchModifyDialog; break; case "insertTable": this.alwaysAvailable = true; this.buttonClass = dijit.form.DropDownButton; this.modTable = this.launchInsertDialog; break; case "tableContextMenu": this.connect(this, "setEditor", function(){ this._createContextMenu(); this.button.domNode.style.display = "none"; }); break; } dojo.subscribe("available", this, "onDisplayChanged"); }, onDisplayChanged: function(withinTable){ // subscribed to from the global object's publish method // //console.log("onDisplayChanged", this.commandName); if(!this.alwaysAvailable){ this.available = withinTable; this.button.attr('disabled', !this.available); } }, setEditor: function(){ this.inherited(arguments); this.onEditorLoaded(); }, onEditorLoaded: function(){ //stub // call global object to initialize it tablePluginHandler.initialize(this.editor); }, _createContextMenu: function(){ // summary // Building context menu for right-click shortcuts within a table // var node = dojo.isFF ? this.editor.editNode : this.editorDomNode; var pMenu = new dijit.Menu({targetNodeIds:[node], id:"progMenu", contextMenuForWindow:dojo.isIE}); var _M = dijit.MenuItem; var messages = dojo.i18n.getLocalization("dojox.editor.plugins", "TableDialog", this.lang); pMenu.addChild(new _M({label: messages.selectTableLabel, onClick: dojo.hitch(this, "selectTable")})); pMenu.addChild(new dijit.MenuSeparator()); pMenu.addChild(new _M({label: messages.insertTableRowBeforeLabel, onClick: dojo.hitch(this, "modTable", "insertTableRowBefore" )})); pMenu.addChild(new _M({label: messages.insertTableRowAfterLabel, onClick: dojo.hitch(this, "modTable", "insertTableRowAfter" )})); pMenu.addChild(new _M({label: messages.insertTableColumnBeforeLabel, onClick: dojo.hitch(this, "modTable", "insertTableColumnBefore" )})); pMenu.addChild(new _M({label: messages.insertTableColumnAfterLabel, onClick: dojo.hitch(this, "modTable", "insertTableColumnAfter" )})); pMenu.addChild(new dijit.MenuSeparator()); pMenu.addChild(new _M({label: messages.deleteTableRowLabel, onClick: dojo.hitch(this, "modTable", "deleteTableRow" )})); pMenu.addChild(new _M({label: messages.deleteTableColumnLabel, onClick: dojo.hitch(this, "modTable", "deleteTableColumn" )})); // overwriting this method, as the menu's coordinates // are not accurate in the editor's iframe // FIXME: Works well in IE - all others, sometimes inaccurate. pMenu._openMyself = function(e){ if(!tablePluginHandler.checkAvailable()){ return; } if(this.leftClickToOpen && e.button>0){ return; } dojo.stopEvent(e); var x,y; if(dojo.isIE){ x = e.x; y = e.y; }else{ x = e.screenX; y = e.screenY + 25; } var self=this; var savedFocus = dijit.getFocus(this); function closeAndRestoreFocus(){ // user has clicked on a menu or popup dijit.focus(savedFocus); dijit.popup.close(self); } var res = dijit.popup.open({ popup: this, x: x, y: y, onExecute: closeAndRestoreFocus, onCancel: closeAndRestoreFocus, orient: this.isLeftToRight() ? 'L' : 'R' }); var v = dijit.getViewport(); if(res.y+res.h>v.h){ if(e.screenY-res.h>=0){ y = e.screenY - res.h; }else{ y = 0; } dijit.popup.close(this); // FIXME: Not very DRY here. // Reopening popup if the location was not good. res = dijit.popup.open({ popup: this, x: x, y: y, onExecute: closeAndRestoreFocus, onCancel: closeAndRestoreFocus, orient: this.isLeftToRight() ? 'L' : 'R' }); } console.log(dijit.getViewport()); this.focus(); this._onBlur = function(){ this.inherited('_onBlur', arguments); dijit.popup.close(this); } } this.menu = pMenu; }, selectTable: function(){ // selects table that is in focus var o = this.getTableInfo(); dojo.withGlobal(this.editor.window, "selectElement",dijit._editor.selection, [o.tbl]); }, launchInsertDialog: function(){ var w = new dojox.editor.plugins.EditorTableDialog({}); w.show(); var c = dojo.connect(w, "onBuildTable", this, function(obj){ dojo.disconnect(c); var res = this.editor.execCommand('inserthtml', obj.htmlText); // commenting this line, due to msg below //var td = this.editor.query("td", this.editor.byId(obj.id)); //HMMMM.... This throws a security error now. didn't used to. //this.editor.selectElement(td); }); }, launchModifyDialog: function(){ var o = this.getTableInfo(); console.log("LAUNCH DIALOG") var w = new dojox.editor.plugins.EditorModifyTableDialog({table:o.tbl}); w.show(); this.connect(w, "onSetTable", function(color){ // uhm... not sure whats going on here... var o = this.getTableInfo(); console.log("set color:", color) dojo.attr(o.td, "bgcolor", color); }); }, _initButton: function(){ this.command = this.commandName; this.label = this.editor.commands[this.command] = this._makeTitle(this.command); this.inherited(arguments); delete this.command; if(this.commandName != "colorTableCell") this.connect(this.button.domNode, "click", "modTable"); if(this.commandName=="tableContextMenu") this.button.domNode.display = "none"; this.onDisplayChanged(false); }, modTable: function(cmd, args){ // summary // Where each plugin performs its action // Note: not using execCommand. In spite of their presence in the // Editor as query-able plugins, I was not able to find any evidence // that they are supported (especially in NOT IE). If they are // supported in other browsers, it may help with the undo problem. // this.begEdit(); var o = this.getTableInfo(); var sw = (dojo.isString(cmd))?cmd : this.commandName; var r, c, i; var adjustColWidth = false; //console.log("modTable:", sw) switch(sw){ case "insertTableRowBefore": r = o.tbl.insertRow(o.trIndex); for(i=0;imike

"); this.editor.setValue(this.valBeforeUndo); this.editor.replaceValue(afterUndo); } this.editor.onDisplayChanged(); } }, makeColumnsEven: function(){ //summary // After changing column amount, change widths to // keep columns even // // the timeout helps prevent an occasional snafu setTimeout(dojo.hitch(this, function(){ var o = this.getTableInfo(true); var w = Math.floor(100/o.cols); o.tds.forEach(function(d){ dojo.attr(d, "width", w+"%"); }); }), 10); }, getTableInfo: function(forceNewData){ // summary // Gets the table in focus // Collects info on the table - see return params // return tablePluginHandler.getTableInfo(forceNewData); }, _makeTitle: function(str){ // Parses the commandName into a Title // based on camelCase var s = str.split(""), ns = []; dojo.forEach(str, function(c, i){ if(c.charCodeAt(0)<91 && i>0 && ns[i-1].charCodeAt(0)!=32){ ns.push(" "); } if(i==0) c = c.toUpperCase(); ns.push(c); }); return ns.join(""); }, getSelectedCells: function(){ // summary // Gets the selected cells from the passed table // Returns: array of TDs or empty array // var cells = []; var tbl = this.getTableInfo().tbl; var tds = tablePluginHandler._prepareTable(tbl); var e = this.editor; var r; if(!dojo.isIE){ r = dijit.range.getSelection(e.window); var foundFirst=false; var foundLast=false; if(r.anchorNode && r.anchorNode.tagName && r.anchorNode.tagName.toLowerCase()=="tr"){ // Firefox // Geez - and I thought IE was hard.... // In the Editor, FF refuses to grab a multiple cell selection at the TD level // in spite of multiple selection techniques // Resorting to going ahead with its TR selection and selecting // the entire row // Has no problem with individual cell selection though // var trs = dojo.query("tr", tbl); var rows = []; trs.forEach(function(tr, i){ if(!foundFirst && (tr == r.anchorNode || tr == r.focusNode)){ rows.push(tr); foundFirst = true; if(r.anchorNode == r.focusNode){ foundLast = true; } }else if(foundFirst && !foundLast){ rows.push(tr); if(tr == r.anchorNode || tr == r.focusNode){ foundLast = true; } } }); dojo.forEach(rows, function(tr){ cells = cells.concat(dojo.query("td", tr)); }, this); }else{ // Safari // Yay! It works like expected // Getting the cells from anchorNode to focusNode // tds.forEach(function(td, i){ if(!foundFirst && (td.id == r.anchorNode.parentNode.id || td.id == r.focusNode.parentNode.id)){ cells.push(td); foundFirst = true; if(r.anchorNode.parentNode.id == r.focusNode.parentNode.id){ foundLast = true; } }else if(foundFirst && !foundLast){ cells.push(td) if(td.id == r.focusNode.parentNode.id || td.id == r.anchorNode.parentNode.id){ foundLast = true; } } }); console.log("SAF CELLS:", cells); } } if(dojo.isIE){ // IE // Although the code is tight - there's some funkiness here // Can only get the htmlText, so we add IDs to the cells (above) // And pull them from the htmlText, then search for those cells // r = document.selection.createRange() var str = r.htmlText.match(/id=\w*/g); dojo.forEach(str, function(a){ var id = a.substring(3, a.length); cells.push(e.byId(id)); }, this) } return cells; } } ); dojo.provide("dojox.editor.plugins.EditorTableDialog"); dojo.require("dijit.Dialog"); dojo.require("dijit.form.TextBox"); dojo.require("dijit.form.FilteringSelect"); dojo.require("dijit.form.Button"); dojo.declare("dojox.editor.plugins.EditorTableDialog", [dijit.Dialog], { // summary // Dialog box with options for table creation // baseClass:"EditorTableDialog", widgetsInTemplate:true, templatePath: dojo.moduleUrl("dojox.editor.plugins", "resources/insertTable.html"), postMixInProperties: function(){ var messages = dojo.i18n.getLocalization("dojox.editor.plugins", "TableDialog", this.lang); dojo.mixin(this, messages); this.inherited(arguments); }, postCreate: function(){ dojo.addClass(this.domNode, this.baseClass); //FIXME - why isn't Dialog accepting the baseClass? this.inherited(arguments); }, onInsert: function(){ console.log("insert"); var rows = this.selectRow.attr("value") || 1, cols = this.selectCol.attr("value") || 1, width = this.selectWidth.attr("value"), widthType = this.selectWidthType.attr("value"), border = this.selectBorder.attr("value"), pad = this.selectPad.attr("value"), space = this.selectSpace.attr("value"), _id = "tbl_"+(new Date().getTime()), t = '\n'; for(var r=0;r \n'; } t += '\t\n'; } t += '
'; //console.log(t); this.onBuildTable({htmlText:t, id:_id}); this.hide(); }, onBuildTable: function(tableText){ //stub";s:7:"summary";s:0:"";}s:44:"dojox.editor.plugins.EditorModifyTableDialog";a:4:{s:4:"type";s:8:"Function";s:6:"chains";a:2:{s:9:"prototype";a:1:{i:0;s:12:"dijit.Dialog";}s:4:"call";a:1:{i:0;s:12:"dijit.Dialog";}}s:9:"classlike";b:1;s:7:"summary";s:0:"";}s:54:"dojox.editor.plugins.EditorModifyTableDialog.baseClass";a:2:{s:9:"prototype";s:44:"dojox.editor.plugins.EditorModifyTableDialog";s:7:"summary";s:0:"";}s:62:"dojox.editor.plugins.EditorModifyTableDialog.widgetsInTemplate";a:2:{s:9:"prototype";s:44:"dojox.editor.plugins.EditorModifyTableDialog";s:7:"summary";s:0:"";}s:50:"dojox.editor.plugins.EditorModifyTableDialog.table";a:2:{s:9:"prototype";s:44:"dojox.editor.plugins.EditorModifyTableDialog";s:7:"summary";s:0:"";}s:54:"dojox.editor.plugins.EditorModifyTableDialog.tableAtts";a:2:{s:9:"prototype";s:44:"dojox.editor.plugins.EditorModifyTableDialog";s:7:"summary";s:0:"";}s:30:"this.editor.getAncestorElement";a:4:{s:4:"type";s:8:"Function";s:10:"parameters";a:1:{s:7:"tagName";a:1:{s:4:"type";s:0:"";}}s:6:"source";s:97:" return dojo.withGlobal(this.window, "getAncestorElement",dijit._editor.selection, [tagName]);";s:7:"summary";s:0:"";}s:30:"this.editor.hasAncestorElement";a:4:{s:4:"type";s:8:"Function";s:10:"parameters";a:1:{s:7:"tagName";a:1:{s:4:"type";s:0:"";}}s:6:"source";s:113:" return true return dojo.withGlobal(this.window, "hasAncestorElement",dijit._editor.selection, [tagName]);";s:7:"summary";s:0:"";}s:25:"this.editor.selectElement";a:4:{s:4:"type";s:8:"Function";s:10:"parameters";a:1:{s:4:"elem";a:1:{s:4:"type";s:0:"";}}s:6:"source";s:82:" dojo.withGlobal(this.window, "selectElement",dijit._editor.selection, [elem]);";s:7:"summary";s:0:"";}s:16:"this.editor.byId";a:4:{s:4:"type";s:8:"Function";s:10:"parameters";a:1:{s:2:"id";a:1:{s:4:"type";s:0:"";}}s:6:"source";s:60:" return dojo.withGlobal(this.window, "byId", dojo, [id]);";s:7:"summary";s:0:"";}s:17:"this.editor.query";a:4:{s:4:"type";s:8:"Function";s:10:"parameters";a:3:{s:3:"arg";a:1:{s:4:"type";s:0:"";}s:5:"scope";a:1:{s:4:"type";s:0:"";}s:15:"returnFirstOnly";a:1:{s:4:"type";s:0:"";}}s:6:"source";s:2667:"dojo.provide("dojox.editor.plugins.TablePlugins"); dojo.require("dijit._editor._Plugin"); dojo.require("dijit._editor.selection"); dojo.require("dijit.Menu"); dojo.require("dojo.i18n"); dojo.requireLocalization("dojox.editor.plugins", "TableDialog"); dojo.experimental("dojox.editor.plugins.TablePlugins"); // summary: // A series of plugins that give the Editor the ability to create and edit // HTML tables. See the end of this document for all avaiable plugins // and dojox/editorPlugins/tests/editorTablePlugs.html for an example // // example: // |
// | Editor text is here // |
// // TODO: // Currently not supporting merging or splitting cells // // FIXME: Undo is very buggy, and therefore unimeplented in all browsers // except IE - which itself has only been lightly tested. // // FIXME: Selecting multiple table cells in Firefox looks to be impossible. // This affect the 'colorTableCell' plugin. Cells can still be // colored individually or in rows. dojo.declare("dojox.editor.plugins.GlobalTableHandler", dijit._editor._Plugin,{ // summary: // A global object that handles common tasks for all the plugins. Since // there are several plugins that are all calling common methods, it's preferable // that they call a centralized location that either has a set variable or a // timeout to only repeat code-heavy calls when necessary. // tablesConnected:false, currentlyAvailable: false, alwaysAvailable:false, availableCurrentlySet:false, initialized:false, tableData: null, shiftKeyDown:false, editorDomNode: null, undoEnabled: dojo.isIE, //FIXME: doMixins: function(){ dojo.mixin(this.editor,{ getAncestorElement: function(tagName){ return dojo.withGlobal(this.window, "getAncestorElement",dijit._editor.selection, [tagName]); }, hasAncestorElement: function(tagName){ return true return dojo.withGlobal(this.window, "hasAncestorElement",dijit._editor.selection, [tagName]); }, selectElement: function(elem){ dojo.withGlobal(this.window, "selectElement",dijit._editor.selection, [elem]); }, byId: function(id){ return dojo.withGlobal(this.window, "byId", dojo, [id]); }, query: function(arg, scope, returnFirstOnly){ // this shortcut is dubious - not sure scoping is necessary var ar = dojo.withGlobal(this.window, "query", dojo, [arg, scope]); return (returnFirstOnly) ? ar[0] : ar;";s:7:"summary";s:0:"";}s:4:"this";a:2:{s:6:"mixins";a:1:{s:6:"normal";a:2:{i:0;s:8:"messages";i:1;s:8:"messages";}}s:7:"summary";s:0:"";}s:18:"tablePluginHandler";a:1:{s:7:"summary";s:0:"";}s:3:"cmd";a:1:{s:7:"summary";s:0:"";}s:8:"o.plugin";a:1:{s:7:"summary";s:0:"";}s:20:"dojox.editor.plugins";a:2:{s:4:"type";s:6:"Object";s:7:"summary";s:0:"";}s:12:"dojox.editor";a:2:{s:4:"type";s:6:"Object";s:7:"summary";s:0:"";}s:5:"dojox";a:2:{s:4:"type";s:6:"Object";s:7:"summary";s:0:"";}}