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('') + '' + values.style + '>';
+ };
+ } 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 + '' + item.id + '>';
+ };
+ } 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 + '' + item.id + '>';
+ };
+ } 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();
}
},