You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by jk...@apache.org on 2006/09/29 05:43:06 UTC
svn commit: r451106 [26/40] - in /tapestry/tapestry4/trunk: ./
tapestry-framework/src/java/org/apache/tapestry/asset/
tapestry-framework/src/js/dojo/ tapestry-framework/src/js/dojo/src/
tapestry-framework/src/js/dojo/src/animation/ tapestry-framework/s...
Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Plugin/ContextMenu.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Plugin/ContextMenu.js?view=auto&rev=451106
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Plugin/ContextMenu.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Plugin/ContextMenu.js Thu Sep 28 20:42:39 2006
@@ -0,0 +1,243 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.widget.Editor2Plugin.ContextMenu");
+
+dojo.require("dojo.widget.Menu2");
+
+dojo.event.topic.subscribe("dojo.widget.Editor2::onLoad", function(editor){
+ var p = new dojo.widget.Editor2Plugin.ContextMenu(editor);
+});
+dojo.widget.Editor2Plugin.ContextMenuManager = {
+ menuGroups: ['Generic', 'Link', 'Anchor', 'Image', 'List', 'Table'],
+ _registeredGroups: {},
+ registerGroup: function(name, handler){
+ if(this._registeredGroups[name]){
+ alert("dojo.widget.Editor2Plugin.ContextMenuManager.registerGroup: menu group "+name+"is already registered. Ignored.");
+ return;
+ }
+ this._registeredGroups[name] = handler;
+ },
+ removeGroup: function(name){
+ delete this._registeredGroups[name];
+ },
+ getGroup: function(name, contextmenuplugin){
+ if(this._registeredGroups[name]){
+ var item = this._registeredGroups[name](name, contextmenuplugin);
+ if(item){
+ return item;
+ }
+ }
+ switch(name){
+ case 'Generic':
+ case 'Link':
+ case 'Image':
+ return new dojo.widget.Editor2Plugin[name+"ContextMenu"](contextmenuplugin);
+ //TODO
+ case 'Anchor':
+ case 'List':
+ }
+ }
+};
+
+dojo.declare("dojo.widget.Editor2Plugin.ContextMenu", null,
+ function(editor){
+ this.groups = [];
+ this.separators = [];
+ this.editor = editor;
+ this.editor.registerLoadedPlugin(this);
+ this.contextMenu = dojo.widget.createWidget("PopupMenu2", {});
+ dojo.body().appendChild(this.contextMenu.domNode);
+ this.contextMenu.bindDomNode(this.editor.document.body);
+
+ dojo.event.connect(this.contextMenu, "aboutToShow", this, "aboutToShow");
+ dojo.event.connect(this.editor, "destroy", this, "destroy");
+
+ this.setup();
+ },
+ {
+ setup: function(){
+ var gs = dojo.widget.Editor2Plugin.ContextMenuManager.menuGroups;
+ for(var i in gs){
+ var g = dojo.widget.Editor2Plugin.ContextMenuManager.getGroup(gs[i], this);
+ if(g){
+ this.groups.push(g);
+ }
+ }
+ },
+ aboutToShow: function(){
+ var first = true;
+ for(var i in this.groups){
+ if(i>0 && this.separators.length != this.groups.length-1){
+ this.separators.push(dojo.widget.createWidget("MenuSeparator2", {}));
+ this.contextMenu.addChild(this.separators[this.separators.length-1]);
+ }
+ if(this.groups[i].refresh()){
+ if(i>0){
+ if(first){
+ this.separators[i-1].hide();
+ }else{
+ this.separators[i-1].show();
+ }
+ }
+ if(first){ first = false; }
+ }else{
+ if(i>0){
+ this.separators[i-1].hide();
+ }
+ }
+ }
+ },
+ destroy: function(){
+ this.editor.unregisterLoadedPlugin(this);
+ delete this.groups;
+ delete this.separators;
+ this.contextMenu.destroy();
+ delete this.contextMenu;
+ }
+});
+
+dojo.widget.defineWidget(
+ "dojo.widget.Editor2ContextMenuItem",
+ dojo.widget.MenuItem2, {
+ command: null,
+ postCreate: function(){
+ if(!this.command){
+ this.command = this.caption;
+ }
+
+ dojo.widget.Editor2ContextMenuItem.superclass.postCreate.apply(this, arguments);
+ },
+ setup: function(){
+ this.cmd = dojo.widget.Editor2Manager.getCommand(this.command);
+ if(!this.cmd){
+ alert("command " + this.command + " is not recognized!");
+ }
+ },
+ onClick: function(){
+ if(!this.cmd){
+ this.setup();
+ }
+ if(this.cmd){
+ this.cmd.execute();
+ }
+ },
+ refresh: function(){
+ if(!this.cmd){
+ this.setup();
+ }
+ if(this.cmd){
+ if(this.cmd.getState() == dojo.widget.Editor2Manager.commandState.Disabled){
+ this.disable();
+ return false;
+ }else{
+ this.enable();
+ return true;
+ }
+ }
+ },
+ //improve performance by skipping animation
+ hide: function(){
+ this.domNode.style.display = "none";
+ },
+ show: function(){
+ this.domNode.style.display = "";
+ }
+});
+dojo.declare("dojo.widget.Editor2Plugin.SimpleContextMenu", null,
+ function(contextmenuplugin){
+ this.contextMenu = contextmenuplugin.contextMenu;
+ this.items = [];
+
+ dojo.event.connect(contextmenuplugin, "destroy", this, "destroy");
+ },
+ {
+ refresh: function(){
+ if(!this.items.length){
+ this.createItems();
+ for(var i in this.items){
+ this.contextMenu.addChild(this.items[i]);
+ }
+ }
+
+ return this.checkVisibility();
+ },
+ destroy: function(){
+ this.contextmenu = null;
+ delete this.items;
+ delete this.contextMenu;
+ },
+ //implement this to fill in the menu items
+ createItems: function(){ },
+
+ //overload this to show/hide items
+ checkVisibility: function(){
+ var show = false;
+ for(var i in this.items){
+ show = show || this.items[i].refresh();
+ }
+ var action = show ? "show" : "hide";
+ for(var i in this.items){
+ this.items[i][action]();
+ }
+ return show;
+ }
+});
+dojo.declare("dojo.widget.Editor2Plugin.GenericContextMenu",
+ dojo.widget.Editor2Plugin.SimpleContextMenu,
+{
+ createItems: function(){
+ this.items.push(dojo.widget.createWidget("Editor2ContextMenuItem", {caption: "Cut", iconClass: "dojoE2TBIcon dojoE2TBIcon_Cut"}));
+ this.items.push(dojo.widget.createWidget("Editor2ContextMenuItem", {caption: "Copy", iconClass: "dojoE2TBIcon dojoE2TBIcon_Copy"}));
+ this.items.push(dojo.widget.createWidget("Editor2ContextMenuItem", {caption: "Paste", iconClass: "dojoE2TBIcon dojoE2TBIcon_Paste"}));
+ }
+});
+dojo.declare("dojo.widget.Editor2Plugin.LinkContextMenu",
+ dojo.widget.Editor2Plugin.SimpleContextMenu,
+{
+ createItems: function(){
+ this.items.push(dojo.widget.createWidget("Editor2ContextMenuItem", {caption: "Modify Link", command: 'createlink', iconClass: "dojoE2TBIcon dojoE2TBIcon_Link"}));
+ this.items.push(dojo.widget.createWidget("Editor2ContextMenuItem", {caption: "Remove Link", command: 'unlink', iconClass: "dojoE2TBIcon dojoE2TBIcon_UnLink"}));
+ },
+ checkVisibility: function(){
+ var show = this.items[1].refresh();
+ if(show){
+ this.items[0].refresh();
+ for(var i in this.items){
+ this.items[i].show();
+ }
+ }else{
+ for(var i in this.items){
+ this.items[i].hide();
+ }
+ }
+
+ return show;
+ }
+});
+dojo.declare("dojo.widget.Editor2Plugin.ImageContextMenu",
+ dojo.widget.Editor2Plugin.SimpleContextMenu,
+{
+ createItems: function(){
+ this.items.push(dojo.widget.createWidget("Editor2ContextMenuItem", {caption: "Edit Image", command: 'insertimage', iconClass: "dojoE2TBIcon dojoE2TBIcon_Image"}));
+ },
+ checkVisibility: function(){
+ var curInst = dojo.widget.Editor2Manager.getCurrentInstance();
+ var img = dojo.withGlobal(curInst.window, "getSelectedElement", dojo.html.selection);
+
+ if(img && img.tagName.toLowerCase() == 'img'){
+ this.items[0].show();
+ return true;
+ }else{
+ this.items[0].hide();
+ return false;
+ }
+ }
+});
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Plugin/ContextMenu.js
------------------------------------------------------------------------------
svn:eol-style = native
Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Plugin/CreateLinkDialog.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Plugin/CreateLinkDialog.js?view=auto&rev=451106
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Plugin/CreateLinkDialog.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Plugin/CreateLinkDialog.js Thu Sep 28 20:42:39 2006
@@ -0,0 +1,74 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.widget.Editor2Plugin.CreateLinkDialog");
+dojo.provide("dojo.widget.Editor2CreateLinkDialog");
+
+dojo.widget.defineWidget(
+ "dojo.widget.Editor2CreateLinkDialog",
+ dojo.widget.Editor2DialogContent,
+{
+ templatePath: dojo.uri.dojoUri("src/widget/templates/Editor2/Dialog/createlink.html"),
+
+ editableAttributes: ['href', 'target', 'class'],
+ loadContent: function(){
+ var curInst = dojo.widget.Editor2Manager.getCurrentInstance();
+
+ this.linkNode = dojo.withGlobal(curInst.window, "getAncestorElement", dojo.html.selection, ['a']);
+ var linkAttributes = {};
+ this.extraAttribText = "";
+ if(this.linkNode){
+ var attrs = this.linkNode.attributes;
+ for(var i=0; i<attrs.length; i++) {
+ if(dojo.lang.find(this.editableAttributes, attrs[i].name.toLowerCase())>-1){
+ linkAttributes[attrs[i].name] = attrs[i].value;
+ }else{
+ //IE lists all attributes, even default ones, filter them
+ if(attrs[i].specified == undefined || attrs[i].specified){
+ this.extraAttribText += attrs[i].name + '="'+attrs[i].value+'" ';
+ }
+ }
+ }
+ }else{
+ var html = dojo.withGlobal(curInst.window, "getSelectedText", dojo.html.selection);
+ if(html == null || html.length == 0){
+ alert("Please select some text to create a link.");
+ return false;//do not show the dialog
+ }
+ }
+
+ for(var i=0; i<this.editableAttributes.length; ++i){
+ name = this.editableAttributes[i];
+ this["link_"+name].value = (linkAttributes[name] == undefined) ? "" : linkAttributes[name] ;
+ }
+ return true;
+ },
+ ok: function(){
+ var curInst = dojo.widget.Editor2Manager.getCurrentInstance();
+ if(!this.linkNode){
+ var html = dojo.withGlobal(curInst.window, "getSelectedHtml", dojo.html.selection);
+ }else{
+ var html = this.linkNode.innerHTML;
+ dojo.withGlobal(curInst.window, "selectElement", dojo.html.selection, [this.linkNode]);
+ }
+
+ var attstr='';
+ for(var i=0; i<this.editableAttributes.length; ++i){
+ name = this.editableAttributes[i];
+ var value = this["link_"+name].value;
+ if(value.length > 0){
+ attstr += name + '="'+value+'" ';
+ }
+ }
+ curInst.execCommand('inserthtml', '<a '+attstr+this.extraAttribText+'>'+html+'</a>');
+
+ this.cancel();
+ }
+});
\ No newline at end of file
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Plugin/CreateLinkDialog.js
------------------------------------------------------------------------------
svn:eol-style = native
Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Plugin/FindReplace.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Plugin/FindReplace.js?view=auto&rev=451106
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Plugin/FindReplace.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Plugin/FindReplace.js Thu Sep 28 20:42:39 2006
@@ -0,0 +1,74 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.widget.Editor2Plugin.FindReplace");
+
+dojo.require("dojo.widget.Editor2");
+
+//TODO replace, better GUI
+
+dojo.declare("dojo.widget.Editor2Plugin.FindCommand", dojo.widget.Editor2DialogCommand,{
+ SearchOption: {
+ CaseSensitive: 4,
+ SearchBackwards: 64,
+ WholeWord: 2,
+ WrapSearch: 128
+ },
+ find: function(text, option){
+ var curInst = dojo.widget.Editor2Manager.getCurrentInstance();
+ if(curInst){
+ curInst.focus();
+ if(window.find){ //moz
+ curInst.window.find(text,
+ option & this.SearchOption.CaseSensitive ? true : false,
+ option & this.SearchOption.SearchBackwards ? true : false,
+ option & this.SearchOption.WrapSearch ? true : false,
+ option & this.SearchOption.WholeWord ? true : false
+ );
+ }else if(dojo.body().createTextRange){ //IE
+ var range = curInst.document.body.createTextRange();
+ var found = range.findText(text, (option&this.SearchOption.SearchBackwards)?1:-1, option );
+ if(found){
+ range.scrollIntoView() ;
+ range.select() ;
+ }else{
+ alert("Can not find "+text+" in the document");
+ }
+ }else{
+ alert("No idea how to search in this browser. Please submit patch if you know.");
+ }
+ }
+ }
+});
+
+dojo.widget.Editor2Manager.registerCommand("Find", new dojo.widget.Editor2Plugin.FindCommand('find',
+ {contentFile: "dojo.widget.Editor2Plugin.FindReplaceDialog",
+ contentClass: "Editor2FindDialog",
+ title: "Find", width: "350px", height: "150px", modal: false}));
+dojo.widget.Editor2Manager.registerCommand("Replace", new dojo.widget.Editor2DialogCommand('replace',
+ {contentFile: "dojo.widget.Editor2Plugin.FindReplaceDialog",
+ contentClass: "Editor2ReplaceDialog",
+ href: dojo.uri.dojoUri("src/widget/templates/Editor2/Dialog/replace.html"),
+ title: "Replace", width: "350px", height: "200px", modal: false}));
+
+dojo.widget.Editor2Plugin.FindReplace = function(name){
+ var name = name.toLowerCase();
+
+ var item;
+ if(name == 'replace'){
+ item = new dojo.widget.Editor2ToolbarButton('Replace');
+ }else if(name == 'find') {
+ item = new dojo.widget.Editor2ToolbarButton('Find');
+ }
+
+ return item;
+}
+
+dojo.widget.Editor2ToolbarItemManager.registerHandler(dojo.widget.Editor2Plugin.FindReplace);
\ No newline at end of file
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Plugin/FindReplace.js
------------------------------------------------------------------------------
svn:eol-style = native
Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Plugin/FindReplaceDialog.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Plugin/FindReplaceDialog.js?view=auto&rev=451106
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Plugin/FindReplaceDialog.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Plugin/FindReplaceDialog.js Thu Sep 28 20:42:39 2006
@@ -0,0 +1,51 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.widget.Editor2Plugin.FindReplaceDialog");
+dojo.provide("dojo.widget.Editor2FindDialog");
+dojo.provide("dojo.widget.Editor2ReplaceDialog");
+
+dojo.widget.defineWidget(
+ "dojo.widget.Editor2FindDialog",
+ dojo.widget.Editor2DialogContent,
+{
+ templatePath: dojo.uri.dojoUri("src/widget/templates/Editor2/Dialog/find.html"),
+
+ find: function(){
+ var findcmd = dojo.widget.Editor2Manager.getCommand('find');
+ var option = 0;
+
+ if(this["find_option_casesens"].checked){
+ option |= findcmd.SearchOption.CaseSensitive;
+ }
+ if(this["find_option_backwards"].checked){
+ option |= findcmd.SearchOption.SearchBackwards;
+ }
+
+ if(this["find_option_wholeword"].checked){
+ option |= findcmd.SearchOption.WholeWord;
+ }
+ findcmd.find(this["find_text"].value, option);
+ }
+});
+
+dojo.widget.defineWidget(
+ "dojo.widget.Editor2ReplaceDialog",
+ dojo.widget.Editor2DialogContent,
+{
+ templatePath: dojo.uri.dojoUri("src/widget/templates/Editor2/Dialog/replace.html"),
+
+ replace: function(){
+ alert("not implemented yet");
+ },
+ replaceAll: function(){
+ alert("not implemented yet");
+ }
+});
\ No newline at end of file
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Plugin/FindReplaceDialog.js
------------------------------------------------------------------------------
svn:eol-style = native
Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Plugin/InsertImageDialog.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Plugin/InsertImageDialog.js?view=auto&rev=451106
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Plugin/InsertImageDialog.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Plugin/InsertImageDialog.js Thu Sep 28 20:42:39 2006
@@ -0,0 +1,65 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.widget.Editor2Plugin.InsertImageDialog");
+dojo.provide("dojo.widget.Editor2InsertImageDialog");
+
+dojo.widget.defineWidget(
+ "dojo.widget.Editor2InsertImageDialog",
+ dojo.widget.Editor2DialogContent,
+{
+ templatePath: dojo.uri.dojoUri("src/widget/templates/Editor2/Dialog/insertimage.html"),
+
+ editableAttributes: ['src', 'alt', 'width', 'height', 'hspace', 'vspace', 'border', 'align'],
+ loadContent: function(){
+ var curInst = dojo.widget.Editor2Manager.getCurrentInstance();
+ this.imageNode = dojo.withGlobal(curInst.window, "getSelectedElement", dojo.html.selection);
+ if(!this.imageNode){
+ this.imageNode = dojo.withGlobal(curInst.window, "getAncestorElement", dojo.html.selection, ['img']);
+ }
+ var imageAttributes = {};
+ this.extraAttribText = "";
+ if(this.imageNode){
+ var attrs = this.imageNode.attributes;
+ for(var i=0; i<attrs.length; i++) {
+ if(dojo.lang.find(this.editableAttributes, attrs[i].name.toLowerCase())>-1){
+ imageAttributes[attrs[i].name] = attrs[i].value;
+ }else{
+ this.extraAttribText += attrs[i].name + '="'+attrs[i].value+'" ';
+ }
+ }
+ }
+ for(var i=0; i<this.editableAttributes.length; ++i){
+ name = this.editableAttributes[i];
+ this["image_"+name].value = (imageAttributes[name] == undefined) ? "" : imageAttributes[name] ;
+ }
+ return true;
+ },
+ ok: function(){
+ var curInst = dojo.widget.Editor2Manager.getCurrentInstance();
+ var insertcmd = dojo.widget.Editor2Manager.getCommand('inserthtml');
+ var option = 0;
+
+ var attstr='';
+ for(var i=0; i<this.editableAttributes.length; ++i){
+ name = this.editableAttributes[i];
+ var value = this["image_"+name].value;
+ if(value.length > 0){
+ attstr += name + '="'+value+'" ';
+ }
+ }
+ if(this.imageNode){
+ dojo.withGlobal(curInst.window, "selectElement", dojo.html.selection, [this.imageNode]);
+ }
+ insertcmd.execute('<img '+attstr+this.extraAttribText+'/>');
+
+ this.cancel();
+ }
+});
\ No newline at end of file
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Plugin/InsertImageDialog.js
------------------------------------------------------------------------------
svn:eol-style = native
Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Plugin/InsertTableDialog.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Plugin/InsertTableDialog.js?view=auto&rev=451106
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Plugin/InsertTableDialog.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Plugin/InsertTableDialog.js Thu Sep 28 20:42:39 2006
@@ -0,0 +1,148 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.widget.Editor2Plugin.InsertTableDialog");
+dojo.provide("dojo.widget.Editor2InsertTableDialog");
+
+dojo.widget.defineWidget(
+ "dojo.widget.Editor2InsertTableDialog",
+ dojo.widget.Editor2DialogContent,
+{
+ templatePath: dojo.uri.dojoUri("src/widget/templates/Editor2/Dialog/inserttable.html"),
+
+ editableAttributes: ['summery', 'height', 'cellspacing', 'cellpadding', 'border', 'align'],
+
+ loadContent: function(){
+ var curInst = dojo.widget.Editor2Manager.getCurrentInstance();
+ this.tableNode = dojo.withGlobal(curInst.window, "getSelectedElement", dojo.html.selection);
+ if(!this.tableNode || this.tableNode.tagName.toLowerCase() != 'table'){
+ this.tableNode = dojo.withGlobal(curInst.window, "getAncestorElement", dojo.html.selection, ['table']);
+ }
+
+ var tableAttributes = {};
+ this.extraAttribText = "";
+ if(this.tableNode){
+ this["table_rows"].value = this.tableNode.rows.length;
+ this["table_rows"].disabled = true;
+ this["table_cols"].value = this.tableNode.rows[0].cells.length;
+ this["table_cols"].disabled = true;
+
+ if (this.tableNode.caption){
+ this["table_caption"].value = this.tableNode.caption.innerHTML;
+ }else{
+ this["table_caption"].value = "";
+ }
+
+ var width = this.tableNode.style.width || this.tableNode.width;
+ if(width){
+ this["table_width"].value = parseInt(width);
+ if (width.indexOf('%') > -1){
+ this["table_widthtype"].value = "percent";
+ }else{
+ this["table_widthtype"].value = "pixels";
+ }
+ }else{
+ this["table_width"].value = "100";
+ }
+
+ var height = this.tableNode.style.height || this.tableNode.height;
+ if(height){
+ this["table_height"].value = parseInt(width);
+ }else{
+ this["table_height"].value = "";
+ }
+
+ var attrs = this.tableNode.attributes;
+ for(var i=0; i<attrs.length; i++) {
+ if(dojo.lang.find(this.editableAttributes, attrs[i].name.toLowerCase())>-1){
+ tableAttributes[attrs[i].name] = attrs[i].value;
+ }else{
+ this.extraAttribText += attrs[i].name + '="'+attrs[i].value+'" ';
+ }
+ }
+ }else{
+ this["table_rows"].value = 3;
+ this["table_rows"].disabled = false;
+ this["table_cols"].value = 2;
+ this["table_cols"].disabled = false;
+ this["table_width"].value = 100;
+ this["table_widthtype"].value = "percent";
+ this["table_height"].value = "";
+ }
+
+ for(var i=0; i<this.editableAttributes.length; ++i){
+ name = this.editableAttributes[i];
+ this["table_"+name].value = (tableAttributes[name] == undefined) ? "" : tableAttributes[name];
+ if(name == 'height' && tableAttributes[name] != undefined){
+ this["table_"+name].value = tableAttributes[name];
+ }
+ }
+ return true;
+ },
+ ok: function(){
+ var curInst = dojo.widget.Editor2Manager.getCurrentInstance();
+ var args = {};
+
+ args['rows'] = this["table_rows"].value;
+ args['cols'] = this["table_cols"].value;
+ args['caption'] = this["table_caption"].value;
+ args["tableattrs"] = "";
+ if(this["table_widthtype"].value == "percent"){
+ args["tableattrs"] += 'width="'+this["table_width"].value +'%" ';
+ }else{
+ args["tableattrs"] += 'width="'+this["table_width"].value +'px" ';
+ }
+ for(var i=0; i<this.editableAttributes.length; ++i){
+ var name = this.editableAttributes[i];
+ var value = this["table_"+name].value;
+ if(value.length > 0){
+ args["tableattrs"] += name + '="'+value+'" ';
+ }
+ }
+
+ if(!args["tableattrs"]){
+ args["tableattrs"] = "";
+ }
+
+ //show the border in IE by applying a custom class
+ if(dojo.render.html.ie && !this["table_border"].value){
+ args["tableattrs"] += 'class="dojoShowIETableBorders" ';
+ }
+
+ var html = "<table "+args["tableattrs"]+">";
+ if(args['caption']){
+ html += "<caption>"+args["caption"]+"</caption>";
+ }
+ var outertbody = "<tbody>";
+ if(this.tableNode){
+ //retain the content
+ var tbody = this.tableNode.getElementsByTagName("tbody")[0];
+ outertbody = tbody.outerHTML;
+ if(!outertbody){
+ var cnode = tbody.cloneNode(true);
+ var tmpnode = tbody.ownerDocument.createElement("div");
+ tmpnode.appendChild(cnode);
+ outertbody = tmpnode.innerHTML;
+ }
+ //TODO: save current selection and restore it later
+ dojo.withGlobal(curInst.window, "selectElement", dojo.html.selection, [this.tableNode]);
+ }else{
+ var cols = "<tr>";
+ for (var i = 0; i < +args.cols; i++) { cols += "<td></td>"; }
+ cols += "</tr>";
+ for (var i = 0; i < args.rows; i++) { outertbody += cols; }
+ outertbody += "</tbody>";
+ }
+ html += outertbody+"</table>";
+ curInst.execCommand("inserthtml", html);
+
+ this.cancel();
+ }
+});
\ No newline at end of file
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Plugin/InsertTableDialog.js
------------------------------------------------------------------------------
svn:eol-style = native
Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Plugin/SimpleSignalCommands.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Plugin/SimpleSignalCommands.js?view=auto&rev=451106
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Plugin/SimpleSignalCommands.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Plugin/SimpleSignalCommands.js Thu Sep 28 20:42:39 2006
@@ -0,0 +1,72 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+/*
+ * This plugin adds save() and insertImage() to Editor2 widget, and add two commands for each
+ * of them. When the corresponding button is clicked in the toolbar, the added function in the
+ * Editor2 widget is called. This mimics the original Editor2 behavior. If you want to have other
+ * signals on the Editor2 widget, add them to dojo.widget.Editor2Plugin.SimpleSignalCommands.signals
+ * NOTE: Please consider writing your own Editor2 plugin rather than using this backward compatible
+ * plugin
+ * ATTENTION: This plugin overwrites the new built-in insertImage dialog. (If this is not desired, set
+ * dojo.widget.Editor2Plugin.SimpleSignalCommands.signals to not contain insertImage)
+ */
+
+//uncomment this line to add save only (do not overwrite the new built-in insertImage dialog
+//this line should present before require dojo.widget.Editor2Plugin.SimpleSignalCommands
+//dojo.widget.Editor2Plugin['SimpleSignalCommands'] = {signals: ['save']};
+
+dojo.provide("dojo.widget.Editor2Plugin.SimpleSignalCommands");
+
+dojo.require("dojo.widget.Editor2");
+
+dojo.declare("dojo.widget.Editor2Plugin.SimpleSignalCommand", dojo.widget.Editor2Command,
+ function(name){
+ if(dojo.widget.Editor2.prototype[name] == undefined){
+ dojo.widget.Editor2.prototype[name] = function(){ dojo.debug("Editor2::"+name); };
+ }
+ },
+{
+ execute: function(){
+ var curInst = dojo.widget.Editor2Manager.getCurrentInstance();
+
+ if(curInst){
+ curInst[this._name]();
+ }
+ }
+});
+
+if(dojo.widget.Editor2Plugin['SimpleSignalCommands']){
+ dojo.widget.Editor2Plugin['_SimpleSignalCommands']=dojo.widget.Editor2Plugin['SimpleSignalCommands'];
+}
+
+dojo.widget.Editor2Plugin.SimpleSignalCommands = {
+ signals: ['save', 'insertImage'],
+ Handler: function(name){
+ if(name.toLowerCase() == 'save'){
+ return new dojo.widget.Editor2ToolbarButton('Save');
+ }else if(name.toLowerCase() == 'insertimage'){
+ return new dojo.widget.Editor2ToolbarButton('InsertImage');
+ }
+ },
+ registerAllSignalCommands: function(){
+ for(var i=0;i<this.signals.length;i++){
+ dojo.widget.Editor2Manager.registerCommand(this.signals[i],
+ new dojo.widget.Editor2Plugin.SimpleSignalCommand(this.signals[i]));
+ }
+ }
+};
+
+if(dojo.widget.Editor2Plugin['_SimpleSignalCommands']){
+ dojo.lang.mixin(dojo.widget.Editor2Plugin.SimpleSignalCommands, dojo.widget.Editor2Plugin['_SimpleSignalCommands']);
+}
+
+dojo.widget.Editor2Plugin.SimpleSignalCommands.registerAllSignalCommands();
+dojo.widget.Editor2ToolbarItemManager.registerHandler(dojo.widget.Editor2Plugin.SimpleSignalCommands.Handler);
\ No newline at end of file
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Plugin/SimpleSignalCommands.js
------------------------------------------------------------------------------
svn:eol-style = native
Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Plugin/TableOperation.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Plugin/TableOperation.js?view=auto&rev=451106
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Plugin/TableOperation.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Plugin/TableOperation.js Thu Sep 28 20:42:39 2006
@@ -0,0 +1,150 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.widget.Editor2Plugin.TableOperation");
+
+dojo.require("dojo.widget.Editor2");
+
+//subscribe to dojo.widget.RichText::init, not onLoad because after onLoad
+//the stylesheets for the editing areas are already applied and the prefilters
+//are executed, so we have to insert our own trick before that point
+dojo.event.topic.subscribe("dojo.widget.RichText::init", function(editor){
+ editor.__TableOperationShowBorder = false;
+
+ if(dojo.render.html.moz && false){
+ //include the css file to show table border when border=0
+ editor.__TableOperationShowBorder = true;
+ editor.addStyleSheet(dojo.uri.dojoUri("src/widget/templates/Editor2/showtableborder_gecko.css"));
+// editor.editingAreaStyleSheets.push(dojo.uri.dojoUri("src/widget/templates/Editor2/showtableborder_gecko.css"));
+ }else if(dojo.render.html.ie){
+ //add/remove a class to a table with border=0 to show the border when loading/saving
+ editor.contentDomPreFilters.push(dojo.widget.Editor2Plugin.TableOperation.showIETableBorder);
+ editor.contentDomPostFilters.push(dojo.widget.Editor2Plugin.TableOperation.removeIEFakeClass);
+ //include the css file to show table border when border=0
+// editor.__TableOperationShowBorder = true;
+// editor.addStyleSheet(dojo.uri.dojoUri("src/widget/templates/Editor2/showtableborder_ie.css"));
+// editor.editingAreaStyleSheets.push(dojo.uri.dojoUri("src/widget/templates/Editor2/showtableborder_ie.css"));
+ }
+ dojo.widget.Editor2Plugin.TableOperation.toggleTableBorderCommand.execute(editor);
+});
+
+dojo.widget.Editor2Plugin.TableOperation = {
+ getToolbarItem: function(name){
+ var name = name.toLowerCase();
+
+ var item;
+ switch(name){
+ case 'inserttable':
+ case 'toggletableborder':
+ item = new dojo.widget.Editor2ToolbarButton(name);
+ }
+
+ return item;
+ },
+ getContextMenuGroup: function(name, contextmenuplugin){
+ return new dojo.widget.Editor2Plugin.TableContextMenu(contextmenuplugin);
+ },
+ deleteTableCommand: {
+ execute: function(){
+ var curInst = dojo.widget.Editor2Manager.getCurrentInstance();
+ var table = dojo.withGlobal(curInst.window, "getAncestorElement", dojo.html.selection, ['table']);
+ if(table){
+ dojo.withGlobal(curInst.window, "selectElement", dojo.html.selection, [table]);
+ curInst.execCommand("inserthtml", " "); //Moz does not like an empty string, so a space here instead
+ }
+ },
+ getState: function(){
+ var curInst = dojo.widget.Editor2Manager.getCurrentInstance();
+ var table = dojo.withGlobal(curInst.window, "hasAncestorElement", dojo.html.selection, ['table']);
+ return table ? dojo.widget.Editor2Manager.commandState.Enabled : dojo.widget.Editor2Manager.commandState.Disabled;
+ },
+ destory: function(){}
+ },
+ toggleTableBorderCommand: {
+ execute: function(instance){
+ var curInst = instance || dojo.widget.Editor2Manager.getCurrentInstance();
+ if(curInst.__TableOperationShowBorder){
+ curInst.__TableOperationShowBorder = false;
+ if(dojo.render.html.moz){
+ curInst.removeStyleSheet(dojo.uri.dojoUri("src/widget/templates/Editor2/showtableborder_gecko.css"));
+ }else if(dojo.render.html.ie){
+ curInst.removeStyleSheet(dojo.uri.dojoUri("src/widget/templates/Editor2/showtableborder_ie.css"));
+ }
+ }else{
+ curInst.__TableOperationShowBorder = true;
+ if(dojo.render.html.moz){
+ curInst.addStyleSheet(dojo.uri.dojoUri("src/widget/templates/Editor2/showtableborder_gecko.css"));
+ }else if(dojo.render.html.ie){
+ curInst.addStyleSheet(dojo.uri.dojoUri("src/widget/templates/Editor2/showtableborder_ie.css"));
+ }
+ }
+ },
+ getState: function(){
+ var curInst = dojo.widget.Editor2Manager.getCurrentInstance();
+ return curInst.__TableOperationShowBorder ? dojo.widget.Editor2Manager.commandState.Latched : dojo.widget.Editor2Manager.commandState.Enabled;
+ },
+ destory: function(){}
+ },
+ showIETableBorder: function(dom){
+ var tables = dom.getElementsByTagName('table');
+ dojo.lang.forEach(tables, function(t){
+ dojo.html.addClass(t, "dojoShowIETableBorders");
+ });
+ return dom;
+ },
+ removeIEFakeClass: function(dom){
+ var tables = dom.getElementsByTagName('table');
+ dojo.lang.forEach(tables, function(t){
+ dojo.html.removeClass(t, "dojoShowIETableBorders");
+ });
+ return dom;
+ }
+}
+
+//register commands: toggletableborder, inserttable, deletetable
+dojo.widget.Editor2Manager.registerCommand("toggletableborder", dojo.widget.Editor2Plugin.TableOperation.toggleTableBorderCommand);
+
+dojo.widget.Editor2Manager.registerCommand("inserttable", new dojo.widget.Editor2DialogCommand('inserttable',
+ {contentFile: "dojo.widget.Editor2Plugin.InsertTableDialog",
+ contentClass: "Editor2InsertTableDialog",
+ title: "Insert/Edit Table", width: "450px", height: "250px"}));
+
+dojo.widget.Editor2Manager.registerCommand("deletetable", dojo.widget.Editor2Plugin.TableOperation.deleteTableCommand);
+
+//register toggletableborder and inserttable as toolbar item
+dojo.widget.Editor2ToolbarItemManager.registerHandler(dojo.widget.Editor2Plugin.TableOperation.getToolbarItem);
+
+//add context menu support if dojo.widget.Editor2Plugin.ContextMenu is included before this plugin
+if(dojo.widget.Editor2Plugin.ContextMenuManager){
+ dojo.widget.Editor2Plugin.ContextMenuManager.registerGroup('Table', dojo.widget.Editor2Plugin.TableOperation.getContextMenuGroup);
+
+ dojo.declare("dojo.widget.Editor2Plugin.TableContextMenu",
+ dojo.widget.Editor2Plugin.SimpleContextMenu,
+ {
+ createItems: function(){
+ this.items.push(dojo.widget.createWidget("Editor2ContextMenuItem", {caption: "Delete Table", command: 'deletetable'}));
+ this.items.push(dojo.widget.createWidget("Editor2ContextMenuItem", {caption: "Table Property", command: 'inserttable', iconClass: "TB_Button_Icon TB_Button_Table"}));
+ },
+ checkVisibility: function(){
+ var curInst = dojo.widget.Editor2Manager.getCurrentInstance();
+ var table = dojo.withGlobal(curInst.window, "hasAncestorElement", dojo.html.selection, ['table']);
+
+ if(dojo.withGlobal(curInst.window, "hasAncestorElement", dojo.html.selection, ['table'])){
+ this.items[0].show();
+ this.items[1].show();
+ return true;
+ }else{
+ this.items[0].hide();
+ this.items[1].hide();
+ return false;
+ }
+ }
+ });
+}
\ No newline at end of file
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Plugin/TableOperation.js
------------------------------------------------------------------------------
svn:eol-style = native
Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Plugin/ToolbarDndSupport.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Plugin/ToolbarDndSupport.js?view=auto&rev=451106
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Plugin/ToolbarDndSupport.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Plugin/ToolbarDndSupport.js Thu Sep 28 20:42:39 2006
@@ -0,0 +1,68 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+/*TODO:
+ * Add a command to toggle DnD support for a toolbar
+ * Save/restore order of toolbar/item
+ */
+dojo.provide("dojo.widget.Editor2Plugin.ToolbarDndSupport");
+dojo.require("dojo.dnd.*");
+
+dojo.event.topic.subscribe("dojo.widget.Editor2::preLoadingToolbar", function(editor){
+ dojo.dnd.dragManager.nestedTargets = true;
+ var p = new dojo.widget.Editor2Plugin.ToolbarDndSupport(editor);
+});
+
+dojo.declare("dojo.widget.Editor2Plugin.ToolbarDndSupport", null,{
+ lookForClass: "dojoEditorToolbarDnd TB_ToolbarSet TB_Toolbar",
+ initializer: function(editor){
+ this.editor = editor;
+ dojo.event.connect(this.editor, "toolbarLoaded", this, "setup");
+ this.editor.registerLoadedPlugin(this);
+ },
+
+ setup: function(){
+ dojo.event.disconnect(this.editor, "toolbarLoaded", this, "setup");
+ var tbw = this.editor.toolbarWidget;
+ dojo.event.connect("before", tbw, "destroy", this, "destroy");
+
+ var nodes = dojo.html.getElementsByClass(this.lookForClass, tbw.domNode, null, dojo.html.classMatchType.ContainsAny);
+ if(!nodes){
+ dojo.debug("dojo.widget.Editor2Plugin.ToolbarDndSupport: No dom node with class in "+this.lookForClass);
+ return;
+ }
+ for(var i=0; i<nodes.length; i++){
+ var node = nodes[i];
+ var droptarget = node.getAttribute("dojoETDropTarget");
+ if(droptarget){
+ (new dojo.dnd.HtmlDropTarget(node, [droptarget+tbw.widgetId])).vertical = true;
+ }
+ var dragsource = node.getAttribute("dojoETDragSource");
+ if(dragsource){
+ new dojo.dnd.HtmlDragSource(node, dragsource+tbw.widgetId);
+ }
+ }
+ },
+
+ destroy: function(){
+ this.editor.unregisterLoadedPlugin(this);
+ }
+});
+
+//let's have a command to enable DnD
+/*dojo.declare("dojo.widget.Editor2Plugin.ToolbarDndCommand", dojo.widget.Editor2Command,{
+ execute: function(text, option){
+ var curInst = dojo.widget.Editor2Manager.getCurrentInstance();
+ if(curInst){
+ }
+ },
+ getState: function(){
+ }
+});*/
\ No newline at end of file
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Plugin/ToolbarDndSupport.js
------------------------------------------------------------------------------
svn:eol-style = native
Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Plugin/__package__.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Plugin/__package__.js?view=auto&rev=451106
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Plugin/__package__.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Plugin/__package__.js Thu Sep 28 20:42:39 2006
@@ -0,0 +1,15 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.kwCompoundRequire({
+ common: [ "dojo.widget.Editor2",
+ "dojo.widget.Editor2Toolbar"]
+});
+dojo.provide("dojo.widget.Editor2Plugin.*");
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Plugin/__package__.js
------------------------------------------------------------------------------
svn:eol-style = native
Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Toolbar.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Toolbar.js?view=auto&rev=451106
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Toolbar.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Toolbar.js Thu Sep 28 20:42:39 2006
@@ -0,0 +1,564 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.widget.Editor2Toolbar");
+
+dojo.require("dojo.lang.*");
+dojo.require("dojo.widget.*");
+dojo.require("dojo.event.*");
+dojo.require("dojo.html.layout");
+dojo.require("dojo.html.display");
+dojo.require("dojo.widget.RichText");
+dojo.require("dojo.widget.PopupContainer");
+dojo.require("dojo.widget.ColorPalette");
+
+dojo.widget.Editor2ToolbarItemManager = {
+ _registeredItemHandlers: [],
+ registerHandler: function(obj, func){
+ if(arguments.length == 1){
+// for(i in this._registeredItemHandlers){
+// if(func === this._registeredItemHandlers[i]){
+// dojo.debug("Editor2ToolbarItemManager handler "+func+" is already registered, ignored");
+// return;
+// }
+// }
+ this._registeredItemHandlers.push(obj);
+ }else{
+ this._registeredItemHandlers.push(function(){return obj[func].apply(obj, arguments);});
+ }
+ },
+ removeHandler: function(func){
+ for(var i in this._registeredItemHandlers){
+ if(func === this._registeredItemHandlers[i]){
+ delete this._registeredItemHandlers[i];
+ return;
+ }
+ }
+ dojo.debug("Editor2ToolbarItemManager handler "+func+" is not registered, can not remove.");
+ },
+ destroy: function(){
+ for(var i in this._registeredItemHandlers){
+ delete this._registeredItemHandlers[i];
+ }
+ },
+ getToolbarItem: function(name){
+ var item;
+ name = name.toLowerCase();
+ for(var i in this._registeredItemHandlers){
+ item = this._registeredItemHandlers[i](name);
+ if(item){
+ break;
+ }
+ }
+
+ if(!item){
+ switch(name){
+ //button for builtin functions
+ case 'bold':
+ case 'copy':
+ case 'cut':
+ case 'delete':
+ case 'indent':
+ case 'inserthorizontalrule':
+ case 'insertorderedlist':
+ case 'insertunorderedlist':
+ case 'italic':
+ case 'justifycenter':
+ case 'justifyfull':
+ case 'justifyleft':
+ case 'justifyright':
+ case 'outdent':
+ case 'paste':
+ case 'redo':
+ case 'removeformat':
+ case 'selectall':
+ case 'strikethrough':
+ case 'subscript':
+ case 'superscript':
+ case 'underline':
+ case 'undo':
+ case 'unlink':
+ case 'createlink':
+ case 'insertimage':
+ //extra simple buttons
+ case 'htmltoggle':
+ item = new dojo.widget.Editor2ToolbarButton(name);
+ break;
+ case 'forecolor':
+ case 'hilitecolor':
+ item = new dojo.widget.Editor2ToolbarColorPaletteButton(name);
+ break;
+ case 'plainformatblock':
+ item = new dojo.widget.Editor2ToolbarFormatBlockPlainSelect("formatblock");
+ break;
+ case 'formatblock':
+ item = new dojo.widget.Editor2ToolbarFormatBlockSelect("formatblock");
+ break;
+ case 'fontsize':
+ item = new dojo.widget.Editor2ToolbarFontSizeSelect("fontsize");
+ break;
+ case 'fontname':
+ item = new dojo.widget.Editor2ToolbarFontNameSelect("fontname");
+ break;
+ case 'inserttable':
+ case 'insertcell':
+ case 'insertcol':
+ case 'insertrow':
+ case 'deletecells':
+ case 'deletecols':
+ case 'deleterows':
+ case 'mergecells':
+ case 'splitcell':
+ dojo.debug(name + " is implemented in dojo.widget.Editor2Plugin.TableOperation, please require it first.");
+ break;
+ //TODO:
+ case 'inserthtml':
+ case 'blockdirltr':
+ case 'blockdirrtl':
+ case 'dirltr':
+ case 'dirrtl':
+ case 'inlinedirltr':
+ case 'inlinedirrtl':
+ dojo.debug("Not yet implemented toolbar item: "+name);
+ break;
+ default:
+ dojo.debug("dojo.widget.Editor2ToolbarItemManager.getToolbarItem: Unknown toolbar item: "+name);
+ }
+ }
+ return item;
+ }
+};
+
+dojo.addOnUnload(dojo.widget.Editor2ToolbarItemManager, "destroy");
+
+dojo.declare("dojo.widget.Editor2ToolbarButton", null,{
+ initializer: function(name){
+ this._name = name;
+ this._command = dojo.widget.Editor2Manager.getCommand(name);
+ },
+ create: function(node, toolbar, isMenu){
+ this._domNode = node;
+ //make this unselectable: different browsers
+ //use different properties for this, so use
+ //js do it automatically
+ this.disableSelection(this._domNode);
+ this._parentToolbar = toolbar;
+ dojo.event.connect(this._domNode, 'onclick', this, 'onClick');
+ if(!isMenu){
+ dojo.event.connect(this._domNode, 'onmouseover', this, 'onMouseOver');
+ dojo.event.connect(this._domNode, 'onmouseout', this, 'onMouseOut');
+ }
+ },
+ disableSelection: function(rootnode){
+ dojo.html.disableSelection(rootnode);
+ var nodes = rootnode.all || rootnode.getElementsByTagName("*");
+ for(var x=0; x<nodes.length; x++){
+ dojo.html.disableSelection(nodes[x]);
+ }
+ },
+ onMouseOver: function(){
+ if(this._command.getState() != dojo.widget.Editor2Manager.commandState.Disabled){
+ this.highlightToolbarItem();
+ }
+ },
+ onMouseOut: function(){
+ this.unhighlightToolbarItem();
+ },
+ destroy: function(){
+ this._domNode = null;
+ delete this._command;
+ this._parentToolbar = null;
+ },
+ onClick: function(e){
+ if(this._domNode && !this._domNode.disabled && this._command){
+ e.preventDefault();
+ e.stopPropagation();
+ this._command.execute();
+ }
+ },
+ refreshState: function(){
+ if(this._domNode && this._command){
+ var em = dojo.widget.Editor2Manager;
+ var state = this._command.getState();
+ if(state != this._lastState){
+ switch(state){
+ case em.commandState.Latched:
+ this.latchToolbarItem();
+ break;
+ case em.commandState.Enabled:
+ this.enableToolbarItem();
+ break;
+ case em.commandState.Disabled:
+ default:
+ this.disableToolbarItem();
+ }
+ this._lastState = state;
+ }
+ return state;
+ }
+ },
+
+ latchToolbarItem: function(){
+ this._domNode.disabled = false;
+ this.removeToolbarItemStyle(this._domNode);
+ dojo.html.addClass(this._domNode, this._parentToolbar.ToolbarLatchedItemStyle);
+ },
+
+ enableToolbarItem: function(){
+ this._domNode.disabled = false;
+ this.removeToolbarItemStyle(this._domNode);
+ dojo.html.addClass(this._domNode, this._parentToolbar.ToolbarEnabledItemStyle);
+ },
+
+ disableToolbarItem: function(){
+ this._domNode.disabled = true;
+ this.removeToolbarItemStyle(this._domNode);
+ dojo.html.addClass(this._domNode, this._parentToolbar.ToolbarDisabledItemStyle);
+ },
+
+ highlightToolbarItem: function(){
+ dojo.html.addClass(this._domNode, this._parentToolbar.ToolbarHighlightedItemStyle);
+ },
+
+ unhighlightToolbarItem: function(){
+ dojo.html.removeClass(this._domNode, this._parentToolbar.ToolbarHighlightedItemStyle);
+ },
+
+ removeToolbarItemStyle: function(){
+ dojo.html.removeClass(this._domNode, this._parentToolbar.ToolbarEnabledItemStyle);
+ dojo.html.removeClass(this._domNode, this._parentToolbar.ToolbarLatchedItemStyle);
+ dojo.html.removeClass(this._domNode, this._parentToolbar.ToolbarDisabledItemStyle);
+ this.unhighlightToolbarItem();
+ }
+});
+
+dojo.declare("dojo.widget.Editor2ToolbarDropDownButton", dojo.widget.Editor2ToolbarButton,{
+ onClick: function(){
+ if(this._domNode){
+ if(!this._dropdown){
+ this._dropdown = dojo.widget.createWidget("PopupContainer", {});
+ this._domNode.appendChild(this._dropdown.domNode);
+ }
+ if(this._dropdown.isShowingNow){
+ this._dropdown.close();
+ }else{
+ this.onDropDownShown();
+ this._dropdown.open(this._domNode, null, this._domNode);
+ }
+ }
+ },
+ destroy: function(){
+ this.onDropDownDestroy();
+ if(this._dropdown){
+ this._dropdown.destroy();
+ }
+ dojo.widget.Editor2ToolbarDropDownButton.superclass.destroy.call(this);
+ },
+ onDropDownShown: function(){},
+ onDropDownDestroy: function(){}
+});
+
+dojo.declare("dojo.widget.Editor2ToolbarColorPaletteButton", dojo.widget.Editor2ToolbarDropDownButton,{
+ onDropDownShown: function(){
+ if(!this._colorpalette){
+ this._colorpalette = dojo.widget.createWidget("ColorPalette", {});
+ this._dropdown.addChild(this._colorpalette);
+
+ this.disableSelection(this._dropdown.domNode);
+ this.disableSelection(this._colorpalette.domNode);
+ //do we need a destory to delete this._colorpalette manually?
+ //I assume as it is added to this._dropdown via addChild, it
+ //should be deleted when this._dropdown is destroyed
+
+ dojo.event.connect(this._colorpalette, "onColorSelect", this, 'setColor');
+ dojo.event.connect(this._dropdown, "open", this, 'latchToolbarItem');
+ dojo.event.connect(this._dropdown, "close", this, 'enableToolbarItem');
+ }
+ },
+ setColor: function(color){
+ this._dropdown.close();
+ this._command.execute(color);
+ }
+});
+
+dojo.declare("dojo.widget.Editor2ToolbarFormatBlockPlainSelect", dojo.widget.Editor2ToolbarButton,{
+ create: function(node, toolbar){
+ //TODO: check node is a select
+ this._domNode = node;
+ this.disableSelection(this._domNode);
+ this._parentToolbar = toolbar;
+ dojo.event.connect(this._domNode, 'onchange', this, 'onChange');
+ },
+
+ destroy: function(){
+ this._domNode = null;
+ this._command = null;
+ this._parentToolbar = null;
+ },
+
+ onChange: function(){
+ if(this._domNode){
+ var sv = this._domNode.value.toLowerCase();
+ this._command.execute(sv);
+ }
+ },
+
+ refreshState: function(){
+ if(this._domNode && this._command){
+ dojo.widget.Editor2ToolbarFormatBlockPlainSelect.superclass.refreshState.call(this);
+ var format = this._command.getValue();
+ if(!format){ format = ""; }
+ dojo.lang.forEach(this._domNode.options, function(item){
+ if(item.value.toLowerCase() == format.toLowerCase()){
+ item.selected = true;
+ }
+ });
+ }
+ }
+});
+
+dojo.declare("dojo.widget.Editor2ToolbarComboItem", dojo.widget.Editor2ToolbarDropDownButton,{
+ href: null,
+ create: function(node, toolbar){
+ dojo.widget.Editor2ToolbarComboItem.superclass.create.call(this, node, toolbar);
+ //do not use lazy initilization, as we need the local names in refreshState()
+ if(!this._contentPane){
+ dojo.require("dojo.widget.ContentPane");
+ this._contentPane = dojo.widget.createWidget("ContentPane", {preload: 'true'});
+ this._contentPane.addOnLoad(this, "setup");
+ this._contentPane.setUrl(this.href);
+ }
+ },
+
+ onMouseOver: function(e){
+ dojo.html.addClass(e.currentTarget, this._parentToolbar.ToolbarHighlightedSelectStyle);
+ },
+ onMouseOut:function(e){
+ dojo.html.removeClass(e.currentTarget, this._parentToolbar.ToolbarHighlightedSelectStyle);
+ },
+
+ onDropDownShown: function(){
+ if(!this._dropdown.__addedContentPage){
+ this._dropdown.addChild(this._contentPane);
+ this._dropdown.__addedContentPage = true;
+ }
+ },
+
+ //overload this to connect event
+ setup: function(){},
+
+ onChange: function(e){
+ var name = e.currentTarget.getAttribute("dropDownItemName");
+ this._command.execute(name);
+ this._dropdown.close();
+ },
+
+ onMouseOverItem: function(e){
+ dojo.html.addClass(e.currentTarget, this._parentToolbar.ToolbarHighlightedSelectItemStyle);
+ },
+
+ onMouseOutItem: function(e){
+ dojo.html.removeClass(e.currentTarget, this._parentToolbar.ToolbarHighlightedSelectItemStyle);
+ },
+
+ //overload this to update GUI item
+ refreshState: function(){}
+});
+
+dojo.declare("dojo.widget.Editor2ToolbarFormatBlockSelect", dojo.widget.Editor2ToolbarComboItem,{
+ href: dojo.uri.dojoUri("src/widget/templates/Editor2/EditorToolbar_FormatBlock.html"),
+
+ setup: function(){
+ dojo.widget.Editor2ToolbarFormatBlockSelect.superclass.setup.call(this);
+
+ var nodes = this._contentPane.domNode.all || this._contentPane.domNode.getElementsByTagName("*");
+ this._blockNames = {};
+ this._blockDisplayNames = {};
+ for(var x=0; x<nodes.length; x++){
+ var node = nodes[x];
+ dojo.html.disableSelection(node);
+ var name=node.getAttribute("dropDownItemName")
+ if(name){
+ this._blockNames[name] = node;
+ var childrennodes = node.getElementsByTagName(name);
+ this._blockDisplayNames[name] = childrennodes[childrennodes.length-1].innerHTML;
+ }
+ }
+ for(var name in this._blockNames){
+ dojo.event.connect(this._blockNames[name], "onclick", this, "onChange");
+ dojo.event.connect(this._blockNames[name], "onmouseover", this, "onMouseOverItem");
+ dojo.event.connect(this._blockNames[name], "onmouseout", this, "onMouseOutItem");
+ }
+ },
+
+ onDropDownDestroy: function(){
+ if(this._blockNames){
+ for(var name in this._blockNames){
+ delete this._blockNames[name];
+ delete this._blockDisplayNames[name];
+ }
+ }
+ },
+
+ refreshState: function(){
+ if(this._command){
+ //dojo.widget.Editor2ToolbarFormatBlockSelect.superclass.refreshState.call(this);
+ var format = this._command.getValue();
+ if(format == this._lastSelectedFormat && this._blockDisplayNames){
+ return;
+ }
+ this._lastSelectedFormat = format;
+ var label = this._domNode.getElementsByTagName("label")[0];
+ var isSet = false;
+ if(this._blockDisplayNames){
+ for(var name in this._blockDisplayNames){
+ if(name == format){
+ label.innerHTML = this._blockDisplayNames[name];
+ isSet = true;
+ break;
+ }
+ }
+ if(!isSet){
+ label.innerHTML = " ";
+ }
+ }
+ }
+ }
+});
+
+dojo.declare("dojo.widget.Editor2ToolbarFontSizeSelect", dojo.widget.Editor2ToolbarComboItem,{
+ href: dojo.uri.dojoUri("src/widget/templates/Editor2/EditorToolbar_FontSize.html"),
+
+ setup: function(){
+ dojo.widget.Editor2ToolbarFormatBlockSelect.superclass.setup.call(this);
+
+ var nodes = this._contentPane.domNode.all || this._contentPane.domNode.getElementsByTagName("*");
+ this._fontsizes = {};
+ this._fontSizeDisplayNames = {};
+ for(var x=0; x<nodes.length; x++){
+ var node = nodes[x];
+ dojo.html.disableSelection(node);
+ var name=node.getAttribute("dropDownItemName")
+ if(name){
+ this._fontsizes[name] = node;
+ this._fontSizeDisplayNames[name] = node.getElementsByTagName('font')[0].innerHTML;
+ }
+ }
+ for(var name in this._fontsizes){
+ dojo.event.connect(this._fontsizes[name], "onclick", this, "onChange");
+ dojo.event.connect(this._fontsizes[name], "onmouseover", this, "onMouseOverItem");
+ dojo.event.connect(this._fontsizes[name], "onmouseout", this, "onMouseOutItem");
+ }
+ },
+
+ onDropDownDestroy: function(){
+ if(this._fontsizes){
+ for(var name in this._fontsizes){
+ delete this._fontsizes[name];
+ delete this._fontSizeDisplayNames[name];
+ }
+ }
+ },
+
+ refreshState: function(){
+ if(this._command){
+ //dojo.widget.Editor2ToolbarFormatBlockSelect.superclass.refreshState.call(this);
+ var size = this._command.getValue();
+ if(size == this._lastSelectedSize && this._fontSizeDisplayNames){
+ return;
+ }
+ this._lastSelectedSize = size;
+ var label = this._domNode.getElementsByTagName("label")[0];
+ var isSet = false;
+ if(this._fontSizeDisplayNames){
+ for(var name in this._fontSizeDisplayNames){
+ if(name == size){
+ label.innerHTML = this._fontSizeDisplayNames[name];
+ isSet = true;
+ break;
+ }
+ }
+ if(!isSet){
+ label.innerHTML = " ";
+ }
+ }
+ }
+ }
+});
+
+dojo.declare("dojo.widget.Editor2ToolbarFontNameSelect", dojo.widget.Editor2ToolbarFontSizeSelect,{
+ href: dojo.uri.dojoUri("src/widget/templates/Editor2/EditorToolbar_FontName.html")
+});
+
+dojo.widget.defineWidget(
+ "dojo.widget.Editor2Toolbar",
+ dojo.widget.HtmlWidget,
+ {
+ templatePath: dojo.uri.dojoUri("src/widget/templates/EditorToolbar.html"),
+ templateCssPath: dojo.uri.dojoUri("src/widget/templates/EditorToolbar.css"),
+
+ // DOM Nodes
+ saveButton: null,
+
+ ToolbarLatchedItemStyle: "ToolbarButtonLatched",
+ ToolbarEnabledItemStyle: "ToolbarButtonEnabled",
+ ToolbarDisabledItemStyle: "ToolbarButtonDisabled",
+ ToolbarHighlightedItemStyle: "ToolbarButtonHighlighted",
+ ToolbarHighlightedSelectStyle: "ToolbarSelectHighlighted",
+ ToolbarHighlightedSelectItemStyle: "ToolbarSelectHighlightedItem",
+
+// itemNodeType: 'span', //all the items (with attribute dojoETItemName set) defined in the toolbar should be a of this type
+
+ postCreate: function(){
+ var nodes = dojo.html.getElementsByClass("dojoEditorToolbarItem", this.domNode/*, this.itemNodeType*/);
+
+ this.items = {};
+ for(var x=0; x<nodes.length; x++){
+ var node = nodes[x];
+ var itemname = node.getAttribute("dojoETItemName");
+ if(itemname){
+ var item = dojo.widget.Editor2ToolbarItemManager.getToolbarItem(itemname);
+ if(item){
+ item.create(node, this);
+ this.items[itemname.toLowerCase()] = item;
+ }else{
+ //hide unsupported toolbar items
+ node.style.display = "none";
+ }
+ }
+ }
+ },
+
+ update: function(){
+ for(var cmd in this.items){
+ this.items[cmd].refreshState();
+ }
+ },
+
+ destroy: function(){
+ for(var it in this.items){
+ this.items[it].destroy();
+ delete this.items[it];
+ }
+ dojo.widget.Editor2Toolbar.superclass.destroy.call(this);
+ }//,
+
+ // stub for observers
+// exec: function(what, arg){ /* dojo.debug(what, new Date()); */ }
+ },
+ "html",
+ function(){
+ dojo.event.connect(this, "fillInTemplate", dojo.lang.hitch(this, function(){
+ if(dojo.render.html.ie){
+ this.domNode.style.zoom = 1.0;
+ }
+ }));
+ }
+);
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/Editor2Toolbar.js
------------------------------------------------------------------------------
svn:eol-style = native
Added: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/FilteringTable.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/FilteringTable.js?view=auto&rev=451106
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/FilteringTable.js (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/FilteringTable.js Thu Sep 28 20:42:39 2006
@@ -0,0 +1,897 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.widget.FilteringTable");
+
+dojo.require("dojo.date.format");
+dojo.require("dojo.collections.Store");
+dojo.require("dojo.html.*");
+dojo.require("dojo.html.util");
+dojo.require("dojo.html.style");
+dojo.require("dojo.html.selection");
+dojo.require("dojo.event.*");
+dojo.require("dojo.widget.*");
+dojo.require("dojo.widget.HtmlWidget");
+
+dojo.widget.defineWidget(
+ "dojo.widget.FilteringTable",
+ dojo.widget.HtmlWidget,
+ function(){
+ this.store=new dojo.collections.Store();
+
+ //declare per instance changeable widget properties
+ this.valueField="Id";
+ this.multiple=false;
+ this.maxSelect=0;
+ this.maxSortable=1; // how many columns can be sorted at once.
+ this.minRows=0;
+ this.defaultDateFormat = "%D";
+ this.isInitialized=false;
+ this.alternateRows=false;
+
+ this.columns=[];
+ this.sortInformation=[{
+ index:0,
+ direction:0
+ }];
+
+ // CSS definitions
+ this.headClass="";
+ this.tbodyClass="";
+ this.headerClass="";
+ this.headerUpClass="selectedUp";
+ this.headerDownClass="selectedDown";
+ this.rowClass="";
+ this.rowAlternateClass="alt";
+ this.rowSelectedClass="selected";
+ this.columnSelected="sorted-column";
+ },
+{
+ // dojo widget properties
+ isContainer: false,
+ templatePath: null,
+ templateCssPath: null,
+
+ // methods.
+ getTypeFromString: function(s){
+ var parts = s.split("."), i = 0, obj = dj_global;
+ do{
+ obj = obj[parts[i++]];
+ } while (i < parts.length && obj);
+ return (obj != dj_global) ? obj : null;
+ },
+
+ // custom data access.
+ getByRow: function(/*HTMLTableRow*/row){
+ return this.store.getByKey(dojo.html.getAttribute(row, "value"));
+ },
+ getDataByRow: function(/*HTMLTableRow*/row){
+ return this.store.getDataByKey(dojo.html.getAttribute(row, "value"));
+ },
+
+ getRow: function(/* Object */ obj){
+ var rows = this.domNode.tBodies[0].rows;
+ for(var i=0; i<rows.length; i++){
+ if(this.store.getDataByKey(dojo.html.getAttribute(rows[i], "value")) == obj){
+ return rows[i];
+ }
+ }
+ return null;
+ },
+ getColumnIndex: function(/* string */fieldPath){
+ for(var i=0; i<this.columns.length; i++){
+ if(this.columns[i].getField() == fieldPath){
+ return i;
+ }
+ }
+ return -1;
+ },
+
+ getSelectedData: function(){
+ // summary
+ // returns all objects that are selected.
+ var data=this.store.get();
+ var a=[];
+ for(var i=0; i<data.length; i++){
+ if(data[i].isSelected){
+ a.push(data[i].src);
+ }
+ }
+ if(this.multiple){
+ return a; // array
+ } else {
+ return a[0]; // object
+ }
+ },
+
+ isSelected: function(/* object */obj){
+ var data = this.store.get();
+ for(var i=0; i<data.length; i++){
+ if(data[i].src == obj){
+ return true; // boolean
+ }
+ }
+ return false; // boolean
+ },
+ isValueSelected: function(/* string */val){
+ var v = this.store.getByKey(val);
+ if(v){
+ return v.isSelected;
+ }
+ return false;
+ },
+ isIndexSelected: function(/* number */idx){
+ var v = this.store.getByIndex(idx);
+ if(v){
+ return v.isSelected;
+ }
+ return false;
+ },
+ isRowSelected: function(/* HTMLTableRow */row){
+ var v = this.getByRow(row);
+ if(v){
+ return v.isSelected;
+ }
+ return false;
+ },
+
+ reset: function(){
+ this.store.clearData();
+ this.columns = [];
+ this.sortInformation = [ {index:0, direction:0} ];
+ this.resetSelections();
+ this.isInitialized = false;
+ this.onReset();
+ },
+ resetSelections: function(){
+ this.store.forEach(function(element){
+ element.isSelected = false;
+ });
+ },
+ onReset:function(){ },
+
+ // selection and toggle functions
+ select: function(/*object*/ obj){
+ var data = this.store.get();
+ for(var i=0; i<data.length; i++){
+ if(data[i].src == obj){
+ data[i].isSelected = true;
+ break;
+ }
+ }
+ this.onDataSelect(obj);
+ },
+ selectByValue: function(/*string*/ val){
+ this.select(this.store.getDataByKey(val));
+ },
+ selectByIndex: function(/*number*/ idx){
+ this.select(this.store.getDataByIndex(idx));
+ },
+ selectByRow: function(/*HTMLTableRow*/ row){
+ this.select(this.getDataByRow(row));
+ },
+ selectAll: function(){
+ this.store.forEach(function(element){
+ element.isSelected = true;
+ });
+ },
+ onDataSelect: function(/* object */obj){ },
+
+ toggleSelection: function(/*object*/obj){
+ var data = this.store.get();
+ for(var i=0; i<data.length; i++){
+ if(data[i].src == obj){
+ data[i].isSelected = !data[i].isSelected;
+ break;
+ }
+ }
+ this.onDataToggle(obj);
+ },
+ toggleSelectionByValue: function(/*string*/val){
+ this.toggleSelection(this.store.getDataByKey(val));
+ },
+ toggleSelectionByIndex: function(/*number*/idx){
+ this.toggleSelection(this.store.getDataByIndex(idx));
+ },
+ toggleSelectionByRow: function(/*HTMLTableRow*/row){
+ this.toggleSelection(this.getDataByRow(row));
+ },
+ toggleAll: function(){
+ this.store.forEach(function(element){
+ element.isSelected = !element.isSelected;
+ });
+ },
+ onDataToggle: function(/* object */obj){ },
+
+ // parsing functions, from HTML to metadata/SimpleStore
+ _meta:{
+ field:null,
+ format:null,
+ filterer:null,
+ noSort:false,
+ sortType:"String",
+ dataType:String,
+ sortFunction:null,
+ filterFunction:null,
+ label:null,
+ align:"left",
+ valign:"middle",
+ getField:function(){
+ return this.field || this.label;
+ },
+ getType:function(){
+ return this.dataType;
+ }
+ },
+ createMetaData: function(/* object */obj){
+ // summary
+ // Take a JSON-type structure and make it into a ducktyped metadata object.
+ for(var p in this._meta){
+ // rudimentary mixin
+ if(!obj[p]){
+ obj[p] = this._meta[p];
+ }
+ }
+ if(!obj.label){
+ obj.label=obj.field;
+ }
+ if(!obj.filterFunction){
+ obj.filterFunction=this._defaultFilter;
+ }
+ return obj; // object
+ },
+ parseMetadata: function(/* HTMLTableHead */head){
+ this.columns=[];
+ this.sortInformation=[];
+ var row = head.getElementsByTagName("tr")[0];
+ var cells = row.getElementsByTagName("td");
+ if (cells.length == 0){
+ cells = row.getElementsByTagName("th");
+ }
+ for(var i=0; i<cells.length; i++){
+ var o = this.createMetaData({ });
+
+ // presentation attributes
+ if(dojo.html.hasAttribute(cells[i], "align")){
+ o.align = dojo.html.getAttribute(cells[i],"align");
+ }
+ if(dojo.html.hasAttribute(cells[i], "valign")){
+ o.valign = dojo.html.getAttribute(cells[i],"valign");
+ }
+ if(dojo.html.hasAttribute(cells[i], "nosort")){
+ o.noSort = (dojo.html.getAttribute(cells[i],"nosort")=="true");
+ }
+ if(dojo.html.hasAttribute(cells[i], "sortusing")){
+ var trans = dojo.html.getAttribute(cells[i],"sortusing");
+ var f = this.getTypeFromString(trans);
+ if (f != null && f != window && typeof(f)=="function"){
+ o.sortFunction=f;
+ }
+ }
+ o.label = dojo.html.renderedTextContent(cells[i]);
+ if(dojo.html.hasAttribute(cells[i], "field")){
+ o.field=dojo.html.getAttribute(cells[i],"field");
+ } else if(o.label.length > 0){
+ o.field=o.label;
+ } else {
+ o.field = "field" + i;
+ }
+ if(dojo.html.hasAttribute(cells[i], "format")){
+ o.format=dojo.html.getAttribute(cells[i],"format");
+ }
+ if(dojo.html.hasAttribute(cells[i], "dataType")){
+ var sortType = dojo.html.getAttribute(cells[i],"dataType");
+ if(sortType.toLowerCase()=="html" || sortType.toLowerCase()=="markup"){
+ o.sortType = "__markup__"; // always convert to "__markup__"
+ }else{
+ var type = this.getTypeFromString(sortType);
+ if(type){
+ o.sortType = sortType;
+ o.dataType = type;
+ }
+ }
+ }
+
+ // TODO: set up filtering mechanisms here.
+ if(dojo.html.hasAttribute(cells[i], "filterusing")){
+ var trans = dojo.html.getAttribute(cells[i],"filterusing");
+ var f = this.getTypeFromString(trans);
+ if (f != null && f != window && typeof(f)=="function"){
+ o.filterFunction=f;
+ }
+ }
+
+ this.columns.push(o);
+
+ // check to see if there's a default sort, and set the properties necessary
+ if(dojo.html.hasAttribute(cells[i], "sort")){
+ var info = {
+ index:i,
+ direction:0
+ };
+ var dir = dojo.html.getAttribute(cells[i], "sort");
+ if(!isNaN(parseInt(dir))){
+ dir = parseInt(dir);
+ info.direction = (dir != 0) ? 1 : 0;
+ }else{
+ info.direction = (dir.toLowerCase() == "desc") ? 1 : 0;
+ }
+ this.sortInformation.push(info);
+ }
+ }
+ if(this.sortInformation.length == 0){
+ this.sortInformation.push({
+ index:0,
+ direction:0
+ });
+ } else if (this.sortInformation.length > this.maxSortable){
+ this.sortInformation.length = this.maxSortable;
+ }
+ },
+ parseData: function(/* HTMLTableBody */body){
+ // summary
+ // Parse HTML data into native JSON structure for the store.
+ if(body.rows.length == 0 && this.columns.length == 0){
+ return; // there's no data, ignore me.
+ }
+
+ // create a data constructor based on what we've got for the fields.
+ var self=this;
+ this["__selected__"] = [];
+ var arr = this.store.getFromHtml(this.columns, body, function(obj, row){
+ obj[self.valueField] = dojo.html.getAttribute(row, "value");
+ if(dojo.html.getAttribute(row, "selected")=="true"){
+ self["__selected__"].push(obj);
+ }
+ });
+ this.store.setData(arr);
+ for(var i=0; i<this["__selected__"].length; i++){
+ this.select(this["__selected__"][i]);
+ }
+ this.renderSelections();
+
+ delete this["__selected__"];
+
+ // say that we are already initialized so that we don't kill anything
+ this.isInitialized=true;
+ },
+
+ // standard events
+ onSelect: function(/* HTMLEvent */e){
+ // summary
+ // Handles the onclick event of any element.
+ var row = dojo.html.getParentByType(e.target,"tr");
+ if(dojo.html.hasAttribute(row,"emptyRow")){
+ return;
+ }
+ var body = dojo.html.getParentByType(row,"tbody");
+ if(this.multiple){
+ if(e.shiftKey){
+ var startRow;
+ var rows=body.rows;
+ for(var i=0;i<rows.length;i++){
+ if(rows[i]==row){
+ break;
+ }
+ if(this.isRowSelected(rows[i])){
+ startRow=rows[i];
+ }
+ }
+ if(!startRow){
+ startRow = row;
+ for(; i<rows.length; i++){
+ if(this.isRowSelected(rows[i])){
+ row = rows[i];
+ break;
+ }
+ }
+ }
+ this.resetSelections();
+ if(startRow == row){
+ this.toggleSelectionByRow(row);
+ } else {
+ var doSelect = false;
+ for(var i=0; i<rows.length; i++){
+ if(rows[i] == startRow){
+ doSelect=true;
+ }
+ if(doSelect){
+ this.selectByRow(rows[i]);
+ }
+ if(rows[i] == row){
+ doSelect = false;
+ }
+ }
+ }
+ } else {
+ this.toggleSelectionByRow(row);
+ }
+ } else {
+ this.resetSelections();
+ this.toggleSelectionByRow(row);
+ }
+ this.renderSelections();
+ },
+ onSort: function(/* HTMLEvent */e){
+ // summary
+ // Sort the table based on the column selected.
+ var oldIndex=this.sortIndex;
+ var oldDirection=this.sortDirection;
+
+ var source=e.target;
+ var row=dojo.html.getParentByType(source,"tr");
+ var cellTag="td";
+ if(row.getElementsByTagName(cellTag).length==0){
+ cellTag="th";
+ }
+
+ var headers=row.getElementsByTagName(cellTag);
+ var header=dojo.html.getParentByType(source,cellTag);
+
+ for(var i=0; i<headers.length; i++){
+ dojo.html.setClass(headers[i], this.headerClass);
+ if(headers[i]==header){
+ if(this.sortInformation[0].index != i){
+ this.sortInformation.unshift({
+ index:i,
+ direction:0
+ });
+ } else {
+ this.sortInformation[0] = {
+ index:i,
+ direction:(~this.sortInformation[0].direction)&1
+ };
+ }
+ }
+ }
+
+ this.sortInformation.length = Math.min(this.sortInformation.length, this.maxSortable);
+ for(var i=0; i<this.sortInformation.length; i++){
+ var idx=this.sortInformation[i].index;
+ var dir=(~this.sortInformation[i].direction)&1;
+ dojo.html.setClass(headers[idx], dir==0?this.headerDownClass:this.headerUpClass);
+ }
+ this.render();
+ },
+ onFilter: function(){
+ // summary
+ // show or hide rows based on the parameters of the passed filter.
+ },
+
+ // Filtering methods
+ _defaultFilter: function(/* Object */obj){
+ // summary
+ // Always return true as the result of the default filter.
+ return true;
+ },
+ setFilter: function(/* string */field, /* function */fn){
+ // summary
+ // set a filtering function on the passed field.
+ for(var i=0; i<this.columns.length; i++){
+ if(this.columns[i].getField() == field){
+ this.columns[i].filterFunction=fn;
+ break;
+ }
+ }
+ this.applyFilters();
+ },
+ setFilterByIndex: function(/* number */idx, /* function */fn){
+ // summary
+ // set a filtering function on the passed column index.
+ this.columns[idx].filterFunction=fn;
+ this.applyFilters();
+ },
+ clearFilter: function(/* string */field){
+ // summary
+ // clear a filtering function on the passed field.
+ for(var i=0; i<this.columns.length; i++){
+ if(this.columns[i].getField() == field){
+ this.columns[i].filterFunction=this._defaultFilter;
+ break;
+ }
+ }
+ this.applyFilters();
+ },
+ clearFilterByIndex: function(/* number */idx){
+ // summary
+ // clear a filtering function on the passed column index.
+ this.columns[idx].filterFunction=this._defaultFilter;
+ this.applyFilters();
+ },
+ clearFilters: function(){
+ // summary
+ // clears all filters.
+ for(var i=0; i<this.columns.length; i++){
+ this.columns[i].filterFunction=this._defaultFilter;
+ }
+ // we'll do the clear manually, it will be faster.
+ var rows=this.domNode.tBodies[0].rows;
+ for(var i=0; i<rows.length; i++){
+ rows[i].style.display="";
+ if(this.alternateRows){
+ dojo.html[((i % 2 == 1)?"addClass":"removeClass")](rows[i], this.rowAlternateClass);
+ }
+ }
+ this.onFilter();
+ },
+ applyFilters: function(){
+ // summary
+ // apply all filters to the table.
+ var alt=0;
+ var rows=this.domNode.tBodies[0].rows;
+ for(var i=0; i<rows.length; i++){
+ var b=true;
+ var row=rows[i];
+ for(var j=0; j<this.columns.length; j++){
+ var value = this.store.getField(this.getDataByRow(row), this.columns[j].getField());
+ if(this.columns[j].getType() == Date && value != null && !value.getYear){
+ value = new Date(value);
+ }
+ if(!this.columns[j].filterFunction(value)){
+ b=false;
+ break;
+ }
+ }
+ row.style.display=(b?"":"none");
+ if(b && this.alternateRows){
+ dojo.html[((alt++ % 2 == 1)?"addClass":"removeClass")](row, this.rowAlternateClass);
+ }
+ }
+ this.onFilter();
+ },
+
+ // sorting functionality
+ createSorter: function(/* array */info){
+ // summary
+ // creates a custom function to be used for sorting.
+ var self=this;
+ var sortFunctions=[]; // our function stack.
+
+ function createSortFunction(fieldIndex, dir){
+ var meta=self.columns[fieldIndex];
+ var field=meta.getField();
+ return function(rowA, rowB){
+ if(dojo.html.hasAttribute(rowA,"emptyRow") || dojo.html.hasAttribute(rowB,"emptyRow")){
+ return -1;
+ }
+ // TODO: check for markup and compare by rendered text.
+ var a = self.store.getField(self.getDataByRow(rowA), field);
+ var b = self.store.getField(self.getDataByRow(rowB), field);
+ var ret = 0;
+ if(a > b) ret = 1;
+ if(a < b) ret = -1;
+ return dir * ret;
+ }
+ }
+
+ var current=0;
+ var max = Math.min(info.length, this.maxSortable, this.columns.length);
+ while(current < max){
+ var direction = (info[current].direction == 0) ? 1 : -1;
+ sortFunctions.push(
+ createSortFunction(info[current].index, direction)
+ );
+ current++;
+ }
+
+ return function(rowA, rowB){
+ var idx=0;
+ while(idx < sortFunctions.length){
+ var ret = sortFunctions[idx++](rowA, rowB);
+ if(ret != 0) return ret;
+ }
+ // if we got here then we must be equal.
+ return 0;
+ }; // function
+ },
+
+ // rendering
+ createRow: function(/* object */obj){
+ var row=document.createElement("tr");
+ dojo.html.disableSelection(row);
+ if(obj.key != null){
+ row.setAttribute("value", obj.key);
+ }
+ for(var j=0; j<this.columns.length; j++){
+ var cell=document.createElement("td");
+ cell.setAttribute("align", this.columns[j].align);
+ cell.setAttribute("valign", this.columns[j].valign);
+ dojo.html.disableSelection(cell);
+ var val = this.store.getField(obj.src, this.columns[j].getField());
+ if(typeof(val)=="undefined"){
+ val="";
+ }
+ this.fillCell(cell, this.columns[j], val);
+ row.appendChild(cell);
+ }
+ return row;
+ },
+ fillCell: function(/* HTMLTableCell */cell, /* object */meta, /* object */val){
+ if(meta.sortType=="__markup__"){
+ cell.innerHTML=val;
+ } else {
+ if(meta.getType()==Date) {
+ val=new Date(val);
+ if(!isNaN(val)){
+ var format = this.defaultDateFormat;
+ if(meta.format){
+ format = meta.format;
+ }
+ cell.innerHTML = dojo.date.strftime(val, format);
+ } else {
+ cell.innerHTML = val;
+ }
+ } else if ("Number number int Integer float Float".indexOf(meta.getType())>-1){
+ // TODO: number formatting
+ if(val.length == 0){
+ val="0";
+ }
+ var n = parseFloat(val, 10) + "";
+ // TODO: numeric formatting + rounding :)
+ if(n.indexOf(".")>-1){
+ n = dojo.math.round(parseFloat(val,10),2);
+ }
+ cell.innerHTML = n;
+ }else{
+ cell.innerHTML = val;
+ }
+ }
+ },
+ prefill: function(){
+ // summary
+ // if there's no data in the table, then prefill it with this.minRows.
+ this.isInitialized = false;
+ var body = this.domNode.tBodies[0];
+ while (body.childNodes.length > 0){
+ body.removeChild(body.childNodes[0]);
+ }
+
+ if(this.minRows>0){
+ for(var i=0; i < this.minRows; i++){
+ var row = document.createElement("tr");
+ if(this.alternateRows){
+ dojo.html[((i % 2 == 1)?"addClass":"removeClass")](row, this.rowAlternateClass);
+ }
+ row.setAttribute("emptyRow","true");
+ for(var j=0; j<this.columns.length; j++){
+ var cell = document.createElement("td");
+ cell.innerHTML = " ";
+ row.appendChild(cell);
+ }
+ body.appendChild(row);
+ }
+ }
+ },
+ init: function(){
+ // summary
+ // initializes the table of data
+ this.isInitialized=false;
+
+ // if there is no thead, create it now.
+ var head=this.domNode.getElementsByTagName("thead")[0];
+ if(head.getElementsByTagName("tr").length == 0){
+ // render the column code.
+ var row=document.createElement("tr");
+ for(var i=0; i<this.columns.length; i++){
+ var cell=document.createElement("td");
+ cell.setAttribute("align", this.columns[i].align);
+ cell.setAttribute("valign", this.columns[i].valign);
+ dojo.html.disableSelection(cell);
+ cell.innerHTML=this.columns[i].label;
+ row.appendChild(cell);
+
+ // attach the events.
+ if(!this.columns[i].noSort){
+ dojo.event.connect(cell, "onclick", this, "onSort");
+ }
+ }
+ dojo.html.prependChild(row, head);
+ }
+
+ if(this.store.get().length == 0){
+ return false;
+ }
+
+ var idx=this.domNode.tBodies[0].rows.length;
+ if(!idx || idx==0 || this.domNode.tBodies[0].rows[0].getAttribute("emptyRow")=="true"){
+ idx = 0;
+ var body = this.domNode.tBodies[0];
+ while(body.childNodes.length>0){
+ body.removeChild(body.childNodes[0]);
+ }
+
+ var data = this.store.get();
+ for(var i=0; i<data.length; i++){
+ var row = this.createRow(data[i]);
+ dojo.event.connect(row, "onclick", this, "onSelect");
+ body.appendChild(row);
+ idx++;
+ }
+ }
+
+ // add empty rows
+ if(this.minRows > 0 && idx < this.minRows){
+ idx = this.minRows - idx;
+ for(var i=0; i<idx; i++){
+ row=document.createElement("tr");
+ row.setAttribute("emptyRow","true");
+ for(var j=0; j<this.columns.length; j++){
+ cell=document.createElement("td");
+ cell.innerHTML=" ";
+ row.appendChild(cell);
+ }
+ body.appendChild(row);
+ }
+ }
+
+ // last but not least, show any columns that have sorting already on them.
+ var row=this.domNode.getElementsByTagName("thead")[0].rows[0];
+ var cellTag="td";
+ if(row.getElementsByTagName(cellTag).length==0) cellTag="th";
+ var headers=row.getElementsByTagName(cellTag);
+ for(var i=0; i<headers.length; i++){
+ dojo.html.setClass(headers[i], this.headerClass);
+ }
+ for(var i=0; i<this.sortInformation.length; i++){
+ var idx=this.sortInformation[i].index;
+ var dir=(~this.sortInformation[i].direction)&1;
+ dojo.html.setClass(headers[idx], dir==0?this.headerDownClass:this.headerUpClass);
+ }
+
+ this.isInitialized=true;
+ return this.isInitialized;
+ },
+ render: function(){
+ /* The method that should be called once underlying changes
+ * are made, including sorting, filtering, data changes.
+ * Rendering the selections themselves are a different method,
+ * which render() will call as the last step.
+ ****************************************************************/
+ if(!this.isInitialized){
+ var b = this.init();
+ if(!b){
+ this.prefill();
+ return;
+ }
+ }
+
+ // do the sort
+ var rows=[];
+ var body=this.domNode.tBodies[0];
+ var emptyRowIdx=-1;
+ for(var i=0; i<body.rows.length; i++){
+ rows.push(body.rows[i]);
+ }
+
+ // build the sorting function, and do the sorting.
+ var sortFunction = this.createSorter(this.sortInformation);
+ if(sortFunction){
+ rows.sort(sortFunction);
+ }
+
+ // append the rows without killing them, this should help with the HTML problems.
+ for(var i=0; i<rows.length; i++){
+ if(this.alternateRows){
+ dojo.html[((i%2==1)?"addClass":"removeClass")](rows[i], this.rowAlternateClass);
+ }
+ dojo.html[(this.isRowSelected(body.rows[i])?"addClass":"removeClass")](body.rows[i], this.rowSelectedClass);
+ body.appendChild(rows[i]);
+ }
+ },
+ renderSelections: function(){
+ var body=this.domNode.tBodies[0];
+ for(var i=0; i<body.rows.length; i++){
+ dojo.html[(this.isRowSelected(body.rows[i])?"addClass":"removeClass")](body.rows[i], this.rowSelectedClass);
+ }
+ },
+
+ // widget lifetime handlers
+ initialize: function(){
+ var self=this;
+ // connect up binding listeners here.
+ dojo.event.connect(this.store, "onSetData", function(){
+ self.store.forEach(function(element){
+ element.isSelected = false;
+ });
+ self.isInitialized=false;
+ var body = self.domNode.tBodies[0];
+ if(body){
+ while(body.childNodes.length>0){
+ body.removeChild(body.childNodes[0]);
+ }
+ }
+ self.render();
+ });
+ dojo.event.connect(this.store, "onClearData", function(){
+ self.render();
+ });
+ dojo.event.connect(this.store, "onAddData", function(addedObject){
+ var row=self.createRow(addedObject);
+ dojo.event.connect(row, "onclick", self, "onSelect");
+ self.domNode.tBodies[0].appendChild(row);
+ self.render();
+ });
+ dojo.event.connect(this.store, "onAddDataRange", function(arr){
+ for(var i=0; i<arr.length; i++){
+ arr[i].isSelected=false;
+ var row=self.createRow(arr[i]);
+ dojo.event.connect(row, "onclick", self, "onSelect");
+ self.domNode.tBodies[0].appendChild(row);
+ };
+ self.render();
+ });
+ dojo.event.connect(this.store, "onRemoveData", function(removedObject){
+ var rows = self.domNode.tBodies[0].rows;
+ for(var i=0; i<rows.length; i++){
+ if(self.getDataByRow(rows[i]) == removedObject.src){
+ rows[i].parentNode.removeChild(rows[i]);
+ break;
+ }
+ }
+ self.render();
+ });
+ dojo.event.connect(this.store, "onUpdateField", function(obj, fieldPath, val){
+ var row = self.getRow(obj);
+ var idx = self.getColumnIndex(fieldPath);
+ if(row && row.cells[idx] && self.columns[idx]){
+ self.fillCell(row.cells[idx], self.columns[idx], val);
+ }
+ });
+ },
+// fillInTemplate: function(args, frag){ },
+ postCreate: function(){
+ // summary
+ // finish widget initialization.
+
+ this.store.keyField = this.valueField;
+
+ if(this.domNode){
+ // start by making sure domNode is a table element;
+ if(this.domNode.nodeName.toLowerCase() != "table"){
+ }
+
+ // see if there is columns set up already
+ if(this.domNode.getElementsByTagName("thead")[0]){
+ var head=this.domNode.getElementsByTagName("thead")[0];
+ if(this.headClass.length > 0){
+ head.className = this.headClass;
+ }
+ dojo.html.disableSelection(this.domNode);
+ this.parseMetadata(head);
+
+ var header="td";
+ if(head.getElementsByTagName(header).length==0){
+ header="th";
+ }
+ var headers = head.getElementsByTagName(header);
+ for(var i=0; i<headers.length; i++){
+ if(!this.columns[i].noSort){
+ dojo.event.connect(headers[i], "onclick", this, "onSort");
+ }
+ }
+ } else {
+ this.domNode.appendChild(document.createElement("thead"));
+ }
+
+ // if the table doesn't have a tbody already, add one and grab a reference to it
+ if (this.domNode.tBodies.length < 1) {
+ var body = document.createElement("tbody");
+ this.domNode.appendChild(body);
+ } else {
+ var body = this.domNode.tBodies[0];
+ }
+
+ if (this.tbodyClass.length > 0){
+ body.className = this.tbodyClass;
+ }
+ this.parseData(body);
+ }
+ }
+});
Propchange: tapestry/tapestry4/trunk/tapestry-framework/src/js/dojo/src/widget/FilteringTable.js
------------------------------------------------------------------------------
svn:eol-style = native