diff --git a/source/Ox/js/HTML.js b/source/Ox/js/HTML.js
index 35518f4b..b5cf839b 100644
--- a/source/Ox/js/HTML.js
+++ b/source/Ox/js/HTML.js
@@ -55,8 +55,10 @@
{
'name': 'a',
'required': ['href'],
+ 'optional': ['target'],
'validate': {
- 'href': /^((https?:\/\/|\/|mailto:).*?)/
+ 'href': /^((https?:\/\/|\/|mailto:).*?)/,
+ 'target': /^_blank$/
}
},
{'name': 'br'},
@@ -507,6 +509,8 @@
'http://www.foo.com/'
> Ox.sanitizeHTML('foo')
'foo'
+ > Ox.sanitizeHTML('foo')
+ 'foo'
> Ox.sanitizeHTML('foo')
'<a href="javascript:alert()">foo</a>'
> Ox.sanitizeHTML('foo')
diff --git a/source/Ox/js/Locale.js b/source/Ox/js/Locale.js
index 9a6fe862..324f8646 100644
--- a/source/Ox/js/Locale.js
+++ b/source/Ox/js/Locale.js
@@ -31,7 +31,6 @@
Ox.LOCALE = locale;
if (locale == 'en') {
translations = {};
- callback(true);
} else {
translations = {};
Ox.forEach(Ox.LOCALES, function(locales, module) {
@@ -45,15 +44,19 @@
]);
}
});
- url && Ox.makeArray(url).forEach(function(value) {
- urls.push(Ox.makeArray(value));
- });
+ }
+ url && Ox.makeArray(url).forEach(function(value) {
+ urls.push(Ox.makeArray(value));
+ });
+ if (urls.length) {
Ox.getJSON(urls, function(data) {
Ox.forEach(data, function(values, url) {
Ox.extend(translations, values);
});
callback(true);
- });
+ })
+ } else {
+ callback(true);
}
} else {
callback(false);
diff --git a/source/UI/js/Core/URL.js b/source/UI/js/Core/URL.js
index 784e27ec..f411d692 100644
--- a/source/UI/js/Core/URL.js
+++ b/source/UI/js/Core/URL.js
@@ -810,7 +810,8 @@ Ox.URL = function(options) {
function parseURL(str, callback) {
// remove facebook spam
- str = str.replace(/\?fbclid=[A-Za-z0-9_]+/, '')
+ //str = str.replace(/\?fbclid=[A-Za-z0-9_]+/, '')
+ str = str.replace(/\?fbclid=.*/, '')
// fixme: removing trailing slash makes it impossible to search for '/'
var split = str.split('#'),
diff --git a/source/UI/js/Form/ArrayEditable.js b/source/UI/js/Form/ArrayEditable.js
index ea890b1e..f361569d 100644
--- a/source/UI/js/Form/ArrayEditable.js
+++ b/source/UI/js/Form/ArrayEditable.js
@@ -220,10 +220,11 @@ Ox.ArrayEditable = function(options, self) {
}, 250);
},
cancel: function(data) {
+ var id = $(this).data('id');
self.editing = false;
that.gainFocus();
data.value === ''
- ? submitItem(i, '')
+ ? submitItem(id, '')
: that.triggerEvent('blur', data);
},
change: function(data) {
@@ -247,9 +248,10 @@ Ox.ArrayEditable = function(options, self) {
that.triggerEvent('open');
},
submit: function(data) {
+ var id = $(this).data('id');
self.editing = false;
that.gainFocus();
- submitItem(i, data.value);
+ submitItem(id, data.value);
}
})
.appendTo(that);
@@ -364,8 +366,9 @@ Ox.ArrayEditable = function(options, self) {
}
}
- function submitItem(position, value) {
- var item = self.options.items[position];
+ function submitItem(id, value) {
+ var item = Ox.getObjectById(self.options.items, id);
+ Ox.Log('AE', 'submitItem', id, item)
if (value === '') {
deleteItem(item.id);
} else {
diff --git a/source/UI/js/Video/AnnotationFolder.js b/source/UI/js/Video/AnnotationFolder.js
index 977575fe..f6fb3127 100644
--- a/source/UI/js/Video/AnnotationFolder.js
+++ b/source/UI/js/Video/AnnotationFolder.js
@@ -71,8 +71,10 @@ Ox.AnnotationFolder = function(options, self) {
}
if (['in', 'out'].indexOf(key) > -1 && self.editing) {
var item = Ox.getObjectById(self.options.items, self.options.selected);
- item[key] = value;
- item.duration = self.options.out - self.options['in'];
+ if (item) {
+ item[key] = value;
+ item.duration = self.options.out - self.options['in'];
+ }
self.points = getPoints();
}
if (key == 'in') {
@@ -325,7 +327,7 @@ Ox.AnnotationFolder = function(options, self) {
that.triggerEvent('add', {value: data.value || ''});
},
blur: function(data) {
- if (data && data.id[0] == '_') {
+ if (data && data.id && data.id[0] == '_') {
changeAnnotation(data);
that.triggerEvent('blur');
} else {
@@ -620,10 +622,12 @@ Ox.AnnotationFolder = function(options, self) {
function submitAnnotation(data) {
var item = Ox.getObjectById(self.options.items, data.id);
- item.value = data.value;
- self.editing = false;
- self.options.sort == 'text' && self.$annotations.reloadItems();
- that.triggerEvent('submit', item);
+ if (item) {
+ item.value = data.value;
+ self.editing = false;
+ self.options.sort == 'text' && self.$annotations.reloadItems();
+ that.triggerEvent('submit', item);
+ }
}
function toggleLayer() {
@@ -749,6 +753,7 @@ Ox.AnnotationFolder = function(options, self) {
(id, data) -> update item
@*/
that.updateItem = function(id, data) {
+ Ox.Log('AF', 'updateItem', id, data)
var item = Ox.getObjectById(self.options.items, id);
Ox.forEach(data, function(value, key) {
item[key] = value;
@@ -760,7 +765,7 @@ Ox.AnnotationFolder = function(options, self) {
if (id != item.id) {
self.$annotations.find('.OxEditableElement').each(function() {
var $element = $(this);
- if ($element.data('id') == self.options.selected) {
+ if ($element.data('id') == id) {
$element.data({id: item.id});
}
});
diff --git a/source/UI/js/Video/AnnotationPanel.js b/source/UI/js/Video/AnnotationPanel.js
index 4e896767..83036b77 100644
--- a/source/UI/js/Video/AnnotationPanel.js
+++ b/source/UI/js/Video/AnnotationPanel.js
@@ -737,7 +737,10 @@ Ox.AnnotationPanel = function(options, self) {
@*/
that.blurItem = function() {
self.editing = false;
- getFolder(self.options.selected).blurItem();
+ var $folder = getFolder(self.options.selected)
+ if ($folder) {
+ $folder.blurItem();
+ }
renderEditMenu();
return that;
};
@@ -805,7 +808,10 @@ Ox.AnnotationPanel = function(options, self) {
// called from editannotation callback
// on the first update of a new annotation, the id will change
self.options.selected = item.id;
- getFolder(id).updateItem(id, item);
+ var $folder = getFolder(id);
+ if ($folder) {
+ $folder.updateItem(id, item);
+ }
updateLanguages();
renderOptionsMenu();
renderEditMenu();
diff --git a/source/UI/js/Video/VideoAnnotationPanel.js b/source/UI/js/Video/VideoAnnotationPanel.js
index a3935b1e..639fa1fa 100644
--- a/source/UI/js/Video/VideoAnnotationPanel.js
+++ b/source/UI/js/Video/VideoAnnotationPanel.js
@@ -938,7 +938,7 @@ Ox.VideoAnnotationPanel = function(options, self) {
that.triggerEvent('resizemap', data);
},
select: function(data) {
- selectAnnotation(data, true);
+ selectAnnotation(data, !self.updating);
},
showentityinfo: function(data) {
that.triggerEvent('showentityinfo', data);
@@ -1340,7 +1340,7 @@ Ox.VideoAnnotationPanel = function(options, self) {
that.triggerEvent('annotationssize', {size: data.size});
}
- function selectAnnotation(data, stayAtPosition) {
+ function selectAnnotation(data, moveToPosition) {
if (Ox.isUndefined(data)) {
// doubleclick on small timeline
data = getAnnotation();
@@ -1351,13 +1351,11 @@ Ox.VideoAnnotationPanel = function(options, self) {
// FIXME
// self.editing = false;
if (data.id) {
- if (!stayAtPosition || (
- self.options.annotationsRange != 'position' && (
- self.options.position < data['in']
- || self.options.position > data.out
- )
- )
- ) {
+ var outOfRange = self.options.annotationsRange != 'position' && (
+ self.options.position < data['in']
+ || self.options.position > data.out
+ )
+ if (moveToPosition && outOfRange) {
setPosition(data['in']);
// if annotationsRange is 'position',
// this may cause a deselect
@@ -1717,6 +1715,7 @@ Ox.VideoAnnotationPanel = function(options, self) {
(id, annotation) -> update annotation with id
@*/
that.updateAnnotation = function(id, annotation) {
+ self.updating = true
// called from editannotation callback
// id might have changed if new annotation was created
if (annotation.id) {
@@ -1730,6 +1729,7 @@ Ox.VideoAnnotationPanel = function(options, self) {
self.annotations = getAnnotations();
setTimelineState();
}
+ self.updating = false
};
/*@