Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
// This file is part of Moodle - http://moodle.org/
2
//
3
// Moodle is free software: you can redistribute it and/or modify
4
// it under the terms of the GNU General Public License as published by
5
// the Free Software Foundation, either version 3 of the License, or
6
// (at your option) any later version.
7
//
8
// Moodle is distributed in the hope that it will be useful,
9
// but WITHOUT ANY WARRANTY; without even the implied warranty of
10
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
// GNU General Public License for more details.
12
//
13
// You should have received a copy of the GNU General Public License
14
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
15
 
16
/*
17
 * @package    atto_html
18
 * @copyright  2013 Damyon Wiese  <damyon@moodle.com>
19
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
20
 */
21
 
22
/**
23
 * @module     moodle-atto_html-button
24
 */
25
 
26
/**
27
 * Atto text editor HTML plugin.
28
 *
29
 * @namespace M.atto_html
30
 * @class button
31
 * @extends M.editor_atto.EditorPlugin
32
 */
33
 
34
Y.namespace('M.atto_html').Button = Y.Base.create('button', Y.M.editor_atto.EditorPlugin, [], {
35
 
36
    _codeMirror: null,
37
 
38
    initializer: function() {
39
        this.addButton({
40
            icon: 'e/source_code',
41
            callback: this._toggleHTML
42
        });
43
 
44
        // Attach a submit listener to the form.
45
        // This ensures that the codeMirror is converted back to the original text before form submission.
46
        var form = this.get('host').textarea.ancestor('form');
47
        if (form) {
48
            form.on('submit', function() {
49
                if (this.get('isHTML')) {
50
                    this._hideCodeMirror();
51
                }
52
            }, this);
53
        }
54
    },
55
 
56
    /**
57
     * Toggle the view between the content editable div, and the textarea,
58
     * updating the content as it goes.
59
     *
60
     * @method _toggleHTML
61
     * @private
62
     */
63
    _toggleHTML: function() {
64
        // Toggle the HTML status.
65
        this.set('isHTML', !this.get('isHTML'));
66
 
67
        if (!this.get('isHTML')) {
68
            this._hideCodeMirror();
69
        } else {
70
            this._showCodeMirror();
71
        }
72
    },
73
 
74
    /**
75
     * Show the code mirror.
76
     *
77
     * @method _showCodeMirror
78
     * @private
79
     */
80
    _showCodeMirror: function() {
81
        var host = this.get('host');
82
 
83
        // Disable all plugins.
84
        host.disablePlugins();
85
 
86
        // And then re-enable this one.
87
        host.enablePlugins(this.name);
88
 
89
        // Copy the text to the contenteditable div.
90
        host.updateOriginal();
91
 
92
        // Hide the editor, and show the textarea.
93
        var dimensions = {
94
            width: this.editor.getComputedStyle('width'),
95
            height: this.editor.getComputedStyle('height')
96
        };
97
 
98
        // Tidy up the content if possible.
99
        var beautified = Y.M.atto_html.beautify.html_beautify(host.textarea.get('value'), {
100
            'indent_size': 4,
101
            'indent_inner_html': true
102
        });
103
        host.textarea.set('value', beautified);
104
 
105
        // Create the codeMirror from the textarea.
106
        this._codeMirror = Y.M.atto_html.CodeMirror.fromTextArea(host.textarea.getDOMNode(), {
107
            lineNumbers: true,
108
            mode: 'htmlmixed',
109
            tabSize: 2,
110
            lineWrapping: true
111
        });
112
        this._codeMirror.on('change', function(cm) {
113
            cm.save();
114
        });
115
 
116
        // Hide the text area and ensure that the codeMirror is displayed.
117
        this.editor.hide();
118
        this._codeMirror.setSize(dimensions.width, dimensions.height);
119
 
120
        // Focus on the codeMirror.
121
        this._codeMirror.focus();
122
    },
123
 
124
    /**
125
     * Hide the code mirror.
126
     *
127
     * @method _hideCodeMirror
128
     * @private
129
     */
130
    _hideCodeMirror: function() {
131
        var host = this.get('host');
132
 
133
        // Disable placeholder for empty content.
134
        // This will prevent the editor to copy and submit the empty placeholder.
135
        host.disablePlaceholderForEmptyContent();
136
 
137
        // Enable all plugins.
138
        host.enablePlugins();
139
 
140
        // Copy the text to the contenteditable div.
141
        host.updateFromTextArea();
142
 
143
        // Hide the textarea, and show the editor.
144
        if (this._codeMirror) {
145
            Y.one(this._codeMirror.getWrapperElement()).hide();
146
 
147
            // Calling toTextArea will remove the editor and all of its handlers.
148
            this._codeMirror.toTextArea();
149
 
150
            // Detach any remaining handlers.
151
            Y.Object.each(this._codeMirror._handlers, function(handlers, eventName) {
152
                Y.Array.each(handlers, function(handler) {
153
                    this.off(eventName, handler);
154
                }, this);
155
            }, this._codeMirror);
156
 
157
            // Cleanup.
158
            delete this._codeMirror;
159
            this._codeMirror = null;
160
        }
161
        host.textarea.hide();
162
        this.editor.show();
163
 
164
        // Focus on the editor.
165
        host.focus();
166
 
167
        // And re-mark everything as updated.
168
        this.markUpdated();
169
 
170
        // Enable placeholder for empty content.
171
        host.enablePlaceholderForEmptyContent();
172
    }
173
}, {
174
    ATTRS: {
175
        /**
176
         * The current state for the HTML view. If true, the HTML source is
177
         * shown in a textarea, otherwise the contenteditable area is
178
         * displayed.
179
         *
180
         * @attribute isHTML
181
         * @type Boolean
182
         * @default false
183
         */
184
        isHTML: {
185
            value: false
186
        }
187
    }
188
});