[ Index ] |
PHP Cross Reference of Joomla 4.2.2 documentation |
[Summary view] [Print] [Text view]
1 (function () { 2 'use strict'; 3 4 /** 5 * source.js 6 * 7 * Original code by Arjan Haverkamp 8 * Copyright 2013-2015 Arjan Haverkamp ([email protected]) 9 */ 10 if (!window.parent.Joomla || typeof window.parent.Joomla.getOptions !== 'function') { 11 throw new Error('Joomla API not found'); 12 } // Get the base path for CodeMirror 13 14 15 var rootPath = window.parent.Joomla.getOptions('system.paths').rootFull; 16 var cmPath = rootPath + "/media/vendor/codemirror"; // CodeMirror settings 17 18 var CMsettings = { 19 indentOnInit: true, 20 config: { 21 mode: 'htmlmixed', 22 theme: 'default', 23 lineNumbers: true, 24 lineWrapping: true, 25 indentUnit: 2, 26 tabSize: 2, 27 indentWithTabs: true, 28 matchBrackets: true, 29 saveCursorPosition: true, 30 styleActiveLine: true 31 }, 32 jsFiles: [// Default JS files 33 cmPath + "/lib/codemirror.min.js", cmPath + "/addon/edit/matchbrackets.min.js", cmPath + "/mode/xml/xml.min.js", cmPath + "/mode/javascript/javascript.min.js", cmPath + "/mode/css/css.min.js", cmPath + "/mode/htmlmixed/htmlmixed.min.js", cmPath + "/addon/dialog/dialog.min.js", cmPath + "/addon/search/searchcursor.min.js", cmPath + "/addon/search/search.min.js", cmPath + "/addon/selection/active-line.min.js"], 34 cssFiles: [// Default CSS files 35 cmPath + "/lib/codemirror.css", cmPath + "/addon/dialog/dialog.css"] 36 }; // Declare some variables: 37 38 var tinymce; // Reference to TinyMCE 39 40 var editor; // Reference to TinyMCE editor 41 42 var codemirror; // CodeMirror instance 43 44 var chr = 0; // Unused utf-8 character, placeholder for cursor 45 46 var isMac = /macintosh|mac os/i.test(navigator.userAgent); // Utility function to load CodeMirror script files 47 48 var loadScript = function loadScript(url) { 49 return new Promise(function (resolve, reject) { 50 var script = document.createElement('script'); 51 script.src = url; 52 53 script.onload = function () { 54 return resolve(); 55 }; 56 57 script.onerror = function () { 58 return reject(new Error("Failed to load the script " + url)); 59 }; 60 61 document.head.appendChild(script); 62 }); 63 }; 64 /** 65 * Find the depth level 66 */ 67 68 69 var findDepth = function findDepth(haystack, needle) { 70 var idx = haystack.indexOf(needle); 71 var depth = 0; 72 73 for (var x = idx - 1; x >= 0; x -= 1) { 74 switch (haystack.charAt(x)) { 75 case '<': 76 depth -= 1; 77 break; 78 79 case '>': 80 depth += 1; 81 break; 82 83 case '&': 84 depth += 1; 85 break; 86 } 87 } 88 89 return depth; 90 }; 91 /** 92 * This function is called by plugin.js, when user clicks 'Ok' button 93 */ 94 95 96 window.tinymceHighlighterSubmit = function () { 97 var cc = '�'; 98 var _codemirror = codemirror, 99 isDirty = _codemirror.isDirty; 100 var _codemirror2 = codemirror, 101 doc = _codemirror2.doc; 102 103 if (doc.somethingSelected()) { 104 // Clear selection: 105 doc.setCursor(doc.getCursor()); 106 } // Insert cursor placeholder (�) 107 108 109 doc.replaceSelection(cc); 110 var pos = codemirror.getCursor(); 111 var curLineHTML = doc.getLine(pos.line); 112 113 if (findDepth(curLineHTML, cc) !== 0) { 114 // Cursor is inside a <tag>, don't set cursor: 115 curLineHTML = curLineHTML.replace(cc, ''); 116 doc.replaceRange(curLineHTML, window.CodeMirror.Pos(pos.line, 0), window.CodeMirror.Pos(pos.line)); 117 } // Submit HTML to TinyMCE: 118 // [FIX] Cursor position inside JS, style or &nbps; 119 // Workaround to fix cursor position if inside script tag 120 121 122 var code = codemirror.getValue(); 123 /* Regex to check if inside script or style tags */ 124 125 var ccScript = new RegExp("<script(.*?)>(.*?)" + cc + "(.*?)</script>", 'ms'); 126 var ccStyle = new RegExp("<style(.*?)>(.*?)" + cc + "(.*?)</style>", 'ms'); 127 /* Regex to check if in beginning or end or if between < & > */ 128 129 var ccLocationCheck = new RegExp("<[^>]*(" + cc + ").*>|^(" + cc + ")|(" + cc + ")$"); 130 131 if (code.search(ccScript) !== -1 || code.search(ccStyle) !== -1 || code.search(ccLocationCheck) !== -1) { 132 editor.setContent(code.replace(cc, '')); 133 } else { 134 editor.setContent(code.replace(cc, '<span id="CmCaReT"></span>')); 135 } 136 137 editor.isNotDirty = !isDirty; 138 139 if (isDirty) { 140 editor.nodeChanged(); 141 } // Set cursor: 142 143 144 var el = editor.dom.select('span#CmCaReT')[0]; 145 146 if (el) { 147 editor.selection.scrollIntoView(el); 148 editor.selection.setCursorLocation(el, 0); 149 editor.dom.remove(el); 150 } 151 }; 152 /** 153 * Listen for the escape key and close the modal 154 * 155 * @param {Event} evt 156 */ 157 158 159 document.addEventListener('keydown', function (evt) { 160 var event = evt || window.event; 161 var isEscape = false; 162 if ('key' in event) isEscape = event.key === 'Escape' || event.key === 'Esc';else isEscape = event.keyCode === 27; 163 if (isEscape) tinymce.activeEditor.windowManager.close(); 164 }); 165 /** 166 * Append some help text in the modal footer 167 */ 168 169 var start = function start() { 170 // Initialise (on load) 171 if (typeof window.CodeMirror !== 'function') { 172 throw new Error("CodeMirror not found in \"" + CMsettings.path + "\", aborting..."); 173 } // Create legend for keyboard shortcuts for find & replace: 174 175 176 var head = window.parent.document.querySelectorAll('.tox-dialog__footer')[0]; 177 var div = window.parent.document.createElement('div'); 178 var td1 = '<td style="font-size:11px;background:#777;color:#fff;padding:0 4px">'; 179 var td2 = '<td style="font-size:11px;padding-right:5px">'; 180 div.innerHTML = "\n<table cellspacing=\"0\" cellpadding=\"0\" style=\"border-spacing:4px\">\n <tr>\n " + td1 + (isMac ? '⌘-F' : 'Ctrl-F</td>') + td2 + tinymce.translate('Start search') + "</td>\n " + td1 + (isMac ? '⌘-G' : 'Ctrl-G') + "</td>\n " + td2 + tinymce.translate('Find next') + "</td>\n " + td1 + (isMac ? '⌘-Alt-F' : 'Shift-Ctrl-F') + "</td>\n " + td2 + tinymce.translate('Find previous') + "</td>\n </tr>\n <tr>\n " + td1 + (isMac ? '⌘-Alt-F' : 'Shift-Ctrl-F') + "</td>\n " + td2 + tinymce.translate('Replace') + "</td>\n " + td1 + (isMac ? 'Shift-⌘-Alt-F' : 'Shift-Ctrl-R') + "</td>\n " + td2 + tinymce.translate('Replace all') + "</td>\n </tr>\n</table>"; 181 div.style.position = 'absolute'; 182 div.style.left = '5px'; 183 div.style.bottom = '5px'; 184 head.appendChild(div); // Set CodeMirror cursor and bookmark to same position as cursor was in TinyMCE: 185 186 var html = editor.getContent({ 187 source_view: true 188 }); // [FIX] #6 z-index issue with table panel and source code dialog 189 // editor.selection.getBookmark(); 190 191 html = html.replace(/<span\s+style="display: none;"\s+class="CmCaReT"([^>]*)>([^<]*)<\/span>/gm, String.fromCharCode(chr)); 192 editor.dom.remove(editor.dom.select('.CmCaReT')); // Hide TinyMCE toolbar panels, [FIX] #6 z-index issue with table panel and source code dialog 193 // https://github.com/christiaan/tinymce-codemirror/issues/6 194 195 tinymce.each(editor.contextToolbars, function (toolbar) { 196 if (toolbar.panel) { 197 toolbar.panel.hide(); 198 } 199 }); 200 window.CodeMirror.defineInitHook(function (inst) { 201 // Move cursor to correct position: 202 inst.focus(); 203 var cursor = inst.getSearchCursor(String.fromCharCode(chr), false); 204 205 if (cursor.findNext()) { 206 inst.setCursor(cursor.to()); 207 cursor.replace(''); 208 } // Indent all code, if so requested: 209 210 211 if (editor.settings.codemirror.indentOnInit) { 212 var last = inst.lineCount(); 213 inst.operation(function () { 214 // eslint-disable-next-line no-plusplus 215 for (var i = 0; i < last; ++i) { 216 inst.indentLine(i); 217 } 218 }); 219 } 220 }); 221 CMsettings.config.value = html; // Instantiate CodeMirror: 222 223 codemirror = window.CodeMirror(document.body, CMsettings.config); 224 codemirror.isDirty = false; 225 codemirror.on('change', function (inst) { 226 inst.isDirty = true; 227 }); 228 codemirror.setSize('100%', '100%'); 229 codemirror.refresh(); 230 }; // Initialise 231 232 233 tinymce = window.parent.tinymce; 234 235 if (!tinymce) { 236 throw new Error('tinyMCE not found'); 237 } 238 239 editor = tinymce.activeEditor; 240 var userSettings = editor.settings.codemirror; 241 242 if (userSettings.fullscreen) { 243 CMsettings.jsFiles.push(cmPath + "/addon/display/fullscreen.min.js"); 244 CMsettings.cssFiles.push(cmPath + "/addon/display/fullscreen.css"); 245 } // Merge config 246 247 248 CMsettings = Object.assign({}, CMsettings, userSettings); // Append the stylesheets 249 250 CMsettings.cssFiles.forEach(function (css) { 251 var link = document.createElement('link'); 252 link.rel = 'stylesheet'; 253 link.href = css; 254 document.head.appendChild(link); 255 }); 256 /** 257 * Append javascript files ensuring the order of execution. 258 * Then execute the start function. 259 */ 260 261 CMsettings.jsFiles.reduce(function (p, item) { 262 return p.then(function () { 263 return loadScript(item); 264 }); 265 }, Promise.resolve(true)).then(function () { 266 // Borrowed from codemirror.js themeChanged function. Sets the theme's class names to the html element. 267 // Without this, the background color outside of the codemirror wrapper element remains white. 268 // [TMP] commented temporary, cause JS error: Uncaught TypeError: Cannot read property 'replace' of undefined 269 if (CMsettings.config.theme) { 270 document.documentElement.className += CMsettings.config.theme.replace(/(^|\s)\s*/g, ' cm-s-'); 271 } 272 273 start(); 274 }); 275 276 })();
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Sep 7 05:41:13 2022 | Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer |