define([ "dojo/_base/array", // array.forEach "dojo/aspect", // Aspect commands for advice "dojo/_base/declare", // declare "dojo/dom-attr", // domAttr.set "dojo/dom-construct", // domConstruct.create domConstruct.place "dojo/dom-geometry", // domGeometry.setMarginBox domGeometry.position "dojo/dom-style", // domStyle.set "dojo/i18n", // i18n.getLocalization "dojo/keys", // keys.F12 "dojo/_base/lang", // lang.hitch "dojo/on", // on() "dojo/sniff", // has("ie") "dojo/window", // winUtils.getBox "../../focus", // focus.focus() "../_Plugin", "../../form/ToggleButton", "../..", // dijit._scopeName "../../registry", // registry.getEnclosingWidget() "dojo/i18n!../nls/commands" ], function(array, aspect, declare, domAttr, domConstruct, domGeometry, domStyle, i18n, keys, lang, on, has, winUtils, focus, _Plugin, ToggleButton, dijit, registry){ // module: // dijit/_editor/plugins/ViewSource var ViewSource = declare("dijit._editor.plugins.ViewSource", _Plugin, { // summary: // This plugin provides a simple view source capability. When view // source mode is enabled, it disables all other buttons/plugins on the RTE. // It also binds to the hotkey: CTRL-SHIFT-F11 for toggling ViewSource mode. // stripScripts: [public] Boolean // Boolean flag used to indicate if script tags should be stripped from the document. // Defaults to true. stripScripts: true, // stripComments: [public] Boolean // Boolean flag used to indicate if comment tags should be stripped from the document. // Defaults to true. stripComments: true, // stripComments: [public] Boolean // Boolean flag used to indicate if iframe tags should be stripped from the document. // Defaults to true. stripIFrames: true, // stripEventHandlers: [public] Boolean // Boolean flag used to indicate if event handler attributes like onload should be // stripped from the document. // Defaults to true. stripEventHandlers: true, // readOnly: [const] Boolean // Boolean flag used to indicate if the source view should be readonly or not. // Cannot be changed after initialization of the plugin. // Defaults to false. readOnly: false, // _fsPlugin: [private] Object // Reference to a registered fullscreen plugin so that viewSource knows // how to scale. _fsPlugin: null, toggle: function(){ // summary: // Function to allow programmatic toggling of the view. // For Webkit, we have to focus a very particular way. // when swapping views, otherwise focus doesn't shift right // but can't focus this way all the time, only for VS changes. // If we did it all the time, buttons like bold, italic, etc // break. if(has("webkit")){ this._vsFocused = true; } this.button.set("checked", !this.button.get("checked")); }, _initButton: function(){ // summary: // Over-ride for creation of the resize button. var strings = i18n.getLocalization("dijit._editor", "commands"), editor = this.editor; this.button = new ToggleButton({ label: strings["viewSource"], ownerDocument: editor.ownerDocument, dir: editor.dir, lang: editor.lang, showLabel: false, iconClass: this.iconClassPrefix + " " + this.iconClassPrefix + "ViewSource", tabIndex: "-1", onChange: lang.hitch(this, "_showSource") }); // Make sure readonly mode doesn't make the wrong cursor appear over the button. this.button.set("readOnly", false); }, setEditor: function(/*dijit/Editor*/ editor){ // summary: // Tell the plugin which Editor it is associated with. // editor: Object // The editor object to attach the print capability to. this.editor = editor; this._initButton(); // Filter the html content when it is set and retrieved in the editor. this.removeValueFilterHandles(); this._setValueFilterHandle = aspect.before(this.editor, "setValue", lang.hitch(this, function (html) { return [this._filter(html)]; })); this._getValueFilterHandle = aspect.after(this.editor, "getValue", lang.hitch(this, function (html) { return this._filter(html); })); this.editor.addKeyHandler(keys.F12, true, true, lang.hitch(this, function(e){ // Move the focus before switching // It'll focus back. Hiding a focused // node causes issues. this.button.focus(); this.toggle(); e.stopPropagation(); e.preventDefault(); // Call the focus shift outside of the handler. setTimeout(lang.hitch(this, function(){ // Focus the textarea... unless focus has moved outside of the editor completely during the timeout. // Since we override focus, so we just need to call it. if(this.editor.focused){ this.editor.focus(); } }), 100); })); }, _showSource: function(source){ // summary: // Function to toggle between the source and RTE views. // source: boolean // Boolean value indicating if it should be in source mode or not. // tags: // private var ed = this.editor; var edPlugins = ed._plugins; var html; this._sourceShown = source; var self = this; try{ if(!this.sourceArea){ this._createSourceView(); } if(source){ // Update the QueryCommandEnabled function to disable everything but // the source view mode. Have to over-ride a function, then kick all // plugins to check their state. ed._sourceQueryCommandEnabled = ed.queryCommandEnabled; ed.queryCommandEnabled = function(cmd){ return cmd.toLowerCase() === "viewsource"; }; this.editor.onDisplayChanged(); array.forEach(edPlugins, function(p){ // Turn off any plugins not controlled by queryCommandenabled. if(p && !(p instanceof ViewSource) && p.isInstanceOf(_Plugin)){ p.set("disabled", true) } }); // We actually do need to trap this plugin and adjust how we // display the textarea. if(this._fsPlugin){ this._fsPlugin._getAltViewNode = function(){ return self.sourceArea; }; } this.sourceArea.value = ed.get("value"); // Since neither iframe nor textarea have margin, border, or padding, // just set sizes equal. this.sourceArea.style.height = ed.iframe.style.height; this.sourceArea.style.width = ed.iframe.style.width; // Hide the iframe and show the HTML source