fix issues with automatically opening annotation folders; add annotations option to video player to make find work for all layers
This commit is contained in:
parent
61402492c6
commit
94cfbdb45c
7 changed files with 108 additions and 30 deletions
|
@ -20,6 +20,7 @@ Ox.CollapsePanel = function(options, self) {
|
|||
self = self || {};
|
||||
var that = Ox.Panel({}, self)
|
||||
.defaults({
|
||||
animate: true,
|
||||
collapsed: false,
|
||||
extras: [],
|
||||
size: 16,
|
||||
|
@ -92,11 +93,18 @@ Ox.CollapsePanel = function(options, self) {
|
|||
!self.options.collapsed && that.$content.css({
|
||||
marginTop: -that.$content.height() + 'px'
|
||||
}).show();
|
||||
that.$content.animate({
|
||||
marginTop: marginTop + 'px'
|
||||
}, 250, function() {
|
||||
if (self.options.animate) {
|
||||
that.$content.animate({
|
||||
marginTop: marginTop + 'px'
|
||||
}, 250, function() {
|
||||
self.options.collapsed && that.$content.hide();
|
||||
});
|
||||
} else {
|
||||
that.$content.css({
|
||||
marginTop: marginTop + 'px'
|
||||
});
|
||||
self.options.collapsed && that.$content.hide();
|
||||
});
|
||||
}
|
||||
that.triggerEvent('toggle', {
|
||||
collapsed: self.options.collapsed
|
||||
});
|
||||
|
@ -110,7 +118,8 @@ Ox.CollapsePanel = function(options, self) {
|
|||
if (key == 'collapsed') {
|
||||
// will be toggled again in toggleCollapsed
|
||||
self.options.collapsed = !self.options.collapsed;
|
||||
self.$button.trigger('click');
|
||||
self.$button.toggle();
|
||||
toggleCollapsed();
|
||||
} else if (key == 'title') {
|
||||
self.$title.html(self.options.title);
|
||||
}
|
||||
|
|
|
@ -45,6 +45,10 @@ Ox.AnnotationFolder = function(options, self) {
|
|||
})
|
||||
.options(options || {});
|
||||
|
||||
if (self.options.selected) {
|
||||
self.options.collapsed = false;
|
||||
}
|
||||
|
||||
self.annotations = getAnnotations();
|
||||
self.points = getPoints();
|
||||
self.position = self.options.position;
|
||||
|
@ -526,8 +530,11 @@ Ox.AnnotationFolder = function(options, self) {
|
|||
if (value === '') {
|
||||
self.editing = false;
|
||||
}
|
||||
value && Ox.print('----------------- select item in folder', value, self.options.collapsed)
|
||||
if (value && self.options.collapsed) {
|
||||
toggleLayer();
|
||||
self.$panel.options({animate: false});
|
||||
self.$panel.options({collapsed: false});
|
||||
self.$panel.options({animate: true});
|
||||
}
|
||||
self.$annotations.options({selected: value});
|
||||
} else if (key == 'sort') {
|
||||
|
|
|
@ -110,6 +110,7 @@ Ox.AnnotationPanel = function(options, self) {
|
|||
that.triggerEvent('submit', Ox.extend({layer: layer.id}, data));
|
||||
},
|
||||
togglelayer: function(data) {
|
||||
self.options.showLayers[layer.id] = !data.collapsed;
|
||||
that.triggerEvent('togglelayer', Ox.extend({layer: layer.id}, data));
|
||||
},
|
||||
togglewidget: function(data) {
|
||||
|
|
|
@ -74,6 +74,7 @@ Ox.VideoPanel = function(options, self) {
|
|||
});
|
||||
|
||||
self.$video = Ox.VideoPlayer({
|
||||
annotations: getAnnotations(),
|
||||
censored: self.options.censored,
|
||||
controlsTop: ['fullscreen', 'title', 'find'],
|
||||
controlsBottom: ['play', 'volume', 'scale', 'timeline', 'position', 'settings'],
|
||||
|
@ -127,6 +128,7 @@ Ox.VideoPanel = function(options, self) {
|
|||
scale: function(data) {
|
||||
that.triggerEvent('scale', data);
|
||||
},
|
||||
select: selectAnnotation,
|
||||
subtitles: function(data) {
|
||||
that.triggerEvent('subtitles', data);
|
||||
},
|
||||
|
@ -269,6 +271,14 @@ Ox.VideoPanel = function(options, self) {
|
|||
that.triggerEvent('position', {position: self.options.position});
|
||||
}
|
||||
|
||||
function getAnnotations() {
|
||||
return Ox.flatten(Ox.merge(self.options.layers.map(function(layer) {
|
||||
return layer.items.map(function(item) {
|
||||
return {id: item.id, 'in': item['in'], out: item.out, text: item.value};
|
||||
});
|
||||
}))).sort(sortAnnotations);
|
||||
}
|
||||
|
||||
function getPlayerHeight() {
|
||||
return self.options.height -
|
||||
self.options.showTimeline * 80 - 1;
|
||||
|
@ -330,6 +340,7 @@ Ox.VideoPanel = function(options, self) {
|
|||
setPoint('in', data['in']);
|
||||
setPoint('out', data.out);
|
||||
}
|
||||
self.$annotationPanel.options({selected: self.options.selected});
|
||||
that.triggerEvent('select', {id: self.options.selected});
|
||||
}
|
||||
|
||||
|
@ -347,6 +358,24 @@ Ox.VideoPanel = function(options, self) {
|
|||
self.$annotationPanel.options({position: self.options.position});
|
||||
}
|
||||
|
||||
function sortAnnotations(a, b) {
|
||||
var ret = 0;
|
||||
if (a['in'] < b['in']) {
|
||||
ret = -1;
|
||||
} else if (a['in'] > b['in']) {
|
||||
ret = 1;
|
||||
} else if (a.out < b.out) {
|
||||
ret = -1;
|
||||
} else if (a.out > b.out) {
|
||||
ret = 1;
|
||||
} else if (a.value < b.value) {
|
||||
ret = -1;
|
||||
} else if (a.value > b.value) {
|
||||
ret = 1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
function toggleAnnotations(data) {
|
||||
self.options.showAnnotations = !data.collapsed;
|
||||
self.$video.options({
|
||||
|
|
|
@ -6,12 +6,11 @@
|
|||
Ox.VideoPlayer <f> Generic Video Player
|
||||
(options, self) -> <o> Video Player
|
||||
options <o> Options
|
||||
annotation <[o]> Array of annotation tracks
|
||||
name <s> Name of the annotation track
|
||||
data <[o]> Annotation data
|
||||
in <n> In point (sec)
|
||||
out <n> Out point (sec)
|
||||
text <s> Text
|
||||
annotations <[]> Array of annotations
|
||||
id <s> Optional id
|
||||
in <n> In point (sec)
|
||||
out <n> Out point (sec)
|
||||
text <s> Text
|
||||
censored <a|[]> Array of censored ranges
|
||||
controlsBottom <[s]|[]> Bottom controls, from left to right
|
||||
Can be 'close', fullscreen', 'scale', 'title', 'find', 'open',
|
||||
|
@ -60,6 +59,7 @@ Ox.VideoPlayer <f> Generic Video Player
|
|||
showProgress <|false> If true, show buffering progress
|
||||
sizeIsLarge <b|false> If true, initial state of the size control is large
|
||||
subtitles <s|[o]|[]> URL or SRT or array of subtitles
|
||||
id <s> Optional id
|
||||
in <n> In point (sec)
|
||||
out <n> Out point (sec)
|
||||
text <s> Text
|
||||
|
@ -146,6 +146,10 @@ Ox.VideoPlayer = function(options, self) {
|
|||
}
|
||||
});
|
||||
|
||||
if (Ox.isEmpty(self.options.annotations)) {
|
||||
self.options.annotations = self.options.subtitles;
|
||||
}
|
||||
|
||||
if (Ox.isObject(self.options.video)) {
|
||||
self.resolutions = Ox.sort(Object.keys(self.options.video));
|
||||
if (!(self.options.resolution in self.options.video)) {
|
||||
|
@ -1160,13 +1164,17 @@ Ox.VideoPlayer = function(options, self) {
|
|||
var results = [];
|
||||
if (query.length) {
|
||||
query = query.toLowerCase();
|
||||
results = Ox.map(self.options.subtitles, function(subtitle) {
|
||||
return subtitle.text.toLowerCase().indexOf(query) > -1 ? {
|
||||
'in': subtitle['in'],
|
||||
out: subtitle.out
|
||||
results = Ox.map(self.options.annotations, function(annotation) {
|
||||
return Ox.decodeHTML(Ox.stripTags(
|
||||
annotation.text.toLowerCase()
|
||||
)).indexOf(query) > -1 ? {
|
||||
id: annotation.id,
|
||||
'in': annotation['in'],
|
||||
out: annotation.out
|
||||
} : null;
|
||||
});
|
||||
}
|
||||
Ox.print('FIND RESULTS:', results);
|
||||
return results;
|
||||
}
|
||||
|
||||
|
@ -1500,24 +1508,29 @@ Ox.VideoPlayer = function(options, self) {
|
|||
|
||||
function goToNextResult(direction) {
|
||||
var found = false,
|
||||
position = 0;
|
||||
result;
|
||||
if (self.results.length) {
|
||||
direction == -1 && self.results.reverse();
|
||||
Ox.forEach(self.results, function(v) {
|
||||
if (direction == 1 ? v['in'] > self.options.position : v.out < self.options.position) {
|
||||
position = v['in'];
|
||||
if (
|
||||
direction == 1
|
||||
? v['in'] > self.options.position
|
||||
: v.out < self.options.position
|
||||
) {
|
||||
result = v
|
||||
found = true;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
direction == -1 && self.results.reverse();
|
||||
if (!found) {
|
||||
position = self.results[direction == 1 ? 0 : self.results.length - 1]['in'];
|
||||
result = self.results[direction == 1 ? 0 : self.results.length - 1];
|
||||
}
|
||||
setPosition(position + self.secondsPerFrame);
|
||||
setPosition(result['in'] + self.secondsPerFrame);
|
||||
that.triggerEvent('position', {
|
||||
position: self.options.position
|
||||
});
|
||||
result.id && that.triggerEvent('select', result);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2132,7 +2145,12 @@ Ox.VideoPlayer = function(options, self) {
|
|||
results: self.results
|
||||
});
|
||||
if (hasPressedEnter) {
|
||||
self.results.length ? goToNextResult(1) : self.$findInput.focusInput(true);
|
||||
if (self.results.length) {
|
||||
goToNextResult(1);
|
||||
that.gainFocus();
|
||||
} else {
|
||||
self.$findInput.focusInput(true);
|
||||
}
|
||||
}
|
||||
that.triggerEvent('find', {find: self.options.find});
|
||||
}
|
||||
|
|
|
@ -794,21 +794,21 @@ Video
|
|||
.OxThemeClassic .OxAnnotationFolder .OxArrayEditable .OxEditableElement.OxSelected .OxHighlight {
|
||||
background-color: transparent;
|
||||
background-image: -moz-repeating-linear-gradient(
|
||||
-45deg, rgb(192, 192, 255) 0, rgb(192, 192, 255) 25%,
|
||||
-45deg, transparent 0%, transparent 25%,
|
||||
rgb(255, 255, 0) 25%, rgb(255, 255, 0) 50%,
|
||||
rgb(192, 192, 255) 50%, rgb(192, 192, 255) 75%,
|
||||
transparent 50%, transparent 75%,
|
||||
rgb(255, 255, 0) 75%, rgb(255, 255, 0) 100%
|
||||
);
|
||||
background-image: -o-repeating-linear-gradient(
|
||||
-45deg, rgb(192, 192, 255) 0, rgb(192, 192, 255) 25%,
|
||||
-45deg, transparent 0%, transparent 25%,
|
||||
rgb(255, 255, 0) 25%, rgb(255, 255, 0) 50%,
|
||||
rgb(192, 192, 255) 50%, rgb(192, 192, 255) 75%,
|
||||
transparent 50%, transparent 75%,
|
||||
rgb(255, 255, 0) 75%, rgb(255, 255, 0) 100%
|
||||
);
|
||||
background-image: -webkit-repeating-linear-gradient(
|
||||
-45deg, rgb(192, 192, 255) 0, rgb(192, 192, 255) 25%,
|
||||
-45deg, transparent 0%, transparent 25%,
|
||||
rgb(255, 255, 0) 25%, rgb(255, 255, 0) 50%,
|
||||
rgb(192, 192, 255) 50%, rgb(192, 192, 255) 75%,
|
||||
transparent 50%, transparent 75%,
|
||||
rgb(255, 255, 0) 75%, rgb(255, 255, 0) 100%
|
||||
);
|
||||
background-size: 4px 4px;
|
||||
|
|
|
@ -75,7 +75,9 @@ Ox.highlightHTML <f> Highlight matches in an HTML string
|
|||
> Ox.highlightHTML('AT&T', 'amp', 'h')
|
||||
'AT&T'
|
||||
> Ox.highlightHTML('a <b> c', '<b>', 'h')
|
||||
'<span class="h">a <span class="h"><b></span> c'
|
||||
'a <span class="h"><b></span> c'
|
||||
> Ox.highlightHTML('a <br> c', 'b', 'h')
|
||||
'a <br> c'
|
||||
@*/
|
||||
Ox.highlightHTML = function(html, str, classname, tags) {
|
||||
var count = 0,
|
||||
|
@ -83,7 +85,19 @@ Ox.highlightHTML = function(html, str, classname, tags) {
|
|||
isTag = false,
|
||||
position,
|
||||
positions = [];
|
||||
tags = Ox.merge(tags || [], ['a', 'b', 'code', 'i', 's', 'sub', 'sup', 'u']);
|
||||
//fixme: default tags should be same as in parseHTML
|
||||
tags = Ox.merge(tags || [], [
|
||||
// inline formatting
|
||||
'b', 'code', 'i', 's', 'sub', 'sup', 'u',
|
||||
// block formatting
|
||||
'blockquote', 'h1', 'h2', 'h3', 'p', 'pre',
|
||||
// lists
|
||||
'li', 'ol', 'ul',
|
||||
// tables
|
||||
'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr',
|
||||
// other
|
||||
'a', 'br', 'img',
|
||||
]);
|
||||
str = Ox.encodeHTML(str).toLowerCase();
|
||||
Ox.forEach(html.toLowerCase(), function(chr, i) {
|
||||
// check for entity or tag start
|
||||
|
|
Loading…
Reference in a new issue