1/** 2 * (c) Copyright 2002-2017 by authors of the Tiki Wiki CMS Groupware Project 3 * 4 * All Rights Reserved. See copyright.txt for details and a complete list of authors. 5 * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details. 6 * $Id: pluginedit.js 70098 2019-05-29 08:41:34Z jyhem $ 7 * 8 * Handles wiki plugin edit forms 9 */ 10 11 12(function ($) { 13 14 /* wikiplugin editor */ 15 window.popupPluginForm = function (area_id, type, index, pageName, pluginArgs, bodyContent, edit_icon, selectedMod) { 16 17 var $textArea = $("#" + area_id); 18 19 if ($textArea.length && $textArea[0].createTextRange) { // save selection for IE 20 storeTASelection(area_id); 21 } 22 23 var container = $('<div class="plugin"></div>'); 24 25 if (!index) { 26 index = 0; 27 } 28 if (!pageName) { 29 pageName = ''; 30 } 31 var textarea = $textArea[0]; 32 var replaceText = false; 33 34 if (!pluginArgs && !bodyContent) { 35 pluginArgs = {}; 36 bodyContent = ""; 37 38 dialogSelectElement(area_id, '{' + type.toUpperCase(), '{' + type.toUpperCase() + '}'); 39 var sel = getTASelection(textarea); 40 if (sel && sel.length > 0) { 41 sel = sel.replace(/^\s\s*/, "").replace(/\s\s*$/g, ""); // trim 42 if (sel.length > 0 && sel.substring(0, 1) === '{') { // whole plugin selected 43 var l = type.length, 44 thisType = sel.match(/\{(\w+)/); 45 thisType = thisType[1].toUpperCase(); 46 if (thisType === type.toUpperCase()) { // same plugin 47 var rx = new RegExp("{" + type + "[\\(]?([\\s\\S^\\)]*?)[\\)]?}([\\s\\S]*){" + type + "}", "mi"); // using \s\S matches all chars including lineends 48 var m = sel.match(rx); 49 if (!m) { 50 rx = new RegExp("{" + type + "[\\(]?([\\s\\S^\\)]*?)[\\)]?}([\\s\\S]*)", "mi"); // no closing tag 51 m = sel.match(rx); 52 } 53 if (m) { 54 var paramStr = m[1]; 55 bodyContent = m[2]; 56 57 var pm = paramStr.match(/([^=]*)=\"([^\"]*)\"\s?/gi); 58 if (pm) { 59 for (var i = 0; i < pm.length; i++) { 60 var ar = pm[i].split("="); 61 if (ar.length) { // add cleaned vals to params object 62 pluginArgs[ar[0].replace(/^[,\s\"\(\)]*/g, "")] = ar[1].replace(/^[,\s\"\(\)]*/g, "").replace(/[,\s\"\(\)]*$/g, ""); 63 } 64 } 65 } 66 } 67 replaceText = sel; 68 } else if (confirm("Click OK to include the " + thisType + " plugin inside a " + type.toUpperCase() + " plugin. Click Cancel to edit the " + thisType + " plugin.")) { 69 bodyContent = sel; 70 replaceText = true; 71 } else { 72 // different plugin, try again with the selected plugin type 73 window.popupPluginForm(area_id, thisType, index, pageName, null, "", edit_icon, selectedMod); 74 return; 75 } 76 } else { // not (this) plugin 77 if (type === 'mouseover') { // For MOUSEOVER, we want the selected text as label instead of body 78 bodyContent = ''; 79 pluginArgs = {}; 80 pluginArgs['label'] = sel; 81 } else { 82 bodyContent = sel; 83 } 84 replaceText = true; 85 } 86 } else { // no selection 87 replaceText = false; 88 } 89 } 90 91 var $modal = $('.modal.fade:not(.in)').first(); 92 93 var url = $.service("plugin", "edit", { 94 area_id: area_id, 95 type: type, 96 index: index, 97 page: pageName, 98 pluginArgs: pluginArgs, 99 bodyContent: bodyContent, 100 edit_icon: !!edit_icon, 101 selectedMod: selectedMod ? selectedMod : "", 102 modal: 1 103 }); 104 105 // Make the form appear 106 $modal 107 .modal({ 108 remote: url, 109 backdrop: "static", 110 show: false // if it's the first time the show.bs.modal doesn't trigger sometimes 111 }) 112 .one('loaded.bs.modal', function () { // Bind remote loaded event 113 // enables conditional display of inputs with a "parentparam" selector 114 handlePluginFieldsHierarchy(); 115 // bind form button events and form validation 116 handleFormSubmit(this, type, edit_icon, area_id, replaceText); 117 // Trigger jQuery event 'plugin_#type#_ready' (see plugin_code_ready in codemirror_tiki.js for example) 118 $document 119 .trigger({ 120 type: 'plugin_' + type + '_ready', 121 container: container, 122 arguments: arguments, 123 modal: $modal 124 }) 125 .trigger({ 126 type: 'plugin_ready', 127 container: container, 128 arguments: arguments, 129 modal: $modal 130 }); 131 }) 132 // unset semaphore on object/page on cancel 133 .one("hidden.bs.modal", function () { 134 if ($("form", this).length && edit_icon) { 135 $.getJSON($.service("semaphore", "unset"), { 136 object_id: pageName 137 }); 138 } 139 }) 140 .modal("show")
141 .find('.modal-dialog').addClass("modal-lg"); 142 143 144 }; 145 146 /* 147 * Hides all children fields in a wiki-plugin form and 148 * add javascript events to display them when the appropriate 149 * values are selected in the parentparam fields. 150 */ 151 function handlePluginFieldsHierarchy() { 152 var $container = $('#plugin_params'); 153 154 var parents = {}; 155 156 $("[data-parent_name]", $container).each(function () { 157 var parentName = $(this).data("parent_name"), 158 parentValue = $(this).data("parent_value"); 159 if (parentName) { 160 var $parent = $('[name$="params[' + parentName + ']"]', $container); 161 162 var $row = $(this).parents(".form-group"); 163 $row.addClass('parent_' + parentName + '_' + parentValue); 164 165 if ($parent.val() !== parentValue) { 166 if (!$parent.val() && $("input, select", $row).val()) { 167 $parent.val(parentValue); 168 } else { 169 $row.hide(); 170 } 171 } 172 173 if (!parents[parentName]) { 174 parents[parentName] = { 175 children: [], 176 parentElement: $parent 177 }; 178 } 179 180 parents[parentName]['children'].push($(this).attr("id")); 181 } 182 }); 183 184 $.each(parents, function (parentName, parent) { 185 parent.parentElement.change(function () { 186 $.each(parent.children, function (index, id) { 187 $container.find('#' + id).parents(".form-group").hide(); 188 }); 189 $container.find('.parent_' + parentName + '_' + this.value).show(); 190 }) 191 .change().trigger("chosen:updated"); 192 }); 193 } 194 195 /** 196 * set up insert/replace button and submit handler in "textarea" edit mode 197 * 198 * @param container 199 * @param type 200 * @param edit_icon 201 * @param area_id 202 * @param replaceText 203 */ 204 function handleFormSubmit(container, type, edit_icon, area_id, replaceText) { 205 206 var params = [], viewPageMode = !!edit_icon, bodyContent = ""; 207 208 var $form = $("form", container); 209 210 $form.submit(function () { 211 212 if (!process_submit(this)) { 213 return false; 214 } 215 216 if (type === "list" && ! viewPageMode && typeof jqueryTiki.plugins.list.saveToTextarea === "function") { 217 jqueryTiki.plugins.list.saveToTextarea(); 218 } 219 220 $("[name^=params]", $form).each(function () { 221 222 var name = $(this).attr("name"), 223 matches = name.match(/params\[(.*)\]/), 224 val = $(this).val(); 225 226 if (!matches) { 227 // it's not a parameter, skip 228 if (name === "content") { 229 bodyContent = $(this).val(); 230 } 231 return; 232 } 233 234 if (val && ! viewPageMode) { 235 val = val.replace(/"/g, '\\"'); // escape double quotes 236 params.push(matches[1] + '="' + val + '"'); 237 } 238 }); 239 240 var blob, pluginContentTextarea = $("[name=content]", $form), 241 pluginContentTextareaEditor = syntaxHighlighter.get(pluginContentTextarea); 242 243 if (! viewPageMode) { 244 if (!bodyContent) { 245 bodyContent = (pluginContentTextareaEditor ? pluginContentTextareaEditor.getValue() : pluginContentTextarea.val()); 246 } 247 if (bodyContent) { 248 blob = '{' + type.toUpperCase() + '(' + params.join(' ') + ')}' + bodyContent + '{' + type.toUpperCase() + '}'; 249 } else { 250 blob = '{' + type.toLowerCase() + ' ' + params.join(' ') + '}'; 251 } 252 253 insertAt(area_id, blob, false, false, replaceText); 254 $(container).modal("hide"); 255 256 return false; 257 } 258 }); 259 } 260 261})(jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.