/trunk/api/js/dojo1.0/dijit/_editor/RichText.js |
---|
New file |
0,0 → 1,1446 |
if(!dojo._hasResource["dijit._editor.RichText"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. |
dojo._hasResource["dijit._editor.RichText"] = true; |
dojo.provide("dijit._editor.RichText"); |
dojo.require("dijit._Widget"); |
dojo.require("dijit._editor.selection"); |
dojo.require("dojo.i18n"); |
dojo.requireLocalization("dijit", "Textarea", null, "ROOT"); |
// used to restore content when user leaves this page then comes back |
// but do not try doing document.write if we are using xd loading. |
// document.write will only work if RichText.js is included in the dojo.js |
// file. If it is included in dojo.js and you want to allow rich text saving |
// for back/forward actions, then set djConfig.allowXdRichTextSave = true. |
if(!djConfig["useXDomain"] || djConfig["allowXdRichTextSave"]){ |
if(dojo._postLoad){ |
(function(){ |
var savetextarea = dojo.doc.createElement('textarea'); |
savetextarea.id = "dijit._editor.RichText.savedContent"; |
var s = savetextarea.style; |
s.display='none'; |
s.position='absolute'; |
s.top="-100px"; |
s.left="-100px" |
s.height="3px"; |
s.width="3px"; |
dojo.body().appendChild(savetextarea); |
})(); |
}else{ |
//dojo.body() is not available before onLoad is fired |
try { |
dojo.doc.write('<textarea id="dijit._editor.RichText.savedContent" ' + |
'style="display:none;position:absolute;top:-100px;left:-100px;height:3px;width:3px;overflow:hidden;"></textarea>'); |
}catch(e){ } |
} |
} |
dojo.declare("dijit._editor.RichText", [ dijit._Widget ], { |
constructor: function(){ |
// summary: |
// dijit._editor.RichText is the core of the WYSIWYG editor in dojo, which |
// provides the basic editing features. It also encapsulates the differences |
// of different js engines for various browsers |
// |
// contentPreFilters: Array |
// pre content filter function register array. |
// these filters will be executed before the actual |
// editing area get the html content |
this.contentPreFilters = []; |
// contentPostFilters: Array |
// post content filter function register array. |
// these will be used on the resulting html |
// from contentDomPostFilters. The resuling |
// content is the final html (returned by getValue()) |
this.contentPostFilters = []; |
// contentDomPreFilters: Array |
// pre content dom filter function register array. |
// these filters are applied after the result from |
// contentPreFilters are set to the editing area |
this.contentDomPreFilters = []; |
// contentDomPostFilters: Array |
// post content dom filter function register array. |
// these filters are executed on the editing area dom |
// the result from these will be passed to contentPostFilters |
this.contentDomPostFilters = []; |
// editingAreaStyleSheets: Array |
// array to store all the stylesheets applied to the editing area |
this.editingAreaStyleSheets=[]; |
this._keyHandlers = {}; |
this.contentPreFilters.push(dojo.hitch(this, "_preFixUrlAttributes")); |
if(dojo.isMoz){ |
this.contentPreFilters.push(this._fixContentForMoz); |
} |
//this.contentDomPostFilters.push(this._postDomFixUrlAttributes); |
this.onLoadDeferred = new dojo.Deferred(); |
}, |
// inheritWidth: Boolean |
// whether to inherit the parent's width or simply use 100% |
inheritWidth: false, |
// focusOnLoad: Boolean |
// whether focusing into this instance of richtext when page onload |
focusOnLoad: false, |
// name: String |
// If a save name is specified the content is saved and restored when the user |
// leave this page can come back, or if the editor is not properly closed after |
// editing has started. |
name: "", |
// styleSheets: String |
// semicolon (";") separated list of css files for the editing area |
styleSheets: "", |
// _content: String |
// temporary content storage |
_content: "", |
// height: String |
// set height to fix the editor at a specific height, with scrolling. |
// By default, this is 300px. If you want to have the editor always |
// resizes to accommodate the content, use AlwaysShowToolbar plugin |
// and set height="" |
height: "300px", |
// minHeight: String |
// The minimum height that the editor should have |
minHeight: "1em", |
// isClosed: Boolean |
isClosed: true, |
// isLoaded: Boolean |
isLoaded: false, |
// _SEPARATOR: String |
// used to concat contents from multiple textareas into a single string |
_SEPARATOR: "@@**%%__RICHTEXTBOUNDRY__%%**@@", |
// onLoadDeferred: dojo.Deferred |
// deferred which is fired when the editor finishes loading |
onLoadDeferred: null, |
postCreate: function(){ |
// summary: init |
dojo.publish("dijit._editor.RichText::init", [this]); |
this.open(); |
this.setupDefaultShortcuts(); |
}, |
setupDefaultShortcuts: function(){ |
// summary: add some default key handlers |
// description: |
// Overwrite this to setup your own handlers. The default |
// implementation does not use Editor commands, but directly |
// executes the builtin commands within the underlying browser |
// support. |
var ctrl = this.KEY_CTRL; |
var exec = function(cmd, arg){ |
return arguments.length == 1 ? function(){ this.execCommand(cmd); } : |
function(){ this.execCommand(cmd, arg); } |
} |
this.addKeyHandler("b", ctrl, exec("bold")); |
this.addKeyHandler("i", ctrl, exec("italic")); |
this.addKeyHandler("u", ctrl, exec("underline")); |
this.addKeyHandler("a", ctrl, exec("selectall")); |
this.addKeyHandler("s", ctrl, function () { this.save(true); }); |
this.addKeyHandler("1", ctrl, exec("formatblock", "h1")); |
this.addKeyHandler("2", ctrl, exec("formatblock", "h2")); |
this.addKeyHandler("3", ctrl, exec("formatblock", "h3")); |
this.addKeyHandler("4", ctrl, exec("formatblock", "h4")); |
this.addKeyHandler("\\", ctrl, exec("insertunorderedlist")); |
if(!dojo.isIE){ |
this.addKeyHandler("Z", ctrl, exec("redo")); |
} |
}, |
// events: Array |
// events which should be connected to the underlying editing area |
events: ["onKeyPress", "onKeyDown", "onKeyUp", "onClick"], |
// events: Array |
// events which should be connected to the underlying editing |
// area, events in this array will be addListener with |
// capture=true |
captureEvents: [], |
_editorCommandsLocalized: false, |
_localizeEditorCommands: function(){ |
if(this._editorCommandsLocalized){ |
return; |
} |
this._editorCommandsLocalized = true; |
//in IE, names for blockformat is locale dependent, so we cache the values here |
//if the normal way fails, we try the hard way to get the list |
//do not use _cacheLocalBlockFormatNames here, as it will |
//trigger security warning in IE7 |
//in the array below, ul can not come directly after ol, |
//otherwise the queryCommandValue returns Normal for it |
var formats = ['p', 'pre', 'address', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ol', 'div', 'ul']; |
var localhtml = "", format, i=0; |
while((format=formats[i++])){ |
if(format.charAt(1) != 'l'){ |
localhtml += "<"+format+"><span>content</span></"+format+">"; |
}else{ |
localhtml += "<"+format+"><li>content</li></"+format+">"; |
} |
} |
//queryCommandValue returns empty if we hide editNode, so move it out of screen temporary |
var div=document.createElement('div'); |
div.style.position = "absolute"; |
div.style.left = "-2000px"; |
div.style.top = "-2000px"; |
document.body.appendChild(div); |
div.innerHTML = localhtml; |
var node = div.firstChild; |
while(node){ |
dijit._editor.selection.selectElement(node.firstChild); |
dojo.withGlobal(this.window, "selectElement", dijit._editor.selection, [node.firstChild]); |
var nativename = node.tagName.toLowerCase(); |
this._local2NativeFormatNames[nativename] = document.queryCommandValue("formatblock");//this.queryCommandValue("formatblock"); |
this._native2LocalFormatNames[this._local2NativeFormatNames[nativename]] = nativename; |
node = node.nextSibling; |
} |
document.body.removeChild(div); |
}, |
open: function(/*DomNode?*/element){ |
// summary: |
// Transforms the node referenced in this.domNode into a rich text editing |
// node. This will result in the creation and replacement with an <iframe> |
// if designMode(FF)/contentEditable(IE) is used. |
if((!this.onLoadDeferred)||(this.onLoadDeferred.fired >= 0)){ |
this.onLoadDeferred = new dojo.Deferred(); |
} |
if(!this.isClosed){ this.close(); } |
dojo.publish("dijit._editor.RichText::open", [ this ]); |
this._content = ""; |
if((arguments.length == 1)&&(element["nodeName"])){ this.domNode = element; } // else unchanged |
if( (this.domNode["nodeName"])&& |
(this.domNode.nodeName.toLowerCase() == "textarea")){ |
// if we were created from a textarea, then we need to create a |
// new editing harness node. |
this.textarea = this.domNode; |
this.name=this.textarea.name; |
var html = this._preFilterContent(this.textarea.value); |
this.domNode = dojo.doc.createElement("div"); |
this.domNode.setAttribute('widgetId',this.id); |
this.textarea.removeAttribute('widgetId'); |
this.domNode.cssText = this.textarea.cssText; |
this.domNode.className += " "+this.textarea.className; |
dojo.place(this.domNode, this.textarea, "before"); |
var tmpFunc = dojo.hitch(this, function(){ |
//some browsers refuse to submit display=none textarea, so |
//move the textarea out of screen instead |
with(this.textarea.style){ |
display = "block"; |
position = "absolute"; |
left = top = "-1000px"; |
if(dojo.isIE){ //nasty IE bug: abnormal formatting if overflow is not hidden |
this.__overflow = overflow; |
overflow = "hidden"; |
} |
} |
}); |
if(dojo.isIE){ |
setTimeout(tmpFunc, 10); |
}else{ |
tmpFunc(); |
} |
// this.domNode.innerHTML = html; |
// if(this.textarea.form){ |
// // FIXME: port: this used to be before advice!!! |
// dojo.connect(this.textarea.form, "onsubmit", this, function(){ |
// // FIXME: should we be calling close() here instead? |
// this.textarea.value = this.getValue(); |
// }); |
// } |
}else{ |
var html = this._preFilterContent(this.getNodeChildrenHtml(this.domNode)); |
this.domNode.innerHTML = ''; |
} |
if(html == ""){ html = " "; } |
var content = dojo.contentBox(this.domNode); |
// var content = dojo.contentBox(this.srcNodeRef); |
this._oldHeight = content.h; |
this._oldWidth = content.w; |
this.savedContent = html; |
// If we're a list item we have to put in a blank line to force the |
// bullet to nicely align at the top of text |
if( (this.domNode["nodeName"]) && |
(this.domNode.nodeName == "LI") ){ |
this.domNode.innerHTML = " <br>"; |
} |
this.editingArea = dojo.doc.createElement("div"); |
this.domNode.appendChild(this.editingArea); |
if(this.name != "" && (!djConfig["useXDomain"] || djConfig["allowXdRichTextSave"])){ |
var saveTextarea = dojo.byId("dijit._editor.RichText.savedContent"); |
if(saveTextarea.value != ""){ |
var datas = saveTextarea.value.split(this._SEPARATOR), i=0, dat; |
while((dat=datas[i++])){ |
var data = dat.split(":"); |
if(data[0] == this.name){ |
html = data[1]; |
datas.splice(i, 1); |
break; |
} |
} |
} |
// FIXME: need to do something different for Opera/Safari |
dojo.connect(window, "onbeforeunload", this, "_saveContent"); |
// dojo.connect(window, "onunload", this, "_saveContent"); |
} |
this.isClosed = false; |
// Safari's selections go all out of whack if we do it inline, |
// so for now IE is our only hero |
//if (typeof document.body.contentEditable != "undefined") { |
if(dojo.isIE || dojo.isSafari || dojo.isOpera){ // contentEditable, easy |
var ifr = this.iframe = dojo.doc.createElement('iframe'); |
ifr.src = 'javascript:void(0)'; |
this.editorObject = ifr; |
ifr.style.border = "none"; |
ifr.style.width = "100%"; |
ifr.frameBorder = 0; |
// ifr.style.scrolling = this.height ? "auto" : "vertical"; |
this.editingArea.appendChild(ifr); |
this.window = ifr.contentWindow; |
this.document = this.window.document; |
this.document.open(); |
this.document.write(this._getIframeDocTxt(html)); |
this.document.close(); |
if(dojo.isIE >= 7){ |
if(this.height){ |
ifr.style.height = this.height; |
} |
if(this.minHeight){ |
ifr.style.minHeight = this.minHeight; |
} |
}else{ |
ifr.style.height = this.height ? this.height : this.minHeight; |
} |
if(dojo.isIE){ |
this._localizeEditorCommands(); |
} |
this.onLoad(); |
}else{ // designMode in iframe |
this._drawIframe(html); |
} |
// TODO: this is a guess at the default line-height, kinda works |
if(this.domNode.nodeName == "LI"){ this.domNode.lastChild.style.marginTop = "-1.2em"; } |
this.domNode.className += " RichTextEditable"; |
}, |
//static cache variables shared among all instance of this class |
_local2NativeFormatNames: {}, |
_native2LocalFormatNames: {}, |
_localizedIframeTitles: null, |
_getIframeDocTxt: function(/* String */ html){ |
var _cs = dojo.getComputedStyle(this.domNode); |
if(!this.height && !dojo.isMoz){ |
html="<div>"+html+"</div>"; |
} |
var font = [ _cs.fontWeight, _cs.fontSize, _cs.fontFamily ].join(" "); |
// line height is tricky - applying a units value will mess things up. |
// if we can't get a non-units value, bail out. |
var lineHeight = _cs.lineHeight; |
if(lineHeight.indexOf("px") >= 0){ |
lineHeight = parseFloat(lineHeight)/parseFloat(_cs.fontSize); |
// console.debug(lineHeight); |
}else if(lineHeight.indexOf("em")>=0){ |
lineHeight = parseFloat(lineHeight); |
}else{ |
lineHeight = "1.0"; |
} |
return [ |
this.isLeftToRight() ? "<html><head>" : "<html dir='rtl'><head>", |
(dojo.isMoz ? "<title>" + this._localizedIframeTitles.iframeEditTitle + "</title>" : ""), |
"<style>", |
"body,html {", |
" background:transparent;", |
" padding: 0;", |
" margin: 0;", |
"}", |
// TODO: left positioning will cause contents to disappear out of view |
// if it gets too wide for the visible area |
"body{", |
" top:0px; left:0px; right:0px;", |
((this.height||dojo.isOpera) ? "" : "position: fixed;"), |
" font:", font, ";", |
// FIXME: IE 6 won't understand min-height? |
" min-height:", this.minHeight, ";", |
" line-height:", lineHeight, |
"}", |
"p{ margin: 1em 0 !important; }", |
(this.height ? |
"" : "body,html{overflow-y:hidden;/*for IE*/} body > div {overflow-x:auto;/*for FF to show vertical scrollbar*/}" |
), |
"li > ul:-moz-first-node, li > ol:-moz-first-node{ padding-top: 1.2em; } ", |
"li{ min-height:1.2em; }", |
"</style>", |
this._applyEditingAreaStyleSheets(), |
"</head><body>"+html+"</body></html>" |
].join(""); // String |
}, |
_drawIframe: function(/*String*/html){ |
// summary: |
// Draws an iFrame using the existing one if one exists. |
// Used by Mozilla, Safari, and Opera |
if(!this.iframe){ |
var ifr = this.iframe = dojo.doc.createElement("iframe"); |
// this.iframe.src = "about:blank"; |
// document.body.appendChild(this.iframe); |
// console.debug(this.iframe.contentDocument.open()); |
// dojo.body().appendChild(this.iframe); |
var ifrs = ifr.style; |
// ifrs.border = "1px solid black"; |
ifrs.border = "none"; |
ifrs.lineHeight = "0"; // squash line height |
ifrs.verticalAlign = "bottom"; |
// ifrs.scrolling = this.height ? "auto" : "vertical"; |
this.editorObject = this.iframe; |
// get screen reader text for mozilla here, too |
this._localizedIframeTitles = dojo.i18n.getLocalization("dijit", "Textarea"); |
// need to find any associated label element and update iframe document title |
var label=dojo.query('label[for="'+this.id+'"]'); |
if(label.length){ |
this._localizedIframeTitles.iframeEditTitle = label[0].innerHTML + " " + this._localizedIframeTitles.iframeEditTitle; |
} |
} |
// opera likes this to be outside the with block |
// this.iframe.src = "javascript:void(0)";//dojo.uri.dojoUri("src/widget/templates/richtextframe.html") + ((dojo.doc.domain != currentDomain) ? ("#"+dojo.doc.domain) : ""); |
this.iframe.style.width = this.inheritWidth ? this._oldWidth : "100%"; |
if(this.height){ |
this.iframe.style.height = this.height; |
}else{ |
this.iframe.height = this._oldHeight; |
} |
if(this.textarea){ |
var tmpContent = this.srcNodeRef; |
}else{ |
var tmpContent = dojo.doc.createElement('div'); |
tmpContent.style.display="none"; |
tmpContent.innerHTML = html; |
//append tmpContent to under the current domNode so that the margin |
//calculation below is correct |
this.editingArea.appendChild(tmpContent); |
} |
this.editingArea.appendChild(this.iframe); |
//do we want to show the content before the editing area finish loading here? |
//if external style sheets are used for the editing area, the appearance now |
//and after loading of the editing area won't be the same (and padding/margin |
//calculation above may not be accurate) |
// tmpContent.style.display = "none"; |
// this.editingArea.appendChild(this.iframe); |
var _iframeInitialized = false; |
// console.debug(this.iframe); |
// var contentDoc = this.iframe.contentWindow.document; |
// note that on Safari lower than 420+, we have to get the iframe |
// by ID in order to get something w/ a contentDocument property |
var contentDoc = this.iframe.contentDocument; |
contentDoc.open(); |
contentDoc.write(this._getIframeDocTxt(html)); |
contentDoc.close(); |
// now we wait for onload. Janky hack! |
var ifrFunc = dojo.hitch(this, function(){ |
if(!_iframeInitialized){ |
_iframeInitialized = true; |
}else{ return; } |
if(!this.editNode){ |
try{ |
if(this.iframe.contentWindow){ |
this.window = this.iframe.contentWindow; |
this.document = this.iframe.contentWindow.document |
}else if(this.iframe.contentDocument){ |
// for opera |
this.window = this.iframe.contentDocument.window; |
this.document = this.iframe.contentDocument; |
} |
if(!this.document.body){ |
throw 'Error'; |
} |
}catch(e){ |
setTimeout(ifrFunc,500); |
_iframeInitialized = false; |
return; |
} |
dojo._destroyElement(tmpContent); |
this.document.designMode = "on"; |
// try{ |
// this.document.designMode = "on"; |
// }catch(e){ |
// this._tryDesignModeOnClick=true; |
// } |
this.onLoad(); |
}else{ |
dojo._destroyElement(tmpContent); |
this.editNode.innerHTML = html; |
this.onDisplayChanged(); |
} |
this._preDomFilterContent(this.editNode); |
}); |
ifrFunc(); |
}, |
_applyEditingAreaStyleSheets: function(){ |
// summary: |
// apply the specified css files in styleSheets |
var files = []; |
if(this.styleSheets){ |
files = this.styleSheets.split(';'); |
this.styleSheets = ''; |
} |
//empty this.editingAreaStyleSheets here, as it will be filled in addStyleSheet |
files = files.concat(this.editingAreaStyleSheets); |
this.editingAreaStyleSheets = []; |
var text='', i=0, url; |
while((url=files[i++])){ |
var abstring = (new dojo._Url(dojo.global.location, url)).toString(); |
this.editingAreaStyleSheets.push(abstring); |
text += '<link rel="stylesheet" type="text/css" href="'+abstring+'"/>' |
} |
return text; |
}, |
addStyleSheet: function(/*dojo._Url*/uri){ |
// summary: |
// add an external stylesheet for the editing area |
// uri: a dojo.uri.Uri pointing to the url of the external css file |
var url=uri.toString(); |
//if uri is relative, then convert it to absolute so that it can be resolved correctly in iframe |
if(url.charAt(0) == '.' || (url.charAt(0) != '/' && !uri.host)){ |
url = (new dojo._Url(dojo.global.location, url)).toString(); |
} |
if(dojo.indexOf(this.editingAreaStyleSheets, url) > -1){ |
console.debug("dijit._editor.RichText.addStyleSheet: Style sheet "+url+" is already applied to the editing area!"); |
return; |
} |
this.editingAreaStyleSheets.push(url); |
if(this.document.createStyleSheet){ //IE |
this.document.createStyleSheet(url); |
}else{ //other browser |
var head = this.document.getElementsByTagName("head")[0]; |
var stylesheet = this.document.createElement("link"); |
with(stylesheet){ |
rel="stylesheet"; |
type="text/css"; |
href=url; |
} |
head.appendChild(stylesheet); |
} |
}, |
removeStyleSheet: function(/*dojo._Url*/uri){ |
// summary: |
// remove an external stylesheet for the editing area |
var url=uri.toString(); |
//if uri is relative, then convert it to absolute so that it can be resolved correctly in iframe |
if(url.charAt(0) == '.' || (url.charAt(0) != '/' && !uri.host)){ |
url = (new dojo._Url(dojo.global.location, url)).toString(); |
} |
var index = dojo.indexOf(this.editingAreaStyleSheets, url); |
if(index == -1){ |
console.debug("dijit._editor.RichText.removeStyleSheet: Style sheet "+url+" is not applied to the editing area so it can not be removed!"); |
return; |
} |
delete this.editingAreaStyleSheets[index]; |
dojo.withGlobal(this.window,'query', dojo, ['link:[href="'+url+'"]']).orphan() |
}, |
disabled: false, |
_mozSettingProps: ['styleWithCSS','insertBrOnReturn'], |
setDisabled: function(/*Boolean*/ disabled){ |
if(dojo.isIE || dojo.isSafari || dojo.isOpera){ |
this.editNode.contentEditable=!disabled; |
}else{ //moz |
if(disabled){ |
this._mozSettings=[false,this.blockNodeForEnter==='BR']; |
} |
this.document.designMode=(disabled?'off':'on'); |
if(!disabled){ |
dojo.forEach(this._mozSettingProps, function(s,i){ |
this.document.execCommand(s,false,this._mozSettings[i]); |
},this); |
} |
// this.document.execCommand('contentReadOnly', false, disabled); |
// if(disabled){ |
// this.blur(); //to remove the blinking caret |
// } |
// |
} |
this.disabled=disabled; |
}, |
/* Event handlers |
*****************/ |
_isResized: function(){ return false; }, |
onLoad: function(/* Event */ e){ |
// summary: handler after the content of the document finishes loading |
this.isLoaded = true; |
if(this.height || dojo.isMoz){ |
this.editNode=this.document.body; |
}else{ |
this.editNode=this.document.body.firstChild; |
} |
this.editNode.contentEditable = true; //should do no harm in FF |
this._preDomFilterContent(this.editNode); |
var events=this.events.concat(this.captureEvents),i=0,et; |
while((et=events[i++])){ |
this.connect(this.document, et.toLowerCase(), et); |
} |
if(!dojo.isIE){ |
try{ // sanity check for Mozilla |
// this.document.execCommand("useCSS", false, true); // old moz call |
this.document.execCommand("styleWithCSS", false, false); // new moz call |
//this.document.execCommand("insertBrOnReturn", false, false); // new moz call |
}catch(e2){ } |
// FIXME: when scrollbars appear/disappear this needs to be fired |
}else{ // IE contentEditable |
// give the node Layout on IE |
this.editNode.style.zoom = 1.0; |
} |
if(this.focusOnLoad){ |
this.focus(); |
} |
this.onDisplayChanged(e); |
if(this.onLoadDeferred){ |
this.onLoadDeferred.callback(true); |
} |
}, |
onKeyDown: function(/* Event */ e){ |
// summary: Fired on keydown |
// console.info("onkeydown:", e.keyCode); |
// we need this event at the moment to get the events from control keys |
// such as the backspace. It might be possible to add this to Dojo, so that |
// keyPress events can be emulated by the keyDown and keyUp detection. |
if(dojo.isIE){ |
if(e.keyCode === dojo.keys.BACKSPACE && this.document.selection.type === "Control"){ |
// IE has a bug where if a non-text object is selected in the editor, |
// hitting backspace would act as if the browser's back button was |
// clicked instead of deleting the object. see #1069 |
dojo.stopEvent(e); |
this.execCommand("delete"); |
}else if( (65 <= e.keyCode&&e.keyCode <= 90) || |
(e.keyCode>=37&&e.keyCode<=40) // FIXME: get this from connect() instead! |
){ //arrow keys |
e.charCode = e.keyCode; |
this.onKeyPress(e); |
} |
} |
else if (dojo.isMoz){ |
if(e.keyCode == dojo.keys.TAB && !e.shiftKey && !e.ctrlKey && !e.altKey && this.iframe){ |
// update iframe document title for screen reader |
this.iframe.contentDocument.title = this._localizedIframeTitles.iframeFocusTitle; |
// Place focus on the iframe. A subsequent tab or shift tab will put focus |
// on the correct control. |
this.iframe.focus(); // this.focus(); won't work |
dojo.stopEvent(e); |
}else if (e.keyCode == dojo.keys.TAB && e.shiftKey){ |
// if there is a toolbar, set focus to it, otherwise ignore |
if (this.toolbar){ |
this.toolbar.focus(); |
} |
dojo.stopEvent(e); |
} |
} |
}, |
onKeyUp: function(e){ |
// summary: Fired on keyup |
return; |
}, |
KEY_CTRL: 1, |
KEY_SHIFT: 2, |
onKeyPress: function(e){ |
// summary: Fired on keypress |
// console.info("onkeypress:", e.keyCode); |
// handle the various key events |
var modifiers = e.ctrlKey ? this.KEY_CTRL : 0 | e.shiftKey?this.KEY_SHIFT : 0; |
var key = e.keyChar||e.keyCode; |
if(this._keyHandlers[key]){ |
// console.debug("char:", e.key); |
var handlers = this._keyHandlers[key], i = 0, h; |
while((h = handlers[i++])){ |
if(modifiers == h.modifiers){ |
if(!h.handler.apply(this,arguments)){ |
e.preventDefault(); |
} |
break; |
} |
} |
} |
// function call after the character has been inserted |
setTimeout(dojo.hitch(this, function(){ |
this.onKeyPressed(e); |
}), 1); |
}, |
addKeyHandler: function(/*String*/key, /*Int*/modifiers, /*Function*/handler){ |
// summary: add a handler for a keyboard shortcut |
if(!dojo.isArray(this._keyHandlers[key])){ this._keyHandlers[key] = []; } |
this._keyHandlers[key].push({ |
modifiers: modifiers || 0, |
handler: handler |
}); |
}, |
onKeyPressed: function(/*Event*/e){ |
this.onDisplayChanged(/*e*/); // can't pass in e |
}, |
onClick: function(/*Event*/e){ |
// console.debug('onClick',this._tryDesignModeOnClick); |
// if(this._tryDesignModeOnClick){ |
// try{ |
// this.document.designMode='on'; |
// this._tryDesignModeOnClick=false; |
// }catch(e){} |
// } |
this.onDisplayChanged(e); }, |
_onBlur: function(e){ |
var _c=this.getValue(true); |
if(_c!=this.savedContent){ |
this.onChange(_c); |
this.savedContent=_c; |
} |
if (dojo.isMoz && this.iframe){ |
this.iframe.contentDocument.title = this._localizedIframeTitles.iframeEditTitle; |
} |
// console.info('_onBlur') |
}, |
_initialFocus: true, |
_onFocus: function(/*Event*/e){ |
// console.info('_onFocus') |
// summary: Fired on focus |
if( (dojo.isMoz)&&(this._initialFocus) ){ |
this._initialFocus = false; |
if(this.editNode.innerHTML.replace(/^\s+|\s+$/g, "") == " "){ |
this.placeCursorAtStart(); |
// this.execCommand("selectall"); |
// this.window.getSelection().collapseToStart(); |
} |
} |
}, |
blur: function(){ |
// summary: remove focus from this instance |
if(this.iframe){ |
this.window.blur(); |
}else if(this.editNode){ |
this.editNode.blur(); |
} |
}, |
focus: function(){ |
// summary: move focus to this instance |
if(this.iframe && !dojo.isIE){ |
dijit.focus(this.iframe); |
}else if(this.editNode && this.editNode.focus){ |
// editNode may be hidden in display:none div, lets just punt in this case |
dijit.focus(this.editNode); |
}else{ |
console.debug("Have no idea how to focus into the editor!"); |
} |
}, |
// _lastUpdate: 0, |
updateInterval: 200, |
_updateTimer: null, |
onDisplayChanged: function(/*Event*/e){ |
// summary: |
// This event will be fired everytime the display context |
// changes and the result needs to be reflected in the UI. |
// description: |
// If you don't want to have update too often, |
// onNormalizedDisplayChanged should be used instead |
// var _t=new Date(); |
if(!this._updateTimer){ |
// this._lastUpdate=_t; |
if(this._updateTimer){ |
clearTimeout(this._updateTimer); |
} |
this._updateTimer=setTimeout(dojo.hitch(this,this.onNormalizedDisplayChanged),this.updateInterval); |
} |
}, |
onNormalizedDisplayChanged: function(){ |
// summary: |
// This event is fired every updateInterval ms or more |
// description: |
// If something needs to happen immidiately after a |
// user change, please use onDisplayChanged instead |
this._updateTimer=null; |
}, |
onChange: function(newContent){ |
// summary: |
// this is fired if and only if the editor loses focus and |
// the content is changed |
// console.log('onChange',newContent); |
}, |
_normalizeCommand: function(/*String*/cmd){ |
// summary: |
// Used as the advice function by dojo.connect to map our |
// normalized set of commands to those supported by the target |
// browser |
var command = cmd.toLowerCase(); |
if(command == "formatblock"){ |
if(dojo.isSafari){ command = "heading"; } |
}else if(command == "hilitecolor" && !dojo.isMoz){ |
command = "backcolor"; |
} |
return command; |
}, |
queryCommandAvailable: function(/*String*/command){ |
// summary: |
// Tests whether a command is supported by the host. Clients SHOULD check |
// whether a command is supported before attempting to use it, behaviour |
// for unsupported commands is undefined. |
// command: The command to test for |
var ie = 1; |
var mozilla = 1 << 1; |
var safari = 1 << 2; |
var opera = 1 << 3; |
var safari420 = 1 << 4; |
var gt420 = dojo.isSafari; |
function isSupportedBy(browsers){ |
return { |
ie: Boolean(browsers & ie), |
mozilla: Boolean(browsers & mozilla), |
safari: Boolean(browsers & safari), |
safari420: Boolean(browsers & safari420), |
opera: Boolean(browsers & opera) |
} |
} |
var supportedBy = null; |
switch(command.toLowerCase()){ |
case "bold": case "italic": case "underline": |
case "subscript": case "superscript": |
case "fontname": case "fontsize": |
case "forecolor": case "hilitecolor": |
case "justifycenter": case "justifyfull": case "justifyleft": |
case "justifyright": case "delete": case "selectall": |
supportedBy = isSupportedBy(mozilla | ie | safari | opera); |
break; |
case "createlink": case "unlink": case "removeformat": |
case "inserthorizontalrule": case "insertimage": |
case "insertorderedlist": case "insertunorderedlist": |
case "indent": case "outdent": case "formatblock": |
case "inserthtml": case "undo": case "redo": case "strikethrough": |
supportedBy = isSupportedBy(mozilla | ie | opera | safari420); |
break; |
case "blockdirltr": case "blockdirrtl": |
case "dirltr": case "dirrtl": |
case "inlinedirltr": case "inlinedirrtl": |
supportedBy = isSupportedBy(ie); |
break; |
case "cut": case "copy": case "paste": |
supportedBy = isSupportedBy( ie | mozilla | safari420); |
break; |
case "inserttable": |
supportedBy = isSupportedBy(mozilla | ie); |
break; |
case "insertcell": case "insertcol": case "insertrow": |
case "deletecells": case "deletecols": case "deleterows": |
case "mergecells": case "splitcell": |
supportedBy = isSupportedBy(ie | mozilla); |
break; |
default: return false; |
} |
return (dojo.isIE && supportedBy.ie) || |
(dojo.isMoz && supportedBy.mozilla) || |
(dojo.isSafari && supportedBy.safari) || |
(gt420 && supportedBy.safari420) || |
(dojo.isOpera && supportedBy.opera); // Boolean return true if the command is supported, false otherwise |
}, |
execCommand: function(/*String*/command, argument){ |
// summary: Executes a command in the Rich Text area |
// command: The command to execute |
// argument: An optional argument to the command |
var returnValue; |
//focus() is required for IE to work |
//In addition, focus() makes sure after the execution of |
//the command, the editor receives the focus as expected |
this.focus(); |
command = this._normalizeCommand(command); |
if(argument != undefined){ |
if(command == "heading"){ |
throw new Error("unimplemented"); |
}else if((command == "formatblock") && dojo.isIE){ |
argument = '<'+argument+'>'; |
} |
} |
if(command == "inserthtml"){ |
//TODO: we shall probably call _preDomFilterContent here as well |
argument=this._preFilterContent(argument); |
if(dojo.isIE){ |
var insertRange = this.document.selection.createRange(); |
insertRange.pasteHTML(argument); |
insertRange.select(); |
//insertRange.collapse(true); |
returnValue=true; |
}else if(dojo.isMoz && !argument.length){ |
//mozilla can not inserthtml an empty html to delete current selection |
//so we delete the selection instead in this case |
dojo.withGlobal(this.window,'remove',dijit._editor.selection); // FIXME |
returnValue=true; |
}else{ |
returnValue=this.document.execCommand(command, false, argument); |
} |
}else if( |
(command == "unlink")&& |
(this.queryCommandEnabled("unlink"))&& |
(dojo.isMoz || dojo.isSafari) |
){ |
// fix up unlink in Mozilla to unlink the link and not just the selection |
// grab selection |
// Mozilla gets upset if we just store the range so we have to |
// get the basic properties and recreate to save the selection |
var selection = this.window.getSelection(); |
// var selectionRange = selection.getRangeAt(0); |
// var selectionStartContainer = selectionRange.startContainer; |
// var selectionStartOffset = selectionRange.startOffset; |
// var selectionEndContainer = selectionRange.endContainer; |
// var selectionEndOffset = selectionRange.endOffset; |
// select our link and unlink |
var a = dojo.withGlobal(this.window, "getAncestorElement",dijit._editor.selection, ['a']); |
dojo.withGlobal(this.window, "selectElement", dijit._editor.selection, [a]); |
returnValue=this.document.execCommand("unlink", false, null); |
}else if((command == "hilitecolor")&&(dojo.isMoz)){ |
// // mozilla doesn't support hilitecolor properly when useCSS is |
// // set to false (bugzilla #279330) |
this.document.execCommand("styleWithCSS", false, true); |
returnValue = this.document.execCommand(command, false, argument); |
this.document.execCommand("styleWithCSS", false, false); |
}else if((dojo.isIE)&&( (command == "backcolor")||(command == "forecolor") )){ |
// Tested under IE 6 XP2, no problem here, comment out |
// IE weirdly collapses ranges when we exec these commands, so prevent it |
// var tr = this.document.selection.createRange(); |
argument = arguments.length > 1 ? argument : null; |
returnValue = this.document.execCommand(command, false, argument); |
// timeout is workaround for weird IE behavior were the text |
// selection gets correctly re-created, but subsequent input |
// apparently isn't bound to it |
// setTimeout(function(){tr.select();}, 1); |
}else{ |
argument = arguments.length > 1 ? argument : null; |
// if(dojo.isMoz){ |
// this.document = this.iframe.contentWindow.document |
// } |
if(argument || command!="createlink"){ |
returnValue = this.document.execCommand(command, false, argument); |
} |
} |
this.onDisplayChanged(); |
return returnValue; |
}, |
queryCommandEnabled: function(/*String*/command){ |
// summary: check whether a command is enabled or not |
command = this._normalizeCommand(command); |
if(dojo.isMoz || dojo.isSafari){ |
if(command == "unlink"){ // mozilla returns true always |
// console.debug(dojo.withGlobal(this.window, "hasAncestorElement",dijit._editor.selection, ['a'])); |
return dojo.withGlobal(this.window, "hasAncestorElement",dijit._editor.selection, ['a']); |
}else if (command == "inserttable"){ |
return true; |
} |
} |
//see #4109 |
if(dojo.isSafari) |
if(command == "copy"){ |
command="cut"; |
}else if(command == "paste"){ |
return true; |
} |
// return this.document.queryCommandEnabled(command); |
var elem = (dojo.isIE) ? this.document.selection.createRange() : this.document; |
return elem.queryCommandEnabled(command); |
}, |
queryCommandState: function(command){ |
// summary: check the state of a given command |
command = this._normalizeCommand(command); |
return this.document.queryCommandState(command); |
}, |
queryCommandValue: function(command){ |
// summary: check the value of a given command |
command = this._normalizeCommand(command); |
if(dojo.isIE && command == "formatblock"){ |
return this._local2NativeFormatNames[this.document.queryCommandValue(command)]; |
} |
return this.document.queryCommandValue(command); |
}, |
// Misc. |
placeCursorAtStart: function(){ |
// summary: |
// place the cursor at the start of the editing area |
this.focus(); |
//see comments in placeCursorAtEnd |
var isvalid=false; |
if(dojo.isMoz){ |
var first=this.editNode.firstChild; |
while(first){ |
if(first.nodeType == 3){ |
if(first.nodeValue.replace(/^\s+|\s+$/g, "").length>0){ |
isvalid=true; |
dojo.withGlobal(this.window, "selectElement", dijit._editor.selection, [first]); |
break; |
} |
}else if(first.nodeType == 1){ |
isvalid=true; |
dojo.withGlobal(this.window, "selectElementChildren",dijit._editor.selection, [first]); |
break; |
} |
first = first.nextSibling; |
} |
}else{ |
isvalid=true; |
dojo.withGlobal(this.window, "selectElementChildren",dijit._editor.selection, [this.editNode]); |
} |
if(isvalid){ |
dojo.withGlobal(this.window, "collapse", dijit._editor.selection, [true]); |
} |
}, |
placeCursorAtEnd: function(){ |
// summary: |
// place the cursor at the end of the editing area |
this.focus(); |
//In mozilla, if last child is not a text node, we have to use selectElementChildren on this.editNode.lastChild |
//otherwise the cursor would be placed at the end of the closing tag of this.editNode.lastChild |
var isvalid=false; |
if(dojo.isMoz){ |
var last=this.editNode.lastChild; |
while(last){ |
if(last.nodeType == 3){ |
if(last.nodeValue.replace(/^\s+|\s+$/g, "").length>0){ |
isvalid=true; |
dojo.withGlobal(this.window, "selectElement",dijit._editor.selection, [last]); |
break; |
} |
}else if(last.nodeType == 1){ |
isvalid=true; |
if(last.lastChild){ |
dojo.withGlobal(this.window, "selectElement",dijit._editor.selection, [last.lastChild]); |
}else{ |
dojo.withGlobal(this.window, "selectElement",dijit._editor.selection, [last]); |
} |
break; |
} |
last = last.previousSibling; |
} |
}else{ |
isvalid=true; |
dojo.withGlobal(this.window, "selectElementChildren",dijit._editor.selection, [this.editNode]); |
} |
if(isvalid){ |
dojo.withGlobal(this.window, "collapse", dijit._editor.selection, [false]); |
} |
}, |
getValue: function(/*Boolean?*/nonDestructive){ |
// summary: |
// return the current content of the editing area (post filters are applied) |
if(this.textarea){ |
if(this.isClosed || !this.isLoaded){ |
return this.textarea.value; |
} |
} |
return this._postFilterContent(null, nonDestructive); |
}, |
setValue: function(/*String*/html){ |
// summary: |
// this function set the content. No undo history is preserved |
if(this.textarea && (this.isClosed || !this.isLoaded)){ |
this.textarea.value=html; |
}else{ |
html = this._preFilterContent(html); |
if(this.isClosed){ |
this.domNode.innerHTML = html; |
this._preDomFilterContent(this.domNode); |
}else{ |
this.editNode.innerHTML = html; |
this._preDomFilterContent(this.editNode); |
} |
} |
}, |
replaceValue: function(/*String*/html){ |
// summary: |
// this function set the content while trying to maintain the undo stack |
// (now only works fine with Moz, this is identical to setValue in all |
// other browsers) |
if(this.isClosed){ |
this.setValue(html); |
}else if(this.window && this.window.getSelection && !dojo.isMoz){ // Safari |
// look ma! it's a totally f'd browser! |
this.setValue(html); |
}else if(this.window && this.window.getSelection){ // Moz |
html = this._preFilterContent(html); |
this.execCommand("selectall"); |
if(dojo.isMoz && !html){ html = " " } |
this.execCommand("inserthtml", html); |
this._preDomFilterContent(this.editNode); |
}else if(this.document && this.document.selection){//IE |
//In IE, when the first element is not a text node, say |
//an <a> tag, when replacing the content of the editing |
//area, the <a> tag will be around all the content |
//so for now, use setValue for IE too |
this.setValue(html); |
} |
}, |
_preFilterContent: function(/*String*/html){ |
// summary: |
// filter the input before setting the content of the editing area |
var ec = html; |
dojo.forEach(this.contentPreFilters, function(ef){ if(ef){ ec = ef(ec); } }); |
return ec; |
}, |
_preDomFilterContent: function(/*DomNode*/dom){ |
// summary: |
// filter the input |
dom = dom || this.editNode; |
dojo.forEach(this.contentDomPreFilters, function(ef){ |
if(ef && dojo.isFunction(ef)){ |
ef(dom); |
} |
}, this); |
}, |
_postFilterContent: function(/*DomNode|DomNode[]?*/dom,/*Boolean?*/nonDestructive){ |
// summary: |
// filter the output after getting the content of the editing area |
dom = dom || this.editNode; |
if(this.contentDomPostFilters.length){ |
if(nonDestructive && dom['cloneNode']){ |
dom = dom.cloneNode(true); |
} |
dojo.forEach(this.contentDomPostFilters, function(ef){ |
dom = ef(dom); |
}); |
} |
var ec = this.getNodeChildrenHtml(dom); |
if(!ec.replace(/^(?:\s|\xA0)+/g, "").replace(/(?:\s|\xA0)+$/g,"").length){ ec = ""; } |
// if(dojo.isIE){ |
// //removing appended <P> </P> for IE |
// ec = ec.replace(/(?:<p> </p>[\n\r]*)+$/i,""); |
// } |
dojo.forEach(this.contentPostFilters, function(ef){ |
ec = ef(ec); |
}); |
return ec; |
}, |
_saveContent: function(/*Event*/e){ |
// summary: |
// Saves the content in an onunload event if the editor has not been closed |
var saveTextarea = dojo.byId("dijit._editor.RichText.savedContent"); |
saveTextarea.value += this._SEPARATOR + this.name + ":" + this.getValue(); |
}, |
escapeXml: function(/*String*/str, /*Boolean*/noSingleQuotes){ |
//summary: |
// Adds escape sequences for special characters in XML: &<>"' |
// Optionally skips escapes for single quotes |
str = str.replace(/&/gm, "&").replace(/</gm, "<").replace(/>/gm, ">").replace(/"/gm, """); |
if(!noSingleQuotes){ |
str = str.replace(/'/gm, "'"); |
} |
return str; // string |
}, |
getNodeHtml: function(/* DomNode */node){ |
switch(node.nodeType){ |
case 1: //element node |
var output = '<'+node.tagName.toLowerCase(); |
if(dojo.isMoz){ |
if(node.getAttribute('type')=='_moz'){ |
node.removeAttribute('type'); |
} |
if(node.getAttribute('_moz_dirty') != undefined){ |
node.removeAttribute('_moz_dirty'); |
} |
} |
//store the list of attributes and sort it to have the |
//attributes appear in the dictionary order |
var attrarray = []; |
if(dojo.isIE){ |
var s = node.outerHTML; |
s = s.substr(0,s.indexOf('>')); |
s = s.replace(/(?:['"])[^"']*\1/g, '');//to make the following regexp safe |
var reg = /([^\s=]+)=/g; |
var m, key; |
while((m = reg.exec(s)) != undefined){ |
key=m[1]; |
if(key.substr(0,3) != '_dj'){ |
if(key == 'src' || key == 'href'){ |
if(node.getAttribute('_djrealurl')){ |
attrarray.push([key,node.getAttribute('_djrealurl')]); |
continue; |
} |
} |
if(key == 'class'){ |
attrarray.push([key,node.className]); |
}else{ |
attrarray.push([key,node.getAttribute(key)]); |
} |
} |
} |
}else{ |
var attr, i=0, attrs = node.attributes; |
while((attr=attrs[i++])){ |
//ignore all attributes starting with _dj which are |
//internal temporary attributes used by the editor |
if(attr.name.substr(0,3) != '_dj' /*&& |
(attr.specified == undefined || attr.specified)*/){ |
var v = attr.value; |
if(attr.name == 'src' || attr.name == 'href'){ |
if(node.getAttribute('_djrealurl')){ |
v = node.getAttribute('_djrealurl'); |
} |
} |
attrarray.push([attr.name,v]); |
} |
} |
} |
attrarray.sort(function(a,b){ |
return a[0]<b[0]?-1:(a[0]==b[0]?0:1); |
}); |
i=0; |
while((attr=attrarray[i++])){ |
output += ' '+attr[0]+'="'+attr[1]+'"'; |
} |
if(node.childNodes.length){ |
output += '>' + this.getNodeChildrenHtml(node)+'</'+node.tagName.toLowerCase()+'>'; |
}else{ |
output += ' />'; |
} |
break; |
case 3: //text |
// FIXME: |
var output = this.escapeXml(node.nodeValue,true); |
break; |
case 8: //comment |
// FIXME: |
var output = '<!--'+this.escapeXml(node.nodeValue,true)+'-->'; |
break; |
default: |
var output = "Element not recognized - Type: " + node.nodeType + " Name: " + node.nodeName; |
} |
return output; |
}, |
getNodeChildrenHtml: function(/* DomNode */dom){ |
// summary: Returns the html content of a DomNode and children |
var out = ""; |
if(!dom){ return out; } |
var nodes = dom["childNodes"]||dom; |
var i=0; |
var node; |
while((node=nodes[i++])){ |
out += this.getNodeHtml(node); |
} |
return out; // String |
}, |
close: function(/*Boolean*/save, /*Boolean*/force){ |
// summary: |
// Kills the editor and optionally writes back the modified contents to the |
// element from which it originated. |
// save: |
// Whether or not to save the changes. If false, the changes are discarded. |
// force: |
if(this.isClosed){return false; } |
if(!arguments.length){ save = true; } |
this._content = this.getValue(); |
var changed = (this.savedContent != this._content); |
// line height is squashed for iframes |
// FIXME: why was this here? if (this.iframe){ this.domNode.style.lineHeight = null; } |
if(this.interval){ clearInterval(this.interval); } |
if(this.textarea){ |
with(this.textarea.style){ |
position = ""; |
left = top = ""; |
if(dojo.isIE){ |
overflow = this.__overflow; |
this.__overflow = null; |
} |
} |
if(save){ |
this.textarea.value = this._content; |
}else{ |
this.textarea.value = this.savedContent; |
} |
dojo._destroyElement(this.domNode); |
this.domNode = this.textarea; |
}else{ |
if(save){ |
//why we treat moz differently? comment out to fix #1061 |
// if(dojo.isMoz){ |
// var nc = dojo.doc.createElement("span"); |
// this.domNode.appendChild(nc); |
// nc.innerHTML = this.editNode.innerHTML; |
// }else{ |
// this.domNode.innerHTML = this._content; |
// } |
this.domNode.innerHTML = this._content; |
}else{ |
this.domNode.innerHTML = this.savedContent; |
} |
} |
dojo.removeClass(this.domNode, "RichTextEditable"); |
this.isClosed = true; |
this.isLoaded = false; |
// FIXME: is this always the right thing to do? |
delete this.editNode; |
if(this.window && this.window._frameElement){ |
this.window._frameElement = null; |
} |
this.window = null; |
this.document = null; |
this.editingArea = null; |
this.editorObject = null; |
return changed; // Boolean: whether the content has been modified |
}, |
destroyRendering: function(){ |
// summary: stub |
}, |
destroy: function(){ |
this.destroyRendering(); |
if(!this.isClosed){ this.close(false); } |
this.inherited("destroy",arguments); |
//dijit._editor.RichText.superclass.destroy.call(this); |
}, |
_fixContentForMoz: function(/* String */ html){ |
// summary: |
// Moz can not handle strong/em tags correctly, convert them to b/i |
html = html.replace(/<(\/)?strong([ \>])/gi, '<$1b$2' ); |
html = html.replace(/<(\/)?em([ \>])/gi, '<$1i$2' ); |
return html; // String |
}, |
_srcInImgRegex : /(?:(<img(?=\s).*?\ssrc=)("|')(.*?)\2)|(?:(<img\s.*?src=)([^"'][^ >]+))/gi , |
_hrefInARegex : /(?:(<a(?=\s).*?\shref=)("|')(.*?)\2)|(?:(<a\s.*?href=)([^"'][^ >]+))/gi , |
_preFixUrlAttributes: function(/* String */ html){ |
html = html.replace(this._hrefInARegex, '$1$4$2$3$5$2 _djrealurl=$2$3$5$2') ; |
html = html.replace(this._srcInImgRegex, '$1$4$2$3$5$2 _djrealurl=$2$3$5$2') ; |
return html; // String |
} |
}); |
} |
/trunk/api/js/dojo1.0/dijit/_editor/range.js |
---|
New file |
0,0 → 1,566 |
if(!dojo._hasResource["dijit._editor.range"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. |
dojo._hasResource["dijit._editor.range"] = true; |
dojo.provide("dijit._editor.range"); |
dijit.range={}; |
dijit.range.getIndex=function(/*DomNode*/node, /*DomNode*/parent){ |
// dojo.profile.start("dijit.range.getIndex"); |
var ret=[], retR=[]; |
var stop = parent; |
var onode = node; |
while(node != stop){ |
var i = 0; |
var pnode = node.parentNode, n; |
while(n=pnode.childNodes[i++]){ |
if(n===node){ |
--i; |
break; |
} |
} |
if(i>=pnode.childNodes.length){ |
dojo.debug("Error finding index of a node in dijit.range.getIndex"); |
} |
ret.unshift(i); |
retR.unshift(i-pnode.childNodes.length); |
node = pnode; |
} |
//normalized() can not be called so often to prevent |
//invalidating selection/range, so we have to detect |
//here that any text nodes in a row |
if(ret.length>0 && onode.nodeType==3){ |
var n = onode.previousSibling; |
while(n && n.nodeType==3){ |
ret[ret.length-1]--; |
n = n.previousSibling; |
} |
n = onode.nextSibling; |
while(n && n.nodeType==3){ |
retR[retR.length-1]++; |
n = n.nextSibling; |
} |
} |
// dojo.profile.end("dijit.range.getIndex"); |
return {o: ret, r:retR}; |
} |
dijit.range.getNode = function(/*Array*/index, /*DomNode*/parent){ |
if(!dojo.isArray(index) || index.length==0){ |
return parent; |
} |
var node = parent; |
// if(!node)debugger |
dojo.every(index, function(i){ |
if(i>=0&&i< node.childNodes.length){ |
node = node.childNodes[i]; |
}else{ |
node = null; |
console.debug('Error: can not find node with index',index,'under parent node',parent ); |
return false; //terminate dojo.every |
} |
return true; //carry on the every loop |
}); |
return node; |
} |
dijit.range.getCommonAncestor = function(n1,n2,root){ |
var getAncestors = function(n,root){ |
var as=[]; |
while(n){ |
as.unshift(n); |
if(n!=root && n.tagName!='BODY'){ |
n = n.parentNode; |
}else{ |
break; |
} |
} |
return as; |
}; |
var n1as = getAncestors(n1,root); |
var n2as = getAncestors(n2,root); |
var m = Math.min(n1as.length,n2as.length); |
var com = n1as[0]; //at least, one element should be in the array: the root (BODY by default) |
for(var i=1;i<m;i++){ |
if(n1as[i]===n2as[i]){ |
com = n1as[i] |
}else{ |
break; |
} |
} |
return com; |
} |
dijit.range.getAncestor = function(/*DomNode*/node, /*RegEx?*/regex, /*DomNode?*/root){ |
root = root || node.ownerDocument.body; |
while(node && node !== root){ |
var name = node.nodeName.toUpperCase() ; |
if(regex.test(name)){ |
return node; |
} |
node = node.parentNode; |
} |
return null; |
} |
dijit.range.BlockTagNames = /^(?:P|DIV|H1|H2|H3|H4|H5|H6|ADDRESS|PRE|OL|UL|LI|DT|DE)$/; |
dijit.range.getBlockAncestor = function(/*DomNode*/node, /*RegEx?*/regex, /*DomNode?*/root){ |
root = root || node.ownerDocument.body; |
regex = regex || dijit.range.BlockTagNames; |
var block=null, blockContainer; |
while(node && node !== root){ |
var name = node.nodeName.toUpperCase() ; |
if(!block && regex.test(name)){ |
block = node; |
} |
if(!blockContainer && (/^(?:BODY|TD|TH|CAPTION)$/).test(name)){ |
blockContainer = node; |
} |
node = node.parentNode; |
} |
return {blockNode:block, blockContainer:blockContainer || node.ownerDocument.body}; |
} |
dijit.range.atBeginningOfContainer = function(/*DomNode*/container, /*DomNode*/node, /*Int*/offset){ |
var atBeginning = false; |
var offsetAtBeginning = (offset == 0); |
if(!offsetAtBeginning && node.nodeType==3){ //if this is a text node, check whether the left part is all space |
if(dojo.trim(node.nodeValue.substr(0,offset))==0){ |
offsetAtBeginning = true; |
} |
} |
if(offsetAtBeginning){ |
var cnode = node; |
atBeginning = true; |
while(cnode && cnode !== container){ |
if(cnode.previousSibling){ |
atBeginning = false; |
break; |
} |
cnode = cnode.parentNode; |
} |
} |
return atBeginning; |
} |
dijit.range.atEndOfContainer = function(/*DomNode*/container, /*DomNode*/node, /*Int*/offset){ |
var atEnd = false; |
var offsetAtEnd = (offset == (node.length || node.childNodes.length)); |
if(!offsetAtEnd && node.nodeType==3){ //if this is a text node, check whether the right part is all space |
if(dojo.trim(node.nodeValue.substr(offset))==0){ |
offsetAtEnd = true; |
} |
} |
if(offsetAtEnd){ |
var cnode = node; |
atEnd = true; |
while(cnode && cnode !== container){ |
if(cnode.nextSibling){ |
atEnd = false; |
break; |
} |
cnode = cnode.parentNode; |
} |
} |
return atEnd; |
} |
dijit.range.adjacentNoneTextNode=function(startnode, next){ |
var node = startnode; |
var len = (0-startnode.length) || 0; |
var prop = next?'nextSibling':'previousSibling'; |
while(node){ |
if(node.nodeType!=3){ |
break; |
} |
len += node.length |
node = node[prop]; |
} |
return [node,len]; |
} |
dijit.range._w3c = Boolean(window['getSelection']); |
dijit.range.create = function(){ |
if(dijit.range._w3c){ |
return document.createRange(); |
}else{//IE |
return new dijit.range.W3CRange; |
} |
} |
dijit.range.getSelection = function(win, /*Boolean?*/ignoreUpdate){ |
if(dijit.range._w3c){ |
return win.getSelection(); |
}else{//IE |
var id=win.__W3CRange; |
if(!id || !dijit.range.ie.cachedSelection[id]){ |
var s = new dijit.range.ie.selection(win); |
//use win as the key in an object is not reliable, which |
//can leads to quite odd behaviors. thus we generate a |
//string and use it as a key in the cache |
id=(new Date).getTime(); |
while(id in dijit.range.ie.cachedSelection){ |
id=id+1; |
} |
id=String(id); |
dijit.range.ie.cachedSelection[id] = s; |
}else{ |
var s = dijit.range.ie.cachedSelection[id]; |
} |
if(!ignoreUpdate){ |
s._getCurrentSelection(); |
} |
return s; |
} |
} |
if(!dijit.range._w3c){ |
dijit.range.ie={ |
cachedSelection: {}, |
selection: function(win){ |
this._ranges = []; |
this.addRange = function(r, /*boolean*/internal){ |
this._ranges.push(r); |
if(!internal){ |
r._select(); |
} |
this.rangeCount = this._ranges.length; |
}; |
this.removeAllRanges = function(){ |
//don't detach, the range may be used later |
// for(var i=0;i<this._ranges.length;i++){ |
// this._ranges[i].detach(); |
// } |
this._ranges = []; |
this.rangeCount = 0; |
}; |
var _initCurrentRange = function(){ |
var r = win.document.selection.createRange(); |
var type=win.document.selection.type.toUpperCase(); |
if(type == "CONTROL"){ |
//TODO: multiple range selection(?) |
return new dijit.range.W3CRange(dijit.range.ie.decomposeControlRange(r)); |
}else{ |
return new dijit.range.W3CRange(dijit.range.ie.decomposeTextRange(r)); |
} |
}; |
this.getRangeAt = function(i){ |
return this._ranges[i]; |
}; |
this._getCurrentSelection = function(){ |
this.removeAllRanges(); |
var r=_initCurrentRange(); |
if(r){ |
this.addRange(r, true); |
} |
}; |
}, |
decomposeControlRange: function(range){ |
var firstnode = range.item(0), lastnode = range.item(range.length-1) |
var startContainer = firstnode.parentNode, endContainer = lastnode.parentNode; |
var startOffset = dijit.range.getIndex(firstnode, startContainer).o; |
var endOffset = dijit.range.getIndex(lastnode, endContainer).o+1; |
return [[startContainer, startOffset],[endContainer, endOffset]]; |
}, |
getEndPoint: function(range, end){ |
var atmrange = range.duplicate(); |
atmrange.collapse(!end); |
var cmpstr = 'EndTo' + (end?'End':'Start'); |
var parentNode = atmrange.parentElement(); |
var startnode, startOffset, lastNode; |
if(parentNode.childNodes.length>0){ |
dojo.every(parentNode.childNodes, function(node,i){ |
var calOffset; |
if(node.nodeType != 3){ |
atmrange.moveToElementText(node); |
if(atmrange.compareEndPoints(cmpstr,range) > 0){ |
startnode = node.previousSibling; |
if(lastNode && lastNode.nodeType == 3){ |
//where share we put the start? in the text node or after? |
startnode = lastNode; |
calOffset = true; |
}else{ |
startnode = parentNode; |
startOffset = i; |
return false; |
} |
}else{ |
if(i==parentNode.childNodes.length-1){ |
startnode = parentNode; |
startOffset = parentNode.childNodes.length; |
return false; |
} |
} |
}else{ |
if(i==parentNode.childNodes.length-1){//at the end of this node |
startnode = node; |
calOffset = true; |
} |
} |
// try{ |
if(calOffset && startnode){ |
var prevnode = dijit.range.adjacentNoneTextNode(startnode)[0]; |
if(prevnode){ |
startnode = prevnode.nextSibling; |
}else{ |
startnode = parentNode.firstChild; //firstChild must be a text node |
} |
var prevnodeobj = dijit.range.adjacentNoneTextNode(startnode); |
prevnode = prevnodeobj[0]; |
var lenoffset = prevnodeobj[1]; |
if(prevnode){ |
atmrange.moveToElementText(prevnode); |
atmrange.collapse(false); |
}else{ |
atmrange.moveToElementText(parentNode); |
} |
atmrange.setEndPoint(cmpstr, range); |
startOffset = atmrange.text.length-lenoffset; |
return false; |
} |
// }catch(e){ debugger } |
lastNode = node; |
return true; |
}); |
}else{ |
startnode = parentNode; |
startOffset = 0; |
} |
//if at the end of startnode and we are dealing with start container, then |
//move the startnode to nextSibling if it is a text node |
//TODO: do this for end container? |
if(!end && startnode.nodeType!=3 && startOffset == startnode.childNodes.length){ |
if(startnode.nextSibling && startnode.nextSibling.nodeType==3){ |
startnode = startnode.nextSibling; |
startOffset = 0; |
} |
} |
return [startnode, startOffset]; |
}, |
setEndPoint: function(range, container, offset){ |
//text node |
var atmrange = range.duplicate(); |
if(container.nodeType!=3){ //normal node |
atmrange.moveToElementText(container); |
atmrange.collapse(true); |
if(offset == container.childNodes.length){ |
if(offset > 0){ |
//a simple atmrange.collapse(false); won't work here: |
//although moveToElementText(node) is supposed to encompass the content of the node, |
//but when collapse to end, it is in fact after the ending tag of node (collapse to start |
//is after the begining tag of node as expected) |
var node = container.lastChild; |
var len = 0; |
while(node && node.nodeType == 3){ |
len += node.length; |
container = node; //pass through |
node = node.previousSibling; |
} |
if(node){ |
atmrange.moveToElementText(node); |
} |
atmrange.collapse(false); |
offset = len; //pass through |
}else{ //no childNodes |
atmrange.moveToElementText(container); |
atmrange.collapse(true); |
} |
}else{ |
if(offset > 0){ |
var node = container.childNodes[offset-1]; |
if(node.nodeType==3){ |
container = node; |
offset = node.length; |
//pass through |
}else{ |
atmrange.moveToElementText(node); |
atmrange.collapse(false); |
} |
} |
} |
} |
if(container.nodeType==3){ |
var prevnodeobj = dijit.range.adjacentNoneTextNode(container); |
var prevnode = prevnodeobj[0], len = prevnodeobj[1]; |
if(prevnode){ |
atmrange.moveToElementText(prevnode); |
atmrange.collapse(false); |
//if contentEditable is not inherit, the above collapse won't make the end point |
//in the correctly position: it always has a -1 offset, so compensate it |
if(prevnode.contentEditable!='inherit'){ |
len++; |
} |
}else{ |
atmrange.moveToElementText(container.parentNode); |
atmrange.collapse(true); |
} |
offset += len; |
if(offset>0){ |
if(atmrange.moveEnd('character',offset) != offset){ |
alert('Error when moving!'); |
} |
atmrange.collapse(false); |
} |
} |
return atmrange; |
}, |
decomposeTextRange: function(range){ |
var tmpary = dijit.range.ie.getEndPoint(range); |
var startContainter = tmpary[0], startOffset = tmpary[1]; |
var endContainter = tmpary[0], endOffset = tmpary[1]; |
if(range.htmlText.length){ |
if(range.htmlText == range.text){ //in the same text node |
endOffset = startOffset+range.text.length; |
}else{ |
tmpary = dijit.range.ie.getEndPoint(range,true); |
endContainter = tmpary[0], endOffset = tmpary[1]; |
} |
} |
return [[startContainter, startOffset],[endContainter, endOffset], range.parentElement()]; |
}, |
setRange: function(range, startContainter, |
startOffset, endContainter, endOffset, check){ |
var startrange = dijit.range.ie.setEndPoint(range, startContainter, startOffset); |
range.setEndPoint('StartToStart', startrange); |
if(!this.collapsed){ |
var endrange = dijit.range.ie.setEndPoint(range, endContainter, endOffset); |
range.setEndPoint('EndToEnd', endrange); |
} |
return range; |
} |
} |
dojo.declare("dijit.range.W3CRange",null, { |
constructor: function(){ |
if(arguments.length>0){ |
this.setStart(arguments[0][0][0],arguments[0][0][1]); |
this.setEnd(arguments[0][1][0],arguments[0][1][1],arguments[0][2]); |
}else{ |
this.commonAncestorContainer = null; |
this.startContainer = null; |
this.startOffset = 0; |
this.endContainer = null; |
this.endOffset = 0; |
this.collapsed = true; |
} |
}, |
_simpleSetEndPoint: function(node, range, end){ |
var r = (this._body||node.ownerDocument.body).createTextRange(); |
if(node.nodeType!=1){ |
r.moveToElementText(node.parentNode); |
}else{ |
r.moveToElementText(node); |
} |
r.collapse(true); |
range.setEndPoint(end?'EndToEnd':'StartToStart',r); |
}, |
_updateInternal: function(__internal_common){ |
if(this.startContainer !== this.endContainer){ |
if(!__internal_common){ |
var r = (this._body||this.startContainer.ownerDocument.body).createTextRange(); |
this._simpleSetEndPoint(this.startContainer,r); |
this._simpleSetEndPoint(this.endContainer,r,true); |
__internal_common = r.parentElement(); |
} |
this.commonAncestorContainer = dijit.range.getCommonAncestor(this.startContainer, this.endContainer, __internal_common); |
}else{ |
this.commonAncestorContainer = this.startContainer; |
} |
this.collapsed = (this.startContainer === this.endContainer) && (this.startOffset == this.endOffset); |
}, |
setStart: function(node, offset, __internal_common){ |
if(this.startContainer === node && this.startOffset == offset){ |
return; |
} |
delete this._cachedBookmark; |
this.startContainer = node; |
this.startOffset = offset; |
if(!this.endContainer){ |
this.setEnd(node, offset, __internal_common); |
}else{ |
this._updateInternal(__internal_common); |
} |
}, |
setEnd: function(node, offset, __internal_common){ |
if(this.endContainer === node && this.endOffset == offset){ |
return; |
} |
delete this._cachedBookmark; |
this.endContainer = node; |
this.endOffset = offset; |
if(!this.startContainer){ |
this.setStart(node, offset, __internal_common); |
}else{ |
this._updateInternal(__internal_common); |
} |
}, |
setStartAfter: function(node, offset){ |
this._setPoint('setStart', node, offset, 1); |
}, |
setStartBefore: function(node, offset){ |
this._setPoint('setStart', node, offset, 0); |
}, |
setEndAfter: function(node, offset){ |
this._setPoint('setEnd', node, offset, 1); |
}, |
setEndBefore: function(node, offset){ |
this._setPoint('setEnd', node, offset, 0); |
}, |
_setPoint: function(what, node, offset, ext){ |
var index = dijit.range.getIndex(node, node.parentNode).o; |
this[what](node.parentNode, index.pop()+ext); |
}, |
_getIERange: function(){ |
var r=(this._body||this.endContainer.ownerDocument.body).createTextRange(); |
dijit.range.ie.setRange(r, this.startContainer, this.startOffset, this.endContainer, this.endOffset); |
return r; |
}, |
getBookmark: function(body){ |
this._getIERange(); |
return this._cachedBookmark; |
}, |
_select: function(){ |
var r = this._getIERange(); |
r.select(); |
}, |
deleteContents: function(){ |
var r = this._getIERange(); |
r.pasteHTML(''); |
this.endContainer = this.startContainer; |
this.endOffset = this.startOffset; |
this.collapsed = true; |
}, |
cloneRange: function(){ |
var r = new dijit.range.W3CRange([[this.startContainer,this.startOffset], |
[this.endContainer,this.endOffset]]); |
r._body = this._body; |
return r; |
}, |
detach: function(){ |
this._body = null; |
this.commonAncestorContainer = null; |
this.startContainer = null; |
this.startOffset = 0; |
this.endContainer = null; |
this.endOffset = 0; |
this.collapsed = true; |
} |
}); |
} //if(!dijit.range._w3c) |
} |
/trunk/api/js/dojo1.0/dijit/_editor/_Plugin.js |
---|
New file |
0,0 → 1,91 |
if(!dojo._hasResource["dijit._editor._Plugin"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. |
dojo._hasResource["dijit._editor._Plugin"] = true; |
dojo.provide("dijit._editor._Plugin"); |
dojo.require("dijit._Widget"); |
dojo.require("dijit.Editor"); |
dojo.require("dijit.form.Button"); |
dojo.declare("dijit._editor._Plugin", null, { |
// summary |
// This represents a "plugin" to the editor, which is basically |
// a single button on the Toolbar and some associated code |
constructor: function(/*Object?*/args, /*DomNode?*/node){ |
if(args){ |
dojo.mixin(this, args); |
} |
}, |
editor: null, |
iconClassPrefix: "dijitEditorIcon", |
button: null, |
queryCommand: null, |
command: "", |
commandArg: null, |
useDefaultCommand: true, |
buttonClass: dijit.form.Button, |
updateInterval: 200, // only allow updates every two tenths of a second |
_initButton: function(){ |
if(this.command.length){ |
var label = this.editor.commands[this.command]; |
var className = "dijitEditorIcon "+this.iconClassPrefix + this.command.charAt(0).toUpperCase() + this.command.substr(1); |
if(!this.button){ |
var props = { |
label: label, |
showLabel: false, |
iconClass: className, |
dropDown: this.dropDown |
}; |
this.button = new this.buttonClass(props); |
} |
} |
}, |
updateState: function(){ |
var _e = this.editor; |
var _c = this.command; |
if(!_e){ return; } |
if(!_e.isLoaded){ return; } |
if(!_c.length){ return; } |
if(this.button){ |
try{ |
var enabled = _e.queryCommandEnabled(_c); |
this.button.setDisabled(!enabled); |
if(this.button.setChecked){ |
this.button.setChecked(_e.queryCommandState(_c)); |
} |
}catch(e){ |
console.debug(e); |
} |
} |
}, |
setEditor: function(/*Widget*/editor){ |
// FIXME: detatch from previous editor!! |
this.editor = editor; |
// FIXME: prevent creating this if we don't need to (i.e., editor can't handle our command) |
this._initButton(); |
// FIXME: wire up editor to button here! |
if( (this.command.length) && |
(!this.editor.queryCommandAvailable(this.command)) |
){ |
// console.debug("hiding:", this.command); |
if(this.button){ |
this.button.domNode.style.display = "none"; |
} |
} |
if(this.button && this.useDefaultCommand){ |
dojo.connect(this.button, "onClick", |
dojo.hitch(this.editor, "execCommand", this.command, this.commandArg) |
); |
} |
dojo.connect(this.editor, "onNormalizedDisplayChanged", this, "updateState"); |
}, |
setToolbar: function(/*Widget*/toolbar){ |
if(this.button){ |
toolbar.addChild(this.button); |
} |
// console.debug("adding", this.button, "to:", toolbar); |
} |
}); |
} |
/trunk/api/js/dojo1.0/dijit/_editor/nls/zh/LinkDialog.js |
---|
New file |
0,0 → 1,0 |
({"set": "设定", "text": "文本:", "title": "链接 URL", "url": "URL:", "urlInvalidMessage": "URL 无效。请输入完整的 URL,如“http://www.dojotoolkit.org”"}) |
/trunk/api/js/dojo1.0/dijit/_editor/nls/zh/commands.js |
---|
New file |
0,0 → 1,0 |
({"removeFormat": "除去格式", "copy": "复制", "paste": "粘贴", "selectAll": "全选", "insertOrderedList": "编号列表", "insertTable": "插入/编辑表", "underline": "下划线", "foreColor": "前景色", "htmlToggle": "HTML 源代码", "formatBlock": "段落样式", "insertHorizontalRule": "水平线", "delete": "删除", "insertUnorderedList": "符号列表", "tableProp": "表属性", "insertImage": "插入图像", "superscript": "上标", "subscript": "下标", "createLink": "创建链接", "undo": "撤销", "italic": "斜体", "fontName": "字体名称", "justifyLeft": "左对齐", "unlink": "除去链接", "toggleTableBorder": "切换表边框", "fontSize": "字体大小", "indent": "增加缩进", "redo": "重做", "strikethrough": "删除线", "justifyFull": "对齐", "justifyCenter": "居中", "hiliteColor": "背景色", "deleteTable": "删除表", "outdent": "减少缩进", "cut": "剪切", "plainFormatBlock": "段落样式", "bold": "粗体", "systemShortcutFF": "只能在 Mozilla Firefox 中通过键盘快捷方式执行“${0}”操作。请使用 ${1}。", "justifyRight": "右对齐", "appleKey": "⌘${0}", "ctrlKey": "ctrl+${0}"}) |
/trunk/api/js/dojo1.0/dijit/_editor/nls/pt/LinkDialog.js |
---|
New file |
0,0 → 1,0 |
({"set": "Definir\n", "text": "Texto:\n", "title": "Vincular URL", "url": "URL:", "urlInvalidMessage": "URL inválida. Digite uma URL completa, como 'http://www.dojotoolkit.org'"}) |
/trunk/api/js/dojo1.0/dijit/_editor/nls/pt/commands.js |
---|
New file |
0,0 → 1,0 |
({"removeFormat": "Remover Formato", "copy": "Copiar", "paste": "Colar", "selectAll": "Selecionar Todos", "insertOrderedList": "Lista Numerada", "insertTable": "Inserir/Editar Tabela", "underline": "Sublinhado", "foreColor": "Cor do Primeiro Plano", "htmlToggle": "Origem HTML", "formatBlock": "Estilo de Parágrafo", "insertHorizontalRule": "Régua Horizontal", "delete": "Excluir ", "insertUnorderedList": "Lista com Marcadores", "tableProp": "Propriedade da Tabela", "insertImage": "Inserir Imagem", "superscript": "Sobrescrito", "subscript": "Subscrito", "createLink": "Criar Link", "undo": "Desfazer", "italic": "Itálico", "fontName": "Nome da Fonte", "justifyLeft": "Alinhar pela Esquerda", "unlink": "Remover Link", "toggleTableBorder": "Alternar Moldura da Tabela", "fontSize": "Tamanho da Fonte", "indent": "Recuar", "redo": "Refazer", "strikethrough": "Tachado", "justifyFull": "Justificar", "justifyCenter": "Alinhar pelo Centro", "hiliteColor": "Cor de segundo plano", "deleteTable": "Excluir Tabela", "outdent": "Avançar", "cut": "Recortar", "plainFormatBlock": "Estilo de Parágrafo", "bold": "Negrito", "systemShortcutFF": "A ação \"${0}\" está disponível apenas no Mozilla Firefox utilizando um atalho do teclado. Utilize ${1}.", "justifyRight": "Alinhar pela Direita", "appleKey": "⌘${0}", "ctrlKey": "ctrl+${0}"}) |
/trunk/api/js/dojo1.0/dijit/_editor/nls/ru/LinkDialog.js |
---|
New file |
0,0 → 1,0 |
({"set": "Задать", "text": "Текст:", "title": "URL ссылки", "url": "URL:", "urlInvalidMessage": "Недопустимый адрес URL. Укажите полный URL, например: 'http://www.dojotoolkit.org'"}) |
/trunk/api/js/dojo1.0/dijit/_editor/nls/ru/commands.js |
---|
New file |
0,0 → 1,0 |
({"removeFormat": "Удалить формат", "copy": "Копировать", "paste": "Вставить", "selectAll": "Выбрать все", "insertOrderedList": "Нумерованный список", "insertTable": "Вставить/изменить таблицу", "underline": "Подчеркивание", "foreColor": "Цвет текста", "htmlToggle": "Код HTML", "formatBlock": "Стиль абзаца", "insertHorizontalRule": "Горизонтальная линейка", "delete": "Удалить", "insertUnorderedList": "Список с маркерами", "tableProp": "Свойства таблицы", "insertImage": "Вставить изображение", "superscript": "Верхний индекс", "subscript": "Нижний индекс", "createLink": "Создать ссылку", "undo": "Отменить", "italic": "Курсив", "fontName": "Название шрифта", "justifyLeft": "По левому краю", "unlink": "Удалить ссылку", "toggleTableBorder": "Переключить рамку таблицы", "fontSize": "Размер шрифта", "indent": "Отступ", "redo": "Повторить", "strikethrough": "Перечеркивание", "justifyFull": "По ширине", "justifyCenter": "По центру", "hiliteColor": "Цвет фона", "deleteTable": "Удалить таблицу", "outdent": "Втяжка", "cut": "Вырезать", "plainFormatBlock": "Стиль абзаца", "bold": "Полужирный", "systemShortcutFF": "Действие \"${0}\" доступно в Mozilla Firefox только через сочетание клавиш. Используйте ${1}.", "justifyRight": "По правому краю", "appleKey": "⌘${0}", "ctrlKey": "ctrl+${0}"}) |
/trunk/api/js/dojo1.0/dijit/_editor/nls/LinkDialog.js |
---|
New file |
0,0 → 1,0 |
({"set": "Set", "text": "Text:", "title": "Link URL", "url": "URL:", "urlInvalidMessage": "Invalid URL. Enter a full URL like 'http://www.dojotoolkit.org'"}) |
/trunk/api/js/dojo1.0/dijit/_editor/nls/de/LinkDialog.js |
---|
New file |
0,0 → 1,0 |
({"set": "Festlegen", "text": "Text:", "title": "Link-URL", "url": "URL:", "urlInvalidMessage": "Ungültiger URL. Geben Sie einen vollständigen URL ein. Beispiel: 'http://www.dojotoolkit.org'"}) |
/trunk/api/js/dojo1.0/dijit/_editor/nls/de/commands.js |
---|
New file |
0,0 → 1,0 |
({"removeFormat": "Formatierung entfernen", "copy": "Kopieren", "paste": "Einfügen", "selectAll": "Alles auswählen", "insertOrderedList": "Nummerierung", "insertTable": "Tabelle einfügen/bearbeiten", "underline": "Unterstrichen", "foreColor": "Vordergrundfarbe", "htmlToggle": "HTML-Quelltext", "formatBlock": "Absatzstil", "insertHorizontalRule": "Horizontaler Strich", "delete": "Löschen", "insertUnorderedList": "Aufzählungszeichen", "tableProp": "Tabelleneigenschaft", "insertImage": "Grafik einfügen", "superscript": "Hochgestellt", "subscript": "Tiefgestellt", "createLink": "Link erstellen", "undo": "Rückgängig", "italic": "Kursiv", "fontName": "Schriftartname", "justifyLeft": "Linksbündig", "unlink": "Link entfernen", "toggleTableBorder": "Tabellenumrandung ein-/ausschalten", "ctrlKey": "Strg+${0}", "fontSize": "Schriftgröße", "indent": "Einrücken", "redo": "Wiederherstellen", "strikethrough": "Durchgestrichen", "justifyFull": "Blocksatz", "justifyCenter": "Zentriert", "hiliteColor": "Hintergrundfarbe", "deleteTable": "Tabelle löschen", "outdent": "Ausrücken", "cut": "Ausschneiden", "plainFormatBlock": "Absatzstil", "bold": "Fett", "systemShortcutFF": "Die Aktion \"${0}\" ist in Mozilla Firefox nur über einen Tastaturkurzbefehl verfügbar. Verwenden Sie ${1}.", "justifyRight": "Rechtsbündig", "appleKey": "⌘${0}"}) |
/trunk/api/js/dojo1.0/dijit/_editor/nls/ja/commands.js |
---|
New file |
0,0 → 1,0 |
({"removeFormat": "形式の除去", "copy": "コピー", "paste": "貼り付け", "selectAll": "すべて選択", "insertOrderedList": "番号付きリスト", "insertTable": "テーブルの挿入/編集", "underline": "下線", "foreColor": "前景色", "htmlToggle": "HTML ソース", "formatBlock": "段落スタイル", "insertHorizontalRule": "水平罫線", "delete": "削除", "insertUnorderedList": "黒丸付きリスト", "tableProp": "テーブル・プロパティー", "insertImage": "イメージの挿入", "superscript": "上付き文字", "subscript": "下付き文字", "createLink": "リンクの作成", "undo": "元に戻す", "italic": "イタリック", "fontName": "フォント名", "justifyLeft": "左揃え", "unlink": "リンクの除去", "toggleTableBorder": "テーブル・ボーダーの切り替え", "fontSize": "フォント・サイズ", "indent": "インデント", "redo": "やり直し", "strikethrough": "取り消し線", "justifyFull": "両端揃え", "justifyCenter": "中央揃え", "hiliteColor": "背景色", "deleteTable": "テーブルの削除", "outdent": "アウトデント", "cut": "切り取り", "plainFormatBlock": "段落スタイル", "bold": "太字", "systemShortcutFF": "\"${0}\" アクションは、キーボード・ショートカットを使用して Mozilla Firefox でのみ使用できます。${1} を使用してください。", "justifyRight": "右揃え", "appleKey": "⌘${0}", "ctrlKey": "ctrl+${0}"}) |
/trunk/api/js/dojo1.0/dijit/_editor/nls/ja/LinkDialog.js |
---|
New file |
0,0 → 1,0 |
({"set": "設定", "text": "テキスト:", "title": "URL にリンク", "url": "URL:", "urlInvalidMessage": "無効な URL です。完全な URL (例えば、http://www.dojotoolkit.org) を入力してください。"}) |
/trunk/api/js/dojo1.0/dijit/_editor/nls/FontChoice.js |
---|
New file |
0,0 → 1,0 |
({"1": "xx-small", "2": "x-small", "formatBlock": "Format", "monospaced": "monospaced", "3": "small", "4": "medium", "5": "large", "6": "x-large", "7": "xx-large", "fantasy": "fantasy", "serif": "serif", "p": "Paragraph", "pre": "Pre-formatted", "sans-serif": "sans-serif", "fontName": "Font", "h1": "Heading", "h2": "Subheading", "h3": "Sub-subheading", "fontSize": "Size", "cursive": "cursive"}) |
/trunk/api/js/dojo1.0/dijit/_editor/nls/cs/LinkDialog.js |
---|
New file |
0,0 → 1,0 |
({"set": "Nastavit", "text": "Text:", "title": "Adresa URL odkazu", "url": "Adresa URL:", "urlInvalidMessage": "Neplatná adresa URL. Zadejte úplnou adresu URL ve tvaru 'http://www.dojotoolkit.org'"}) |
/trunk/api/js/dojo1.0/dijit/_editor/nls/cs/commands.js |
---|
New file |
0,0 → 1,0 |
({"removeFormat": "Odebrat formát", "copy": "Kopírovat", "paste": "Vložit", "selectAll": "Vybrat vše", "insertOrderedList": "Číslovaný seznam", "insertTable": "Vložit/upravit tabulku", "underline": "Podtržení", "foreColor": "Barva popředí", "htmlToggle": "Zdroj HTML", "formatBlock": "Styl odstavce", "insertHorizontalRule": "Vodorovné pravítko", "delete": "Odstranit", "insertUnorderedList": "Seznam s odrážkami", "tableProp": "Vlastnost tabulky", "insertImage": "Vložit obraz", "superscript": "Horní index", "subscript": "Dolní index", "createLink": "Vytvořit odkaz", "undo": "Zpět", "italic": "Kurzíva", "fontName": "Název písma", "justifyLeft": "Zarovnat vlevo", "unlink": "Odebrat odkaz", "toggleTableBorder": "Přepnout ohraničení tabulky", "fontSize": "Velikost písma", "indent": "Odsadit", "redo": "Opakovat", "strikethrough": "Přeškrtnutí", "justifyFull": "Do bloku", "justifyCenter": "Zarovnat na střed", "hiliteColor": "Barva pozadí", "deleteTable": "Odstranit tabulku", "outdent": "Předsadit", "cut": "Vyjmout", "plainFormatBlock": "Styl odstavce", "bold": "Tučné", "systemShortcutFF": "Akce \"${0}\" je v prohlížeči Mozilla Firefox dostupná pouze prostřednictvím klávesové zkratky. Použijte klávesy ${1}.", "justifyRight": "Zarovnat vpravo", "appleKey": "⌘${0}", "ctrlKey": "ctrl+${0}"}) |
/trunk/api/js/dojo1.0/dijit/_editor/nls/es/LinkDialog.js |
---|
New file |
0,0 → 1,0 |
({"set": "Establecer", "text": "Texto:", "title": "Enlazar URL", "url": "URL:", "urlInvalidMessage": "URL no válido. Especifique un URL completo como 'http://www.dojotoolkit.org'"}) |
/trunk/api/js/dojo1.0/dijit/_editor/nls/es/commands.js |
---|
New file |
0,0 → 1,0 |
({"removeFormat": "Eliminar formato", "copy": "Copiar", "paste": "Pegar", "selectAll": "Seleccionar todo", "insertOrderedList": "Lista numerada", "insertTable": "Insertar/Editar tabla", "underline": "Subrayado", "foreColor": "Color de primer plano", "htmlToggle": "Fuente HTML", "formatBlock": "Estilo de párrafo", "insertHorizontalRule": "Regla horizontal", "delete": "Suprimir", "insertUnorderedList": "Lista con viñetas", "tableProp": "Propiedad de tabla", "insertImage": "Insertar imagen", "superscript": "Superíndice", "subscript": "Subíndice", "createLink": "Crear enlace", "undo": "Deshacer", "italic": "Cursiva", "fontName": "Nombre de font", "justifyLeft": "Alinear izquierda", "unlink": "Eliminar enlace", "toggleTableBorder": "Conmutar borde de tabla", "ctrlKey": "Control+${0}", "fontSize": "Tamaño de font", "indent": "Sangría", "redo": "Rehacer", "strikethrough": "Tachado", "justifyFull": "Justificar", "justifyCenter": "Alinear centro", "hiliteColor": "Color de segundo plano", "deleteTable": "Suprimir tabla", "outdent": "Anular sangría", "cut": "Cortar", "plainFormatBlock": "Estilo de párrafo", "bold": "Negrita", "systemShortcutFF": "La acción \"${0}\" sólo está disponible en Mozilla Firefox mediante un atajo de teclado. Utilice ${1}.", "justifyRight": "Alinear derecha", "appleKey": "⌘${0}"}) |
/trunk/api/js/dojo1.0/dijit/_editor/nls/fr/commands.js |
---|
New file |
0,0 → 1,0 |
({"removeFormat": "Supprimer la mise en forme", "copy": "Copier", "paste": "Coller", "selectAll": "Sélectionner tout", "insertOrderedList": "Liste numérotée", "insertTable": "Insérer/Modifier un tableau", "underline": "Souligner", "foreColor": "Couleur d'avant-plan", "htmlToggle": "Source HTML", "formatBlock": "Style de paragraphe", "insertHorizontalRule": "Règle horizontale", "delete": "Supprimer", "insertUnorderedList": "Liste à puces", "tableProp": "Propriété du tableau", "insertImage": "Insérer une image", "superscript": "Exposant", "subscript": "Indice", "createLink": "Créer un lien", "undo": "Annuler", "italic": "Italique", "fontName": "Nom de police", "justifyLeft": "Aligner à gauche", "unlink": "Supprimer le lien", "toggleTableBorder": "Afficher/Masquer la bordure du tableau", "fontSize": "Taille de police", "indent": "Retrait", "redo": "Rétablir", "strikethrough": "Barrer", "justifyFull": "Justifier", "justifyCenter": "Aligner au centre", "hiliteColor": "Couleur d'arrière-plan", "deleteTable": "Supprimer le tableau", "outdent": "Retrait négatif", "cut": "Couper", "plainFormatBlock": "Style de paragraphe", "bold": "Gras", "systemShortcutFF": "L'action \"${0}\" est disponible dans Mozilla Firefox uniquement, par le biais d'un raccourci-clavier. Utilisez ${1}.", "justifyRight": "Aligner à droite", "appleKey": "⌘${0}", "ctrlKey": "ctrl+${0}"}) |
/trunk/api/js/dojo1.0/dijit/_editor/nls/fr/LinkDialog.js |
---|
New file |
0,0 → 1,0 |
({"set": "Définir", "text": "Texte :", "title": "URL du lien", "url": "URL :", "urlInvalidMessage": "Adresse URL non valide. Entrez une adresse URL complète de type 'http://www.dojotoolkit.org'"}) |
/trunk/api/js/dojo1.0/dijit/_editor/nls/ko/LinkDialog.js |
---|
New file |
0,0 → 1,0 |
({"set": "설정", "text": "텍스트:", "title": "URL 링크", "url": "URL:", "urlInvalidMessage": "유효하지 않은 URL입니다. 'http://www.dojotoolkit.org'와 같이 전체 URL을 입력하십시오. "}) |
/trunk/api/js/dojo1.0/dijit/_editor/nls/ko/commands.js |
---|
New file |
0,0 → 1,0 |
({"removeFormat": "형식 제거", "copy": "복사", "paste": "붙여넣기", "selectAll": "모두 선택", "insertOrderedList": "번호 목록", "insertTable": "테이블 삽입/편집", "underline": "밑줄", "foreColor": "전경색", "htmlToggle": "HTML 소스", "formatBlock": "단락 양식", "insertHorizontalRule": "수평 자", "delete": "삭제", "insertUnorderedList": "글머리표 목록", "tableProp": "테이블 특성", "insertImage": "이미지 삽입", "superscript": "위첨자", "subscript": "아래첨자", "createLink": "링크 작성", "undo": "실행 취소", "italic": "이탤릭체", "fontName": "글꼴 이름", "justifyLeft": "왼쪽 맞춤", "unlink": "링크 제거", "toggleTableBorder": "토글 테이블 경계", "fontSize": "글꼴 크기", "indent": "들여쓰기", "redo": "다시 실행", "strikethrough": "취소선", "justifyFull": "양쪽 맞춤", "justifyCenter": "가운데 맞춤", "hiliteColor": "배경색", "deleteTable": "테이블 삭제", "outdent": "내어쓰기", "cut": "잘라내기", "plainFormatBlock": "단락 양식", "bold": "굵은체", "systemShortcutFF": "\"${0}\" 조치는 키보드 바로 가기를 사용하는 Mozilla Firefox에서만 사용 가능합니다. ${1} 사용.", "justifyRight": "오른쪽 맞춤", "appleKey": "⌘${0}", "ctrlKey": "ctrl+${0}"}) |
/trunk/api/js/dojo1.0/dijit/_editor/nls/zh-tw/LinkDialog.js |
---|
New file |
0,0 → 1,0 |
({"set": "設定", "text": "文字:", "title": "鏈結 URL", "url": "URL:", "urlInvalidMessage": "URL 無效。請輸入完整的 URL,例如 'http://www.dojotoolkit.org'"}) |
/trunk/api/js/dojo1.0/dijit/_editor/nls/zh-tw/commands.js |
---|
New file |
0,0 → 1,0 |
({"removeFormat": "移除格式", "copy": "複製", "paste": "貼上", "selectAll": "全選", "insertOrderedList": "編號清單", "insertTable": "插入/編輯表格", "underline": "底線", "foreColor": "前景顏色", "htmlToggle": "HTML 原始檔", "formatBlock": "段落樣式", "insertHorizontalRule": "水平尺規", "delete": "刪除", "insertUnorderedList": "項目符號清單", "tableProp": "表格內容", "insertImage": "插入影像", "superscript": "上標", "subscript": "下標", "createLink": "建立鏈結", "undo": "復原", "italic": "斜體", "fontName": "字型名稱", "justifyLeft": "靠左對齊", "unlink": "移除鏈結", "toggleTableBorder": "切換表格邊框", "fontSize": "字型大小", "indent": "縮排", "redo": "重做", "strikethrough": "加刪除線", "justifyFull": "對齊", "justifyCenter": "置中對齊", "hiliteColor": "背景顏色", "deleteTable": "刪除表格", "outdent": "凸排", "cut": "剪下", "plainFormatBlock": "段落樣式", "bold": "粗體", "systemShortcutFF": "\"${0}\" 動作在 Mozilla Firefox 中,只能使用鍵盤快速鍵。請使用 ${1}。", "justifyRight": "靠右對齊", "appleKey": "⌘${0}", "ctrlKey": "ctrl+${0}"}) |
/trunk/api/js/dojo1.0/dijit/_editor/nls/pl/LinkDialog.js |
---|
New file |
0,0 → 1,0 |
({"set": "Ustaw", "text": "Tekst:", "title": "Adres URL odsyłacza", "url": "Adres URL:", "urlInvalidMessage": "Nieprawidłowy adres URL. Wprowadź pełny adres URL, na przykład http://www.dojotoolkit.org."}) |
/trunk/api/js/dojo1.0/dijit/_editor/nls/pl/commands.js |
---|
New file |
0,0 → 1,0 |
({"removeFormat": "Usuń formatowanie", "copy": "Kopiuj", "paste": "Wklej", "selectAll": "Wybierz wszystko", "insertOrderedList": "Lista numerowana", "insertTable": "Wstaw/edytuj tabelę", "underline": "Podkreślenie", "foreColor": "Kolor pierwszego planu", "htmlToggle": "Źródło HTML", "formatBlock": "Styl akapitu", "insertHorizontalRule": "Linia pozioma", "delete": "Usuń", "insertUnorderedList": "Lista wypunktowana", "tableProp": "Właściwość tabeli", "insertImage": "Wstaw obraz", "superscript": "Indeks górny", "subscript": "Indeks dolny", "createLink": "Utwórz odsyłacz", "undo": "Cofnij", "italic": "Kursywa", "fontName": "Nazwa czcionki", "justifyLeft": "Wyrównaj do lewej", "unlink": "Usuń odsyłacz", "toggleTableBorder": "Przełącz ramkę tabeli", "fontSize": "Wielkość czcionki", "indent": "Wcięcie", "redo": "Przywróć", "strikethrough": "Przekreślenie", "justifyFull": "Wyrównaj do lewej i prawej", "justifyCenter": "Wyrównaj do środka", "hiliteColor": "Kolor tła", "deleteTable": "Usuń tabelę", "outdent": "Usuń wcięcie", "cut": "Wytnij", "plainFormatBlock": "Styl akapitu", "bold": "Pogrubienie", "systemShortcutFF": "Działanie ${0} jest dostępne w przeglądarce Mozilla Firefox wyłącznie za pomocą skrótu klawiaturowego. Użyj ${1}.", "justifyRight": "Wyrównaj do prawej", "appleKey": "⌘${0}", "ctrlKey": "ctrl+${0}"}) |
/trunk/api/js/dojo1.0/dijit/_editor/nls/commands.js |
---|
New file |
0,0 → 1,0 |
({"removeFormat": "Remove Format", "copy": "Copy", "paste": "Paste", "selectAll": "Select All", "insertOrderedList": "Numbered List", "insertTable": "Insert/Edit Table", "underline": "Underline", "foreColor": "Foreground Color", "htmlToggle": "HTML Source", "formatBlock": "Paragraph Style", "insertHorizontalRule": "Horizontal Rule", "delete": "Delete", "appleKey": "⌘${0}", "insertUnorderedList": "Bullet List", "tableProp": "Table Property", "insertImage": "Insert Image", "superscript": "Superscript", "subscript": "Subscript", "createLink": "Create Link", "undo": "Undo", "italic": "Italic", "fontName": "Font Name", "justifyLeft": "Align Left", "unlink": "Remove Link", "toggleTableBorder": "Toggle Table Border", "ctrlKey": "ctrl+${0}", "fontSize": "Font Size", "indent": "Indent", "redo": "Redo", "strikethrough": "Strikethrough", "justifyFull": "Justify", "justifyCenter": "Align Center", "hiliteColor": "Background Color", "deleteTable": "Delete Table", "outdent": "Outdent", "cut": "Cut", "plainFormatBlock": "Paragraph Style", "bold": "Bold", "systemShortcutFF": "The \"${0}\" action is only available in Mozilla Firefox using a keyboard shortcut. Use ${1}.", "justifyRight": "Align Right"}) |
/trunk/api/js/dojo1.0/dijit/_editor/nls/hu/commands.js |
---|
New file |
0,0 → 1,0 |
({"removeFormat": "Formázás eltávolítása", "copy": "Másolás", "paste": "Beillesztés", "selectAll": "Összes kijelölése", "insertOrderedList": "Számozott lista", "insertTable": "Táblázat beszúrása/szerkesztése", "underline": "Aláhúzott", "foreColor": "Előtérszín", "htmlToggle": "HTML forrás", "formatBlock": "Bekezdés stílusa", "insertHorizontalRule": "Vízszintes vonalzó", "delete": "Törlés", "insertUnorderedList": "Felsorolásjeles lista", "tableProp": "Táblázat tulajdonságai", "insertImage": "Kép beszúrása", "superscript": "Felső index", "subscript": "Alsó index", "createLink": "Hivatkozás létrehozása", "undo": "Visszavonás", "italic": "Dőlt", "fontName": "Betűtípus", "justifyLeft": "Balra igazítás", "unlink": "Hivatkozás eltávolítása", "toggleTableBorder": "Táblázatszegély ki-/bekapcsolása", "fontSize": "Betűméret", "indent": "Behúzás", "redo": "Újra", "strikethrough": "Áthúzott", "justifyFull": "Sorkizárás", "justifyCenter": "Középre igazítás", "hiliteColor": "Háttérszín", "deleteTable": "Táblázat törlése", "outdent": "Negatív behúzás", "cut": "Kivágás", "plainFormatBlock": "Bekezdés stílusa", "bold": "Félkövér", "systemShortcutFF": "A(z) \"${0}\" művelet csak Mozilla Firefox böngészőben érhető el billentyűparancs használatával. Használja a következőt: ${1}.", "justifyRight": "Jobbra igazítás", "appleKey": "⌘${0}", "ctrlKey": "ctrl+${0}"}) |
/trunk/api/js/dojo1.0/dijit/_editor/nls/hu/LinkDialog.js |
---|
New file |
0,0 → 1,0 |
({"set": "Beállítás", "text": "Szöveg:", "title": "Hivatkozás URL címe", "url": "URL:", "urlInvalidMessage": "Érvénytelen URL cím. Adjon meg teljes URL címet, például: 'http://www.dojotoolkit.org'"}) |
/trunk/api/js/dojo1.0/dijit/_editor/nls/it/LinkDialog.js |
---|
New file |
0,0 → 1,0 |
({"set": "Imposta", "text": "Testo:", "title": "URL di collegamento", "url": "URL:", "urlInvalidMessage": "URL non valido. Immettere un URL completo come nel seguente esempio: 'http://www.dojotoolkit.org'"}) |
/trunk/api/js/dojo1.0/dijit/_editor/nls/it/commands.js |
---|
New file |
0,0 → 1,0 |
({"removeFormat": "Rimuovi formato", "copy": "Copia", "paste": "Incolla", "selectAll": "Seleziona tutto", "insertOrderedList": "Elenco numerato", "insertTable": "Inserisci/Modifica tabella", "underline": "Sottolineato", "foreColor": "Colore primo piano", "htmlToggle": "Origine HTML", "formatBlock": "Stile paragrafo", "insertHorizontalRule": "Righello orizzontale", "delete": "Elimina", "insertUnorderedList": "Elenco puntato", "tableProp": "Proprietà tabella", "insertImage": "Inserisci immagine", "superscript": "Apice", "subscript": "Pedice", "createLink": "Crea collegamento", "undo": "Annulla", "italic": "Corsivo", "fontName": "Nome carattere", "justifyLeft": "Allinea a sinistra", "unlink": "Rimuovi collegamento", "toggleTableBorder": "Mostra/Nascondi margine tabella", "fontSize": "Dimensione carattere", "indent": "Rientra", "redo": "Ripristina", "strikethrough": "Barrato", "justifyFull": "Giustifica", "justifyCenter": "Allinea al centro", "hiliteColor": "Colore sfondo", "deleteTable": "Elimina tabella", "outdent": "Rimuovi rientro", "cut": "Taglia", "plainFormatBlock": "Stile paragrafo", "bold": "Grassetto", "systemShortcutFF": "L'azione \"${0}\" è disponibile solo in Mozilla Firefox tramite tasti di scelta rapida. Utilizzare ${1}.", "justifyRight": "Allinea a destra", "appleKey": "⌘${0}", "ctrlKey": "ctrl+${0}"}) |
/trunk/api/js/dojo1.0/dijit/_editor/selection.js |
---|
New file |
0,0 → 1,220 |
if(!dojo._hasResource["dijit._editor.selection"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. |
dojo._hasResource["dijit._editor.selection"] = true; |
dojo.provide("dijit._editor.selection"); |
// FIXME: |
// all of these methods branch internally for IE. This is probably |
// sub-optimal in terms of runtime performance. We should investigate the |
// size difference for differentiating at definition time. |
dojo.mixin(dijit._editor.selection, { |
getType: function(){ |
// summary: Get the selection type (like document.select.type in IE). |
if(dojo.doc["selection"]){ //IE |
return dojo.doc.selection.type.toLowerCase(); |
}else{ |
var stype = "text"; |
// Check if the actual selection is a CONTROL (IMG, TABLE, HR, etc...). |
var oSel; |
try{ |
oSel = dojo.global.getSelection(); |
}catch(e){ /*squelch*/ } |
if(oSel && oSel.rangeCount==1){ |
var oRange = oSel.getRangeAt(0); |
if( (oRange.startContainer == oRange.endContainer) && |
((oRange.endOffset - oRange.startOffset) == 1) && |
(oRange.startContainer.nodeType != 3 /* text node*/) |
){ |
stype = "control"; |
} |
} |
return stype; |
} |
}, |
getSelectedText: function(){ |
// summary: |
// Return the text (no html tags) included in the current selection or null if no text is selected |
if(dojo.doc["selection"]){ //IE |
if(dijit._editor.selection.getType() == 'control'){ |
return null; |
} |
return dojo.doc.selection.createRange().text; |
}else{ |
var selection = dojo.global.getSelection(); |
if(selection){ |
return selection.toString(); |
} |
} |
}, |
getSelectedHtml: function(){ |
// summary: |
// Return the html of the current selection or null if unavailable |
if(dojo.doc["selection"]){ //IE |
if(dijit._editor.selection.getType() == 'control'){ |
return null; |
} |
return dojo.doc.selection.createRange().htmlText; |
}else{ |
var selection = dojo.global.getSelection(); |
if(selection && selection.rangeCount){ |
var frag = selection.getRangeAt(0).cloneContents(); |
var div = document.createElement("div"); |
div.appendChild(frag); |
return div.innerHTML; |
} |
return null; |
} |
}, |
getSelectedElement: function(){ |
// summary: |
// Retrieves the selected element (if any), just in the case that |
// a single element (object like and image or a table) is |
// selected. |
if(this.getType() == "control"){ |
if(dojo.doc["selection"]){ //IE |
var range = dojo.doc.selection.createRange(); |
if(range && range.item){ |
return dojo.doc.selection.createRange().item(0); |
} |
}else{ |
var selection = dojo.global.getSelection(); |
return selection.anchorNode.childNodes[ selection.anchorOffset ]; |
} |
} |
}, |
getParentElement: function(){ |
// summary: |
// Get the parent element of the current selection |
if(this.getType() == "control"){ |
var p = this.getSelectedElement(); |
if(p){ return p.parentNode; } |
}else{ |
if(dojo.doc["selection"]){ //IE |
return dojo.doc.selection.createRange().parentElement(); |
}else{ |
var selection = dojo.global.getSelection(); |
if(selection){ |
var node = selection.anchorNode; |
while(node && (node.nodeType != 1)){ // not an element |
node = node.parentNode; |
} |
return node; |
} |
} |
} |
}, |
hasAncestorElement: function(/*String*/tagName /* ... */){ |
// summary: |
// Check whether current selection has a parent element which is |
// of type tagName (or one of the other specified tagName) |
return (this.getAncestorElement.apply(this, arguments) != null); |
}, |
getAncestorElement: function(/*String*/tagName /* ... */){ |
// summary: |
// Return the parent element of the current selection which is of |
// type tagName (or one of the other specified tagName) |
var node = this.getSelectedElement() || this.getParentElement(); |
return this.getParentOfType(node, arguments); |
}, |
isTag: function(/*DomNode*/node, /*Array*/tags){ |
if(node && node.tagName){ |
var _nlc = node.tagName.toLowerCase(); |
for(var i=0; i<tags.length; i++){ |
var _tlc = String(tags[i]).toLowerCase(); |
if(_nlc == _tlc){ |
return _tlc; |
} |
} |
} |
return ""; |
}, |
getParentOfType: function(/*DomNode*/node, /*Array*/tags){ |
while(node){ |
if(this.isTag(node, tags).length){ |
return node; |
} |
node = node.parentNode; |
} |
return null; |
}, |
remove: function(){ |
// summary: delete current selection |
var _s = dojo.doc.selection; |
if(_s){ //IE |
if(_s.type.toLowerCase() != "none"){ |
_s.clear(); |
} |
return _s; |
}else{ |
_s = dojo.global.getSelection(); |
_s.deleteFromDocument(); |
return _s; |
} |
}, |
selectElementChildren: function(/*DomNode*/element,/*Boolean?*/nochangefocus){ |
// summary: |
// clear previous selection and select the content of the node |
// (excluding the node itself) |
var _window = dojo.global; |
var _document = dojo.doc; |
element = dojo.byId(element); |
if(_document.selection && dojo.body().createTextRange){ // IE |
var range = element.ownerDocument.body.createTextRange(); |
range.moveToElementText(element); |
if(!nochangefocus){ |
range.select(); |
} |
}else if(_window["getSelection"]){ |
var selection = _window.getSelection(); |
if(selection["setBaseAndExtent"]){ // Safari |
selection.setBaseAndExtent(element, 0, element, element.innerText.length - 1); |
}else if(selection["selectAllChildren"]){ // Mozilla |
selection.selectAllChildren(element); |
} |
} |
}, |
selectElement: function(/*DomNode*/element,/*Boolean?*/nochangefocus){ |
// summary: |
// clear previous selection and select element (including all its children) |
var _document = dojo.doc; |
element = dojo.byId(element); |
if(_document.selection && dojo.body().createTextRange){ // IE |
try{ |
var range = dojo.body().createControlRange(); |
range.addElement(element); |
if(!nochangefocus){ |
range.select(); |
} |
}catch(e){ |
this.selectElementChildren(element,nochangefocus); |
} |
}else if(dojo.global["getSelection"]){ |
var selection = dojo.global.getSelection(); |
// FIXME: does this work on Safari? |
if(selection["removeAllRanges"]){ // Mozilla |
var range = _document.createRange() ; |
range.selectNode(element) ; |
selection.removeAllRanges() ; |
selection.addRange(range) ; |
} |
} |
} |
}); |
} |
/trunk/api/js/dojo1.0/dijit/_editor/plugins/EnterKeyHandling.js |
---|
New file |
0,0 → 1,422 |
if(!dojo._hasResource["dijit._editor.plugins.EnterKeyHandling"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. |
dojo._hasResource["dijit._editor.plugins.EnterKeyHandling"] = true; |
dojo.provide("dijit._editor.plugins.EnterKeyHandling"); |
dojo.declare("dijit._editor.plugins.EnterKeyHandling",null,{ |
// blockNodeForEnter: String |
// this property decides the behavior of Enter key. It can be either P, |
// DIV, BR, or empty (which means disable this feature). Anything else |
// will trigger errors. |
blockNodeForEnter: 'P', |
constructor: function(args){ |
if(args){ |
dojo.mixin(this,args); |
} |
}, |
setEditor: function(editor){ |
this.editor=editor; |
if(this.blockNodeForEnter=='BR'){ |
if(dojo.isIE){ |
editor.contentDomPreFilters.push(dojo.hitch(this, "regularPsToSingleLinePs")); |
editor.contentDomPostFilters.push(dojo.hitch(this, "singleLinePsToRegularPs")); |
editor.onLoadDeferred.addCallback(dojo.hitch(this, "_fixNewLineBehaviorForIE")); |
}else{ |
editor.onLoadDeferred.addCallback(dojo.hitch(this,function(d){ |
try{ |
this.editor.document.execCommand("insertBrOnReturn", false, true); |
}catch(e){}; |
return d; |
})); |
} |
}else if(this.blockNodeForEnter){ |
//add enter key handler |
// FIXME: need to port to the new event code!! |
dojo['require']('dijit._editor.range'); |
var h=dojo.hitch(this,this.handleEnterKey); |
editor.addKeyHandler(13, 0, h); //enter |
editor.addKeyHandler(13, 2, h); //shift+enter |
this.connect(this.editor,'onKeyPressed','onKeyPressed'); |
} |
}, |
connect: function(o,f,tf){ |
if(!this._connects){ |
this._connects=[]; |
} |
this._connects.push(dojo.connect(o,f,this,tf)); |
}, |
destroy: function(){ |
dojo.forEach(this._connects,dojo.disconnect); |
this._connects=[]; |
}, |
onKeyPressed: function(e){ |
if(this._checkListLater){ |
if(dojo.withGlobal(this.editor.window, 'isCollapsed', dijit._editor.selection)){ |
if(!dojo.withGlobal(this.editor.window, 'hasAncestorElement', dijit._editor.selection, ['LI'])){ |
//circulate the undo detection code by calling RichText::execCommand directly |
dijit._editor.RichText.prototype.execCommand.apply(this.editor, ['formatblock',this.blockNodeForEnter]); |
//set the innerHTML of the new block node |
var block = dojo.withGlobal(this.editor.window, 'getAncestorElement', dijit._editor.selection, [this.blockNodeForEnter]) |
if(block){ |
block.innerHTML=this.bogusHtmlContent; |
if(dojo.isIE){ |
//the following won't work, it will move the caret to the last list item in the previous list |
// var newrange = dijit.range.create(); |
// newrange.setStart(block.firstChild,0); |
// var selection = dijit.range.getSelection(this.editor.window) |
// selection.removeAllRanges(); |
// selection.addRange(newrange); |
//move to the start by move backward one char |
var r = this.editor.document.selection.createRange(); |
r.move('character',-1); |
r.select(); |
} |
}else{ |
alert('onKeyPressed: Can not find the new block node'); |
} |
} |
} |
this._checkListLater = false; |
}else if(this._pressedEnterInBlock){ |
//the new created is the original current P, so we have previousSibling below |
this.removeTrailingBr(this._pressedEnterInBlock.previousSibling); |
delete this._pressedEnterInBlock; |
} |
}, |
bogusHtmlContent: ' ', |
blockNodes: /^(?:H1|H2|H3|H4|H5|H6|LI)$/, |
handleEnterKey: function(e){ |
// summary: manually handle enter key event to make the behavior consistant across |
// all supported browsers. See property blockNodeForEnter for available options |
if(!this.blockNodeForEnter){ return true; } //let browser handle this |
if(e.shiftKey //shift+enter always generates <br> |
|| this.blockNodeForEnter=='BR'){ |
var parent = dojo.withGlobal(this.editor.window, "getParentElement", dijit._editor.selection); |
var header = dijit.range.getAncestor(parent,this.editor.blockNodes); |
if(header){ |
if(header.tagName=='LI'){ |
return true; //let brower handle |
} |
var selection = dijit.range.getSelection(this.editor.window); |
var range = selection.getRangeAt(0); |
if(!range.collapsed){ |
range.deleteContents(); |
} |
if(dijit.range.atBeginningOfContainer(header, range.startContainer, range.startOffset)){ |
dojo.place(this.editor.document.createElement('br'), header, "before"); |
}else if(dijit.range.atEndOfContainer(header, range.startContainer, range.startOffset)){ |
dojo.place(this.editor.document.createElement('br'), header, "after"); |
var newrange = dijit.range.create(); |
newrange.setStartAfter(header); |
selection.removeAllRanges(); |
selection.addRange(newrange); |
}else{ |
return true; //let brower handle |
} |
}else{ |
//don't change this: do not call this.execCommand, as that may have other logic in subclass |
// FIXME |
dijit._editor.RichText.prototype.execCommand.call(this.editor, 'inserthtml', '<br>'); |
} |
return false; |
} |
var _letBrowserHandle = true; |
//blockNodeForEnter is either P or DIV |
//first remove selection |
var selection = dijit.range.getSelection(this.editor.window); |
var range = selection.getRangeAt(0); |
if(!range.collapsed){ |
range.deleteContents(); |
} |
var block = dijit.range.getBlockAncestor(range.endContainer, null, this.editor.editNode); |
if(block.blockNode && block.blockNode.tagName == 'LI'){ |
this._checkListLater = true; |
return true; |
}else{ |
this._checkListLater = false; |
} |
//text node directly under body, let's wrap them in a node |
if(!block.blockNode){ |
this.editor.document.execCommand('formatblock',false, this.blockNodeForEnter); |
//get the newly created block node |
// FIXME |
block = {blockNode:dojo.withGlobal(this.editor.window, "getAncestorElement", dijit._editor.selection, [this.blockNodeForEnter]), |
blockContainer: this.editor.editNode}; |
if(block.blockNode){ |
if((block.blockNode.textContent||block.blockNode.innerHTML).replace(/^\s+|\s+$/g, "").length==0){ |
this.removeTrailingBr(block.blockNode); |
return false; |
} |
}else{ |
block.blockNode = this.editor.editNode; |
} |
selection = dijit.range.getSelection(this.editor.window); |
range = selection.getRangeAt(0); |
} |
var newblock = this.editor.document.createElement(this.blockNodeForEnter); |
newblock.innerHTML=this.bogusHtmlContent; |
this.removeTrailingBr(block.blockNode); |
if(dijit.range.atEndOfContainer(block.blockNode, range.endContainer, range.endOffset)){ |
if(block.blockNode === block.blockContainer){ |
block.blockNode.appendChild(newblock); |
}else{ |
dojo.place(newblock, block.blockNode, "after"); |
} |
_letBrowserHandle = false; |
//lets move caret to the newly created block |
var newrange = dijit.range.create(); |
newrange.setStart(newblock,0); |
selection.removeAllRanges(); |
selection.addRange(newrange); |
if(this.editor.height){ |
newblock.scrollIntoView(false); |
} |
}else if(dijit.range.atBeginningOfContainer(block.blockNode, |
range.startContainer, range.startOffset)){ |
if(block.blockNode === block.blockContainer){ |
dojo.place(newblock, block.blockNode, "first"); |
}else{ |
dojo.place(newblock, block.blockNode, "before"); |
} |
if(this.editor.height){ |
//browser does not scroll the caret position into view, do it manually |
newblock.scrollIntoView(false); |
} |
_letBrowserHandle = false; |
}else{ //press enter in the middle of P |
if(dojo.isMoz){ |
//press enter in middle of P may leave a trailing <br/>, let's remove it later |
this._pressedEnterInBlock = block.blockNode; |
} |
} |
return _letBrowserHandle; |
}, |
removeTrailingBr: function(container){ |
if(/P|DIV|LI/i .test(container.tagName)){ |
var para = container; |
}else{ |
var para = dijit._editor.selection.getParentOfType(container,['P','DIV','LI']); |
} |
if(!para){ return; } |
if(para.lastChild){ |
if(para.childNodes.length>1 && para.lastChild.nodeType==3 && /^[\s\xAD]*$/ .test(para.lastChild.nodeValue)){ |
dojo._destroyElement(para.lastChild); |
} |
if(para.lastChild && para.lastChild.tagName=='BR'){ |
dojo._destroyElement(para.lastChild); |
} |
} |
if(para.childNodes.length==0){ |
para.innerHTML=this.bogusHtmlContent; |
} |
}, |
_fixNewLineBehaviorForIE: function(d){ |
if(typeof this.editor.document.__INSERTED_EDITIOR_NEWLINE_CSS == "undefined"){ |
var lineFixingStyles = "p{margin:0 !important;}"; |
var insertCssText = function( |
/*String*/ cssStr, |
/*Document*/ doc, |
/*String*/ URI) |
{ |
// summary: |
// Attempt to insert CSS rules into the document through inserting a |
// style element |
// DomNode Style = insertCssText(String ".dojoMenu {color: green;}"[, DomDoc document, dojo.uri.Uri Url ]) |
if(!cssStr){ |
return; // HTMLStyleElement |
} |
if(!doc){ doc = document; } |
// if(URI){// fix paths in cssStr |
// cssStr = dojo.html.fixPathsInCssText(cssStr, URI); |
// } |
var style = doc.createElement("style"); |
style.setAttribute("type", "text/css"); |
// IE is b0rken enough to require that we add the element to the doc |
// before changing it's properties |
var head = doc.getElementsByTagName("head")[0]; |
if(!head){ // must have a head tag |
console.debug("No head tag in document, aborting styles"); |
return; // HTMLStyleElement |
}else{ |
head.appendChild(style); |
} |
if(style.styleSheet){// IE |
var setFunc = function(){ |
try{ |
style.styleSheet.cssText = cssStr; |
}catch(e){ dojo.debug(e); } |
}; |
if(style.styleSheet.disabled){ |
setTimeout(setFunc, 10); |
}else{ |
setFunc(); |
} |
}else{ // w3c |
var cssText = doc.createTextNode(cssStr); |
style.appendChild(cssText); |
} |
return style; // HTMLStyleElement |
} |
insertCssText(lineFixingStyles, this.editor.document); |
this.editor.document.__INSERTED_EDITIOR_NEWLINE_CSS = true; |
// this.regularPsToSingleLinePs(this.editNode); |
return d; |
} |
}, |
regularPsToSingleLinePs: function(element, noWhiteSpaceInEmptyP){ |
function wrapLinesInPs(el){ |
// move "lines" of top-level text nodes into ps |
function wrapNodes(nodes){ |
// nodes are assumed to all be siblings |
var newP = nodes[0].ownerDocument.createElement('p'); // FIXME: not very idiomatic |
nodes[0].parentNode.insertBefore(newP, nodes[0]); |
for(var i=0; i<nodes.length; i++){ |
newP.appendChild(nodes[i]); |
} |
} |
var currentNodeIndex = 0; |
var nodesInLine = []; |
var currentNode; |
while(currentNodeIndex < el.childNodes.length){ |
currentNode = el.childNodes[currentNodeIndex]; |
if( (currentNode.nodeName!='BR') && |
(currentNode.nodeType==1) && |
(dojo.style(currentNode, "display")!="block") |
){ |
nodesInLine.push(currentNode); |
}else{ |
// hit line delimiter; process nodesInLine if there are any |
var nextCurrentNode = currentNode.nextSibling; |
if(nodesInLine.length){ |
wrapNodes(nodesInLine); |
currentNodeIndex = (currentNodeIndex+1)-nodesInLine.length; |
if(currentNode.nodeName=="BR"){ |
dojo._destroyElement(currentNode); |
} |
} |
nodesInLine = []; |
} |
currentNodeIndex++; |
} |
if(nodesInLine.length){ wrapNodes(nodesInLine); } |
} |
function splitP(el){ |
// split a paragraph into seperate paragraphs at BRs |
var currentNode = null; |
var trailingNodes = []; |
var lastNodeIndex = el.childNodes.length-1; |
for(var i=lastNodeIndex; i>=0; i--){ |
currentNode = el.childNodes[i]; |
if(currentNode.nodeName=="BR"){ |
var newP = currentNode.ownerDocument.createElement('p'); |
dojo.place(newP, el, "after"); |
if (trailingNodes.length==0 && i != lastNodeIndex) { |
newP.innerHTML = " " |
} |
dojo.forEach(trailingNodes, function(node){ |
newP.appendChild(node); |
}); |
dojo._destroyElement(currentNode); |
trailingNodes = []; |
}else{ |
trailingNodes.unshift(currentNode); |
} |
} |
} |
var pList = []; |
var ps = element.getElementsByTagName('p'); |
dojo.forEach(ps, function(p){ pList.push(p); }); |
dojo.forEach(pList, function(p){ |
if( (p.previousSibling) && |
(p.previousSibling.nodeName == 'P' || dojo.style(p.previousSibling, 'display') != 'block') |
){ |
var newP = p.parentNode.insertBefore(this.document.createElement('p'), p); |
// this is essential to prevent IE from losing the P. |
// if it's going to be innerHTML'd later we need |
// to add the to _really_ force the issue |
newP.innerHTML = noWhiteSpaceInEmptyP ? "" : " "; |
} |
splitP(p); |
},this.editor); |
wrapLinesInPs(element); |
return element; |
}, |
singleLinePsToRegularPs: function(element){ |
function getParagraphParents(node){ |
var ps = node.getElementsByTagName('p'); |
var parents = []; |
for(var i=0; i<ps.length; i++){ |
var p = ps[i]; |
var knownParent = false; |
for(var k=0; k < parents.length; k++){ |
if(parents[k] === p.parentNode){ |
knownParent = true; |
break; |
} |
} |
if(!knownParent){ |
parents.push(p.parentNode); |
} |
} |
return parents; |
} |
function isParagraphDelimiter(node){ |
if(node.nodeType != 1 || node.tagName != 'P'){ |
return (dojo.style(node, 'display') == 'block'); |
}else{ |
if(!node.childNodes.length || node.innerHTML==" "){ return true } |
//return node.innerHTML.match(/^(<br\ ?\/?>| |\ \;)$/i); |
} |
} |
var paragraphContainers = getParagraphParents(element); |
for(var i=0; i<paragraphContainers.length; i++){ |
var container = paragraphContainers[i]; |
var firstPInBlock = null; |
var node = container.firstChild; |
var deleteNode = null; |
while(node){ |
if(node.nodeType != "1" || node.tagName != 'P'){ |
firstPInBlock = null; |
}else if (isParagraphDelimiter(node)){ |
deleteNode = node; |
firstPInBlock = null; |
}else{ |
if(firstPInBlock == null){ |
firstPInBlock = node; |
}else{ |
if( (!firstPInBlock.lastChild || firstPInBlock.lastChild.nodeName != 'BR') && |
(node.firstChild) && |
(node.firstChild.nodeName != 'BR') |
){ |
firstPInBlock.appendChild(this.editor.document.createElement('br')); |
} |
while(node.firstChild){ |
firstPInBlock.appendChild(node.firstChild); |
} |
deleteNode = node; |
} |
} |
node = node.nextSibling; |
if(deleteNode){ |
dojo._destroyElement(deleteNode); |
deleteNode = null; |
} |
} |
} |
return element; |
} |
}); |
} |
/trunk/api/js/dojo1.0/dijit/_editor/plugins/LinkDialog.js |
---|
New file |
0,0 → 1,150 |
if(!dojo._hasResource["dijit._editor.plugins.LinkDialog"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. |
dojo._hasResource["dijit._editor.plugins.LinkDialog"] = true; |
dojo.provide("dijit._editor.plugins.LinkDialog"); |
dojo.require("dijit._Widget"); |
dojo.require("dijit._Templated"); |
dojo.require("dijit._editor._Plugin"); |
dojo.require("dijit.Dialog"); |
dojo.require("dijit.form.Button"); |
dojo.require("dijit.form.ValidationTextBox"); |
dojo.require("dojo.i18n"); |
dojo.require("dojo.string"); |
dojo.requireLocalization("dijit._editor", "LinkDialog", null, "ko,zh,ja,zh-tw,ru,it,ROOT,hu,fr,pt,pl,es,de,cs"); |
dojo.declare("dijit._editor.plugins.DualStateDropDownButton", |
dijit.form.DropDownButton, |
{ |
// summary: a DropDownButton but button can be displayed in two states (checked or unchecked) |
setChecked: dijit.form.ToggleButton.prototype.setChecked |
} |
); |
dojo.declare("dijit._editor.plugins.UrlTextBox", |
dijit.form.ValidationTextBox, |
{ |
// summary: the URL input box we use in our dialog |
// regular expression for URLs, generated from dojo.regexp.url() |
regExp: "((https?|ftps?)\\://|)(([0-9a-zA-Z]([-0-9a-zA-Z]{0,61}[0-9a-zA-Z])?\\.)+(arpa|aero|biz|com|coop|edu|gov|info|int|mil|museum|name|net|org|pro|travel|xxx|jobs|mobi|post|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cu|cv|cx|cy|cz|de|dj|dk|dm|do|dz|ec|ee|eg|er|eu|es|et|fi|fj|fk|fm|fo|fr|ga|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sk|sl|sm|sn|sr|st|su|sv|sy|sz|tc|td|tf|tg|th|tj|tk|tm|tn|to|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zw)|(((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])|(0[xX]0*[\\da-fA-F]?[\\da-fA-F]\\.){3}0[xX]0*[\\da-fA-F]?[\\da-fA-F]|(0+[0-3][0-7][0-7]\\.){3}0+[0-3][0-7][0-7]|(0|[1-9]\\d{0,8}|[1-3]\\d{9}|4[01]\\d{8}|42[0-8]\\d{7}|429[0-3]\\d{6}|4294[0-8]\\d{5}|42949[0-5]\\d{4}|429496[0-6]\\d{3}|4294967[01]\\d{2}|42949672[0-8]\\d|429496729[0-5])|0[xX]0*[\\da-fA-F]{1,8}|([\\da-fA-F]{1,4}\\:){7}[\\da-fA-F]{1,4}|([\\da-fA-F]{1,4}\\:){6}((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])))(\\:(0|[1-9]\\d*))?(/([^?#\\s/]+/)*)?([^?#\\s/]+(\\?[^?#\\s/]*)?(#[A-Za-z][\\w.:-]*)?)?", |
required: true, |
postMixInProperties: function(){ |
this.inherited("postMixInProperties", arguments); |
this.invalidMessage = dojo.i18n.getLocalization("dijit._editor", "LinkDialog", this.lang).urlInvalidMessage; |
}, |
getValue: function(){ |
if(!/^(https?|ftps?)/.test(this.textbox.value)){ |
this.textbox.value="http://"+this.textbox.value; |
} |
return this.textbox.value; |
} |
} |
); |
dojo.declare("dijit._editor.plugins.LinkDialog", |
dijit._editor._Plugin, |
{ |
buttonClass: dijit._editor.plugins.DualStateDropDownButton, |
useDefaultCommand: false, |
command: "createLink", |
linkDialogTemplate: [ |
"<label for='urlInput'>${url} </label>", |
"<input dojoType=dijit._editor.plugins.UrlTextBox name='urlInput'><br>", |
"<label for='textInput'>${text} </label>", |
"<input dojoType=dijit.form.TextBox name='textInput'>", |
"<br>", |
"<button dojoType=dijit.form.Button type='submit'>${set}</button>" |
].join(""), |
constructor: function(){ |
var _this = this; |
var messages = dojo.i18n.getLocalization("dijit._editor", "LinkDialog", this.lang); |
this.dropDown = new dijit.TooltipDialog({ |
title: messages.title, |
execute: dojo.hitch(this, "setValue"), |
onOpen: function(){ |
_this._onOpenDialog(); |
dijit.TooltipDialog.prototype.onOpen.apply(this, arguments); |
}, |
onCancel: function(){ |
setTimeout(dojo.hitch(_this, "_onCloseDialog"),0); |
}, |
onClose: dojo.hitch(this, "_onCloseDialog") |
}); |
this.dropDown.setContent(dojo.string.substitute(this.linkDialogTemplate, messages)); |
this.dropDown.startup(); |
}, |
setValue: function(args){ |
// summary: callback from the dialog when user hits "set" button |
//TODO: prevent closing popup if the text is empty |
this._onCloseDialog(); |
if(dojo.isIE){ //see #4151 |
var a = dojo.withGlobal(this.editor.window, "getAncestorElement",dijit._editor.selection, ['a']); |
if(a){ |
dojo.withGlobal(this.editor.window, "selectElement",dijit._editor.selection, [a]); |
} |
} |
var attstr='href="'+args.urlInput+'" _djrealurl="'+args.urlInput+'"'; |
// console.log(args,this.editor,'<a '+attstr+'>'+args.textInput+'</a>'); |
this.editor.execCommand('inserthtml', '<a '+attstr+'>'+args.textInput+'</a>'); |
// this.editor.execCommand(this.command, args.urlInput); |
}, |
// _savedSelection: null, |
_onCloseDialog: function(){ |
// FIXME: IE is really messed up here!! |
if(dojo.isIE){ |
if(this._savedSelection){ |
var b=this._savedSelection; |
this._savedSelection=null; |
this.editor.focus(); |
var range = this.editor.document.selection.createRange(); |
range.moveToBookmark(b); |
range.select(); |
} |
}else{this.editor.focus(); |
} |
}, |
_onOpenDialog: function(){ |
var a = dojo.withGlobal(this.editor.window, "getAncestorElement",dijit._editor.selection, ['a']); |
var url='',text=''; |
if(a){ |
url=a.getAttribute('_djrealurl'); |
text=a.textContent||a.innerText; |
dojo.withGlobal(this.editor.window, "selectElement",dijit._editor.selection, [a,true]); |
}else{ |
text=dojo.withGlobal(this.editor.window, dijit._editor.selection.getSelectedText); |
} |
// FIXME: IE is *really* b0rken |
if(dojo.isIE){ |
var range = this.editor.document.selection.createRange(); |
this._savedSelection = range.getBookmark(); |
} |
this.dropDown.setValues({'urlInput':url,'textInput':text}); |
//dijit.focus(this.urlInput); |
}, |
updateState: function(){ |
// summary: change shading on button if we are over a link (or not) |
var _e = this.editor; |
if(!_e){ return; } |
if(!_e.isLoaded){ return; } |
if(this.button){ |
try{ |
// display button differently if there is an existing link associated with the current selection |
var hasA = dojo.withGlobal(this.editor.window, "hasAncestorElement",dijit._editor.selection, ['a']); |
this.button.setChecked(hasA); |
}catch(e){ |
console.debug(e); //FIXME: probably shouldn't squelch an exception here |
} |
} |
} |
} |
); |
} |
/trunk/api/js/dojo1.0/dijit/_editor/plugins/FontChoice.js |
---|
New file |
0,0 → 1,66 |
if(!dojo._hasResource["dijit._editor.plugins.FontChoice"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. |
dojo._hasResource["dijit._editor.plugins.FontChoice"] = true; |
dojo.provide("dijit._editor.plugins.FontChoice"); |
dojo.require("dijit._editor._Plugin"); |
dojo.require("dijit.form.FilteringSelect"); |
dojo.require("dojo.data.ItemFileReadStore"); |
dojo.require("dojo.i18n"); |
dojo.requireLocalization("dijit._editor", "FontChoice", null, "ROOT"); |
dojo.declare("dijit._editor.plugins.FontChoice", |
dijit._editor._Plugin, |
{ |
_uniqueId: 0, |
buttonClass: dijit.form.FilteringSelect, |
_initButton: function(){ |
this.inherited("_initButton", arguments); |
//TODO: do we need nls for font names? provide css font lists? or otherwise make this more configurable? |
var names = { |
fontName: ["serif", "sans-serif", "monospaced", "cursive", "fantasy"], |
fontSize: [1,2,3,4,5,6,7], |
formatBlock: ["p", "h1", "h2", "h3", "pre"] }[this.command]; |
var strings = dojo.i18n.getLocalization("dijit._editor", "FontChoice"); |
var items = dojo.map(names, function(x){ return { name: strings[x], value: x }; }); |
items.push({name:"", value:""}); // FilteringSelect doesn't like unmatched blank strings |
this.button.store = new dojo.data.ItemFileReadStore( |
{ data: { identifier: "value", |
items: items } |
}); |
this.button.setValue(""); |
dojo.connect(this.button, "onChange", this, function(choice){ |
this.editor.execCommand(this.command, choice); |
}); |
}, |
updateState: function(){ |
this.inherited("updateState", arguments); |
var _e = this.editor; |
var _c = this.command; |
if(!_e || !_e.isLoaded || !_c.length){ return; } |
if(this.button){ |
var value = _e.queryCommandValue(_c); |
this.button.setValue(value); |
} |
}, |
setToolbar: function(){ |
this.inherited("setToolbar", arguments); |
var forRef = this.button; |
if(!forRef.id){ forRef.id = "dijitEditorButton-"+this.command+(this._uniqueId++); } //TODO: is this necessary? FilteringSelects always seem to have an id? |
var label = dojo.doc.createElement("label"); |
label.setAttribute("for", forRef.id); |
var strings = dojo.i18n.getLocalization("dijit._editor", "FontChoice"); |
label.appendChild(dojo.doc.createTextNode(strings[this.command])); |
dojo.place(label, this.button.domNode, "before"); |
} |
} |
); |
} |
/trunk/api/js/dojo1.0/dijit/_editor/plugins/TextColor.js |
---|
New file |
0,0 → 1,24 |
if(!dojo._hasResource["dijit._editor.plugins.TextColor"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. |
dojo._hasResource["dijit._editor.plugins.TextColor"] = true; |
dojo.provide("dijit._editor.plugins.TextColor"); |
dojo.require("dijit._editor._Plugin"); |
dojo.require("dijit.ColorPalette"); |
dojo.declare("dijit._editor.plugins.TextColor", |
dijit._editor._Plugin, |
{ |
buttonClass: dijit.form.DropDownButton, |
//TODO: set initial focus/selection state? |
constructor: function(){ |
this.dropDown = new dijit.ColorPalette(); |
dojo.connect(this.dropDown, "onChange", this, function(color){ |
this.editor.execCommand(this.command, color); |
}); |
} |
} |
); |
} |
/trunk/api/js/dojo1.0/dijit/_editor/plugins/AlwaysShowToolbar.js |
---|
New file |
0,0 → 1,147 |
if(!dojo._hasResource["dijit._editor.plugins.AlwaysShowToolbar"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. |
dojo._hasResource["dijit._editor.plugins.AlwaysShowToolbar"] = true; |
dojo.provide("dijit._editor.plugins.AlwaysShowToolbar"); |
dojo.declare("dijit._editor.plugins.AlwaysShowToolbar", null, |
{ |
_handleScroll: true, |
setEditor: function(e){ |
this.editor=e; |
// setTimeout(dojo.hitch(this,this.enable),10000); |
e.onLoadDeferred.addCallback(dojo.hitch(this,this.enable)); |
// this.scrollInterval = setInterval(dojo.hitch(this, "globalOnScrollHandler"), 100); |
}, |
enable: function(d){ |
this._updateHeight(); |
this._connects=[dojo.connect(window,'onscroll',this,"globalOnScrollHandler"), |
dojo.connect(this.editor,'onNormalizedDisplayChanged',this,"_updateHeight")]; |
return d; |
}, |
_updateHeight: function(){ |
// summary: |
// Updates the height of the editor area to fit the contents. |
var e=this.editor; |
if(!e.isLoaded){ return; } |
if(e.height){ return; } |
var height = dojo.marginBox(e.editNode).h; |
if(dojo.isOpera){ |
height = e.editNode.scrollHeight; |
} |
// console.debug('height',height); |
// alert(this.editNode); |
//height maybe zero in some cases even though the content is not empty, |
//we try the height of body instead |
if(!height){ |
height = dojo.marginBox(e.document.body).h; |
} |
if(height == 0){ |
console.debug("Can not figure out the height of the editing area!"); |
return; //prevent setting height to 0 |
} |
if(height != this._lastHeight){ |
this._lastHeight = height; |
// this.editorObject.style.height = this._lastHeight + "px"; |
dojo.marginBox(e.iframe, { h: this._lastHeight }); |
// this.iframe.height=this._lastHeight+10+'px'; |
// this.iframe.style.height=this._lastHeight+'px'; |
} |
}, |
_lastHeight: 0, |
globalOnScrollHandler: function(){ |
var isIE = dojo.isIE && dojo.isIE<7; |
if(!this._handleScroll){ return; } |
var tdn = this.editor.toolbar.domNode; |
var db = dojo.body; |
if(!this._scrollSetUp){ |
this._scrollSetUp = true; |
this._scrollThreshold = dojo._abs(tdn, true).y; |
// console.log("threshold:", this._scrollThreshold); |
//what's this for?? comment out for now |
// if((isIE)&&(db)&&(dojo.style(db, "backgroundIimage")=="none")){ |
// db.style.backgroundImage = "url(" + dojo.uri.moduleUri("dijit", "templates/blank.gif") + ")"; |
// db.style.backgroundAttachment = "fixed"; |
// } |
} |
var scrollPos = dojo._docScroll().y; |
if(scrollPos > this._scrollThreshold && scrollPos < this._scrollThreshold+this._lastHeight){ |
// dojo.debug(scrollPos); |
if(!this._fixEnabled){ |
var tdnbox = dojo.marginBox(tdn); |
this.editor.iframe.style.marginTop = tdnbox.h+"px"; |
if(isIE){ |
tdn.style.left = dojo._abs(tdn).x; |
if(tdn.previousSibling){ |
this._IEOriginalPos = ['after',tdn.previousSibling]; |
}else if(tdn.nextSibling){ |
this._IEOriginalPos = ['before',tdn.nextSibling]; |
}else{ |
this._IEOriginalPos = ['last',tdn.parentNode]; |
} |
dojo.body().appendChild(tdn); |
dojo.addClass(tdn,'IEFixedToolbar'); |
}else{ |
with(tdn.style){ |
position = "fixed"; |
top = "0px"; |
} |
} |
dojo.marginBox(tdn, { w: tdnbox.w }); |
tdn.style.zIndex = 2000; |
this._fixEnabled = true; |
} |
// if we're showing the floating toolbar, make sure that if |
// we've scrolled past the bottom of the editor that we hide |
// the toolbar for this instance of the editor. |
// TODO: when we get multiple editor toolbar support working |
// correctly, ensure that we check this against the scroll |
// position of the bottom-most editor instance. |
var eHeight = (this.height) ? parseInt(this.editor.height) : this.editor._lastHeight; |
if(scrollPos > (this._scrollThreshold+eHeight)){ |
tdn.style.display = "none"; |
}else{ |
tdn.style.display = ""; |
} |
}else if(this._fixEnabled){ |
this.editor.iframe.style.marginTop = ''; |
with(tdn.style){ |
position = ""; |
top = ""; |
zIndex = ""; |
display = ""; |
} |
if(isIE){ |
tdn.style.left = ""; |
dojo.removeClass(tdn,'IEFixedToolbar'); |
if(this._IEOriginalPos){ |
dojo.place(tdn, this._IEOriginalPos[1], this._IEOriginalPos[0]); |
this._IEOriginalPos = null; |
}else{ |
dojo.place(tdn, this.editor.iframe,'before'); |
} |
} |
tdn.style.width = ""; |
this._fixEnabled = false; |
} |
}, |
destroy: function(){ |
this._IEOriginalPos = null; |
this._handleScroll = false; |
dojo.forEach(this._connects,dojo.disconnect); |
// clearInterval(this.scrollInterval); |
if(dojo.isIE && dojo.isIE<7){ |
dojo.removeClass(this.editor.toolbar.domNode,'IEFixedToolbar'); |
} |
} |
}); |
} |