richtext.js
来自「Hippo CMS是一个以信息为中心的开源内容管理系统。Hippo CMS目标是」· JavaScript 代码 · 共 1,168 行 · 第 1/3 页
JS
1,168 行
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.widget.RichText");
dojo.require("dojo.widget.*");
dojo.require("dojo.html.*");
dojo.require("dojo.html.layout");
dojo.require("dojo.html.selection");
dojo.require("dojo.event.*");
dojo.require("dojo.string.extras");
dojo.require("dojo.uri.Uri");
dojo.require("dojo.Deferred");
if (!djConfig["useXDomain"] || djConfig["allowXdRichTextSave"]) {
if (dojo.hostenv.post_load_) {
(function () {
var savetextarea = dojo.doc().createElement("textarea");
savetextarea.id = "dojo.widget.RichText.savedContent";
savetextarea.style = "display:none;position:absolute;top:-100px;left:-100px;height:3px;width:3px;overflow:hidden;";
dojo.body().appendChild(savetextarea);
})();
} else {
try {
dojo.doc().write("<textarea id=\"dojo.widget.RichText.savedContent\" " + "style=\"display:none;position:absolute;top:-100px;left:-100px;height:3px;width:3px;overflow:hidden;\"></textarea>");
}
catch (e) {
}
}
}
dojo.widget.defineWidget("dojo.widget.RichText", dojo.widget.HtmlWidget, function () {
this.contentPreFilters = [];
this.contentPostFilters = [];
this.contentDomPreFilters = [];
this.contentDomPostFilters = [];
this.editingAreaStyleSheets = [];
if (dojo.render.html.moz) {
this.contentPreFilters.push(this._fixContentForMoz);
}
this._keyHandlers = {};
if (dojo.Deferred) {
this.onLoadDeferred = new dojo.Deferred();
}
}, {inheritWidth:false, focusOnLoad:false, saveName:"", styleSheets:"", _content:"", height:"", minHeight:"1em", isClosed:true, isLoaded:false, useActiveX:false, relativeImageUrls:false, _SEPARATOR:"@@**%%__RICHTEXTBOUNDRY__%%**@@", onLoadDeferred:null, fillInTemplate:function () {
dojo.event.topic.publish("dojo.widget.RichText::init", this);
this.open();
dojo.event.connect(this, "onKeyPressed", this, "afterKeyPress");
dojo.event.connect(this, "onKeyPress", this, "keyPress");
dojo.event.connect(this, "onKeyDown", this, "keyDown");
dojo.event.connect(this, "onKeyUp", this, "keyUp");
this.setupDefaultShortcuts();
}, setupDefaultShortcuts:function () {
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.render.html.ie) {
this.addKeyHandler("Z", ctrl, exec("redo"));
}
}, events:["onBlur", "onFocus", "onKeyPress", "onKeyDown", "onKeyUp", "onClick"], open:function (element) {
if (this.onLoadDeferred.fired >= 0) {
this.onLoadDeferred = new dojo.Deferred();
}
var h = dojo.render.html;
if (!this.isClosed) {
this.close();
}
dojo.event.topic.publish("dojo.widget.RichText::open", this);
this._content = "";
if ((arguments.length == 1) && (element["nodeName"])) {
this.domNode = element;
}
if ((this.domNode["nodeName"]) && (this.domNode.nodeName.toLowerCase() == "textarea")) {
this.textarea = this.domNode;
var html = this._preFilterContent(this.textarea.value);
this.domNode = dojo.doc().createElement("div");
dojo.html.copyStyle(this.domNode, this.textarea);
var tmpFunc = dojo.lang.hitch(this, function () {
with (this.textarea.style) {
display = "block";
position = "absolute";
left = top = "-1000px";
if (h.ie) {
this.__overflow = overflow;
overflow = "hidden";
}
}
});
if (h.ie) {
setTimeout(tmpFunc, 10);
} else {
tmpFunc();
}
if (!h.safari) {
dojo.html.insertBefore(this.domNode, this.textarea);
}
if (this.textarea.form) {
dojo.event.connect("before", this.textarea.form, "onsubmit", dojo.lang.hitch(this, function () {
this.textarea.value = this.getEditorContent();
}));
}
var editor = this;
dojo.event.connect(this, "postCreate", function () {
dojo.html.insertAfter(editor.textarea, editor.domNode);
});
} else {
var html = this._preFilterContent(dojo.string.trim(this.domNode.innerHTML));
}
if (html == "") {
html = " ";
}
var content = dojo.html.getContentBox(this.domNode);
this._oldHeight = content.height;
this._oldWidth = content.width;
this._firstChildContributingMargin = this._getContributingMargin(this.domNode, "top");
this._lastChildContributingMargin = this._getContributingMargin(this.domNode, "bottom");
this.savedContent = html;
this.domNode.innerHTML = "";
this.editingArea = dojo.doc().createElement("div");
this.domNode.appendChild(this.editingArea);
if ((this.domNode["nodeName"]) && (this.domNode.nodeName == "LI")) {
this.domNode.innerHTML = " <br>";
}
if (this.saveName != "" && (!djConfig["useXDomain"] || djConfig["allowXdRichTextSave"])) {
var saveTextarea = dojo.doc().getElementById("dojo.widget.RichText.savedContent");
if (saveTextarea.value != "") {
var datas = saveTextarea.value.split(this._SEPARATOR);
for (var i = 0; i < datas.length; i++) {
var data = datas[i].split(":");
if (data[0] == this.saveName) {
html = data[1];
datas.splice(i, 1);
break;
}
}
}
dojo.event.connect("before", window, "onunload", this, "_saveContent");
}
if (h.ie70 && this.useActiveX) {
dojo.debug("activeX in ie70 is not currently supported, useActiveX is ignored for now.");
this.useActiveX = false;
}
if (this.useActiveX && h.ie) {
var self = this;
setTimeout(function () {
self._drawObject(html);
}, 0);
} else {
if (h.ie || this._safariIsLeopard() || h.opera) {
this.iframe = dojo.doc().createElement("iframe");
this.iframe.src = "javascript:void(0)";
this.editorObject = this.iframe;
with (this.iframe.style) {
border = "0";
width = "100%";
}
this.iframe.frameBorder = 0;
this.editingArea.appendChild(this.iframe);
this.window = this.iframe.contentWindow;
this.document = this.window.document;
this.document.open();
this.document.write("<html><head><style>body{margin:0;padding:0;border:0;overflow:hidden;}</style></head><body><div></div></body></html>");
this.document.close();
this.editNode = this.document.body.firstChild;
this.editNode.contentEditable = true;
with (this.iframe.style) {
if (h.ie70) {
if (this.height) {
height = this.height;
}
if (this.minHeight) {
minHeight = this.minHeight;
}
} else {
height = this.height ? this.height : this.minHeight;
}
}
var formats = ["p", "pre", "address", "h1", "h2", "h3", "h4", "h5", "h6", "ol", "div", "ul"];
var localhtml = "";
for (var i in formats) {
if (formats[i].charAt(1) != "l") {
localhtml += "<" + formats[i] + "><span>content</span></" + formats[i] + ">";
} else {
localhtml += "<" + formats[i] + "><li>content</li></" + formats[i] + ">";
}
}
with (this.editNode.style) {
position = "absolute";
left = "-2000px";
top = "-2000px";
}
this.editNode.innerHTML = localhtml;
var node = this.editNode.firstChild;
while (node) {
dojo.withGlobal(this.window, "selectElement", dojo.html.selection, [node.firstChild]);
var nativename = node.tagName.toLowerCase();
this._local2NativeFormatNames[nativename] = this.queryCommandValue("formatblock");
this._native2LocalFormatNames[this._local2NativeFormatNames[nativename]] = nativename;
node = node.nextSibling;
}
with (this.editNode.style) {
position = "";
left = "";
top = "";
}
this.editNode.innerHTML = html;
if (this.height) {
this.document.body.style.overflowY = "scroll";
}
dojo.lang.forEach(this.events, function (e) {
dojo.event.connect(this.editNode, e.toLowerCase(), this, e);
}, this);
this.onLoad();
} else {
this._drawIframe(html);
this.editorObject = this.iframe;
}
}
if (this.domNode.nodeName == "LI") {
this.domNode.lastChild.style.marginTop = "-1.2em";
}
dojo.html.addClass(this.domNode, "RichTextEditable");
this.isClosed = false;
}, _hasCollapseableMargin:function (element, side) {
if (dojo.html.getPixelValue(element, "border-" + side + "-width", false)) {
return false;
} else {
if (dojo.html.getPixelValue(element, "padding-" + side, false)) {
return false;
} else {
return true;
}
}
}, _getContributingMargin:function (element, topOrBottom) {
if (topOrBottom == "top") {
var siblingAttr = "previousSibling";
var childSiblingAttr = "nextSibling";
var childAttr = "firstChild";
var marginProp = "margin-top";
var siblingMarginProp = "margin-bottom";
} else {
var siblingAttr = "nextSibling";
var childSiblingAttr = "previousSibling";
var childAttr = "lastChild";
var marginProp = "margin-bottom";
var siblingMarginProp = "margin-top";
}
var elementMargin = dojo.html.getPixelValue(element, marginProp, false);
function isSignificantNode(element) {
return !(element.nodeType == 3 && dojo.string.isBlank(element.data)) && dojo.html.getStyle(element, "display") != "none" && !dojo.html.isPositionAbsolute(element);
}
var childMargin = 0;
var child = element[childAttr];
while (child) {
while ((!isSignificantNode(child)) && child[childSiblingAttr]) {
child = child[childSiblingAttr];
}
childMargin = Math.max(childMargin, dojo.html.getPixelValue(child, marginProp, false));
if (!this._hasCollapseableMargin(child, topOrBottom)) {
break;
}
child = child[childAttr];
}
if (!this._hasCollapseableMargin(element, topOrBottom)) {
return parseInt(childMargin);
}
var contextMargin = 0;
var sibling = element[siblingAttr];
while (sibling) {
if (isSignificantNode(sibling)) {
contextMargin = dojo.html.getPixelValue(sibling, siblingMarginProp, false);
break;
}
sibling = sibling[siblingAttr];
}
if (!sibling) {
contextMargin = dojo.html.getPixelValue(element.parentNode, marginProp, false);
}
if (childMargin > elementMargin) {
return parseInt(Math.max((childMargin - elementMargin) - contextMargin, 0));
} else {
return 0;
}
}, _drawIframe:function (html) {
var oldMoz = Boolean(dojo.render.html.moz && (typeof window.XML == "undefined"));
if (!this.iframe) {
var currentDomain = (new dojo.uri.Uri(dojo.doc().location)).host;
this.iframe = dojo.doc().createElement("iframe");
with (this.iframe) {
style.border = "none";
style.lineHeight = "0";
style.verticalAlign = "bottom";
scrolling = this.height ? "auto" : "no";
}
}
if (djConfig["useXDomain"] && !djConfig["dojoRichTextFrameUrl"]) {
dojo.debug("dojo.widget.RichText: When using cross-domain Dojo builds," + " please save src/widget/templates/richtextframe.html to your domain and set djConfig.dojoRichTextFrameUrl" + " to the path on your domain to richtextframe.html");
}
this.iframe.src = (djConfig["dojoRichTextFrameUrl"] || dojo.uri.moduleUri("dojo.widget", "templates/richtextframe.html")) + ((dojo.doc().domain != currentDomain) ? ("#" + dojo.doc().domain) : "");
this.iframe.width = this.inheritWidth ? this._oldWidth : "100%";
if (this.height) {
this.iframe.style.height = this.height;
} else {
var height = this._oldHeight;
if (this._hasCollapseableMargin(this.domNode, "top")) {
height += this._firstChildContributingMargin;
}
if (this._hasCollapseableMargin(this.domNode, "bottom")) {
height += this._lastChildContributingMargin;
}
this.iframe.height = height;
}
var tmpContent = dojo.doc().createElement("div");
tmpContent.innerHTML = html;
this.editingArea.appendChild(tmpContent);
if (this.relativeImageUrls) {
var imgs = tmpContent.getElementsByTagName("img");
for (var i = 0; i < imgs.length; i++) {
imgs[i].src = (new dojo.uri.Uri(dojo.global().location, imgs[i].src)).toString();
}
html = tmpContent.innerHTML;
}
var firstChild = dojo.html.firstElement(tmpContent);
var lastChild = dojo.html.lastElement(tmpContent);
if (firstChild) {
firstChild.style.marginTop = this._firstChildContributingMargin + "px";
}
if (lastChild) {
lastChild.style.marginBottom = this._lastChildContributingMargin + "px";
}
this.editingArea.appendChild(this.iframe);
if (dojo.render.html.safari) {
this.iframe.src = this.iframe.src;
}
var _iframeInitialized = false;
var ifrFunc = dojo.lang.hitch(this, function () {
if (!_iframeInitialized) {
_iframeInitialized = true;
} else {
return;
}
if (!this.editNode) {
if (this.iframe.contentWindow) {
this.window = this.iframe.contentWindow;
this.document = this.iframe.contentWindow.document;
} else {
if (this.iframe.contentDocument) {
this.window = this.iframe.contentDocument.window;
this.document = this.iframe.contentDocument;
}
}
var getStyle = (function (domNode) {
return function (style) {
return dojo.html.getStyle(domNode, style);
};
})(this.domNode);
var font = getStyle("font-weight") + " " + getStyle("font-size") + " " + getStyle("font-family");
var lineHeight = "1.0";
var lineHeightStyle = dojo.html.getUnitValue(this.domNode, "line-height");
if (lineHeightStyle.value && lineHeightStyle.units == "") {
lineHeight = lineHeightStyle.value;
}
dojo.html.insertCssText("body,html{background:transparent;padding:0;margin:0;}" + "body{top:0;left:0;right:0;" + (((this.height) || (dojo.render.html.opera)) ? "" : "position:fixed;") + "font:" + font + ";" + "min-height:" + this.minHeight + ";" + "line-height:" + lineHeight + "}" + "p{margin: 1em 0 !important;}" + "body > *:first-child{padding-top:0 !important;margin-top:" + this._firstChildContributingMargin + "px !important;}" + "body > *:last-child{padding-bottom:0 !important;margin-bottom:" + this._lastChildContributingMargin + "px !important;}" + "li > ul:-moz-first-node, li > ol:-moz-first-node{padding-top:1.2em;}\n" + "li{min-height:1.2em;}" + "", this.document);
dojo.html.removeNode(tmpContent);
this.document.body.innerHTML = html;
if (oldMoz || dojo.render.html.safari) {
this.document.designMode = "on";
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?