Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
/**
2
 * TinyMCE version 6.8.3 (2024-02-08)
3
 */
4
 
5
(function () {
6
    'use strict';
7
 
8
    var global$2 = tinymce.util.Tools.resolve('tinymce.PluginManager');
9
 
10
    var global$1 = tinymce.util.Tools.resolve('tinymce.dom.RangeUtils');
11
 
12
    var global = tinymce.util.Tools.resolve('tinymce.util.Tools');
13
 
14
    const option = name => editor => editor.options.get(name);
15
    const register$2 = editor => {
16
      const registerOption = editor.options.register;
17
      registerOption('allow_html_in_named_anchor', {
18
        processor: 'boolean',
19
        default: false
20
      });
21
    };
22
    const allowHtmlInNamedAnchor = option('allow_html_in_named_anchor');
23
 
24
    const namedAnchorSelector = 'a:not([href])';
25
    const isEmptyString = str => !str;
26
    const getIdFromAnchor = elm => {
27
      const id = elm.getAttribute('id') || elm.getAttribute('name');
28
      return id || '';
29
    };
30
    const isAnchor = elm => elm.nodeName.toLowerCase() === 'a';
31
    const isNamedAnchor = elm => isAnchor(elm) && !elm.getAttribute('href') && getIdFromAnchor(elm) !== '';
32
    const isEmptyNamedAnchor = elm => isNamedAnchor(elm) && !elm.firstChild;
33
 
34
    const removeEmptyNamedAnchorsInSelection = editor => {
35
      const dom = editor.dom;
36
      global$1(dom).walk(editor.selection.getRng(), nodes => {
37
        global.each(nodes, node => {
38
          if (isEmptyNamedAnchor(node)) {
39
            dom.remove(node, false);
40
          }
41
        });
42
      });
43
    };
44
    const isValidId = id => /^[A-Za-z][A-Za-z0-9\-:._]*$/.test(id);
45
    const getNamedAnchor = editor => editor.dom.getParent(editor.selection.getStart(), namedAnchorSelector);
46
    const getId = editor => {
47
      const anchor = getNamedAnchor(editor);
48
      if (anchor) {
49
        return getIdFromAnchor(anchor);
50
      } else {
51
        return '';
52
      }
53
    };
54
    const createAnchor = (editor, id) => {
55
      editor.undoManager.transact(() => {
56
        if (!allowHtmlInNamedAnchor(editor)) {
57
          editor.selection.collapse(true);
58
        }
59
        if (editor.selection.isCollapsed()) {
60
          editor.insertContent(editor.dom.createHTML('a', { id }));
61
        } else {
62
          removeEmptyNamedAnchorsInSelection(editor);
63
          editor.formatter.remove('namedAnchor', undefined, undefined, true);
64
          editor.formatter.apply('namedAnchor', { value: id });
65
          editor.addVisual();
66
        }
67
      });
68
    };
69
    const updateAnchor = (editor, id, anchorElement) => {
70
      anchorElement.removeAttribute('name');
71
      anchorElement.id = id;
72
      editor.addVisual();
73
      editor.undoManager.add();
74
    };
75
    const insert = (editor, id) => {
76
      const anchor = getNamedAnchor(editor);
77
      if (anchor) {
78
        updateAnchor(editor, id, anchor);
79
      } else {
80
        createAnchor(editor, id);
81
      }
82
      editor.focus();
83
    };
84
 
85
    const insertAnchor = (editor, newId) => {
86
      if (!isValidId(newId)) {
87
        editor.windowManager.alert('ID should start with a letter, followed only by letters, numbers, dashes, dots, colons or underscores.');
88
        return false;
89
      } else {
90
        insert(editor, newId);
91
        return true;
92
      }
93
    };
94
    const open = editor => {
95
      const currentId = getId(editor);
96
      editor.windowManager.open({
97
        title: 'Anchor',
98
        size: 'normal',
99
        body: {
100
          type: 'panel',
101
          items: [{
102
              name: 'id',
103
              type: 'input',
104
              label: 'ID',
105
              placeholder: 'example'
106
            }]
107
        },
108
        buttons: [
109
          {
110
            type: 'cancel',
111
            name: 'cancel',
112
            text: 'Cancel'
113
          },
114
          {
115
            type: 'submit',
116
            name: 'save',
117
            text: 'Save',
118
            primary: true
119
          }
120
        ],
121
        initialData: { id: currentId },
122
        onSubmit: api => {
123
          if (insertAnchor(editor, api.getData().id)) {
124
            api.close();
125
          }
126
        }
127
      });
128
    };
129
 
130
    const register$1 = editor => {
131
      editor.addCommand('mceAnchor', () => {
132
        open(editor);
133
      });
134
    };
135
 
136
    const isNamedAnchorNode = node => isEmptyString(node.attr('href')) && !isEmptyString(node.attr('id') || node.attr('name'));
137
    const isEmptyNamedAnchorNode = node => isNamedAnchorNode(node) && !node.firstChild;
138
    const setContentEditable = state => nodes => {
139
      for (let i = 0; i < nodes.length; i++) {
140
        const node = nodes[i];
141
        if (isEmptyNamedAnchorNode(node)) {
142
          node.attr('contenteditable', state);
143
        }
144
      }
145
    };
146
    const setup = editor => {
147
      editor.on('PreInit', () => {
148
        editor.parser.addNodeFilter('a', setContentEditable('false'));
149
        editor.serializer.addNodeFilter('a', setContentEditable(null));
150
      });
151
    };
152
 
153
    const registerFormats = editor => {
154
      editor.formatter.register('namedAnchor', {
155
        inline: 'a',
156
        selector: namedAnchorSelector,
157
        remove: 'all',
158
        split: true,
159
        deep: true,
160
        attributes: { id: '%value' },
161
        onmatch: (node, _fmt, _itemName) => {
162
          return isNamedAnchor(node);
163
        }
164
      });
165
    };
166
 
167
    const onSetupEditable = editor => api => {
168
      const nodeChanged = () => {
169
        api.setEnabled(editor.selection.isEditable());
170
      };
171
      editor.on('NodeChange', nodeChanged);
172
      nodeChanged();
173
      return () => {
174
        editor.off('NodeChange', nodeChanged);
175
      };
176
    };
177
    const register = editor => {
178
      const onAction = () => editor.execCommand('mceAnchor');
179
      editor.ui.registry.addToggleButton('anchor', {
180
        icon: 'bookmark',
181
        tooltip: 'Anchor',
182
        onAction,
183
        onSetup: buttonApi => {
184
          const unbindSelectorChanged = editor.selection.selectorChangedWithUnbind('a:not([href])', buttonApi.setActive).unbind;
185
          const unbindEditableChanged = onSetupEditable(editor)(buttonApi);
186
          return () => {
187
            unbindSelectorChanged();
188
            unbindEditableChanged();
189
          };
190
        }
191
      });
192
      editor.ui.registry.addMenuItem('anchor', {
193
        icon: 'bookmark',
194
        text: 'Anchor...',
195
        onAction,
196
        onSetup: onSetupEditable(editor)
197
      });
198
    };
199
 
200
    var Plugin = () => {
201
      global$2.add('anchor', editor => {
202
        register$2(editor);
203
        setup(editor);
204
        register$1(editor);
205
        register(editor);
206
        editor.on('PreInit', () => {
207
          registerFormats(editor);
208
        });
209
      });
210
    };
211
 
212
    Plugin();
213
 
214
})();