Subversion Repositories Applications.papyrus

Compare Revisions

Ignore whitespace Rev 2149 → Rev 2150

/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 = "&nbsp;"; }
 
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, "") == "&nbsp;"){
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 = "&nbsp;" }
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>&nbsp;</P> for IE
// ec = ec.replace(/(?:<p>&nbsp;</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, "&amp;").replace(/</gm, "&lt;").replace(/>/gm, "&gt;").replace(/"/gm, "&quot;");
if(!noSingleQuotes){
str = str.replace(/'/gm, "&#39;");
}
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: '&nbsp;',
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 = "&nbsp;"
}
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 &nbsp; to _really_ force the issue
newP.innerHTML = noWhiteSpaceInEmptyP ? "" : "&nbsp;";
}
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=="&nbsp;"){ return true }
//return node.innerHTML.match(/^(<br\ ?\/?>| |\&nbsp\;)$/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}&nbsp;</label>",
"<input dojoType=dijit._editor.plugins.UrlTextBox name='urlInput'><br>",
"<label for='textInput'>${text}&nbsp;</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');
}
}
});
 
}