| 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); |