⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 htmlarea.js

📁 太烦了
💻 JS
📖 第 1 页 / 共 5 页
字号:
	if (height < 0) {
		height = 0;
	}
	iframe.style.height = height + "px";

	// the editor including the toolbar now have the same size as the
	// original textarea.. which means that we need to reduce that a bit.
	textarea.style.width = iframe.style.width;
 	textarea.style.height = iframe.style.height;

	// IMPORTANT: we have to allow Mozilla a short time to recognize the
	// new frame.  Otherwise we get a stupid exception.
	function initIframe() {
		var doc = editor._iframe.contentWindow.document;
		if (!doc) {
			// Try again..
			// FIXME: don't know what else to do here.  Normally
			// we'll never reach this point.
			if (HTMLArea.is_gecko) {
				setTimeout(initIframe, 100);
				return false;
			} else {
				alert("ERROR: IFRAME can't be initialized.");
			}
		}
		if (HTMLArea.is_gecko) {
			// enable editable mode for Mozilla
			doc.designMode = "on";
		}
		editor._doc = doc;
		if (!editor.config.fullPage) {
			doc.open();
			var html = '<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 3.2//EN">\n';
			html += "<html>\n";
			html += "<head>\n";
			if (editor.config.baseURL)
				html += '<base href="' + editor.config.baseURL + '" />';
			html += "<style type=\"text/css\">" + editor.config.pageStyle +
				" html,body { border: 0px; }</style>\n";
			html += "<title> </title>\n";
			html += "</head>\n";
			html += "<body>\n";
			html += editor._textArea.value;
			html += "</body>\n";
			html += "</html>";
			doc.write(html);
			doc.close();
		} else {
			var html = editor._textArea.value;
			if (html.match(HTMLArea.RE_doctype)) {
				editor.setDoctype(RegExp.$1);
				html = html.replace(HTMLArea.RE_doctype, "");
			}
			doc.open();
			doc.write(html);
			doc.close();
		}

		if (HTMLArea.is_ie) {
			// enable editable mode for IE.	 For some reason this
			// doesn't work if done in the same place as for Gecko
			// (above).
			doc.body.contentEditable = true;
		}

		editor.focusEditor();
		// intercept some events; for updating the toolbar & keyboard handlers
		HTMLArea._addEvents
			(doc, ["keydown", "keypress", "mousedown", "mouseup", "drag"],
			 function (event) {
				 return editor._editorEvent(HTMLArea.is_ie ? editor._iframe.contentWindow.event : event);
			 });

		// check if any plugins have registered refresh handlers
		for (var i in editor.plugins) {
			var plugin = editor.plugins[i].instance;
			if (typeof plugin.onGenerate == "function")
				plugin.onGenerate();
			if (typeof plugin.onGenerateOnce == "function") {
				plugin.onGenerateOnce();
				plugin.onGenerateOnce = null;
			}
		}

		setTimeout(function() {
			editor.updateToolbar();
		}, 250);

		if (typeof editor.onGenerate == "function")
			editor.onGenerate();
	};
	setTimeout(initIframe, 100);
};

// Switches editor mode; parameter can be "textmode" or "wysiwyg".  If no
// parameter was passed this function toggles between modes.
HTMLArea.prototype.setMode = function(mode) {
	if (typeof mode == "undefined") {
		mode = ((this._editMode == "textmode") ? "wysiwyg" : "textmode");
	}
	switch (mode) {
	    case "textmode":
		this._textArea.value = this.getHTML();
		this._iframe.style.display = "none";
		this._textArea.style.display = "block";
		if (this.config.statusBar) {
			this._statusBar.innerHTML = HTMLArea.I18N.msg["TEXT_MODE"];
		}
		break;
	    case "wysiwyg":
		if (HTMLArea.is_gecko) {
			// disable design mode before changing innerHTML
			try {
				this._doc.designMode = "off";
			} catch(e) {};
		}
		if (!this.config.fullPage)
			this._doc.body.innerHTML = this.getHTML();
		else
			this.setFullHTML(this.getHTML());
		this._iframe.style.display = "block";
		this._textArea.style.display = "none";
		if (HTMLArea.is_gecko) {
			// we need to refresh that info for Moz-1.3a
			try {
				this._doc.designMode = "on";
			} catch(e) {};
		}
		if (this.config.statusBar) {
			this._statusBar.innerHTML = '';
			// this._statusBar.appendChild(document.createTextNode(HTMLArea.I18N.msg["Path"] + ": "));
			this._statusBar.appendChild(this._statusBarTree);
		}
		break;
	    default:
		alert("Mode <" + mode + "> not defined!");
		return false;
	}
	this._editMode = mode;
	this.focusEditor();

	for (var i in this.plugins) {
		var plugin = this.plugins[i].instance;
		if (typeof plugin.onMode == "function") plugin.onMode(mode);
	}
};

HTMLArea.prototype.setFullHTML = function(html) {
	var save_multiline = RegExp.multiline;
	RegExp.multiline = true;
	if (html.match(HTMLArea.RE_doctype)) {
		this.setDoctype(RegExp.$1);
		html = html.replace(HTMLArea.RE_doctype, "");
	}
	RegExp.multiline = save_multiline;
	if (!HTMLArea.is_ie) {
		if (html.match(HTMLArea.RE_head))
			this._doc.getElementsByTagName("head")[0].innerHTML = RegExp.$1;
		if (html.match(HTMLArea.RE_body))
			this._doc.getElementsByTagName("body")[0].innerHTML = RegExp.$1;
	} else {
		var html_re = /<html>((.|\n)*?)<\/html>/i;
		html = html.replace(html_re, "$1");
		this._doc.open();
		this._doc.write(html);
		this._doc.close();
		this._doc.body.contentEditable = true;
		return true;
	}
};

/***************************************************
 *  Category: PLUGINS
 ***************************************************/

// Create the specified plugin and register it with this HTMLArea
HTMLArea.prototype.registerPlugin = function() {
	var plugin = arguments[0];
	var args = [];
	for (var i = 1; i < arguments.length; ++i)
		args.push(arguments[i]);
	this.registerPlugin2(plugin, args);
};

// this is the variant of the function above where the plugin arguments are
// already packed in an array.  Externally, it should be only used in the
// full-screen editor code, in order to initialize plugins with the same
// parameters as in the opener window.
HTMLArea.prototype.registerPlugin2 = function(plugin, args) {
	if (typeof plugin == "string")
		plugin = eval(plugin);
	if (typeof plugin == "undefined") {
		/* FIXME: This should never happen. But why does it do? */
		return false;
	}
	var obj = new plugin(this, args);
	if (obj) {
		var clone = {};
		var info = plugin._pluginInfo;
		for (var i in info)
			clone[i] = info[i];
		clone.instance = obj;
		clone.args = args;
		this.plugins[plugin._pluginInfo.name] = clone;
	} else
		alert("Can't register plugin " + plugin.toString() + ".");
};

// static function that loads the required plugin and lang file, based on the
// language loaded already for HTMLArea.  You better make sure that the plugin
// _has_ that language, otherwise shit might happen ;-)
HTMLArea.getPluginDir = function(pluginName) {
	return _editor_url + "plugins/" + pluginName;
};

HTMLArea.loadPlugin = function(pluginName) {
	var dir = this.getPluginDir(pluginName);
	var plugin = pluginName.replace(/([a-z])([A-Z])([a-z])/g,
					function (str, l1, l2, l3) {
						return l1 + "-" + l2.toLowerCase() + l3;
					}).toLowerCase() + ".js";
	var plugin_file = dir + "/" + plugin;
	var plugin_lang = dir + "/lang/" + _editor_lang + ".js";
	//document.write("<script type='text/javascript' src='" + plugin_file + "'></script>");
	//document.write("<script type='text/javascript' src='" + plugin_lang + "'></script>");
	this.loadScript(plugin_file);
	this.loadScript(plugin_lang);
};

HTMLArea.loadStyle = function(style, plugin) {
	var url = _editor_url || '';
	if (typeof plugin != "undefined") {
		url += "plugins/" + plugin + "/";
	}
	url += style;
	if (/^\//.test(style))
		url = style;
	var head = document.getElementsByTagName("head")[0];
	var link = document.createElement("link");
	link.rel = "stylesheet";
	link.href = url;
	head.appendChild(link);
	//document.write("<style type='text/css'>@import url(" + url + ");</style>");
};
HTMLArea.loadStyle(typeof _editor_css == "string" ? _editor_css : "htmlarea.css");

/***************************************************
 *  Category: EDITOR UTILITIES
 ***************************************************/

HTMLArea.prototype.debugTree = function() {
	var ta = document.createElement("textarea");
	ta.style.width = "100%";
	ta.style.height = "20em";
	ta.value = "";
	function debug(indent, str) {
		for (; --indent >= 0;)
			ta.value += " ";
		ta.value += str + "\n";
	};
	function _dt(root, level) {
		var tag = root.tagName.toLowerCase(), i;
		var ns = HTMLArea.is_ie ? root.scopeName : root.prefix;
		debug(level, "- " + tag + " [" + ns + "]");
		for (i = root.firstChild; i; i = i.nextSibling)
			if (i.nodeType == 1)
				_dt(i, level + 2);
	};
	_dt(this._doc.body, 0);
	document.body.appendChild(ta);
};

HTMLArea.getInnerText = function(el) {
	var txt = '', i;
	for (i = el.firstChild; i; i = i.nextSibling) {
		if (i.nodeType == 3)
			txt += i.data;
		else if (i.nodeType == 1)
			txt += HTMLArea.getInnerText(i);
	}
	return txt;
};

HTMLArea.prototype._wordClean = function() {
	var
		editor = this,
		stats = {
			empty_tags : 0,
			mso_class  : 0,
			mso_style  : 0,
			mso_xmlel  : 0,
			orig_len   : this._doc.body.innerHTML.length,
			T          : (new Date()).getTime()
		},
		stats_txt = {
			empty_tags : "Empty tags removed: ",
			mso_class  : "MSO class names removed: ",
			mso_style  : "MSO inline style removed: ",
			mso_xmlel  : "MSO XML elements stripped: "
		};
	function showStats() {
		var txt = "HTMLArea word cleaner stats: \n\n";
		for (var i in stats)
			if (stats_txt[i])
				txt += stats_txt[i] + stats[i] + "\n";
		txt += "\nInitial document length: " + stats.orig_len + "\n";
		txt += "Final document length: " + editor._doc.body.innerHTML.length + "\n";
		txt += "Clean-up took " + (((new Date()).getTime() - stats.T) / 1000) + " seconds";
		alert(txt);
	};
	function clearClass(node) {
		var newc = node.className.replace(/(^|\s)mso.*?(\s|$)/ig, ' ');
		if (newc != node.className) {
			node.className = newc;
			if (!/\S/.test(node.className)) {
				node.removeAttribute("className");
				++stats.mso_class;
			}
		}
	};
	function clearStyle(node) {
 		var declarations = node.style.cssText.split(/\s*;\s*/);
		for (var i = declarations.length; --i >= 0;)
			if (/^mso|^tab-stops/i.test(declarations[i]) ||
			    /^margin\s*:\s*0..\s+0..\s+0../i.test(declarations[i])) {
				++stats.mso_style;
				declarations.splice(i, 1);
			}
		node.style.cssText = declarations.join("; ");
	};
	function stripTag(el) {
		if (HTMLArea.is_ie)
			el.outerHTML = HTMLArea.htmlEncode(el.innerText);
		else {
			var txt = document.createTextNode(HTMLArea.getInnerText(el));
			el.parentNode.insertBefore(txt, el);
			el.parentNode.removeChild(el);
		}
		++stats.mso_xmlel;
	};
	function checkEmpty(el) {
		if (/^(a|span|b|strong|i|em|font)$/i.test(el.tagName) &&
		    !el.firstChild) {
			el.parentNode.removeChild(el);
			++stats.empty_tags;
		}
	};
	function parseTree(root) {
		var tag = root.tagName.toLowerCase(), i, next;
		if ((HTMLArea.is_ie && root.scopeName != 'HTML') || (!HTMLArea.is_ie && /:/.test(tag))) {
			stripTag(root);
			return false;
		} else {
			clearClass(root);
			clearStyle(root);
			for (i = root.firstChild; i; i = next) {
				next = i.nextSibling;
				if (i.nodeType == 1 && parseTree(i))
					checkEmpty(i);
			}
		}
		return true;
	};
	parseTree(this._doc.body);
	// showStats();
	// this.debugTree();
	// this.setHTML(this.getHTML());
	// this.setHTML(this.getInnerHTML());
	// this.forceRedraw();
	this.updateToolbar();
};

HTMLArea.prototype.forceRedraw = function() {
	this._doc.body.style.visibility = "hidden";
	this._doc.body.style.visibility = "visible";
	// this._doc.body.innerHTML = this.getInnerHTML();
};

// focuses the iframe window.  returns a reference to the editor document.
HTMLArea.prototype.focusEditor = function() {
	switch (this._editMode) {
	    // notice the try { ... } catch block to avoid some rare exceptions in FireFox
	    // (perhaps also in other Gecko browsers). Manual focus by user is required in
        // case of an error. Somebody has an idea?
	    case "wysiwyg" : try { this._iframe.contentWindow.focus() } catch (e) {} break;
	    case "textmode": try { this._textArea.focus() } catch (e) {} break;
	    default	   : alert("ERROR: mode " + this._editMode + " is not defined");
	}
	return this._doc;
};

// takes a snapshot of the current text (for undo)
HTMLArea.prototype._undoTakeSnapshot = function() {
	++this._undoPos;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -