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:
rlx 2012-02-19 10:49:52 +00:00
parent 61402492c6
commit 94cfbdb45c
7 changed files with 108 additions and 30 deletions

View file

@ -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);
}

View file

@ -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') {

View file

@ -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) {

View file

@ -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({

View file

@ -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});
}

View file

@ -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;

View file

@ -75,7 +75,9 @@ Ox.highlightHTML <f> Highlight matches in an HTML string
> Ox.highlightHTML('AT&amp;T', 'amp', 'h')
'AT&amp;T'
> Ox.highlightHTML('a &lt;b&gt; c', '<b>', 'h')
'<span class="h">a <span class="h">&lt;b&gt;</span> c'
'a <span class="h">&lt;b&gt;</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