📄 ftb-freetextbox.js
字号:
/* main FTB object
-------------------------------------- */
function FTB_FreeTextBox(id, enableToolbars, readOnly, buttons, dropdownlists, breakMode, pasteMode, tabMode, startMode, clientSideTextChanged, designModeCss, designModeBodyTagCssClass, baseUrl, textDirection, buttonImageFormat, imageGalleryUrl, imageGalleryPath, receiveFocus, buttonWidth, buttonHeight) {
this.debug = document.getElementById('debug');
this.id = id;
this.enableToolbars = enableToolbars;
this.readOnly = readOnly;
this.buttons = buttons;
this.dropdownlists = dropdownlists;
this.breakMode = breakMode;
this.pasteMode = pasteMode;
this.tabMode = tabMode;
this.startMode = startMode;
this.clientSideTextChanged = clientSideTextChanged;
this.designModeCss = designModeCss;
this.designModeBodyTagCssClass = designModeBodyTagCssClass;
this.baseUrl = baseUrl;
this.textDirection = textDirection;
this.buttonImageFormat = buttonImageFormat; // currently unused
this.imageGalleryUrl = imageGalleryUrl;
this.imageGalleryPath = imageGalleryPath;
this.hasFocus = false;
this.mode = FTB_MODE_DESIGN;
this.initialized = false;
this.undoArray = new Array();
this.undoArrayMax = 16;
this.undoArrayPos = -1;
this.lastEvent = null;
//};
//FTB_FreeTextBox.prototype.Initialize = function() {
var ftb = this;
// 2. Find everything
//* windows
this.htmlEditor = document.getElementById(this.id);
if (FTB_Browser.isIE) {
this.previewPane = eval(this.id + "_previewPane");
this.designEditor = eval(this.id + "_designEditor");
this.designEditor.ftb = this;
this.designEditor.document.ftb = this;
document.getElementById(this.id + "_designEditor").document.ftb = this;
} else {
this.previewPane = document.getElementById(this.id + "_previewPane").contentWindow;
this.designEditor = document.getElementById(this.id + "_designEditor").contentWindow;
this.designEditor.document.ftb = this;
}
//* areas
this.toolbarArea = document.getElementById(this.id + "_toolbarArea");
this.designEditorArea = document.getElementById(this.id + "_designEditorArea");
this.htmlEditorArea = document.getElementById(this.id + "_htmlEditorArea");
this.previewPaneArea = document.getElementById(this.id + "_previewPaneArea");
//* tabs
this.designModeTab = document.getElementById(this.id + "_designModeTab");
if (this.designModeTab) {
this.designModeTab.ftb = this;
this.designModeTab.onclick = function() { if (!this.ftb.readOnly) {this.ftb.GoToDesignMode(); this.ftb.Focus(); this.ftb.UpdateToolbars(); }}
}
this.htmlModeTab = document.getElementById(this.id + "_htmlModeTab");
if (this.htmlModeTab) {
this.htmlModeTab.ftb = this;
this.htmlModeTab.onclick = function() { if (!this.ftb.readOnly) {this.ftb.GoToHtmlMode(); this.ftb.Focus(); this.ftb.UpdateToolbars(); }}
}
this.previewModeTab = document.getElementById(this.id + "_previewModeTab");
if (this.previewModeTab) {
this.previewModeTab.ftb = this;
this.previewModeTab.onclick = function() { if (!this.ftb.readOnly) {this.ftb.GoToPreviewMode();}}
}
//* ancestor area
this.ancestorArea = document.getElementById(this.id + "_AncestorArea");
// 3. Tell buttons who owns them
//* setup buttons & dropdowns
if (this.enableToolbars) {
for(var i=0; i<this.buttons.length; i++) {
button = this.buttons[i];
button.ftb = this;
if (!this.readOnly)
button.Initialize();
}
for(var i=0; i<this.dropdownlists.length; i++) {
dropdownlist = this.dropdownlists[i];
dropdownlist.ftb = this;
}
}
// 4. Setup editor for use
if (!this.readOnly) {
this.designEditor.document.designMode = 'On';
if (FTB_Browser.isGecko) this.designEditor.document.contentEditable = true;
}
//((this.designModeCss != '') ? "<style type='text/css'>@import url(" + this.designModeCss + ");</style>" : "") +
this.designEditor.document.open();
this.designEditor.document.write("<html" + ((this.textDirection == "rtl") ? " dir='rtl'" : "") + ">" +
"<head>" +
((this.designModeCss != '') ? "<link rel='stylesheet' href='" + this.designModeCss + "' type='text/css' />" : "") +
((this.baseUrl != '') ? "<base href='" + this.baseUrl + "' />" : "") +
"</head>" +
"<body" + ((this.designModeBodyTagCssClass != '') ? " class='" + this.designModeBodyTagCssClass + "'" : "") + ">" +
this.htmlEditor.value +
"</body>" +
"</html>");
this.designEditor.document.close();
if (!this.readOnly) {
if (FTB_Browser.isIE) this.designEditor.document.body.contentEditable = true;
// enable this html area
this.htmlEditor.disabled = '';
}
// silly IE can't get the style right until now...
if (FTB_Browser.isIE) {
this.designEditor.document.body.style.border = '0';
}
// 5. Add events
if (!this.readOnly) {
if (FTB_Browser.isIE) {
FTB_AddEvents(this.designEditor.document,
new Array("keydown","keypress","mousedown"),
function(e) { ftb.hasFocus=true; return ftb.Event(e); }
);
} else {
var evt = function(e) {
this.document.ftb.hasFocus=true;
this.document.ftb.Event(e);
return false;
}
this.designEditor.addEventListener("keydown", evt, true);
this.designEditor.addEventListener("keypress", evt, true);
this.designEditor.addEventListener("mousedown", evt, true);
// no paste event in Mozilla
}
FTB_AddEvents(this.designEditor,
new Array("blur"),
function(e) { ftb.hasFocus=false; ftb.Event(e); ftb.StoreHtml(); }
);
}
if (this.startMode == FTB_MODE_HTML)
this.GoToHtmlMode();
if (this.readOnly)
this.DisableAllToolbarItems();
else
this.UpdateToolbars();
this.undoArray[0] = this.htmlEditorArea.value;
this.initialized = true;
if (this.receiveFocus) this.Focus();
};
FTB_FreeTextBox.prototype.RefreshDesignMode = function() {
if (!this.readOnly && FTB_Browser.isGecko) {
this.designEditor.document.designMode = 'on';
this.designEditor.document.execCommand('useCSS', false, true);
}
}
FTB_FreeTextBox.prototype.AddStyle = function(css) {
var styleEl=document.createElement('style');
styleEl.type='text/css';
styleEl.appendChild(css);
this.designEditor.document.appendChild(styleEl);
};
FTB_FreeTextBox.prototype.Event = function(ev) {
if (ev != null) {
if (FTB_Browser.isIE) {
sel = this.GetSelection();
r = this.CreateRange(sel);
// check for undo && redo
if (ev.ctrlKey && ev.keyCode == FTB_KEY_Z) {
this.Undo();
this.CancelEvent(ev);
} else if (ev.ctrlKey && ev.keyCode == FTB_KEY_Y) {
this.Redo();
this.CancelEvent(ev);
} else {
if (ev.keyCode == FTB_KEY_ENTER) {
if (this.breakMode == FTB_BREAK_BR || ev.ctrlKey) {
if (sel.type == 'Control') {
return;
}
if ((!this.CheckTag(r.parentElement(),'LI'))&&(!this.CheckTag(r.parentElement(),'H'))) {
r.pasteHTML('<br>');
this.CancelEvent(ev);
r.select();
r.collapse(false);
return false;
}
}
} else if ((ev.ctrlKey && !ev.shiftKey && !ev.altKey)) {
if (ev.keyCode == FTB_KEY_V || ev.keyCode == 118) {
this.CapturePaste();
this.CancelEvent(ev);
}
} else if (ev.keyCode == FTB_KEY_TAB) {
if (this.CheckTag(r.parentElement(),'LI')) {
if (ev.shiftKey)
this.ExecuteCommand("outdent");
else
this.ExecuteCommand("indent");
this.CancelEvent(ev);
} else {
switch (this.tabMode) {
default:
case FTB_TAB_NEXTCONTROL:
break;
case FTB_TAB_INSERTSPACES:
this.InsertHtml(" ");
this.CancelEvent(ev);
break;
case FTB_TAB_DISABLED:
this.CancelEvent(ev);
break;
}
}
}
}
} else {
if (ev.type == "keypress" || ev.type == "keydown") {
// check for undo && redo
if (ev.ctrlKey && ev.which && ev.which == FTB_KEY_Z) {
this.Undo();
this.CancelEvent(ev);
} else if (ev.ctrlKey && ev.which && ev.which == FTB_KEY_Y) {
this.Redo();
this.CancelEvent(ev);
} else {
if (ev.keyCode == FTB_KEY_ENTER) {
if (this.breakMode == FTB_BREAK_P) {
/*
var insertP = true;
var parent = this.GetParentElement();
if ( parent != null )
if (this.CheckTag(this.GetParentElement(),'LI') )
insertP = false;
if (!insertP) return;
if ( parent != null ) {
if ( !this.CheckTag(this.GetParentElement(),'P') )
this.ExecuteCommand('formatblock','','p');
} else {
this.ExecuteCommand('formatblock','','p');
}
var parent = this.GetParentElement();
p = this.designEditor.document.createElement('p');
sel = this.GetSelection();
r = this.CreateRange(sel);
r.insertNode(p);
r.selectNode(p);
//p.focus();
//
//parent.insertBefore(p);
this.CancelEvent(ev);
*/
}
// check for control+commands (not in Mozilla by default)
} else if ((ev.ctrlKey && !ev.shiftKey && !ev.altKey)) {
if (ev.which == FTB_KEY_V || ev.which == 118) {
if (ev.which == 118 && this.pasteMode != FTB_PASTE_DEFAULT) {
this.CapturePaste();
this.CancelEvent(ev);
}
} else if (ev.which == FTB_KEY_B || ev.which == 98) {
if (ev.which == FTB_KEY_B) this.ExecuteCommand('bold');
this.CancelEvent(ev);
} else if (ev.which == FTB_KEY_I || ev.which == 105) {
if (ev.which == FTB_KEY_I) this.ExecuteCommand('italic');
this.CancelEvent(ev);
} else if (ev.which == FTB_KEY_U || ev.which == 117) {
if (ev.which == FTB_KEY_U) this.ExecuteCommand('underline');
this.CancelEvent(ev);
}
} else if (ev.which == FTB_KEY_TAB) {
if (this.CheckTag(r.parentElement,'LI')) {
// do it's own thing!
} else {
switch (this.tabMode) {
default:
case FTB_TAB_NEXTCONTROL:
// unsupported in Mozilla
break;
case FTB_TAB_INSERTSPACES:
// do it's own thing
break;
case FTB_TAB_DISABLED:
this.CancelEvent(ev);
break;
}
}
}
}
}
}
}
if (this.mode == FTB_MODE_DESIGN) {
FTB_Timeout.addMethod(this.id+'_UpdateToolbars',this,'UpdateToolbars',200);
}
if (this.clientSideTextChanged)
this.clientSideTextChanged(this);
};
FTB_FreeTextBox.prototype.CancelEvent = function(ev) {
if (FTB_Browser.isIE) {
ev.cancelBubble = true;
ev.returnValue = false;
} else {
ev.preventDefault();
ev.stopPropagation();
}
};
FTB_FreeTextBox.prototype.InsertElement = function(el) {
var sel = this.GetSelection();
var range = this.CreateRange(sel);
if (FTB_Browser.isIE) {
range.pasteHTML(el.outerHTML);
} else {
this.InsertNodeAtSelection(el);
}
};
FTB_FreeTextBox.prototype.RecordUndoStep = function() {
if (!this.initialized) return;
++this.undoArrayPos;
if (this.undoArrayPos >= this.undoArrayMax) {
// remove the first element
this.undoArray.shift();
--this.undoArrayPos;
}
var take = true;
var html = this.designEditor.document.body.innerHTML;
if (this.undoArrayPos > 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -