bsw/jbe@1309: /**
bsw/jbe@1309: * Toolbar Dialog
bsw/jbe@1309: *
bsw/jbe@1309: * @param {Element} link The toolbar link which causes the dialog to show up
bsw/jbe@1309: * @param {Element} container The dialog container
bsw/jbe@1309: *
bsw/jbe@1309: * @example
bsw/jbe@1309: *
bsw/jbe@1309: * insert an image
bsw/jbe@1309: *
bsw/jbe@1309: *
bsw/jbe@1309: *
bsw/jbe@1309: *
bsw/jbe@1309: *
bsw/jbe@1309: *
bsw/jbe@1309: *
bsw/jbe@1309: *
bsw/jbe@1309: */
bsw/jbe@1309: (function(wysihtml) {
bsw/jbe@1309: var dom = wysihtml.dom,
bsw/jbe@1309: CLASS_NAME_OPENED = "wysihtml-command-dialog-opened",
bsw/jbe@1309: SELECTOR_FORM_ELEMENTS = "input, select, textarea",
bsw/jbe@1309: SELECTOR_FIELDS = "[data-wysihtml-dialog-field]",
bsw/jbe@1309: ATTRIBUTE_FIELDS = "data-wysihtml-dialog-field";
bsw/jbe@1309:
bsw/jbe@1309:
bsw/jbe@1309: wysihtml.toolbar.Dialog = wysihtml.lang.Dispatcher.extend(
bsw/jbe@1309: /** @scope wysihtml.toolbar.Dialog.prototype */ {
bsw/jbe@1309: constructor: function(link, container) {
bsw/jbe@1309: this.link = link;
bsw/jbe@1309: this.container = container;
bsw/jbe@1309: },
bsw/jbe@1309:
bsw/jbe@1309: _observe: function() {
bsw/jbe@1309: if (this._observed) {
bsw/jbe@1309: return;
bsw/jbe@1309: }
bsw/jbe@1309:
bsw/jbe@1309: var that = this,
bsw/jbe@1309: callbackWrapper = function(event) {
bsw/jbe@1309: var attributes = that._serialize();
bsw/jbe@1309: that.fire("save", attributes);
bsw/jbe@1309: that.hide();
bsw/jbe@1309: event.preventDefault();
bsw/jbe@1309: event.stopPropagation();
bsw/jbe@1309: };
bsw/jbe@1309:
bsw/jbe@1309: dom.observe(that.link, "click", function() {
bsw/jbe@1309: if (dom.hasClass(that.link, CLASS_NAME_OPENED)) {
bsw/jbe@1309: setTimeout(function() { that.hide(); }, 0);
bsw/jbe@1309: }
bsw/jbe@1309: });
bsw/jbe@1309:
bsw/jbe@1309: dom.observe(this.container, "keydown", function(event) {
bsw/jbe@1309: var keyCode = event.keyCode;
bsw/jbe@1309: if (keyCode === wysihtml.ENTER_KEY) {
bsw/jbe@1309: callbackWrapper(event);
bsw/jbe@1309: }
bsw/jbe@1309: if (keyCode === wysihtml.ESCAPE_KEY) {
bsw/jbe@1309: that.cancel();
bsw/jbe@1309: }
bsw/jbe@1309: });
bsw/jbe@1309:
bsw/jbe@1309: dom.delegate(this.container, "[data-wysihtml-dialog-action=save]", "click", callbackWrapper);
bsw/jbe@1309:
bsw/jbe@1309: dom.delegate(this.container, "[data-wysihtml-dialog-action=cancel]", "click", function(event) {
bsw/jbe@1309: that.cancel();
bsw/jbe@1309: event.preventDefault();
bsw/jbe@1309: event.stopPropagation();
bsw/jbe@1309: });
bsw/jbe@1309:
bsw/jbe@1309: this._observed = true;
bsw/jbe@1309: },
bsw/jbe@1309:
bsw/jbe@1309: /**
bsw/jbe@1309: * Grabs all fields in the dialog and puts them in key=>value style in an object which
bsw/jbe@1309: * then gets returned
bsw/jbe@1309: */
bsw/jbe@1309: _serialize: function() {
bsw/jbe@1309: var data = {},
bsw/jbe@1309: fields = this.container.querySelectorAll(SELECTOR_FIELDS),
bsw/jbe@1309: length = fields.length,
bsw/jbe@1309: i = 0;
bsw/jbe@1309:
bsw/jbe@1309: for (; ifoo
bsw/jbe@1309: *
bsw/jbe@1309: * and we have the following dialog:
bsw/jbe@1309: *
bsw/jbe@1309: *
bsw/jbe@1309: *
bsw/jbe@1309: * after calling _interpolate() the dialog will look like this
bsw/jbe@1309: *
bsw/jbe@1309: *
bsw/jbe@1309: *
bsw/jbe@1309: * Basically it adopted the attribute values into the corresponding input fields
bsw/jbe@1309: *
bsw/jbe@1309: */
bsw/jbe@1309: _interpolate: function(avoidHiddenFields) {
bsw/jbe@1309: var field,
bsw/jbe@1309: fieldName,
bsw/jbe@1309: newValue,
bsw/jbe@1309: focusedElement = document.querySelector(":focus"),
bsw/jbe@1309: fields = this.container.querySelectorAll(SELECTOR_FIELDS),
bsw/jbe@1309: length = fields.length,
bsw/jbe@1309: i = 0;
bsw/jbe@1309: for (; i= 11
bsw/jbe@1309: *
bsw/jbe@1309: * Note that it sends the recorded audio to the google speech recognition api:
bsw/jbe@1309: * http://stackoverflow.com/questions/4361826/does-chrome-have-buil-in-speech-recognition-for-input-type-text-x-webkit-speec
bsw/jbe@1309: *
bsw/jbe@1309: * Current HTML5 draft can be found here
bsw/jbe@1309: * http://lists.w3.org/Archives/Public/public-xg-htmlspeech/2011Feb/att-0020/api-draft.html
bsw/jbe@1309: *
bsw/jbe@1309: * "Accessing Google Speech API Chrome 11"
bsw/jbe@1309: * http://mikepultz.com/2011/03/accessing-google-speech-api-chrome-11/
bsw/jbe@1309: */
bsw/jbe@1309: (function(wysihtml) {
bsw/jbe@1309: var dom = wysihtml.dom;
bsw/jbe@1309:
bsw/jbe@1309: var linkStyles = {
bsw/jbe@1309: position: "relative"
bsw/jbe@1309: };
bsw/jbe@1309:
bsw/jbe@1309: var wrapperStyles = {
bsw/jbe@1309: left: 0,
bsw/jbe@1309: margin: 0,
bsw/jbe@1309: opacity: 0,
bsw/jbe@1309: overflow: "hidden",
bsw/jbe@1309: padding: 0,
bsw/jbe@1309: position: "absolute",
bsw/jbe@1309: top: 0,
bsw/jbe@1309: zIndex: 1
bsw/jbe@1309: };
bsw/jbe@1309:
bsw/jbe@1309: var inputStyles = {
bsw/jbe@1309: cursor: "inherit",
bsw/jbe@1309: fontSize: "50px",
bsw/jbe@1309: height: "50px",
bsw/jbe@1309: marginTop: "-25px",
bsw/jbe@1309: outline: 0,
bsw/jbe@1309: padding: 0,
bsw/jbe@1309: position: "absolute",
bsw/jbe@1309: right: "-4px",
bsw/jbe@1309: top: "50%"
bsw/jbe@1309: };
bsw/jbe@1309:
bsw/jbe@1309: var inputAttributes = {
bsw/jbe@1309: "x-webkit-speech": "",
bsw/jbe@1309: "speech": ""
bsw/jbe@1309: };
bsw/jbe@1309:
bsw/jbe@1309: wysihtml.toolbar.Speech = function(parent, link) {
bsw/jbe@1309: var input = document.createElement("input");
bsw/jbe@1309: if (!wysihtml.browser.supportsSpeechApiOn(input)) {
bsw/jbe@1309: link.style.display = "none";
bsw/jbe@1309: return;
bsw/jbe@1309: }
bsw/jbe@1309: var lang = parent.editor.textarea.element.getAttribute("lang");
bsw/jbe@1309: if (lang) {
bsw/jbe@1309: inputAttributes.lang = lang;
bsw/jbe@1309: }
bsw/jbe@1309:
bsw/jbe@1309: var wrapper = document.createElement("div");
bsw/jbe@1309:
bsw/jbe@1309: wysihtml.lang.object(wrapperStyles).merge({
bsw/jbe@1309: width: link.offsetWidth + "px",
bsw/jbe@1309: height: link.offsetHeight + "px"
bsw/jbe@1309: });
bsw/jbe@1309:
bsw/jbe@1309: dom.insert(input).into(wrapper);
bsw/jbe@1309: dom.insert(wrapper).into(link);
bsw/jbe@1309:
bsw/jbe@1309: dom.setStyles(inputStyles).on(input);
bsw/jbe@1309: dom.setAttributes(inputAttributes).on(input);
bsw/jbe@1309:
bsw/jbe@1309: dom.setStyles(wrapperStyles).on(wrapper);
bsw/jbe@1309: dom.setStyles(linkStyles).on(link);
bsw/jbe@1309:
bsw/jbe@1309: var eventName = "onwebkitspeechchange" in input ? "webkitspeechchange" : "speechchange";
bsw/jbe@1309: dom.observe(input, eventName, function() {
bsw/jbe@1309: parent.execCommand("insertText", input.value);
bsw/jbe@1309: input.value = "";
bsw/jbe@1309: });
bsw/jbe@1309:
bsw/jbe@1309: dom.observe(input, "click", function(event) {
bsw/jbe@1309: if (dom.hasClass(link, "wysihtml-command-disabled")) {
bsw/jbe@1309: event.preventDefault();
bsw/jbe@1309: }
bsw/jbe@1309:
bsw/jbe@1309: event.stopPropagation();
bsw/jbe@1309: });
bsw/jbe@1309: };
bsw/jbe@1309: })(wysihtml);
bsw/jbe@1309:
bsw/jbe@1309: /**
bsw/jbe@1309: * Toolbar
bsw/jbe@1309: *
bsw/jbe@1309: * @param {Object} parent Reference to instance of Editor instance
bsw/jbe@1309: * @param {Element} container Reference to the toolbar container element
bsw/jbe@1309: *
bsw/jbe@1309: * @example
bsw/jbe@1309: *