You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
355 lines
11 KiB
355 lines
11 KiB
define([ |
|
"dojo", |
|
"dijit", |
|
"dojox", |
|
"dijit/_Widget", |
|
"dijit/_TemplatedMixin", |
|
"dijit/_Contained", |
|
"dijit/Toolbar", |
|
"dijit/Menu", |
|
"dijit/MenuItem", |
|
"dijit/MenuSeparator", |
|
"dijit/_editor/_Plugin", |
|
"dijit/form/Button", |
|
"dijit/form/ComboButton", |
|
"dojo/_base/connect", |
|
"dojo/_base/declare", |
|
"dojo/i18n", |
|
"dojo/string", |
|
"dojo/i18n!dojox/editor/plugins/nls/Breadcrumb" |
|
], function(dojo, dijit, dojox, _Widget, _TemplatedMixin, _Contained, Toolbar, Menu, MenuItem, |
|
MenuSeparator, _Plugin) { |
|
|
|
dojo.experimental("dojox.editor.plugins.Breadcrumb"); |
|
|
|
var BreadcrumbMenuTitle = dojo.declare("dojox.editor.plugins._BreadcrumbMenuTitle",[_Widget, _TemplatedMixin, _Contained],{ |
|
// summary: |
|
// Simple internal, non-clickable, menu entry to act as a menu title bar. |
|
templateString: "<tr><td dojoAttachPoint=\"title\" colspan=\"4\" class=\"dijitToolbar\" style=\"font-weight: bold; padding: 3px;\"></td></tr>", |
|
|
|
menuTitle: "", |
|
|
|
postCreate: function(){ |
|
dojo.setSelectable(this.domNode, false); |
|
var label = this.id+"_text"; |
|
this.domNode.setAttribute("aria-labelledby", label); |
|
}, |
|
|
|
_setMenuTitleAttr: function(str){ |
|
this.title.innerHTML = str; |
|
}, |
|
_getMenuTitleAttr: function(str){ |
|
return this.title.innerHTML; |
|
} |
|
}); |
|
|
|
|
|
var Breadcrumb = dojo.declare("dojox.editor.plugins.Breadcrumb", _Plugin,{ |
|
// summary: |
|
// This plugin provides Breadcrumb capability to the editor. As you move |
|
// around the editor, it updates with your current indention depth. |
|
|
|
// _menu: [private] Object |
|
// The popup menu that is displayed. |
|
_menu: null, |
|
|
|
// breadcrumbBar: [protected] dijit/Toolbar |
|
// The toolbar containing the breadcrumb. |
|
breadcrumbBar: null, |
|
|
|
setEditor: function(editor){ |
|
// summary: |
|
// Over-ride for the setting of the editor. |
|
// editor: Object |
|
// The editor to configure for this plugin to use. |
|
this.editor = editor; |
|
this._buttons = []; |
|
this.breadcrumbBar = new dijit.Toolbar(); |
|
|
|
var strings = dojo.i18n.getLocalization("dojox.editor.plugins", "Breadcrumb"); |
|
this._titleTemplate = strings.nodeActions; |
|
|
|
dojo.place(this.breadcrumbBar.domNode, editor.footer); |
|
this.editor.onLoadDeferred.addCallback(dojo.hitch(this, function(){ |
|
this._menu = new dijit.Menu({}); |
|
dojo.addClass(this.breadcrumbBar.domNode, "dojoxEditorBreadcrumbArrow"); |
|
var self = this; |
|
var body = new dijit.form.ComboButton({ |
|
showLabel: true, |
|
label: "body", |
|
_selNode: editor.editNode, |
|
dropDown: this._menu, |
|
onClick: dojo.hitch(this, function(){ |
|
this._menuTarget = editor.editNode; |
|
this._selectContents(); |
|
}) |
|
}); |
|
|
|
// Build the menu |
|
this._menuTitle = new BreadcrumbMenuTitle({menuTitle: strings.nodeActions}); |
|
this._selCMenu = new dijit.MenuItem({label: strings.selectContents, onClick: dojo.hitch(this, this._selectContents)}); |
|
this._delCMenu = new dijit.MenuItem({label: strings.deleteContents, onClick: dojo.hitch(this, this._deleteContents)}); |
|
this._selEMenu = new dijit.MenuItem({label: strings.selectElement, onClick: dojo.hitch(this, this._selectElement)}); |
|
this._delEMenu = new dijit.MenuItem({label: strings.deleteElement, onClick: dojo.hitch(this, this._deleteElement)}); |
|
this._moveSMenu = new dijit.MenuItem({label: strings.moveStart, onClick: dojo.hitch(this, this._moveCToStart)}); |
|
this._moveEMenu = new dijit.MenuItem({label: strings.moveEnd, onClick: dojo.hitch(this, this._moveCToEnd)}); |
|
|
|
this._menu.addChild(this._menuTitle); |
|
this._menu.addChild(this._selCMenu); |
|
this._menu.addChild(this._delCMenu); |
|
this._menu.addChild(new dijit.MenuSeparator({})); |
|
this._menu.addChild(this._selEMenu); |
|
this._menu.addChild(this._delEMenu); |
|
this._menu.addChild(new dijit.MenuSeparator({})); |
|
this._menu.addChild(this._moveSMenu); |
|
this._menu.addChild(this._moveEMenu); |
|
|
|
body._ddConnect = dojo.connect(body, "openDropDown", dojo.hitch(this, function(){ |
|
this._menuTarget = body._selNode; |
|
this._menuTitle.set("menuTitle", dojo.string.substitute(this._titleTemplate,{ |
|
"nodeName": "<body>" |
|
})); |
|
this._selEMenu.set("disabled", true); |
|
this._delEMenu.set("disabled", true); |
|
this._selCMenu.set("disabled", false); |
|
this._delCMenu.set("disabled", false); |
|
this._moveSMenu.set("disabled", false); |
|
this._moveEMenu.set("disabled", false); |
|
})); |
|
this.breadcrumbBar.addChild(body); |
|
this.connect(this.editor, "onNormalizedDisplayChanged", "updateState"); |
|
})); |
|
this.breadcrumbBar.startup(); |
|
if(dojo.isIE){ |
|
// Sometimes IE will mess up layout and needs to be poked. |
|
setTimeout(dojo.hitch(this, function(){this.breadcrumbBar.domNode.className = this.breadcrumbBar.domNode.className;}), 100); |
|
} |
|
}, |
|
|
|
_selectContents: function(){ |
|
// summary: |
|
// Internal function for selecting the contents of a node. |
|
this.editor.focus(); |
|
if(this._menuTarget){ |
|
var nodeName = this._menuTarget.tagName.toLowerCase(); |
|
switch(nodeName){ |
|
case 'br': |
|
case 'hr': |
|
case 'img': |
|
case 'input': |
|
case 'base': |
|
case 'meta': |
|
case 'area': |
|
case 'basefont': |
|
break; |
|
default: |
|
try{ |
|
this.editor._sCall("collapse", [null]); |
|
this.editor._sCall("selectElementChildren", [this._menuTarget]); |
|
this.editor.onDisplayChanged(); |
|
}catch(e){/*squelch*/} |
|
} |
|
} |
|
}, |
|
|
|
_deleteContents: function(){ |
|
// summary: |
|
// Internal function for selecting the contents of a node. |
|
if(this._menuTarget){ |
|
this.editor.beginEditing(); |
|
this._selectContents(); |
|
this.editor._sCall("remove", [this._menuTarget]); |
|
this.editor.endEditing(); |
|
this._updateBreadcrumb(); |
|
this.editor.onDisplayChanged(); |
|
} |
|
}, |
|
|
|
_selectElement: function(){ |
|
// summary: |
|
// Internal function for selecting the contents of a node. |
|
this.editor.focus(); |
|
if(this._menuTarget){ |
|
this.editor._sCall("collapse", [null]); |
|
this.editor._sCall("selectElement", [this._menuTarget]); |
|
this.editor.onDisplayChanged(); |
|
|
|
} |
|
}, |
|
|
|
_deleteElement: function(){ |
|
// summary: |
|
// Internal function for selecting the contents of a node. |
|
if(this._menuTarget){ |
|
this.editor.beginEditing(); |
|
this._selectElement(); |
|
this.editor._sCall("remove", [this._menuTarget]); |
|
this.editor.endEditing(); |
|
this._updateBreadcrumb(); |
|
this.editor.onDisplayChanged(); |
|
} |
|
}, |
|
|
|
_moveCToStart: function(){ |
|
// summary: |
|
// Internal function for selecting the contents of a node. |
|
this.editor.focus(); |
|
if(this._menuTarget){ |
|
this._selectContents(); |
|
this.editor._sCall("collapse", [true]); |
|
} |
|
}, |
|
|
|
_moveCToEnd: function(){ |
|
// summary: |
|
// Internal function for selecting the contents of a node. |
|
this.editor.focus(); |
|
if(this._menuTarget){ |
|
this._selectContents(); |
|
this.editor._sCall("collapse", [false]); |
|
} |
|
}, |
|
|
|
_updateBreadcrumb: function(){ |
|
// summary: |
|
// Function to trigger updating of the breadcrumb |
|
// tags: |
|
// private |
|
var ed = this.editor; |
|
if(ed.window){ |
|
var sel = dijit.range.getSelection(ed.window); |
|
if(sel && sel.rangeCount > 0){ |
|
var range = sel.getRangeAt(0); |
|
|
|
// Check the getSelectedElement call. Needed when dealing with img tags. |
|
var node = ed._sCall("getSelectedElement", []) || range.startContainer; |
|
//var node = range.startContainer; |
|
var bcList = []; |
|
|
|
// Make sure we get a selection within the editor document, |
|
// have seen cases on IE where this wasn't true. |
|
if(node && node.ownerDocument === ed.document){ |
|
while(node && node !== ed.editNode && node != ed.document.body && node != ed.document){ |
|
if(node.nodeType === 1){ |
|
bcList.push({type: node.tagName.toLowerCase(), node: node}); |
|
} |
|
node = node.parentNode; |
|
} |
|
bcList = bcList.reverse(); |
|
|
|
while(this._buttons.length){ |
|
var db = this._buttons.pop(); |
|
dojo.disconnect(db._ddConnect); |
|
this.breadcrumbBar.removeChild(db); |
|
} |
|
this._buttons = []; |
|
|
|
var i; |
|
var self = this; |
|
for(i = 0; i < bcList.length; i++){ |
|
var bc = bcList[i]; |
|
var b = new dijit.form.ComboButton({ |
|
showLabel: true, |
|
label: bc.type, |
|
_selNode: bc.node, |
|
dropDown: this._menu, |
|
onClick: function(){ |
|
self._menuTarget = this._selNode; |
|
self._selectContents(); |
|
} |
|
}); |
|
b._ddConnect = dojo.connect(b, "openDropDown", dojo.hitch(b, function(){ |
|
self._menuTarget = this._selNode; |
|
var nodeName = self._menuTarget.tagName.toLowerCase(); |
|
var title = dojo.string.substitute(self._titleTemplate,{ |
|
"nodeName": "<" + nodeName + ">" |
|
}); |
|
self._menuTitle.set("menuTitle", title); |
|
switch(nodeName){ |
|
case 'br': |
|
case 'hr': |
|
case 'img': |
|
case 'input': |
|
case 'base': |
|
case 'meta': |
|
case 'area': |
|
case 'basefont': |
|
self._selCMenu.set("disabled", true); |
|
self._delCMenu.set("disabled", true); |
|
self._moveSMenu.set("disabled", true); |
|
self._moveEMenu.set("disabled", true); |
|
self._selEMenu.set("disabled", false); |
|
self._delEMenu.set("disabled", false); |
|
break; |
|
default: |
|
self._selCMenu.set("disabled", false); |
|
self._delCMenu.set("disabled", false); |
|
self._selEMenu.set("disabled", false); |
|
self._delEMenu.set("disabled", false); |
|
self._moveSMenu.set("disabled", false); |
|
self._moveEMenu.set("disabled", false); |
|
} |
|
})); |
|
this._buttons.push(b); |
|
this.breadcrumbBar.addChild(b); |
|
} |
|
if(dojo.isIE){ |
|
// Prod it to fix layout. |
|
this.breadcrumbBar.domNode.className = this.breadcrumbBar.domNode.className; |
|
} |
|
|
|
} |
|
} |
|
} |
|
}, |
|
|
|
updateState: function(){ |
|
// summary: |
|
// Over-ride of updateState to hide the toolbar when the iframe is not visible. |
|
// Also triggers the breadcrumb update. |
|
if(dojo.style(this.editor.iframe, "display") === "none" || this.get("disabled")){ |
|
dojo.style(this.breadcrumbBar.domNode, "display", "none"); |
|
}else{ |
|
if(dojo.style(this.breadcrumbBar.domNode, "display") === "none"){ |
|
dojo.style(this.breadcrumbBar.domNode, "display", "block"); |
|
} |
|
this._updateBreadcrumb(); |
|
|
|
// Some themes do padding, so we have to resize again after display. |
|
var size = dojo.marginBox(this.editor.domNode); |
|
this.editor.resize({h: size.h}); |
|
} |
|
}, |
|
|
|
destroy: function(){ |
|
// summary: |
|
// Over-ride to clean up the breadcrumb toolbar. |
|
if(this.breadcrumbBar){ |
|
this.breadcrumbBar.destroyRecursive(); |
|
this.breadcrumbBar = null; |
|
} |
|
if(this._menu){ |
|
this._menu.destroyRecursive(); |
|
delete this._menu; |
|
} |
|
this._buttons = null; |
|
delete this.editor.breadcrumbBar; |
|
this.inherited(arguments); |
|
} |
|
}); |
|
|
|
// For monkey patching |
|
Breadcrumb._BreadcrumbMenuTitle = BreadcrumbMenuTitle; |
|
|
|
// Register this plugin. |
|
dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){ |
|
if(o.plugin){ return; } |
|
var name = o.args.name.toLowerCase(); |
|
if(name === "breadcrumb"){ |
|
o.plugin = new Breadcrumb({}); |
|
} |
|
}); |
|
|
|
return Breadcrumb; |
|
|
|
});
|
|
|