📄 sync.richtextarea.js
字号:
new Echo.Label({ text: richTextArea.peer._msg[ setBackground ? "ColorDialog.PromptBackground" : "ColorDialog.PromptForeground"] }), this._colorSelect = new Extras.ColorSelect({ color: initialColor, displayValue: true }) ] }), new Echo.Grid({ insets: 2, size: 3, children: this._createSwatches() }) ] })); }, _createSwatches: function() { var children = []; var COLORS = Extras.Sync.RichTextArea.ColorDialog.COLORS; var actionListener = Core.method(this, function(e) { this._colorSelect.set("color", e.actionCommand); }); for (var i = 0; i < COLORS.length; ++i) { children.push(new Echo.Button({ height: "1em", width: "3em", background: COLORS[i], border: "1px outset " + COLORS[i], actionCommand: COLORS[i], events: { action: actionListener } })); } return children; }, processOk: function(e) { var color = this._colorSelect.get("color"); this.parent.remove(this); this.fireEvent({type: "colorSelect", source: this, data : color}); }});Extras.Sync.RichTextArea.HyperlinkDialog = Core.extend(Extras.Sync.RichTextArea.AbstractDialog, { $construct: function(richTextArea) { Extras.Sync.RichTextArea.AbstractDialog.call(this, richTextArea, Extras.Sync.RichTextArea.AbstractDialog.TYPE_OK_CANCEL, { title: richTextArea.peer._msg["HyperlinkDialog.Title"], icon: richTextArea.peer._icons.hyperlink }, new Echo.Column({ insets: 10, children: [ new Echo.Label({ text: richTextArea.peer._msg["HyperlinkDialog.PromptURL"] }), this._urlField = new Echo.TextField({ width: "100%" }), new Echo.Label({ text: richTextArea.peer._msg["HyperlinkDialog.PromptDescription"] }), this._descriptionField = new Echo.TextField({ width: "100%" }) ] })); }, processOk: function(e) { var data = { url: this._urlField.get("text"), description: this._descriptionField.get("text") }; if (!data.url) { this.parent.add(new Extras.Sync.RichTextArea.MessageDialog(this._richTextArea, this._richTextArea.peer._msg["HyperlinkDialog.ErrorDialogTitle"], this._richTextArea.peer._msg["HyperlinkDialog.ErrorDialog.URL"])); return; } this.parent.remove(this); this.fireEvent({type: "insertHyperlink", source: this, data: data}); }});Extras.Sync.RichTextArea.ImageDialog = Core.extend(Extras.Sync.RichTextArea.AbstractDialog, { $construct: function(richTextArea) { Extras.Sync.RichTextArea.AbstractDialog.call(this, richTextArea, Extras.Sync.RichTextArea.AbstractDialog.TYPE_OK_CANCEL, { title: richTextArea.peer._msg["ImageDialog.Title"], image: richTextArea.peer._icons.image }, new Echo.Column({ insets: 10, children: [ new Echo.Label({ text: richTextArea.peer._msg["ImageDialog.PromptURL"] }), this._urlField = new Echo.TextField({ width: "100%" }) ] })); }, processOk: function(e) { var data = { url: this._urlField.get("text") }; if (!data.url) { this.parent.add(new Extras.Sync.RichTextArea.MessageDialog(this._richTextArea, this._richTextArea.peer._msg["ImageDialog.ErrorDialogTitle"], this._richTextArea.peer._msg["ImageDialog.ErrorDialog.URL"])); return; } this.parent.remove(this); this.fireEvent({type: "insertImage", source: this, data: data}); }});/** * Pane which renders its content over the body of the application. * This component breaks out of the element-based component hierarchy. */Extras.Sync.RichTextArea.OverlayPane = Core.extend(Echo.Component, { $load: function() { Echo.ComponentFactory.registerType("Extras.RichTextOverlayPane", this); }, _richTextArea: null, componentType: "Extras.RichTextOverlayPane", floatingPane: true, pane: true});Extras.Sync.RichTextArea.OverlayPanePeer = Core.extend(Echo.Render.ComponentSync, { _div: null, $load: function() { Echo.Render.registerPeer("Extras.RichTextOverlayPane", this); }, renderAdd: function(update, parentElement) { this._div = document.createElement("div"); this._div.style.cssText = "position:absolute;top:0;right:0;bottom:0;left:0;z-index:32767;"; if (this.component.children.length == 1) { Echo.Render.renderComponentAdd(update, this.component.children[0], this._div); } else if (this.component.children.length > 1) { throw new Error("Too many children added to OverlayPane."); } this.component._richTextArea.peer.client.domainElement.appendChild(this._div); }, renderDispose: function(update) { if (this._div && this._div.parentNode) { this._div.parentNode.removeChild(this._div); } }, renderDisplay: function(update) { Core.Web.VirtualPosition.redraw(this._div); }, renderUpdate: function(update) { var element = this._div; var containerElement = element.parentNode; Echo.Render.renderComponentDispose(update, update.parent); containerElement.removeChild(element); this.renderAdd(update, containerElement); return true; }});Extras.Sync.RichTextArea.InputComponent = Core.extend(Echo.Component, { /** * The containing RichTextArea component. */ _richTextArea: null, $load: function() { Echo.ComponentFactory.registerType("Extras.RichTextInput", this); }, componentType: "Extras.RichTextInput", focusable: true});Extras.Sync.RichTextArea.InputPeer = Core.extend(Echo.Render.ComponentSync, { $load: function() { Echo.Render.registerPeer("Extras.RichTextInput", this); }, $static: { _CSS_BOLD: /font-weight\:\s*bold/i, _CSS_FOREGROUND_TEST: /^-?color\:/i, _CSS_FOREGROUND_RGB: /^-?color\:\s*rgb\s*\(\s*(\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})/i, _CSS_BACKGROUND_TEST: /background-color\:/i, _CSS_BACKGROUND_RGB: /background-color\:\s*rgb\s*\(\s*(\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})/i, _CSS_ITALIC: /font-style\:\s*italic/i, _CSS_UNDERLINE: /text-decoration\:\s*underline/i, /** * Key codes which may result in cursor navigating into new style, requiring an update of the style indicators. */ _NAVIGATION_KEY_CODES: { 38: 1, 40: 1, 37: 1, 39: 1, 33: 1, 34: 1, 36: 1, 35: 1, 8: 1, 46: 1 } }, _cursorStyleUpdateRequired: false, /** * {Boolean} Flag indicating whether the parent component of the associated RichTextArea is a pane, * and thus whether the RichTextArea's input region should consume available vertical space. */ _paneRender: false, _fireAction: false, _renderedHtml: null, _processPropertyRef: null, $construct: function() { this._processPropertyRef = Core.method(this, this._processProperty); }, execCommand: function(commandName, value) { this._loadRange(); this._iframe.contentWindow.document.execCommand(commandName, false, value); this._storeData(); this._forceIERedraw(); // Flag that cursor style update is required. Some browsers will not render nodes until text is inserted. this._cursorStyleUpdateRequired = true; }, focusDocument: function() { this.client.application.setFocusedComponent(this.component); this._forceIERedraw(); }, _forceIERedraw: function() { if (Core.Web.Env.BROWSER_INTERNET_EXPLORER) { if (this._redrawScheduled || this.component._richTextArea.peer.client.domainElement.offsetHeight !== 0) { // Do not schedule redraw if one is already scheduled, or if height of domain element is nonzero // (the domain element having a height of 0 is indicative of the IE7's blanking bug having occurred). return; } this._redrawScheduled = true; // Force full screen redraw to avoid IE bug where screen mysteriously goes blank in IE. Core.Web.Scheduler.run(Core.method(this, function() { this._redrawScheduled = false; var displayState = document.documentElement.style.display; if (!displayState) { displayState = ""; } document.documentElement.style.display = "none"; document.documentElement.style.display = displayState; })); } }, _getCursorStyle: function() { var selection = this._getSelection(); var style = { }; var rgb; var node = selection.node; while (node) { if (node.nodeType == 1) { switch (node.nodeName.toLowerCase()) { case "b": case "strong": style.bold = true; break; case "i": case "em": style.italic = true; break; case "u": style.underline = true; break; case "h1": case "h2": case "h3": case "h4": case "h5": case "h6": case "p": case "pre": if (!style.paragraphStyle) { style.paragraphStyle = node.nodeName.toLowerCase(); } break; } var css = node.style.cssText; style.bold |= Extras.Sync.RichTextArea.InputPeer._CSS_BOLD.test(css); style.italic |= Extras.Sync.RichTextArea.InputPeer._CSS_ITALIC.test(css); style.underline |= Extras.Sync.RichTextArea.InputPeer._CSS_UNDERLINE.test(css); if (!style.foreground && Extras.Sync.RichTextArea.InputPeer._CSS_FOREGROUND_TEST.test(css)) { rgb = Extras.Sync.RichTextArea.InputPeer._CSS_FOREGROUND_RGB.exec(css); if (rgb) { style.foreground = Echo.Sync.Color.toHex( parseInt(rgb[1], 10), parseInt(rgb[2], 10), parseInt(rgb[3], 10)); } } if (!style.background && Extras.Sync.RichTextArea.InputPeer._CSS_BACKGROUND_TEST.test(css)) { rgb = Extras.Sync.RichTextArea.InputPeer._CSS_BACKGROUND_RGB.exec(css); if (rgb) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -