liquid_feedback_frontend

annotate static/wysihtml/wysihtml.toolbar.js @ 1525:628e1b9126c0

Handle no valid session in session filter correctly
author bsw
date Thu Aug 20 15:55:04 2020 +0200 (2020-08-20)
parents 32cc544d5a5b
children
rev   line source
bsw/jbe@1309 1 /**
bsw/jbe@1309 2 * Toolbar Dialog
bsw/jbe@1309 3 *
bsw/jbe@1309 4 * @param {Element} link The toolbar link which causes the dialog to show up
bsw/jbe@1309 5 * @param {Element} container The dialog container
bsw/jbe@1309 6 *
bsw/jbe@1309 7 * @example
bsw/jbe@1309 8 * <!-- Toolbar link -->
bsw/jbe@1309 9 * <a data-wysihtml-command="insertImage">insert an image</a>
bsw/jbe@1309 10 *
bsw/jbe@1309 11 * <!-- Dialog -->
bsw/jbe@1309 12 * <div data-wysihtml-dialog="insertImage" style="display: none;">
bsw/jbe@1309 13 * <label>
bsw/jbe@1309 14 * URL: <input data-wysihtml-dialog-field="src" value="http://">
bsw/jbe@1309 15 * </label>
bsw/jbe@1309 16 * <label>
bsw/jbe@1309 17 * Alternative text: <input data-wysihtml-dialog-field="alt" value="">
bsw/jbe@1309 18 * </label>
bsw/jbe@1309 19 * </div>
bsw/jbe@1309 20 *
bsw/jbe@1309 21 * <script>
bsw/jbe@1309 22 * var dialog = new wysihtml.toolbar.Dialog(
bsw/jbe@1309 23 * document.querySelector("[data-wysihtml-command='insertImage']"),
bsw/jbe@1309 24 * document.querySelector("[data-wysihtml-dialog='insertImage']")
bsw/jbe@1309 25 * );
bsw/jbe@1309 26 * dialog.observe("save", function(attributes) {
bsw/jbe@1309 27 * // do something
bsw/jbe@1309 28 * });
bsw/jbe@1309 29 * </script>
bsw/jbe@1309 30 */
bsw/jbe@1309 31 (function(wysihtml) {
bsw/jbe@1309 32 var dom = wysihtml.dom,
bsw/jbe@1309 33 CLASS_NAME_OPENED = "wysihtml-command-dialog-opened",
bsw/jbe@1309 34 SELECTOR_FORM_ELEMENTS = "input, select, textarea",
bsw/jbe@1309 35 SELECTOR_FIELDS = "[data-wysihtml-dialog-field]",
bsw/jbe@1309 36 ATTRIBUTE_FIELDS = "data-wysihtml-dialog-field";
bsw/jbe@1309 37
bsw/jbe@1309 38
bsw/jbe@1309 39 wysihtml.toolbar.Dialog = wysihtml.lang.Dispatcher.extend(
bsw/jbe@1309 40 /** @scope wysihtml.toolbar.Dialog.prototype */ {
bsw/jbe@1309 41 constructor: function(link, container) {
bsw/jbe@1309 42 this.link = link;
bsw/jbe@1309 43 this.container = container;
bsw/jbe@1309 44 },
bsw/jbe@1309 45
bsw/jbe@1309 46 _observe: function() {
bsw/jbe@1309 47 if (this._observed) {
bsw/jbe@1309 48 return;
bsw/jbe@1309 49 }
bsw/jbe@1309 50
bsw/jbe@1309 51 var that = this,
bsw/jbe@1309 52 callbackWrapper = function(event) {
bsw/jbe@1309 53 var attributes = that._serialize();
bsw/jbe@1309 54 that.fire("save", attributes);
bsw/jbe@1309 55 that.hide();
bsw/jbe@1309 56 event.preventDefault();
bsw/jbe@1309 57 event.stopPropagation();
bsw/jbe@1309 58 };
bsw/jbe@1309 59
bsw/jbe@1309 60 dom.observe(that.link, "click", function() {
bsw/jbe@1309 61 if (dom.hasClass(that.link, CLASS_NAME_OPENED)) {
bsw/jbe@1309 62 setTimeout(function() { that.hide(); }, 0);
bsw/jbe@1309 63 }
bsw/jbe@1309 64 });
bsw/jbe@1309 65
bsw/jbe@1309 66 dom.observe(this.container, "keydown", function(event) {
bsw/jbe@1309 67 var keyCode = event.keyCode;
bsw/jbe@1309 68 if (keyCode === wysihtml.ENTER_KEY) {
bsw/jbe@1309 69 callbackWrapper(event);
bsw/jbe@1309 70 }
bsw/jbe@1309 71 if (keyCode === wysihtml.ESCAPE_KEY) {
bsw/jbe@1309 72 that.cancel();
bsw/jbe@1309 73 }
bsw/jbe@1309 74 });
bsw/jbe@1309 75
bsw/jbe@1309 76 dom.delegate(this.container, "[data-wysihtml-dialog-action=save]", "click", callbackWrapper);
bsw/jbe@1309 77
bsw/jbe@1309 78 dom.delegate(this.container, "[data-wysihtml-dialog-action=cancel]", "click", function(event) {
bsw/jbe@1309 79 that.cancel();
bsw/jbe@1309 80 event.preventDefault();
bsw/jbe@1309 81 event.stopPropagation();
bsw/jbe@1309 82 });
bsw/jbe@1309 83
bsw/jbe@1309 84 this._observed = true;
bsw/jbe@1309 85 },
bsw/jbe@1309 86
bsw/jbe@1309 87 /**
bsw/jbe@1309 88 * Grabs all fields in the dialog and puts them in key=>value style in an object which
bsw/jbe@1309 89 * then gets returned
bsw/jbe@1309 90 */
bsw/jbe@1309 91 _serialize: function() {
bsw/jbe@1309 92 var data = {},
bsw/jbe@1309 93 fields = this.container.querySelectorAll(SELECTOR_FIELDS),
bsw/jbe@1309 94 length = fields.length,
bsw/jbe@1309 95 i = 0;
bsw/jbe@1309 96
bsw/jbe@1309 97 for (; i<length; i++) {
bsw/jbe@1309 98 data[fields[i].getAttribute(ATTRIBUTE_FIELDS)] = fields[i].value;
bsw/jbe@1309 99 }
bsw/jbe@1309 100 return data;
bsw/jbe@1309 101 },
bsw/jbe@1309 102
bsw/jbe@1309 103 /**
bsw/jbe@1309 104 * Takes the attributes of the "elementToChange"
bsw/jbe@1309 105 * and inserts them in their corresponding dialog input fields
bsw/jbe@1309 106 *
bsw/jbe@1309 107 * Assume the "elementToChange" looks like this:
bsw/jbe@1309 108 * <a href="http://www.google.com" target="_blank">foo</a>
bsw/jbe@1309 109 *
bsw/jbe@1309 110 * and we have the following dialog:
bsw/jbe@1309 111 * <input type="text" data-wysihtml-dialog-field="href" value="">
bsw/jbe@1309 112 * <input type="text" data-wysihtml-dialog-field="target" value="">
bsw/jbe@1309 113 *
bsw/jbe@1309 114 * after calling _interpolate() the dialog will look like this
bsw/jbe@1309 115 * <input type="text" data-wysihtml-dialog-field="href" value="http://www.google.com">
bsw/jbe@1309 116 * <input type="text" data-wysihtml-dialog-field="target" value="_blank">
bsw/jbe@1309 117 *
bsw/jbe@1309 118 * Basically it adopted the attribute values into the corresponding input fields
bsw/jbe@1309 119 *
bsw/jbe@1309 120 */
bsw/jbe@1309 121 _interpolate: function(avoidHiddenFields) {
bsw/jbe@1309 122 var field,
bsw/jbe@1309 123 fieldName,
bsw/jbe@1309 124 newValue,
bsw/jbe@1309 125 focusedElement = document.querySelector(":focus"),
bsw/jbe@1309 126 fields = this.container.querySelectorAll(SELECTOR_FIELDS),
bsw/jbe@1309 127 length = fields.length,
bsw/jbe@1309 128 i = 0;
bsw/jbe@1309 129 for (; i<length; i++) {
bsw/jbe@1309 130 field = fields[i];
bsw/jbe@1309 131
bsw/jbe@1309 132 // Never change elements where the user is currently typing in
bsw/jbe@1309 133 if (field === focusedElement) {
bsw/jbe@1309 134 continue;
bsw/jbe@1309 135 }
bsw/jbe@1309 136
bsw/jbe@1309 137 // Don't update hidden fields
bsw/jbe@1309 138 // See https://github.com/xing/wysihtml5/pull/14
bsw/jbe@1309 139 if (avoidHiddenFields && field.type === "hidden") {
bsw/jbe@1309 140 continue;
bsw/jbe@1309 141 }
bsw/jbe@1309 142
bsw/jbe@1309 143 fieldName = field.getAttribute(ATTRIBUTE_FIELDS);
bsw/jbe@1309 144 newValue = (this.elementToChange && typeof(this.elementToChange) !== 'boolean') ? (this.elementToChange.getAttribute(fieldName) || "") : field.defaultValue;
bsw/jbe@1309 145 field.value = newValue;
bsw/jbe@1309 146 }
bsw/jbe@1309 147 },
bsw/jbe@1309 148
bsw/jbe@1309 149 update: function (elementToChange) {
bsw/jbe@1309 150 this.elementToChange = elementToChange ? elementToChange : this.elementToChange;
bsw/jbe@1309 151 this._interpolate();
bsw/jbe@1309 152 },
bsw/jbe@1309 153
bsw/jbe@1309 154 /**
bsw/jbe@1309 155 * Show the dialog element
bsw/jbe@1309 156 */
bsw/jbe@1309 157 show: function(elementToChange) {
bsw/jbe@1309 158 var firstField = this.container.querySelector(SELECTOR_FORM_ELEMENTS);
bsw/jbe@1309 159
bsw/jbe@1309 160 this._observe();
bsw/jbe@1309 161 this.update(elementToChange);
bsw/jbe@1309 162
bsw/jbe@1309 163 dom.addClass(this.link, CLASS_NAME_OPENED);
bsw/jbe@1309 164 this.container.style.display = "";
bsw/jbe@1309 165 this.isOpen = true;
bsw/jbe@1309 166 this.fire("show");
bsw/jbe@1309 167
bsw/jbe@1309 168 if (firstField && !elementToChange) {
bsw/jbe@1309 169 try {
bsw/jbe@1309 170 firstField.focus();
bsw/jbe@1309 171 } catch(e) {}
bsw/jbe@1309 172 }
bsw/jbe@1309 173 },
bsw/jbe@1309 174
bsw/jbe@1309 175 /**
bsw/jbe@1309 176 * Hide the dialog element
bsw/jbe@1309 177 */
bsw/jbe@1309 178 _hide: function(focus) {
bsw/jbe@1309 179 this.elementToChange = null;
bsw/jbe@1309 180 dom.removeClass(this.link, CLASS_NAME_OPENED);
bsw/jbe@1309 181 this.container.style.display = "none";
bsw/jbe@1309 182 this.isOpen = false;
bsw/jbe@1309 183 },
bsw/jbe@1309 184
bsw/jbe@1309 185 hide: function() {
bsw/jbe@1309 186 this._hide();
bsw/jbe@1309 187 this.fire("hide");
bsw/jbe@1309 188 },
bsw/jbe@1309 189
bsw/jbe@1309 190 cancel: function() {
bsw/jbe@1309 191 this._hide();
bsw/jbe@1309 192 this.fire("cancel");
bsw/jbe@1309 193 }
bsw/jbe@1309 194 });
bsw/jbe@1309 195 })(wysihtml); //jshint ignore:line
bsw/jbe@1309 196
bsw/jbe@1309 197 (function(wysihtml) {
bsw/jbe@1309 198 var dom = wysihtml.dom,
bsw/jbe@1309 199 SELECTOR_FIELDS = "[data-wysihtml-dialog-field]",
bsw/jbe@1309 200 ATTRIBUTE_FIELDS = "data-wysihtml-dialog-field";
bsw/jbe@1309 201
bsw/jbe@1309 202 wysihtml.toolbar.Dialog_bgColorStyle = wysihtml.toolbar.Dialog.extend({
bsw/jbe@1309 203 multiselect: true,
bsw/jbe@1309 204
bsw/jbe@1309 205 _serialize: function() {
bsw/jbe@1309 206 var data = {},
bsw/jbe@1309 207 fields = this.container.querySelectorAll(SELECTOR_FIELDS),
bsw/jbe@1309 208 length = fields.length,
bsw/jbe@1309 209 i = 0;
bsw/jbe@1309 210
bsw/jbe@1309 211 for (; i<length; i++) {
bsw/jbe@1309 212 data[fields[i].getAttribute(ATTRIBUTE_FIELDS)] = fields[i].value;
bsw/jbe@1309 213 }
bsw/jbe@1309 214 return data;
bsw/jbe@1309 215 },
bsw/jbe@1309 216
bsw/jbe@1309 217 _interpolate: function(avoidHiddenFields) {
bsw/jbe@1309 218 var field,
bsw/jbe@1309 219 fieldName,
bsw/jbe@1309 220 newValue,
bsw/jbe@1309 221 focusedElement = document.querySelector(":focus"),
bsw/jbe@1309 222 fields = this.container.querySelectorAll(SELECTOR_FIELDS),
bsw/jbe@1309 223 length = fields.length,
bsw/jbe@1309 224 i = 0,
bsw/jbe@1309 225 firstElement = (this.elementToChange) ? ((wysihtml.lang.object(this.elementToChange).isArray()) ? this.elementToChange[0] : this.elementToChange) : null,
bsw/jbe@1309 226 colorStr = (firstElement) ? firstElement.getAttribute('style') : null,
bsw/jbe@1309 227 color = (colorStr) ? wysihtml.quirks.styleParser.parseColor(colorStr, "background-color") : null;
bsw/jbe@1309 228
bsw/jbe@1309 229 for (; i<length; i++) {
bsw/jbe@1309 230 field = fields[i];
bsw/jbe@1309 231 // Never change elements where the user is currently typing in
bsw/jbe@1309 232 if (field === focusedElement) {
bsw/jbe@1309 233 continue;
bsw/jbe@1309 234 }
bsw/jbe@1309 235 // Don't update hidden fields3
bsw/jbe@1309 236 if (avoidHiddenFields && field.type === "hidden") {
bsw/jbe@1309 237 continue;
bsw/jbe@1309 238 }
bsw/jbe@1309 239 if (field.getAttribute(ATTRIBUTE_FIELDS) === "color") {
bsw/jbe@1309 240 if (color) {
bsw/jbe@1309 241 if (color[3] && color[3] != 1) {
bsw/jbe@1309 242 field.value = "rgba(" + color[0] + "," + color[1] + "," + color[2] + "," + color[3] + ");";
bsw/jbe@1309 243 } else {
bsw/jbe@1309 244 field.value = "rgb(" + color[0] + "," + color[1] + "," + color[2] + ");";
bsw/jbe@1309 245 }
bsw/jbe@1309 246 } else {
bsw/jbe@1309 247 field.value = "rgb(0,0,0);";
bsw/jbe@1309 248 }
bsw/jbe@1309 249 }
bsw/jbe@1309 250 }
bsw/jbe@1309 251 }
bsw/jbe@1309 252
bsw/jbe@1309 253 });
bsw/jbe@1309 254 })(wysihtml);
bsw/jbe@1309 255
bsw/jbe@1309 256 (function(wysihtml) {
bsw/jbe@1309 257 wysihtml.toolbar.Dialog_createTable = wysihtml.toolbar.Dialog.extend({
bsw/jbe@1309 258 show: function(elementToChange) {
bsw/jbe@1309 259 this.base(elementToChange);
bsw/jbe@1309 260 }
bsw/jbe@1309 261 });
bsw/jbe@1309 262 })(wysihtml);
bsw/jbe@1309 263
bsw/jbe@1309 264 (function(wysihtml) {
bsw/jbe@1309 265 var dom = wysihtml.dom,
bsw/jbe@1309 266 SELECTOR_FIELDS = "[data-wysihtml-dialog-field]",
bsw/jbe@1309 267 ATTRIBUTE_FIELDS = "data-wysihtml-dialog-field";
bsw/jbe@1309 268
bsw/jbe@1309 269 wysihtml.toolbar.Dialog_fontSizeStyle = wysihtml.toolbar.Dialog.extend({
bsw/jbe@1309 270 multiselect: true,
bsw/jbe@1309 271
bsw/jbe@1309 272 _serialize: function() {
bsw/jbe@1309 273 return {"size" : this.container.querySelector('[data-wysihtml-dialog-field="size"]').value};
bsw/jbe@1309 274 },
bsw/jbe@1309 275
bsw/jbe@1309 276 _interpolate: function(avoidHiddenFields) {
bsw/jbe@1309 277 var focusedElement = document.querySelector(":focus"),
bsw/jbe@1309 278 field = this.container.querySelector("[data-wysihtml-dialog-field='size']"),
bsw/jbe@1309 279 firstElement = (this.elementToChange) ? ((wysihtml.lang.object(this.elementToChange).isArray()) ? this.elementToChange[0] : this.elementToChange) : null,
bsw/jbe@1309 280 styleStr = (firstElement) ? firstElement.getAttribute('style') : null,
bsw/jbe@1309 281 size = (styleStr) ? wysihtml.quirks.styleParser.parseFontSize(styleStr) : null;
bsw/jbe@1309 282
bsw/jbe@1309 283 if (field && field !== focusedElement && size && !(/^\s*$/).test(size)) {
bsw/jbe@1309 284 field.value = size;
bsw/jbe@1309 285 }
bsw/jbe@1309 286 }
bsw/jbe@1309 287 });
bsw/jbe@1309 288 })(wysihtml);
bsw/jbe@1309 289
bsw/jbe@1309 290 (function(wysihtml) {
bsw/jbe@1309 291 var SELECTOR_FIELDS = "[data-wysihtml-dialog-field]",
bsw/jbe@1309 292 ATTRIBUTE_FIELDS = "data-wysihtml-dialog-field";
bsw/jbe@1309 293
bsw/jbe@1309 294 wysihtml.toolbar.Dialog_foreColorStyle = wysihtml.toolbar.Dialog.extend({
bsw/jbe@1309 295 multiselect: true,
bsw/jbe@1309 296
bsw/jbe@1309 297 _serialize: function() {
bsw/jbe@1309 298 var data = {},
bsw/jbe@1309 299 fields = this.container.querySelectorAll(SELECTOR_FIELDS),
bsw/jbe@1309 300 length = fields.length,
bsw/jbe@1309 301 i = 0;
bsw/jbe@1309 302
bsw/jbe@1309 303 for (; i<length; i++) {
bsw/jbe@1309 304 data[fields[i].getAttribute(ATTRIBUTE_FIELDS)] = fields[i].value;
bsw/jbe@1309 305 }
bsw/jbe@1309 306 return data;
bsw/jbe@1309 307 },
bsw/jbe@1309 308
bsw/jbe@1309 309 _interpolate: function(avoidHiddenFields) {
bsw/jbe@1309 310 var field, colourMode,
bsw/jbe@1309 311 styleParser = wysihtml.quirks.styleParser,
bsw/jbe@1309 312 focusedElement = document.querySelector(":focus"),
bsw/jbe@1309 313 fields = this.container.querySelectorAll(SELECTOR_FIELDS),
bsw/jbe@1309 314 length = fields.length,
bsw/jbe@1309 315 i = 0,
bsw/jbe@1309 316 firstElement = (this.elementToChange) ? ((wysihtml.lang.object(this.elementToChange).isArray()) ? this.elementToChange[0] : this.elementToChange) : null,
bsw/jbe@1309 317 colourStr = (firstElement) ? firstElement.getAttribute("style") : null,
bsw/jbe@1309 318 colour = (colourStr) ? styleParser.parseColor(colourStr, "color") : null;
bsw/jbe@1309 319
bsw/jbe@1309 320 for (; i<length; i++) {
bsw/jbe@1309 321 field = fields[i];
bsw/jbe@1309 322 // Never change elements where the user is currently typing in
bsw/jbe@1309 323 if (field === focusedElement) {
bsw/jbe@1309 324 continue;
bsw/jbe@1309 325 }
bsw/jbe@1309 326 // Don't update hidden fields3
bsw/jbe@1309 327 if (avoidHiddenFields && field.type === "hidden") {
bsw/jbe@1309 328 continue;
bsw/jbe@1309 329 }
bsw/jbe@1309 330 if (field.getAttribute(ATTRIBUTE_FIELDS) === "color") {
bsw/jbe@1309 331 colourMode = (field.dataset.colormode || "rgb").toLowerCase();
bsw/jbe@1309 332 colourMode = colourMode === "hex" ? "hash" : colourMode;
bsw/jbe@1309 333
bsw/jbe@1309 334 if (colour) {
bsw/jbe@1309 335 field.value = styleParser.unparseColor(colour, colourMode);
bsw/jbe@1309 336 } else {
bsw/jbe@1309 337 field.value = styleParser.unparseColor([0, 0, 0], colourMode);
bsw/jbe@1309 338 }
bsw/jbe@1309 339 }
bsw/jbe@1309 340 }
bsw/jbe@1309 341 }
bsw/jbe@1309 342
bsw/jbe@1309 343 });
bsw/jbe@1309 344 })(wysihtml);
bsw/jbe@1309 345
bsw/jbe@1309 346 /**
bsw/jbe@1309 347 * Converts speech-to-text and inserts this into the editor
bsw/jbe@1309 348 * As of now (2011/03/25) this only is supported in Chrome >= 11
bsw/jbe@1309 349 *
bsw/jbe@1309 350 * Note that it sends the recorded audio to the google speech recognition api:
bsw/jbe@1309 351 * http://stackoverflow.com/questions/4361826/does-chrome-have-buil-in-speech-recognition-for-input-type-text-x-webkit-speec
bsw/jbe@1309 352 *
bsw/jbe@1309 353 * Current HTML5 draft can be found here
bsw/jbe@1309 354 * http://lists.w3.org/Archives/Public/public-xg-htmlspeech/2011Feb/att-0020/api-draft.html
bsw/jbe@1309 355 *
bsw/jbe@1309 356 * "Accessing Google Speech API Chrome 11"
bsw/jbe@1309 357 * http://mikepultz.com/2011/03/accessing-google-speech-api-chrome-11/
bsw/jbe@1309 358 */
bsw/jbe@1309 359 (function(wysihtml) {
bsw/jbe@1309 360 var dom = wysihtml.dom;
bsw/jbe@1309 361
bsw/jbe@1309 362 var linkStyles = {
bsw/jbe@1309 363 position: "relative"
bsw/jbe@1309 364 };
bsw/jbe@1309 365
bsw/jbe@1309 366 var wrapperStyles = {
bsw/jbe@1309 367 left: 0,
bsw/jbe@1309 368 margin: 0,
bsw/jbe@1309 369 opacity: 0,
bsw/jbe@1309 370 overflow: "hidden",
bsw/jbe@1309 371 padding: 0,
bsw/jbe@1309 372 position: "absolute",
bsw/jbe@1309 373 top: 0,
bsw/jbe@1309 374 zIndex: 1
bsw/jbe@1309 375 };
bsw/jbe@1309 376
bsw/jbe@1309 377 var inputStyles = {
bsw/jbe@1309 378 cursor: "inherit",
bsw/jbe@1309 379 fontSize: "50px",
bsw/jbe@1309 380 height: "50px",
bsw/jbe@1309 381 marginTop: "-25px",
bsw/jbe@1309 382 outline: 0,
bsw/jbe@1309 383 padding: 0,
bsw/jbe@1309 384 position: "absolute",
bsw/jbe@1309 385 right: "-4px",
bsw/jbe@1309 386 top: "50%"
bsw/jbe@1309 387 };
bsw/jbe@1309 388
bsw/jbe@1309 389 var inputAttributes = {
bsw/jbe@1309 390 "x-webkit-speech": "",
bsw/jbe@1309 391 "speech": ""
bsw/jbe@1309 392 };
bsw/jbe@1309 393
bsw/jbe@1309 394 wysihtml.toolbar.Speech = function(parent, link) {
bsw/jbe@1309 395 var input = document.createElement("input");
bsw/jbe@1309 396 if (!wysihtml.browser.supportsSpeechApiOn(input)) {
bsw/jbe@1309 397 link.style.display = "none";
bsw/jbe@1309 398 return;
bsw/jbe@1309 399 }
bsw/jbe@1309 400 var lang = parent.editor.textarea.element.getAttribute("lang");
bsw/jbe@1309 401 if (lang) {
bsw/jbe@1309 402 inputAttributes.lang = lang;
bsw/jbe@1309 403 }
bsw/jbe@1309 404
bsw/jbe@1309 405 var wrapper = document.createElement("div");
bsw/jbe@1309 406
bsw/jbe@1309 407 wysihtml.lang.object(wrapperStyles).merge({
bsw/jbe@1309 408 width: link.offsetWidth + "px",
bsw/jbe@1309 409 height: link.offsetHeight + "px"
bsw/jbe@1309 410 });
bsw/jbe@1309 411
bsw/jbe@1309 412 dom.insert(input).into(wrapper);
bsw/jbe@1309 413 dom.insert(wrapper).into(link);
bsw/jbe@1309 414
bsw/jbe@1309 415 dom.setStyles(inputStyles).on(input);
bsw/jbe@1309 416 dom.setAttributes(inputAttributes).on(input);
bsw/jbe@1309 417
bsw/jbe@1309 418 dom.setStyles(wrapperStyles).on(wrapper);
bsw/jbe@1309 419 dom.setStyles(linkStyles).on(link);
bsw/jbe@1309 420
bsw/jbe@1309 421 var eventName = "onwebkitspeechchange" in input ? "webkitspeechchange" : "speechchange";
bsw/jbe@1309 422 dom.observe(input, eventName, function() {
bsw/jbe@1309 423 parent.execCommand("insertText", input.value);
bsw/jbe@1309 424 input.value = "";
bsw/jbe@1309 425 });
bsw/jbe@1309 426
bsw/jbe@1309 427 dom.observe(input, "click", function(event) {
bsw/jbe@1309 428 if (dom.hasClass(link, "wysihtml-command-disabled")) {
bsw/jbe@1309 429 event.preventDefault();
bsw/jbe@1309 430 }
bsw/jbe@1309 431
bsw/jbe@1309 432 event.stopPropagation();
bsw/jbe@1309 433 });
bsw/jbe@1309 434 };
bsw/jbe@1309 435 })(wysihtml);
bsw/jbe@1309 436
bsw/jbe@1309 437 /**
bsw/jbe@1309 438 * Toolbar
bsw/jbe@1309 439 *
bsw/jbe@1309 440 * @param {Object} parent Reference to instance of Editor instance
bsw/jbe@1309 441 * @param {Element} container Reference to the toolbar container element
bsw/jbe@1309 442 *
bsw/jbe@1309 443 * @example
bsw/jbe@1309 444 * <div id="toolbar">
bsw/jbe@1309 445 * <a data-wysihtml-command="createLink">insert link</a>
bsw/jbe@1309 446 * <a data-wysihtml-command="formatBlock" data-wysihtml-command-value="h1">insert h1</a>
bsw/jbe@1309 447 * </div>
bsw/jbe@1309 448 *
bsw/jbe@1309 449 * <script>
bsw/jbe@1309 450 * var toolbar = new wysihtml.toolbar.Toolbar(editor, document.getElementById("toolbar"));
bsw/jbe@1309 451 * </script>
bsw/jbe@1309 452 */
bsw/jbe@1309 453 (function(wysihtml) {
bsw/jbe@1309 454 var CLASS_NAME_COMMAND_DISABLED = "wysihtml-command-disabled",
bsw/jbe@1309 455 CLASS_NAME_COMMANDS_DISABLED = "wysihtml-commands-disabled",
bsw/jbe@1309 456 CLASS_NAME_COMMAND_ACTIVE = "wysihtml-command-active",
bsw/jbe@1309 457 CLASS_NAME_ACTION_ACTIVE = "wysihtml-action-active",
bsw/jbe@1309 458 dom = wysihtml.dom;
bsw/jbe@1309 459
bsw/jbe@1309 460 wysihtml.toolbar.Toolbar = Base.extend(
bsw/jbe@1309 461 /** @scope wysihtml.toolbar.Toolbar.prototype */ {
bsw/jbe@1309 462 constructor: function(editor, container, showOnInit) {
bsw/jbe@1309 463 this.editor = editor;
bsw/jbe@1309 464 this.container = typeof(container) === "string" ? document.getElementById(container) : container;
bsw/jbe@1309 465 this.composer = editor.composer;
bsw/jbe@1309 466
bsw/jbe@1309 467 this._getLinks("command");
bsw/jbe@1309 468 this._getLinks("action");
bsw/jbe@1309 469
bsw/jbe@1309 470 this._observe();
bsw/jbe@1309 471 if (showOnInit) { this.show(); }
bsw/jbe@1309 472
bsw/jbe@1309 473 if (editor.config.classNameCommandDisabled != null) {
bsw/jbe@1309 474 CLASS_NAME_COMMAND_DISABLED = editor.config.classNameCommandDisabled;
bsw/jbe@1309 475 }
bsw/jbe@1309 476 if (editor.config.classNameCommandsDisabled != null) {
bsw/jbe@1309 477 CLASS_NAME_COMMANDS_DISABLED = editor.config.classNameCommandsDisabled;
bsw/jbe@1309 478 }
bsw/jbe@1309 479 if (editor.config.classNameCommandActive != null) {
bsw/jbe@1309 480 CLASS_NAME_COMMAND_ACTIVE = editor.config.classNameCommandActive;
bsw/jbe@1309 481 }
bsw/jbe@1309 482 if (editor.config.classNameActionActive != null) {
bsw/jbe@1309 483 CLASS_NAME_ACTION_ACTIVE = editor.config.classNameActionActive;
bsw/jbe@1309 484 }
bsw/jbe@1309 485
bsw/jbe@1309 486 var speechInputLinks = this.container.querySelectorAll("[data-wysihtml-command=insertSpeech]"),
bsw/jbe@1309 487 length = speechInputLinks.length,
bsw/jbe@1309 488 i = 0;
bsw/jbe@1309 489 for (; i<length; i++) {
bsw/jbe@1309 490 new wysihtml.toolbar.Speech(this, speechInputLinks[i]);
bsw/jbe@1309 491 }
bsw/jbe@1309 492 },
bsw/jbe@1309 493
bsw/jbe@1309 494 _getLinks: function(type) {
bsw/jbe@1309 495 var links = this[type + "Links"] = wysihtml.lang.array(this.container.querySelectorAll("[data-wysihtml-" + type + "]")).get(),
bsw/jbe@1309 496 length = links.length,
bsw/jbe@1309 497 i = 0,
bsw/jbe@1309 498 mapping = this[type + "Mapping"] = {},
bsw/jbe@1309 499 link,
bsw/jbe@1309 500 group,
bsw/jbe@1309 501 name,
bsw/jbe@1309 502 value,
bsw/jbe@1309 503 dialog,
bsw/jbe@1309 504 tracksBlankValue;
bsw/jbe@1309 505
bsw/jbe@1309 506 for (; i<length; i++) {
bsw/jbe@1309 507 link = links[i];
bsw/jbe@1309 508 name = link.getAttribute("data-wysihtml-" + type);
bsw/jbe@1309 509 value = link.getAttribute("data-wysihtml-" + type + "-value");
bsw/jbe@1309 510 tracksBlankValue = link.getAttribute("data-wysihtml-" + type + "-blank-value");
bsw/jbe@1309 511 group = this.container.querySelector("[data-wysihtml-" + type + "-group='" + name + "']");
bsw/jbe@1309 512 dialog = this._getDialog(link, name);
bsw/jbe@1309 513
bsw/jbe@1309 514 mapping[name + ":" + value] = {
bsw/jbe@1309 515 link: link,
bsw/jbe@1309 516 group: group,
bsw/jbe@1309 517 name: name,
bsw/jbe@1309 518 value: value,
bsw/jbe@1309 519 tracksBlankValue: tracksBlankValue,
bsw/jbe@1309 520 dialog: dialog,
bsw/jbe@1309 521 state: false
bsw/jbe@1309 522 };
bsw/jbe@1309 523 }
bsw/jbe@1309 524 },
bsw/jbe@1309 525
bsw/jbe@1309 526 _getDialog: function(link, command) {
bsw/jbe@1309 527 var that = this,
bsw/jbe@1309 528 dialogElement = this.container.querySelector("[data-wysihtml-dialog='" + command + "']"),
bsw/jbe@1309 529 dialog, caretBookmark;
bsw/jbe@1309 530
bsw/jbe@1309 531 if (dialogElement) {
bsw/jbe@1309 532 if (wysihtml.toolbar["Dialog_" + command]) {
bsw/jbe@1309 533 dialog = new wysihtml.toolbar["Dialog_" + command](link, dialogElement);
bsw/jbe@1309 534 } else {
bsw/jbe@1309 535 dialog = new wysihtml.toolbar.Dialog(link, dialogElement);
bsw/jbe@1309 536 }
bsw/jbe@1309 537
bsw/jbe@1309 538 dialog.on("show", function() {
bsw/jbe@1309 539 caretBookmark = that.composer.selection.getBookmark();
bsw/jbe@1309 540 that.editor.fire("show:dialog", { command: command, dialogContainer: dialogElement, commandLink: link });
bsw/jbe@1309 541 });
bsw/jbe@1309 542
bsw/jbe@1309 543 dialog.on("save", function(attributes) {
bsw/jbe@1309 544 if (caretBookmark) {
bsw/jbe@1309 545 that.composer.selection.setBookmark(caretBookmark);
bsw/jbe@1309 546 }
bsw/jbe@1309 547 that._execCommand(command, attributes);
bsw/jbe@1309 548 that.editor.fire("save:dialog", { command: command, dialogContainer: dialogElement, commandLink: link });
bsw/jbe@1309 549 that._hideAllDialogs();
bsw/jbe@1309 550 that._preventInstantFocus();
bsw/jbe@1309 551 caretBookmark = undefined;
bsw/jbe@1309 552
bsw/jbe@1309 553 });
bsw/jbe@1309 554
bsw/jbe@1309 555 dialog.on("cancel", function() {
bsw/jbe@1309 556 if (caretBookmark) {
bsw/jbe@1309 557 that.composer.selection.setBookmark(caretBookmark);
bsw/jbe@1309 558 }
bsw/jbe@1309 559 that.editor.fire("cancel:dialog", { command: command, dialogContainer: dialogElement, commandLink: link });
bsw/jbe@1309 560 caretBookmark = undefined;
bsw/jbe@1309 561 that._preventInstantFocus();
bsw/jbe@1309 562 });
bsw/jbe@1309 563
bsw/jbe@1309 564 dialog.on("hide", function() {
bsw/jbe@1309 565 that.editor.fire("hide:dialog", { command: command, dialogContainer: dialogElement, commandLink: link });
bsw/jbe@1309 566 caretBookmark = undefined;
bsw/jbe@1309 567 });
bsw/jbe@1309 568
bsw/jbe@1309 569 }
bsw/jbe@1309 570 return dialog;
bsw/jbe@1309 571 },
bsw/jbe@1309 572
bsw/jbe@1309 573 /**
bsw/jbe@1309 574 * @example
bsw/jbe@1309 575 * var toolbar = new wysihtml.Toolbar();
bsw/jbe@1309 576 * // Insert a <blockquote> element or wrap current selection in <blockquote>
bsw/jbe@1309 577 * toolbar.execCommand("formatBlock", "blockquote");
bsw/jbe@1309 578 */
bsw/jbe@1309 579 execCommand: function(command, commandValue) {
bsw/jbe@1309 580 if (this.commandsDisabled) {
bsw/jbe@1309 581 return;
bsw/jbe@1309 582 }
bsw/jbe@1309 583
bsw/jbe@1309 584 this._execCommand(command, commandValue);
bsw/jbe@1309 585 },
bsw/jbe@1309 586
bsw/jbe@1309 587 _execCommand: function(command, commandValue) {
bsw/jbe@1309 588 // Make sure that composer is focussed (false => don't move caret to the end)
bsw/jbe@1309 589 this.editor.focus(false);
bsw/jbe@1309 590
bsw/jbe@1309 591 this.composer.commands.exec(command, commandValue);
bsw/jbe@1309 592 this._updateLinkStates();
bsw/jbe@1309 593 },
bsw/jbe@1309 594
bsw/jbe@1309 595 execAction: function(action) {
bsw/jbe@1309 596 var editor = this.editor;
bsw/jbe@1309 597 if (action === "change_view") {
bsw/jbe@1309 598 if (editor.currentView === editor.textarea || editor.currentView === "source") {
bsw/jbe@1309 599 editor.fire("change_view", "composer");
bsw/jbe@1309 600 } else {
bsw/jbe@1309 601 editor.fire("change_view", "textarea");
bsw/jbe@1309 602 }
bsw/jbe@1309 603 }
bsw/jbe@1309 604 if (action == "showSource") {
bsw/jbe@1309 605 editor.fire("showSource");
bsw/jbe@1309 606 }
bsw/jbe@1309 607 },
bsw/jbe@1309 608
bsw/jbe@1309 609 _observe: function() {
bsw/jbe@1309 610 var that = this,
bsw/jbe@1309 611 editor = this.editor,
bsw/jbe@1309 612 container = this.container,
bsw/jbe@1309 613 links = this.commandLinks.concat(this.actionLinks),
bsw/jbe@1309 614 length = links.length,
bsw/jbe@1309 615 i = 0;
bsw/jbe@1309 616
bsw/jbe@1309 617 for (; i<length; i++) {
bsw/jbe@1309 618 // 'javascript:;' and unselectable=on Needed for IE, but done in all browsers to make sure that all get the same css applied
bsw/jbe@1309 619 // (you know, a:link { ... } doesn't match anchors with missing href attribute)
bsw/jbe@1309 620 if (links[i].nodeName === "A") {
bsw/jbe@1309 621 dom.setAttributes({
bsw/jbe@1309 622 href: "javascript:;",
bsw/jbe@1309 623 unselectable: "on"
bsw/jbe@1309 624 }).on(links[i]);
bsw/jbe@1309 625 } else {
bsw/jbe@1309 626 dom.setAttributes({ unselectable: "on" }).on(links[i]);
bsw/jbe@1309 627 }
bsw/jbe@1309 628 }
bsw/jbe@1309 629
bsw/jbe@1309 630 // Needed for opera and chrome
bsw/jbe@1309 631 dom.delegate(container, "[data-wysihtml-command], [data-wysihtml-action]", "mousedown", function(event) { event.preventDefault(); });
bsw/jbe@1309 632
bsw/jbe@1309 633 dom.delegate(container, "[data-wysihtml-command]", "click", function(event) {
bsw/jbe@1309 634 var state,
bsw/jbe@1309 635 link = this,
bsw/jbe@1309 636 command = link.getAttribute("data-wysihtml-command"),
bsw/jbe@1309 637 commandValue = link.getAttribute("data-wysihtml-command-value"),
bsw/jbe@1309 638 commandObj = that.commandMapping[command + ":" + commandValue];
bsw/jbe@1309 639
bsw/jbe@1309 640 if (commandValue || !commandObj.dialog) {
bsw/jbe@1309 641 that.execCommand(command, commandValue);
bsw/jbe@1309 642 } else {
bsw/jbe@1309 643 state = getCommandState(that.composer, commandObj);
bsw/jbe@1309 644 commandObj.dialog.show(state);
bsw/jbe@1309 645 }
bsw/jbe@1309 646
bsw/jbe@1309 647 event.preventDefault();
bsw/jbe@1309 648 });
bsw/jbe@1309 649
bsw/jbe@1309 650 dom.delegate(container, "[data-wysihtml-action]", "click", function(event) {
bsw/jbe@1309 651 var action = this.getAttribute("data-wysihtml-action");
bsw/jbe@1309 652 that.execAction(action);
bsw/jbe@1309 653 event.preventDefault();
bsw/jbe@1309 654 });
bsw/jbe@1309 655
bsw/jbe@1309 656 editor.on("interaction:composer", function(event) {
bsw/jbe@1309 657 if (!that.preventFocus) {
bsw/jbe@1309 658 that._updateLinkStates();
bsw/jbe@1309 659 }
bsw/jbe@1309 660 });
bsw/jbe@1309 661
bsw/jbe@1309 662 this._ownerDocumentClick = function(event) {
bsw/jbe@1309 663 if (!wysihtml.dom.contains(that.container, event.target) && !wysihtml.dom.contains(that.composer.element, event.target)) {
bsw/jbe@1309 664 that._updateLinkStates();
bsw/jbe@1309 665 that._preventInstantFocus();
bsw/jbe@1309 666 }
bsw/jbe@1309 667 };
bsw/jbe@1309 668
bsw/jbe@1309 669 this.container.ownerDocument.addEventListener("click", this._ownerDocumentClick, false);
bsw/jbe@1309 670 this.editor.on("destroy:composer", this.destroy.bind(this));
bsw/jbe@1309 671
bsw/jbe@1309 672 if (this.editor.config.handleTables) {
bsw/jbe@1309 673 editor.on("tableselect:composer", function() {
bsw/jbe@1309 674 that.container.querySelectorAll('[data-wysihtml-hiddentools="table"]')[0].style.display = "";
bsw/jbe@1309 675 });
bsw/jbe@1309 676 editor.on("tableunselect:composer", function() {
bsw/jbe@1309 677 that.container.querySelectorAll('[data-wysihtml-hiddentools="table"]')[0].style.display = "none";
bsw/jbe@1309 678 });
bsw/jbe@1309 679 }
bsw/jbe@1309 680
bsw/jbe@1309 681 editor.on("change_view", function(currentView) {
bsw/jbe@1309 682 // Set timeout needed in order to let the blur event fire first
bsw/jbe@1309 683 setTimeout(function() {
bsw/jbe@1309 684 that.commandsDisabled = (currentView !== "composer");
bsw/jbe@1309 685 that._updateLinkStates();
bsw/jbe@1309 686 if (that.commandsDisabled) {
bsw/jbe@1309 687 dom.addClass(container, CLASS_NAME_COMMANDS_DISABLED);
bsw/jbe@1309 688 } else {
bsw/jbe@1309 689 dom.removeClass(container, CLASS_NAME_COMMANDS_DISABLED);
bsw/jbe@1309 690 }
bsw/jbe@1309 691 }, 0);
bsw/jbe@1309 692 });
bsw/jbe@1309 693 },
bsw/jbe@1309 694
bsw/jbe@1309 695 destroy: function() {
bsw/jbe@1309 696 this.container.ownerDocument.removeEventListener("click", this._ownerDocumentClick, false);
bsw/jbe@1309 697 },
bsw/jbe@1309 698
bsw/jbe@1309 699 _hideAllDialogs: function() {
bsw/jbe@1309 700 var commandMapping = this.commandMapping;
bsw/jbe@1309 701 for (var i in commandMapping) {
bsw/jbe@1309 702 if (commandMapping[i].dialog) {
bsw/jbe@1309 703 commandMapping[i].dialog.hide();
bsw/jbe@1309 704 }
bsw/jbe@1309 705 }
bsw/jbe@1309 706 },
bsw/jbe@1309 707
bsw/jbe@1309 708 _preventInstantFocus: function() {
bsw/jbe@1309 709 this.preventFocus = true;
bsw/jbe@1309 710 setTimeout(function() {
bsw/jbe@1309 711 this.preventFocus = false;
bsw/jbe@1309 712 }.bind(this),0);
bsw/jbe@1309 713 },
bsw/jbe@1309 714
bsw/jbe@1309 715 _updateLinkStates: function() {
bsw/jbe@1309 716
bsw/jbe@1309 717 var i, state, action, command, displayDialogAttributeValue,
bsw/jbe@1309 718 commandMapping = this.commandMapping,
bsw/jbe@1309 719 composer = this.composer,
bsw/jbe@1309 720 actionMapping = this.actionMapping;
bsw/jbe@1309 721 // every millisecond counts... this is executed quite often
bsw/jbe@1309 722 for (i in commandMapping) {
bsw/jbe@1309 723 command = commandMapping[i];
bsw/jbe@1309 724 if (this.commandsDisabled) {
bsw/jbe@1309 725 state = false;
bsw/jbe@1309 726 dom.removeClass(command.link, CLASS_NAME_COMMAND_ACTIVE);
bsw/jbe@1309 727 if (command.group) {
bsw/jbe@1309 728 dom.removeClass(command.group, CLASS_NAME_COMMAND_ACTIVE);
bsw/jbe@1309 729 }
bsw/jbe@1309 730 if (command.dialog) {
bsw/jbe@1309 731 command.dialog.hide();
bsw/jbe@1309 732 }
bsw/jbe@1309 733 } else {
bsw/jbe@1309 734 state = this.composer.commands.state(command.name, command.value);
bsw/jbe@1309 735 dom.removeClass(command.link, CLASS_NAME_COMMAND_DISABLED);
bsw/jbe@1309 736 if (command.group) {
bsw/jbe@1309 737 dom.removeClass(command.group, CLASS_NAME_COMMAND_DISABLED);
bsw/jbe@1309 738 }
bsw/jbe@1309 739 }
bsw/jbe@1309 740 if (command.state === state && !command.tracksBlankValue) {
bsw/jbe@1309 741 continue;
bsw/jbe@1309 742 }
bsw/jbe@1309 743
bsw/jbe@1309 744 command.state = state;
bsw/jbe@1309 745 if (state) {
bsw/jbe@1309 746 if (command.tracksBlankValue) {
bsw/jbe@1309 747 dom.removeClass(command.link, CLASS_NAME_COMMAND_ACTIVE);
bsw/jbe@1309 748 } else {
bsw/jbe@1309 749 dom.addClass(command.link, CLASS_NAME_COMMAND_ACTIVE);
bsw/jbe@1309 750 if (command.group) {
bsw/jbe@1309 751 dom.addClass(command.group, CLASS_NAME_COMMAND_ACTIVE);
bsw/jbe@1309 752 }
bsw/jbe@1309 753 // commands with fixed value can not have a dialog.
bsw/jbe@1309 754 if (command.dialog && (typeof command.value === "undefined" || command.value === null)) {
bsw/jbe@1309 755 if (state && typeof state === "object") {
bsw/jbe@1309 756 state = getCommandState(composer, command);
bsw/jbe@1309 757 command.state = state;
bsw/jbe@1309 758
bsw/jbe@1309 759 // If dialog has dataset.showdialogonselection set as true,
bsw/jbe@1309 760 // Dialog displays on text state becoming active regardless of clobal showToolbarDialogsOnSelection options value
bsw/jbe@1309 761 displayDialogAttributeValue = command.dialog.container.dataset ? command.dialog.container.dataset.showdialogonselection : false;
bsw/jbe@1309 762
bsw/jbe@1309 763 if (composer.config.showToolbarDialogsOnSelection || displayDialogAttributeValue) {
bsw/jbe@1309 764 command.dialog.show(state);
bsw/jbe@1309 765 } else {
bsw/jbe@1309 766 command.dialog.update(state);
bsw/jbe@1309 767 }
bsw/jbe@1309 768 } else {
bsw/jbe@1309 769 command.dialog.hide();
bsw/jbe@1309 770 }
bsw/jbe@1309 771 }
bsw/jbe@1309 772 }
bsw/jbe@1309 773 } else {
bsw/jbe@1309 774 if (command.tracksBlankValue) {
bsw/jbe@1309 775 dom.addClass(command.link, CLASS_NAME_COMMAND_ACTIVE);
bsw/jbe@1309 776 } else {
bsw/jbe@1309 777 dom.removeClass(command.link, CLASS_NAME_COMMAND_ACTIVE);
bsw/jbe@1309 778 if (command.group) {
bsw/jbe@1309 779 dom.removeClass(command.group, CLASS_NAME_COMMAND_ACTIVE);
bsw/jbe@1309 780 }
bsw/jbe@1309 781 // commands with fixed value can not have a dialog.
bsw/jbe@1309 782 if (command.dialog && !command.value) {
bsw/jbe@1309 783 command.dialog.hide();
bsw/jbe@1309 784 }
bsw/jbe@1309 785 }
bsw/jbe@1309 786 }
bsw/jbe@1309 787 }
bsw/jbe@1309 788
bsw/jbe@1309 789 for (i in actionMapping) {
bsw/jbe@1309 790 action = actionMapping[i];
bsw/jbe@1309 791
bsw/jbe@1309 792 if (action.name === "change_view") {
bsw/jbe@1309 793 action.state = this.editor.currentView === this.editor.textarea || this.editor.currentView === "source";
bsw/jbe@1309 794 if (action.state) {
bsw/jbe@1309 795 dom.addClass(action.link, CLASS_NAME_ACTION_ACTIVE);
bsw/jbe@1309 796 } else {
bsw/jbe@1309 797 dom.removeClass(action.link, CLASS_NAME_ACTION_ACTIVE);
bsw/jbe@1309 798 }
bsw/jbe@1309 799 }
bsw/jbe@1309 800 }
bsw/jbe@1309 801 },
bsw/jbe@1309 802
bsw/jbe@1309 803 show: function() {
bsw/jbe@1309 804 this.container.style.display = "";
bsw/jbe@1309 805 },
bsw/jbe@1309 806
bsw/jbe@1309 807 hide: function() {
bsw/jbe@1309 808 this.container.style.display = "none";
bsw/jbe@1309 809 }
bsw/jbe@1309 810 });
bsw/jbe@1309 811
bsw/jbe@1309 812 function getCommandState (composer, command) {
bsw/jbe@1309 813 var state = composer.commands.state(command.name, command.value);
bsw/jbe@1309 814
bsw/jbe@1309 815 // Grab first and only object/element in state array, otherwise convert state into boolean
bsw/jbe@1309 816 // to avoid showing a dialog for multiple selected elements which may have different attributes
bsw/jbe@1309 817 // eg. when two links with different href are selected, the state will be an array consisting of both link elements
bsw/jbe@1309 818 // but the dialog interface can only update one
bsw/jbe@1309 819 if (!command.dialog.multiselect && wysihtml.lang.object(state).isArray()) {
bsw/jbe@1309 820 state = state.length === 1 ? state[0] : true;
bsw/jbe@1309 821 }
bsw/jbe@1309 822
bsw/jbe@1309 823 return state;
bsw/jbe@1309 824 }
bsw/jbe@1309 825
bsw/jbe@1309 826 // Extend defaults
bsw/jbe@1309 827
bsw/jbe@1309 828 // Id of the toolbar element, pass falsey value if you don't want any toolbar logic
bsw/jbe@1309 829 wysihtml.Editor.prototype.defaults.toolbar = undefined;
bsw/jbe@1309 830
bsw/jbe@1309 831 // Whether toolbar is displayed after init by script automatically.
bsw/jbe@1309 832 // Can be set to false if toolobar is set to display only on editable area focus
bsw/jbe@1309 833 wysihtml.Editor.prototype.defaults.showToolbarAfterInit = true;
bsw/jbe@1309 834
bsw/jbe@1309 835 // With default toolbar it shows dialogs in toolbar when their related text format state becomes active (click on link in text opens link dialogue)
bsw/jbe@1309 836 wysihtml.Editor.prototype.defaults.showToolbarDialogsOnSelection= true;
bsw/jbe@1309 837
bsw/jbe@1309 838 // Bind toolbar initiation on editor instance creation
bsw/jbe@1309 839 wysihtml.extendEditor(function(editor) {
bsw/jbe@1309 840 if (editor.config.toolbar) {
bsw/jbe@1309 841 editor.toolbar = new wysihtml.toolbar.Toolbar(editor, editor.config.toolbar, editor.config.showToolbarAfterInit);
bsw/jbe@1309 842 editor.on('destroy:composer', function() {
bsw/jbe@1309 843 if (editor && editor.toolbar) {
bsw/jbe@1309 844 editor.toolbar.destroy();
bsw/jbe@1309 845 }
bsw/jbe@1309 846 });
bsw/jbe@1309 847 }
bsw/jbe@1309 848 });
bsw/jbe@1309 849
bsw/jbe@1309 850 })(wysihtml);

Impressum / About Us