diff --git a/source/Ox.UI/js/Form/Ox.ArrayEditable.js b/source/Ox.UI/js/Form/Ox.ArrayEditable.js index 37b6384c..0a221257 100644 --- a/source/Ox.UI/js/Form/Ox.ArrayEditable.js +++ b/source/Ox.UI/js/Form/Ox.ArrayEditable.js @@ -168,6 +168,9 @@ Ox.ArrayEditable = function(options, self) { self.editing = true; that.triggerEvent('edit', data); }, + insert: function(data) { + that.triggerEvent('insert', data); + }, submit: function(data) { self.editing = false; that.gainFocus(); diff --git a/source/Ox.UI/js/Form/Ox.Editable.js b/source/Ox.UI/js/Form/Ox.Editable.js index e7252b7a..0607adf1 100644 --- a/source/Ox.UI/js/Form/Ox.Editable.js +++ b/source/Ox.UI/js/Form/Ox.Editable.js @@ -120,6 +120,9 @@ Ox.Editable = function(options, self) { blur: self.options.submitOnBlur ? submit : blur, cancel: cancel, change: change, + insert: function(data) { + that.triggerEvent('insert', data); + }, submit: submit }) .appendTo(that.$element); diff --git a/source/Ox.UI/js/Form/Ox.Input.js b/source/Ox.UI/js/Form/Ox.Input.js index 5e87b182..5390a960 100644 --- a/source/Ox.UI/js/Form/Ox.Input.js +++ b/source/Ox.UI/js/Form/Ox.Input.js @@ -117,7 +117,7 @@ Ox.Input = function(options, self) { .bindEvent(Ox.extend(self.options.type != 'textarea' ? { key_enter: submit } : {}, { - key_control_v: paste, + key_control_i: insert, key_escape: cancel, key_shift_enter: submit })); @@ -719,6 +719,17 @@ Ox.Input = function(options, self) { - (self.options.style == 'rounded' ? 14 : 6); } + function insert() { + var input = self.$input[0]; + that.triggerEvent('insert', { + end: input.selectionEnd, + id: that.id, + selection: input.value.substring(input.selectionStart, input.selectionEnd), + start: input.selectionStart, + value: input.value + }); + } + function keydown(event) { var oldCursor = cursor(), oldValue = self.options.value, @@ -758,6 +769,7 @@ Ox.Input = function(options, self) { } function paste() { + // fixme: unused var data = Ox.Clipboard.paste(); data.text && self.$input.val(data.text); } diff --git a/source/Ox.UI/js/Form/Ox.InsertHTMLDialog.js b/source/Ox.UI/js/Form/Ox.InsertHTMLDialog.js new file mode 100644 index 00000000..b38ccfb9 --- /dev/null +++ b/source/Ox.UI/js/Form/Ox.InsertHTMLDialog.js @@ -0,0 +1,203 @@ +'use strict'; + +Ox.InsertHTMLDialog = function(options, self) { + + var that; + + self = self || {}; + self.options = Ox.extend({ + callback: void 0, + end: 0, + selection: '', + start: 0 + }, options || {}); + + self.items = [ + {id: 'img', title: 'Image'}, + {id: 'a', title: 'Link'}, + {id: 'li', title: 'List'}, + {}, + {id: 'blockquote', title: 'Blockquote'}, + {id: 'h1', title: 'Headline'}, + {id: 'p', title: 'Paragraph'}, + {id: 'div', title: 'Right-to-Left'}, + {}, + {id: 'b', title: 'Bold'}, + {id: 'i', title: 'Italic'}, + {id: 'code', title: 'Monospace'}, + {id: 's', title: 'Strike'}, + {id: 'sub', title: 'Subscript'}, + {id: 'sup', title: 'Superscript'}, + {id: 'u', title: 'Underline'}, + {}, + {id: 'br', title: 'Linebreak'} + ].map(function(item, i) { + var form, format; + if (item.id == 'img') { + form = [ + Ox.Input({ + id: 'url', + label: 'URL', + labelWidth: 128, + width: 384 + }) + ]; + format = function(values) { + return ''; + }; + } else if (item.id == 'a') { + form = [ + Ox.Input({ + id: 'text', + label: 'Text', + labelWidth: 128, + width: 384, + value: self.options.selection + }), + Ox.Input({ + id: 'url', + label: 'URL', + labelWidth: 128, + width: 384 + }) + ]; + format = function(values) { + return '' + values.text + ''; + }; + } else if (item.id == 'li') { + form = [ + Ox.Select({ + id: 'style', + items: [ + {id: 'ul', title: 'Bullets'}, + {id: 'ol', title: 'Numbers'} + ], + label: 'Style', + labelWidth: 128, + width: 384 + }), + Ox.ArrayInput({ + id: 'items', + label: 'Items', + max: 10, + width: 384 + }) + ]; + format = function(values) { + return '<' + values.style + '>\n' + values.items.map(function(value) { + return '
  • ' + value + '
  • \n'; + }).join('') + ''; + }; + } else if (['p', 'blockquote', 'div'].indexOf(item.id) > -1) { + form = [ + Ox.Input({ + id: 'text', + height: 128, + type: 'textarea', + width: 384, + value: self.options.selection + }) + ]; + format = function(values) { + return '<' + item.id + ( + item.id == 'div' ? ' style="direction: rtl"' : '' + ) + '>' + values.text + ''; + }; + } else if (['h1', 'b', 'i', 'code', 's', 'sub', 'sup', 'u'].indexOf(item.id) > -1) { + form = [ + Ox.Input({ + id: 'text', + label: 'Text', + labelWidth: 128, + width: 384, + value: self.options.selection + }) + ]; + format = function(values) { + return '<' + item.id + '>' + values.text + ''; + }; + } else if (item.id == 'br') { + form = []; + format = function() { + return '
    '; + }; + } + return item.id ? Ox.extend(item, { + form: form, + format: format + }) : item; + }); + + self.$content = $('
    ') + .css({padding: '16px'}); + + self.$select = Ox.Select({ + items: self.items, + label: 'Insert', + labelWidth: 128, + value: 'img', + width: 384 + }) + .bindEvent({ + change: renderForm + }) + .appendTo(self.$content); + + renderForm(); + + that = Ox.Dialog({ + buttons: [ + Ox.Button({ + id: 'cancel', + title: 'Cancel', + width: 64 + }) + .bindEvent({ + click: function() { + that.close(); + } + }), + Ox.Button({ + id: 'insert', + title: 'Insert', + width: 64 + }) + .bindEvent({ + click: function() { + Ox.print('SFV:::::', self.$form.values()) + var item = Ox.getObjectById(self.items, self.$select.value()), + value = item.format( + item.form.length ? self.$form.values() : void 0 + ); + self.options.callback({ + position: self.options.start + value.length, + value: self.options.value.substr(0, self.options.start) + + value + + self.options.value.substr(self.options.end) + }); + that.close(); + } + }) + ], + content: self.$content, + height: 184, + keys: {enter: 'insert', escape: 'cancel'}, + title: 'Insert HTML', + width: 416 + Ox.UI.SCROLLBAR_SIZE + }); + + function renderForm() { + var items = Ox.getObjectById(self.items, self.$select.value()).form; + self.$form && self.$form.remove(); + if (items.length) { + self.$form = Ox.Form({ + items: items + }) + .css({paddingTop: '8px'}) + .appendTo(self.$content); + } + } + + return that; + +}; diff --git a/source/Ox.UI/js/Video/Ox.AnnotationFolder.js b/source/Ox.UI/js/Video/Ox.AnnotationFolder.js index ac2c3c8e..f18fc7fa 100644 --- a/source/Ox.UI/js/Video/Ox.AnnotationFolder.js +++ b/source/Ox.UI/js/Video/Ox.AnnotationFolder.js @@ -226,6 +226,9 @@ Ox.AnnotationFolder = function(options, self) { self.editing = true; that.triggerEvent('edit'); }, + insert: function(data) { + that.triggerEvent('insert', data); + }, select: selectAnnotation, selectafter: function() { that.triggerEvent('selectafter'); diff --git a/source/Ox.UI/js/Video/Ox.AnnotationPanel.js b/source/Ox.UI/js/Video/Ox.AnnotationPanel.js index 6d3d936d..10b915e4 100644 --- a/source/Ox.UI/js/Video/Ox.AnnotationPanel.js +++ b/source/Ox.UI/js/Video/Ox.AnnotationPanel.js @@ -148,8 +148,6 @@ Ox.AnnotationPanel = function(options, self) { that.triggerEvent('add', Ox.extend({layer: layer.id}, data)); }, blur: function() { - self.editing = false; - renderEditMenu(); that.triggerEvent('blur'); }, change: function(data) { @@ -163,6 +161,7 @@ Ox.AnnotationPanel = function(options, self) { info: function(data) { that.triggerEvent('info', {layer: layer.id}); }, + insert: insert, remove: function(data) { that.triggerEvent('remove', Ox.extend({layer: layer.id}, data)); }, @@ -258,6 +257,18 @@ Ox.AnnotationPanel = function(options, self) { return folder; } + function insert(data) { + var id = data.id; + Ox.InsertHTMLDialog(Ox.extend({ + callback: function(data) { + Ox.UI.elements[id] + .value(data.value) + .focusInput(data.position) + .triggerEvent('change', data.value); + } + }, data)).open(); + } + function renderEditMenu() { Ox.print('RENDER EDIT MENU') var annotation, annotationTitle, folder, @@ -288,7 +299,7 @@ Ox.AnnotationPanel = function(options, self) { {id: 'edit', title: 'Edit Annotation', disabled: !self.options.selected || !isEditable || self.editing, keyboard: 'return'}, {id: 'delete', title: 'Delete Annotation', disabled: !self.options.selected || !isEditable, keyboard: 'delete'}, {}, - {id: 'insert', title: 'Insert...', disabled: isString || !self.editing}, + {id: 'insert', title: 'Insert...', disabled: isString || !self.editing, keyboard: 'control i'}, {id: 'undo', title: 'Undo Changes', disabled: !self.editing, keyboard: 'escape'}, {id: 'save', title: 'Save Changes', disabled: !self.editing, keyboard: isString ? 'return' : 'shift return'}, ], @@ -322,6 +333,8 @@ Ox.AnnotationPanel = function(options, self) { that.triggerEvent('find', {value: value}); } else if (data.id == 'findannotations') { that.triggerEvent('findannotations', {key: key, value: value}); + } else if (data.id == 'insert') { + insert({}); } else if (data.id == 'manage') { that.triggerEvent('define', { id: self.options.selected, diff --git a/source/Ox.UI/js/Video/Ox.VideoEditor.js b/source/Ox.UI/js/Video/Ox.VideoEditor.js index 0419490e..c69fcf2d 100644 --- a/source/Ox.UI/js/Video/Ox.VideoEditor.js +++ b/source/Ox.UI/js/Video/Ox.VideoEditor.js @@ -191,7 +191,7 @@ Ox.VideoEditor = function(options, self) { self.results = []; self.words = getWords(); - Ox.print('VIDEO EDITOR OPTIONS', self.options) + //Ox.print('VIDEO EDITOR OPTIONS', self.options) self.$editor = Ox.Element() .addClass('OxVideoEditor') @@ -606,9 +606,13 @@ Ox.VideoEditor = function(options, self) { }, blur: function(data) { Ox.print('VIDEO EDITOR BLUR') - // Only blur if neither the video editor - // nor an active menu layer received the click - if (!self.focused && !$('.OxMenuLayer').length) { + // Only blur if the video editor did not receive the click, + // no dialog is open, and no menu was visible + if ( + !self.focused + && !$('.OxDialogLayer').length + && !$('.OxMenuLayer').length + ) { blurAnnotation(); } },