[Pkg-mozext-commits] [video-without-flash] 01/01: Imported Upstream version 2.0.2
Dmitry Smirnov
onlyjob at moszumanska.debian.org
Thu Jan 1 07:24:19 UTC 2015
This is an automated email from the git hooks/post-receive script.
onlyjob pushed a commit to branch upstream
in repository video-without-flash.
commit b0819e1 (upstream)
Author: Dmitry Smirnov <onlyjob at member.fsf.org>
Date: Thu Jan 1 07:24:08 2015
Imported Upstream version 2.0.2
---
README.md | 139 +++++++++++++++++++++++
bootstrap.js | 73 ++++++++++++
chrome.manifest | 10 +-
chrome/#blip.js# | 85 ++++++++++++++
chrome/#list_modules.js# | 31 +++++
chrome/#vwof.js# | 93 +++++++++++++++
chrome/blip.js | 85 ++++++++++++++
chrome/content/browserOverlay.js | 164 ---------------------------
chrome/content/browserOverlay.xul | 36 ------
chrome/content/onload.js | 18 ---
chrome/content/prefs.xul | 62 ----------
chrome/{content => }/list_modules.js | 7 +-
chrome/listener.js | 156 +++++++++++++++++++++++++
chrome/locale/en-US/browserOverlay.dtd | 3 -
{modules => chrome/modules}/FC2.jsm | 6 +-
{modules => chrome/modules}/HTML5.jsm | 0
chrome/modules/Makefile.in | 2 +
chrome/modules/SWM.jsm | 105 +++++++++++++++++
chrome/modules/ScreenWaveMedia.jsm | 57 ++++++++++
chrome/modules/blip.jsm | 118 +++++++++++++++++++
{modules => chrome/modules}/dailymotion.jsm | 0
chrome/modules/dew.jsm | 20 ++++
{modules => chrome/modules}/niconico.jsm | 4 +-
chrome/modules/springboard.jsm | 25 ++++
chrome/modules/twitch.jsm | 39 +++++++
chrome/modules/ustream.jsm | 48 ++++++++
{modules => chrome/modules}/youtube.jsm | 10 +-
chrome/{content => }/player.js | 6 +-
chrome/prefs.js | 47 ++++++++
chrome/prefs.xul | 79 +++++++++++++
chrome/skin/toolbar-button.css | 14 ---
chrome/skin/video-icon_14.png | Bin 1587 -> 0 bytes
chrome/skin/video-icon_24.png | Bin 2318 -> 0 bytes
chrome/{content => }/utils.js | 11 +-
chrome/vwof.js | 89 +++++++++++++++
chrome/{content => }/youtube_utils.js | 7 +-
{chrome/content => content}/list_modules.js | 7 +-
content/listener.js | 144 +++++++++++++++++++++++
{modules => content/modules}/FC2.jsm | 6 +-
{modules => content/modules}/HTML5.jsm | 0
content/modules/Makefile.in | 2 +
content/modules/ScreenWaveMedia.jsm | 57 ++++++++++
content/modules/blip.jsm | 118 +++++++++++++++++++
{modules => content/modules}/dailymotion.jsm | 0
{modules => content/modules}/niconico.jsm | 4 +-
{modules => content/modules}/youtube.jsm | 10 +-
{chrome/content => content}/player.js | 6 +-
content/prefs.js | 47 ++++++++
content/prefs.xul | 79 +++++++++++++
{chrome/content => content}/utils.js | 11 +-
content/vwof.js | 89 +++++++++++++++
{chrome/content => content}/youtube_utils.js | 7 +-
defaults/preferences/vwof.js | 3 +-
install.rdf | 38 +++++--
locale/en-US/strings.dtd | 1 +
locale/en-US/strings.properties | 3 +
modules/blip.jsm | 111 ------------------
{chrome/content => skin}/player.css | 2 +-
{chrome/skin => skin}/video-icon.png | Bin
59 files changed, 1905 insertions(+), 489 deletions(-)
diff --git a/README.md b/README.md
new file mode 100755
index 0000000..8e2f2dc
--- /dev/null
+++ b/README.md
@@ -0,0 +1,139 @@
+video-without-flash
+===================
+
+Firefox extension for watching videos without the flash plugin
+
+
+<i>Fetch video source of flash based media and play the video directly with Firefox, without the use of the flash plug-in. </i>
+
+<b> Supported sites/embed video player </b>
+<ul>
+<li>Youtube</li>
+<li>Blip</li>
+<li>ScreenWaveMedia</li>
+<li>Dew</li>
+<li>HTML5</li>
+<li>Springboard</li>
+<li>Dailymotion</li>
+<li>UStream </li>
+</ul>
+
+Due to some minor variations of providing the video by a same media provider (different version of there player, use of the embed tag) a few videos may not be detected.
+
+<b> Usage </b>
+By default the video are detected when a page load, you can disable this behavior in the preference pane and manually try to detect video by pressing
+ ALT-W or Right Click and "Watch video without flash".
+
+<b>Why you may want to use this extension</b>
+<ul>
+<li>You experienced some lag or bad CPU performance using flash </li>
+<li>You only use flash to watch videos, and do not want to install a non-free packages on your linux station (this extension is released under the GPL)</li>
+</ul>
+
+<b> Pro tips </b>
+*To read MP4 videos you must install a media plugin like vlc-web-plugin or gecko-mplayer. Under Windows the vlc web plugin can be install when running the vlc install exe.
+
+* The video can be save with a "right click / save as" on the "open in a new tab" link.
+
+* Numerous options in the preference pane : select preferred format / quality when available, disable modules.
+
+<b> Known bugs </b>
+(unfortunately these are upstream bugs, nothing I can do about it)
+
+* YouTube : The video area is not reloading when clicking on a suggested video link. After clicking on such a link, please use the ALT-w command to refresh the player area
+
+* VLC plugin : The video crashes when a video is paused when played with the vlc web plugin.
+
+<b> How does it works </b>
+This extension fetch the direct link to videos using regular expression, XPath, and DOM. When available, a picture and a select control are displayed to read the video with firefox, using the firefox internal HTML5 compliant media player or a plugin like vlc or mplayer if the user had installed it.
+
+Each media provider is handled by a "parser". Javascript modules (.jsm) that are loaded at startup. The extension can fairly easy be extended due to it modular approache, as new media provider can be added by implementing a new jsm file.
+
+<b>Why a HTML5 parser ? </b>
+For licensing reasons firefox do not support at the moment the H264 codec, although it may change in the future. If a site uses HTML5 to display a video, but the video itself is encoded with H264 or a variant you normally wont be able to play it. By using the HTML5 parser, you can read the video if a media player plugin is installed as stated previously.
+
+
+= Technical documentation for developers =
+
+== How to write a new parser ==
+
+<i>Do not esitate to fork and add your own parser</i>
+
+* Step 1 : Add the name of your parser without the .jsm extension in the browser variable "extensions.vwof.modules" you can do it with about:config for test purposes or do it permanently in src/defaults/preferenes/vwof.js
+The boolean value (parsername:1) is eather if your parser is activated or not.
+
+
+* Step 2 : Create a jsm file in the modules directory
+
+The parser must respect the following API :
+
+```javascript
+var parser = {
+ BASE_URI: '',
+ parse_embed: function(cw) {
+ var video_info = [];
+ return video_info;
+ },
+
+ parse_site: function(cw) {
+ var video_info = [];
+ var player = cw.document.getElementById('');
+ if(!player)return;
+
+ return video_info;
+ }
+};
+```
+
+=== video_info variable ===
+
+video player is an array of an hash
+
+each video is an entry in the array and the hash contains video information
+
+If the videos array contains more than one element a combo box (select tag)
+will be added in the player displaying the format and quality
+
+```javascript
+video_info =
+[
+{
+'player':, //DOM where the video player will be embed, replacing all child nodes, if undefined, the video open in a new tab
+
+'video_img':, //string link to the picture displayed as a preview, if undefined the background is black
+
+'videos': [] //array of video informations, see below
+}
+];
+
+videos =
+[
+{
+'quality':, //quality of the video (low, medium, hd720, hd1080)
+
+'format':, //format of the video (webm, mp4, flv, ...)
+
+'url': //direct link to the video, this is the only mandatory variable
+}
+];
+
+
+== How to build ==
+
+This plugin comes with a home made makefile based on mozilla school xul example.
+
+Targets are :
+
+* make
+ Create an .xpi in the ../bin directory (manually create ../bin if necessary)
+
+* make install
+ install the plugin in the profil directory. By default the profil name is "devel"
+ you can change this behaviour by passing the profile_dir variable (example : make install profile_dir default)
+
+* you need to restart firefox to apply the changes, it can be done with the make target
+ make rerun
+
+ which will run the following command : killall firefox ; firefox -purgecaches -P &
+
+
diff --git a/bootstrap.js b/bootstrap.js
new file mode 100755
index 0000000..ce07dc4
--- /dev/null
+++ b/bootstrap.js
@@ -0,0 +1,73 @@
+const {interfaces: Ci, utils: Cu} = Components;
+Cu.import('resource://gre/modules/Services.jsm');
+Cu.import('resource://gre/modules/NetUtil.jsm');
+
+const PREF_BRANCH = "extensions.vwof.";
+
+function listenPageLoad(event) {
+ var cw = event.originalTarget.defaultView;
+ if (cw.frameElement && windowListener.ignoreFrames) {
+ return; //dont want to watch frames
+ }
+
+ var prefManager = Components.classes["@mozilla.org/preferences-service;1"].
+ getService(Components.interfaces.nsIPrefBranch);
+ var activate_onload = prefManager.getBoolPref(PREF_BRANCH+"activate_onload");
+ if(activate_onload){vwof.detectVideo(cw);}
+}
+
+function oncommand_detect_video(window){
+ //window is browser.xul. Pass the contentWindow of the document
+ vwof.detectVideo(window.gBrowser.contentDocument.defaultView);
+}
+
+function init(window){
+ let doc = window.document;
+ keyset = doc.getElementById('mainKeyset');
+
+ //keyboard shortcut
+ let key = doc.createElement('key');
+ key.setAttribute('id', 'vwof-key');
+ key.addEventListener("command", function (){oncommand_detect_video(window);});
+ key.setAttribute("oncommand", "//");
+ key.setAttribute('key', 'w');
+ key.setAttribute('modifiers', 'alt');
+ keyset.appendChild(key);
+ keyset.parentElement.appendChild(keyset);
+}
+
+function startup(aData, aReason) {
+ Services.scriptloader.loadSubScript("chrome://vwof/content/prefs.js")
+ Services.scriptloader.loadSubScript('chrome://vwof/content/vwof.js');
+ Services.scriptloader.loadSubScript('chrome://vwof/content/player.js');
+ Services.scriptloader.loadSubScript('chrome://vwof/content/utils.js');
+ Services.scriptloader.loadSubScript('chrome://vwof/content/youtube_utils.js');
+ Services.scriptloader.loadSubScript('chrome://vwof/content/listener.js');
+ windowListener.register();
+ PrefObserver.register();
+
+ setDefaultPref(PREF_BRANCH, "modules", '{"HTML5":1, "blip":1, "youtube":1, "dailymotion":1, "niconico":1, "FC2":1, "ScreenWaveMedia":1}');
+ setDefaultPref(PREF_BRANCH, "prefered_quality", 'medium');
+ setDefaultPref(PREF_BRANCH, "prefered_format", 'webm');
+ setDefaultPref(PREF_BRANCH, "activate_onload", true);
+
+ // Load into any existing windows
+ let wm = Services.wm,
+ enumerator = wm.getEnumerator('navigator:browser');
+ while (enumerator.hasMoreElements()) {
+ init(enumerator.getNext().QueryInterface(Ci.nsIDOMWindow));
+ }
+
+ vwof.load_modules();
+ vwof.set_parsers_activation();
+}
+
+function shutdown(aData, aReason) {
+ if (aReason == APP_SHUTDOWN) return;
+ windowListener.unregister();
+ PrefObserver.unregister();
+}
+
+function install() {}
+
+function uninstall() {}
diff --git a/chrome.manifest b/chrome.manifest
index 5c6f57d..9032b42 100755
--- a/chrome.manifest
+++ b/chrome.manifest
@@ -1,7 +1,3 @@
-content vwof chrome/content/ contentaccessible=yes
-skin vwof classic/1.0 chrome/skin/
-locale vwof en-US chrome/locale/en-US/
-resource vwof modules/
-
-overlay chrome://browser/content/browser.xul chrome://vwof/content/browserOverlay.xul
-style chrome://global/content/customizeToolbar.xul chrome://vwof/skin/toolbar-button.css
\ No newline at end of file
+content vwof content/ contentaccessible=yes
+locale vwof en-US locale/en-US/
+skin vwof classic/1.0 skin/
diff --git a/chrome/#blip.js# b/chrome/#blip.js#
new file mode 100644
index 0000000..b556232
--- /dev/null
+++ b/chrome/#blip.js#
@@ -0,0 +1,85 @@
+var parser = {
+ BASE_URI: 'blip.tv',
+ URL_PARAM_JSON: '?skin=json&no_wrap=1',
+ parse_embed: function(cw) {
+ const XPATH_PLAYER = "//iframe[starts-with(@src, 'http://blip.tv/play')]";
+ var video_info = [];
+ var player;
+ var video_img;
+
+ var xp_res_player = cw.document.evaluate(XPATH_PLAYER, cw.document, null, cw.XPathResult.UNORDERED_NODE_ITERATOR_TYPE, null );
+ while (player = xp_res_player.iterateNext()) {
+ var videos = [];
+ var player_doc = player.contentDocument;
+ var episode_info = player_doc.getElementById('EpisodeInfo');
+ if(episode_info){
+ //megaplaya method
+ var data_episode_page = episode_info.getAttribute('data-episode-page');
+ var json_string = utils.get(data_episode_page+this.URL_PARAM_JSON);
+ var parse_data = this.parse_json_data(json_string);
+ video_img = parse_data[0];
+ videos = parse_data[1];
+ }
+ else{
+ //embed method
+ var encoded_file = player_doc.body.textContent.match(/"file":"(.+?)",/)[1];
+ var file = decodeURIComponent(encoded_file);
+ file = file.replace('rss/flash', 'posts/view');
+ var json_string = utils.get(file+this.URL_PARAM_JSON);
+ var parse_data = this.parse_json_data(json_string);
+ video_img = parse_data[0];
+ videos = parse_data[1];
+ cw.oalert(videos[0].url);
+ }
+ cw.alert(player);
+ video_info.push({
+ 'player': player,
+ 'video_img':video_img,
+ 'videos': videos
+ });
+ }
+
+ return video_info;
+ },
+
+ parse_site: function(cw) {
+ var video_info = [];
+ var player = cw.document.getElementById('PlayeriFrame');
+ if(!player)return;
+
+ var json_string = utils.get(cw.document.URL+this.URL_PARAM_JSON);
+ var parse_data = this.parse_json_data(json_string);
+ var video_img = parse_data[0];
+ var videos = parse_data[1];
+
+ video_info.push({
+ 'player': player,
+ 'video_img': video_img,
+ 'videos': videos
+ });
+
+ return video_info;
+ },
+
+ parse_json_data: function(json_string){
+ var post = JSON.parse(json_string).Post;
+
+ var videos = [];
+ for(var i=0;i<post.additionalMedia.length;i++){
+ var format = post.additionalMedia[i].primary_mime_type;
+ if(format == 'text/plain')continue;
+
+ //remove video part of the mime type for a prettier display
+ format=format.replace('video/', '');
+
+ videos.push({'format': format,
+ 'quality': post.additionalMedia[i].media_width + '/' + post.additionalMedia[i].media_height,
+ 'url':post.additionalMedia[i].url}
+ );
+ }
+
+ var video_img = post.thumbnailUrl;
+
+ return [video_img, videos];
+ }
+};
diff --git a/chrome/#list_modules.js# b/chrome/#list_modules.js#
new file mode 100644
index 0000000..3948543
--- /dev/null
+++ b/chrome/#list_modules.js#
@@ -0,0 +1,31 @@
+var checkbox_wide = document.getElementById("vwof_yt_wide");
+var wide = youtubeUtils.yt_is_wide();
+checkbox_wide.setAttribute("checked", wide);
+
+var prefPane = document.getElementById('vwof_pref_modules');
+var s_modules = document.getElementById('extensions.vwof.modules').value;
+modules = JSON.parse(s_modules);
+
+var element_label = document.createElement('label');
+element_label.setAttribute('value', ' -- Enable/disable modules -- ');
+dprefPane.appendChild(element_label);
+
+for(var key_module in modules){
+ var element_checkbox = document.createElement('checkbox');
+ element_checkbox.setAttribute('label', key_module);
+ element_checkbox.setAttribute('checked', modules[key_module]?'true':'false');
+ element_checkbox.setAttribute('oncommand', "update_module(event)");
+ prefPane.appendChild(element_checkbox);
+}
+
+function update_module(event){
+ var l = event.target.getAttribute('label');
+ var c = event.target.hasAttribute('checked')?1:0;
+
+ modules[l] = c;
+ var s_modules = JSON.stringify(modules);
+
+ var prefManager = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
+ prefManager.setCharPref("extensions.vwof.modules", s_modules);
+}
+
diff --git a/chrome/#vwof.js# b/chrome/#vwof.js#
new file mode 100644
index 0000000..ae9e0f4
--- /dev/null
+++ b/chrome/#vwof.js#
@@ -0,0 +1,93 @@
+var vwof= {
+ parsers:{}, //hash of the parsers (loaded from jsm modules)
+ parser_name:["blip", "dailymotion", "FC2", "HTML5", "niconico", "youtube", "ScreenWaveMedia"],
+
+ /**
+ Load modules listed in the extensions.vwof.modules pref variable to this.parsers hash
+ */
+ load_modules:function(){
+ //check in the preferences : activated a parser on page load or not
+ Components.utils.import("resource://gre/modules/Services.jsm");
+ var prefManager = Components.classes["@mozilla.org/preferences-service;1"]
+ .getService(Components.interfaces.nsIPrefBranch);
+
+ var modules_list = prefManager.getCharPref("extensions.vwof.modules");
+ var modules = JSON.parse(modules_list); //parser / value from the preferences
+
+ for(var i=0;i<this.parser_name.length;i++){
+ let key_parser = this.parser_name[i];
+ if(modules[key_parser]){
+
+ let context = {};
+ let res = 'chrome://vwof/content/modules/'+key_parser+'.jsm';
+ Services.scriptloader.loadSubScript(res, context, "UTF-8");
+ this.parsers[key_parser] = context;
+ }
+ }
+ },
+ reload_modules:function(){
+ try{
+ // clear the previously loaded parsers
+ delete this.parsers;
+ this.parsers = {};
+
+ //finally load the modules
+ this.load_modules();
+ }
+ catch(err){
+ Components.utils.reportError("vwof exception: "+err);
+ };
+ },
+ getVideoInfo:function (cw) {
+ var video_info = []; // array of video_data
+ var has_parsed_site = false;
+
+ for(var key_parser in this.parsers){
+ try{
+ var parser = this.parsers[key_parser].parser;
+ var video_data = []; //array of video links with quality
+
+ //if the parser has a URI and it's the current location
+ if(parser.BASE_URI && cw.location.hostname == parser.BASE_URI){
+ video_data = parser.parse_site(cw);
+ has_parsed_site = true;
+ }
+ else if(parser.parse_embed){
+ video_data = parser.parse_embed(cw);
+ }
+
+ //if there is at least a video url retreived from the parser
+ if(video_data.length >= 1){
+ //set the source (name of the parser)
+ for(var i=0;i < video_data.length;i++){
+ video_data[i]['source'] = this.parsers[key_parser].name;
+ }
+
+ //concat the chunks of video(s) from this parser
+ video_info = video_info.concat(video_data);
+ }
+ }
+ catch(err){
+ Components.utils.reportError("vwof plugin, exception in "+key_parser+": "+err);
+ };
+
+ //official web sites do not embed several videos, so don't use other parsers
+ if(has_parsed_site){break;}
+ }
+
+ return video_info;
+ },
+
+ detectVideo:function(cw) {
+ var video_info = this.getVideoInfo(cw);
+
+ for (var i = 0; i < video_info.length; i++) {
+ if(video_info[i]['player']){
+ var replace_location = video_info[i]['player'];
+ var player = vwofPlayer.create_video_selector(video_info[i], cw);
+ var replace_parent = replace_location.parentNode;
+ replace_parent.replaceChild(player, replace_location);
+ }
+ }
+ }
+};
diff --git a/chrome/blip.js b/chrome/blip.js
new file mode 100644
index 0000000..03dbc11
--- /dev/null
+++ b/chrome/blip.js
@@ -0,0 +1,85 @@
+var parser = {
+ BASE_URI: 'blip.tv',
+ URL_PARAM_JSON: '?skin=json&no_wrap=1',
+ parse_embed: function(cw) {
+ const XPATH_PLAYER = "//iframe[starts-with(@src, 'http://blip.tv/play')]";
+ var video_info = [];
+ var player;
+ var video_img;
+
+ var xp_res_player = cw.document.evaluate(XPATH_PLAYER, cw.document, null, cw.XPathResult.UNORDERED_NODE_ITERATOR_TYPE, null );
+ while (player = xp_res_player.iterateNext()) {
+ var videos = [];
+ var player_doc = player.contentDocument;
+ var episode_info = player_doc.getElementById('EpisodeInfo');
+ if(episode_info){
+ //megaplaya method
+ var data_episode_page = episode_info.getAttribute('data-episode-page');
+ var json_string = utils.get(data_episode_page+this.URL_PARAM_JSON);
+ var parse_data = this.parse_json_data(json_string);
+ video_img = parse_data[0];
+ videos = parse_data[1];
+ }
+ else{
+ //embed method
+ var encoded_file = player_doc.body.textContent.match(/"file":"(.+?)",/)[1];
+ var file = decodeURIComponent(encoded_file);
+ file = file.replace('rss/flash', 'posts/view');
+ var json_string = utils.get(file+this.URL_PARAM_JSON);
+ var parse_data = this.parse_json_data(json_string);
+ video_img = parse_data[0];
+ videos = parse_data[1];
+ cw.alert(videos[0].url);
+ }
+ cw.alert(player);
+ video_info.push({
+ 'player': player,
+ 'video_img':video_img,
+ 'videos': videos
+ });
+ }
+
+ return video_info;
+ },
+
+ parse_site: function(cw) {
+ var video_info = [];
+ var player = cw.document.getElementById('PlayeriFrame');
+ if(!player)return;
+
+ var json_string = utils.get(cw.document.URL+this.URL_PARAM_JSON);
+ var parse_data = this.parse_json_data(json_string);
+ var video_img = parse_data[0];
+ var videos = parse_data[1];
+
+ video_info.push({
+ 'player': player,
+ 'video_img': video_img,
+ 'videos': videos
+ });
+
+ return video_info;
+ },
+
+ parse_json_data: function(json_string){
+ var post = JSON.parse(json_string).Post;
+
+ var videos = [];
+ for(var i=0;i<post.additionalMedia.length;i++){
+ var format = post.additionalMedia[i].primary_mime_type;
+ if(format == 'text/plain')continue;
+
+ //remove video part of the mime type for a prettier display
+ format=format.replace('video/', '');
+
+ videos.push({'format': format,
+ 'quality': post.additionalMedia[i].media_width + '/' + post.additionalMedia[i].media_height,
+ 'url':post.additionalMedia[i].url}
+ );
+ }
+
+ var video_img = post.thumbnailUrl;
+
+ return [video_img, videos];
+ }
+};
diff --git a/chrome/content/browserOverlay.js b/chrome/content/browserOverlay.js
deleted file mode 100755
index 904bda1..0000000
--- a/chrome/content/browserOverlay.js
+++ /dev/null
@@ -1,164 +0,0 @@
-if("undefined" == typeof(vwofChrome)){
- var vwofChrome = {};
-}
-
-vwofChrome.BrowserOverlay = {
- parser_name:["blip", "dailymotion", "FC2", "HTML5", "niconico", "youtube"],
- parsers:{}, //hash of the parsers (loaded from jsm modules)
-
- /**
- function called at startup
- */
- startup:function() {
- this.load_modules();
- this.set_parsers_activation();
- },
- set_parsers_activation:function(){
- //check in the preferences : activated a parser on page load or not
- Components.utils.import("resource://gre/modules/Services.jsm");
- var prefManager = Components.classes["@mozilla.org/preferences-service;1"]
- .getService(Components.interfaces.nsIPrefBranch);
-
- var modules_list = prefManager.getCharPref("extensions.vwof.modules");
- var modules = JSON.parse(modules_list); //parser / value from the preferences
-
- for(var key_parser in this.parsers){
- var parser = this.parsers[key_parser].parser;
-
- //if a pref is defined for this parser
- if(modules[key_parser])
- parser['activated'] = modules[key_parser]?true:false;
- else
- parser['activated'] = false;
- }
- },
- /**
- Load modules listed in the extensions.vwof.modules pref variable to this.parsers hash
- */
- load_modules:function(){
- try{
- Components.utils.import("resource://gre/modules/Services.jsm");
- var prefManager = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
- var modules_list = prefManager.getCharPref("extensions.vwof.modules");
- var modules = JSON.parse(modules_list);
-
- for(var i=0;i<this.parser_name.length;i++){
- let key_parser = this.parser_name[i];
- let context = {};
- let res = 'resource://vwof/'+key_parser+'.jsm';
- Services.scriptloader.loadSubScript(res, context, "UTF-8");
- this.parsers[key_parser] = context;
- }
- }
- catch(err){
- alert(err);
- };
-
- },
- /**
- call every parse function from loaded parsers
- */
- getVideoInfo:function (cw) {
- var video_info = []; // array of video_data
- var has_parsed_site = false;
-
- for(var key_parser in this.parsers){
-
- try{
- var parser = this.parsers[key_parser].parser;
- var video_data = []; //array of video links with quality
-
- if(parser['activated'] != true)continue;
-
- //if the parser has a URI and it's the current location
- if(parser.BASE_URI && cw.location.hostname == parser.BASE_URI){
- video_data = parser.parse_site(cw);
- has_parsed_site = true;
- }
- else if(parser.parse_embed){
- video_data = parser.parse_embed(cw);
- }
-
- //if there is at least a video url retreived from the parser
- if(video_data.length >= 1){
- //set the source (name of the parser)
- for(var i=0;i < video_data.length;i++){
- video_data[i]['source'] = key_parser;
- }
-
- //concat the chunks of video(s) from this parser
- video_info = video_info.concat(video_data);
- }
- }
- catch(err){
- console.error("vwof plugin, exception in parser "+key_parser+": "+err);
- };
-
- //video web sites never have several videos on a same page,
- //stop the search if a hit was found
- if(has_parsed_site){break;}
- }
-
- return video_info;
- },
-
- /**
- get the video source and add a link in the document
- */
- detectVideo:function(cw) {
-
- //check if the content window is defined
- if (!cw ||
- !cw.document
- ){
- return;
- }
-
- var video_info = this.getVideoInfo(cw);
-
- for (var i = 0; i < video_info.length; i++) {
- if(video_info[i]['player']){
- var replace_location = video_info[i]['player'];
- var player = vwofPlayer.create_video_selector(video_info[i], cw);
- var replace_parent = replace_location.parentNode;
- replace_parent.replaceChild(player, replace_location);
- }
- }
- }
-};
-
-
-/**
- Listeners
-
- initialize the application on startup
-*/
-window.addEventListener("load", function() { vwofChrome.BrowserOverlay.startup(); }, false);
-
-/**
- Listener that observe the prefs variables
-
- If the module list changes (new module, module deactivated/activated), the parser list is reloaded
-*/
-var myPrefObserver = {
- register: function() {
- // load preference service
- var prefService = Components.classes["@mozilla.org/preferences-service;1"]
- .getService(Components.interfaces.nsIPrefService);
- this.branch = prefService.getBranch("extensions.vwof.");
- this.branch.addObserver("", this, false);
- },
-
- unregister: function() {
- this.branch.removeObserver("", this);
- },
-
- observe: function(aSubject, aTopic, aData) {
- switch (aData) {
- case "modules":
- vwofChrome.BrowserOverlay.set_parsers_activation();
- break;
- }
- }
-}
-myPrefObserver.register();
diff --git a/chrome/content/browserOverlay.xul b/chrome/content/browserOverlay.xul
deleted file mode 100755
index cbaeea7..0000000
--- a/chrome/content/browserOverlay.xul
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0"?>
-<?xml-stylesheet href="chrome://vwof/skin/toolbar-button.css" type="text/css"?>
-
-<overlay id="vwof-browser-overlay" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
- <script type="application/x-javascript" src="chrome://vwof/content/browserOverlay.js" />
- <script type="application/x-javascript" src="chrome://vwof/content/utils.js" />
- <script type="application/x-javascript" src="chrome://vwof/content/youtube_utils.js" />
- <script type="application/x-javascript" src="chrome://vwof/content/player.js" />
- <script type="application/x-javascript" src="chrome://vwof/content/onload.js" />
-
- <script type="application/x-javascript">
- function oncommand_detectvideo(){
- var cw = getBrowser().contentWindow;
- vwofChrome.BrowserOverlay.detectVideo(cw);
- }
-
- function vwof_toggle(event){
- var c = event.target.hasAttribute('checked')?1:0;
- var prefManager = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
- prefManager.setBoolPref("extensions.vwof.activate_onload", c);
- }
-
- </script>
-
- <keyset>
- <key id="vwof-key-detect-video" modifiers="alt" key="w" oncommand="oncommand_detectvideo();"/>
- </keyset>
-
- <popup id="contentAreaContextMenu">
- <menuitem id="vwof-detect-video" key="vwof-key-detect-video" label="Watch video without flash" oncommand="oncommand_detectvideo();"/>
- </popup>
-
- <toolbarpalette id="BrowserToolbarPalette">
- <toolbarbutton id="vwof-button" class="vwof-button" tooltiptext="Video WithOut Flash" oncommand="vwof_toggle(event);" type="checkbox"></toolbarbutton>
- </toolbarpalette>
-</overlay>
diff --git a/chrome/content/onload.js b/chrome/content/onload.js
deleted file mode 100755
index 8d4672e..0000000
--- a/chrome/content/onload.js
+++ /dev/null
@@ -1,18 +0,0 @@
-function pageLoad(event) {
- var prefManager = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
- var activate_onload = prefManager.getBoolPref("extensions.vwof.activate_onload");
-
- if (activate_onload
- && event.originalTarget instanceof HTMLDocument
- ){
- var cw = event.originalTarget.defaultView;
- vwofChrome.BrowserOverlay.detectVideo(cw);
- }
-}
-
-window.addEventListener("DOMContentLoaded", function () {
- gBrowser.addEventListener("load", pageLoad, true);
-}, false);
-
-// When no longer needed
-gBrowser.removeEventListener("load", pageLoad, true);
diff --git a/chrome/content/prefs.xul b/chrome/content/prefs.xul
deleted file mode 100755
index 05fe9a4..0000000
--- a/chrome/content/prefs.xul
+++ /dev/null
@@ -1,62 +0,0 @@
-<?xml version="1.0"?>
-<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
-<prefwindow id="vwofPrefWindow" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
- <prefpane id="vwof_pref_general" label="General">
-
- <preferences>
- <preference id="extensions.vwof.activate_onload" name="extensions.vwof.activate_onload" type="bool"/>
- <preference id="plugins.notifyMissingFlash" name="plugins.notifyMissingFlash" type="bool"/>
- <preference id="full-screen-api.approval-required" name="full-screen-api.approval-required" type="bool"/>
- </preferences>
-
- <checkbox label="Activate on page load" preference="extensions.vwof.activate_onload"/>
- <checkbox label="Enable missing flash plugin warnings" preference="plugins.notifyMissingFlash"/>
- <checkbox label="Enable approval message when fullscreen" preference="full-screen-api.approval-required"/>
-
- </prefpane>
-
- <prefpane id="vwof_pref_prefered_format" label="Prefered format">
- <preferences>
- <preference id="extensions.vwof.prefered_quality" name="extensions.vwof.prefered_quality" type="string" />
- <preference id="extensions.vwof.prefered_format" name="extensions.vwof.prefered_format" type="string" />
- </preferences>
-
- <label value="Prefered format" control="prefered_format" />
- <menulist id="prefered_format" preference="extensions.vwof.prefered_format" preference-editable="true">
- <menupopup>
- <menuitem label="webm" value="webm"/>
- <menuitem label="mp4" value="mp4"/>
- <menuitem label="avi" value="avi"/>
- <menuitem label="flv" value="flv"/>
- </menupopup>
- </menulist>
-
- <label value="Prefered quality" control="prefered_quality" />
- <menulist id="prefered_quality" preference="extensions.vwof.prefered_quality" preference-editable="true">
- <menupopup>
- <menuitem label="hd1080" value="hd1080"/>
- <menuitem label="hd720" value="hd720"/>
- <menuitem label="medium" value="medium"/>
- <menuitem label="low" value="low"/>
- </menupopup>
- </menulist>
-
- </prefpane>
-
- <prefpane id="vwof_pref_modules" label="modules">
- <script type="application/x-javascript" src="chrome://vwof/content/browserOverlay.js" />
- <script type="application/x-javascript" src="chrome://vwof/content/youtube_utils.js" />
-
- <preferences>
- <preference id="extensions.vwof.modules" name="extensions.vwof.modules" type="string"/>
- </preferences>
-
- <checkbox id="vwof_yt_wide" label="YouTube theater mode" oncommand="vwofChrome.youtubeUtils.toggle_yt_wide(event)"/>
- <!--button label="Reload modules" oncommand="vwofChrome.BrowserOverlay.reload_modules()"/-->
- </prefpane>
-
- <script src="youtube_utils.js"/>
- <script src="list_modules.js"/>
-
-</prefwindow>
-
diff --git a/chrome/content/list_modules.js b/chrome/list_modules.js
old mode 100755
new mode 100644
similarity index 91%
copy from chrome/content/list_modules.js
copy to chrome/list_modules.js
index 89c55aa..9bda604
--- a/chrome/content/list_modules.js
+++ b/chrome/list_modules.js
@@ -1,5 +1,5 @@
var checkbox_wide = document.getElementById("vwof_yt_wide");
-var wide = vwofChrome.youtubeUtils.yt_is_wide();
+var wide = youtubeUtils.yt_is_wide();
checkbox_wide.setAttribute("checked", wide);
var prefPane = document.getElementById('vwof_pref_modules');
@@ -21,10 +21,10 @@ element_columns.appendChild(element_column_embed);
element_grid.appendChild(element_columns);
element_grid.appendChild(element_rows);
-for(var i=0;i<vwofChrome.BrowserOverlay.parser_name.length;i++){
+for(var i=0;i<vwof.parser_name.length;i++){
var element_row = document.createElement('row');
- let key_module = vwofChrome.BrowserOverlay.parser_name[i];
+ let key_module = vwof.parser_name[i];
var element_label_key = document.createElement('label');
element_label_key.setAttribute('value', key_module);
@@ -53,3 +53,4 @@ function update_module(event){
prefManager.setCharPref("extensions.vwof.modules", s_modules);
}
+
diff --git a/chrome/listener.js b/chrome/listener.js
new file mode 100644
index 0000000..fbb98d5
--- /dev/null
+++ b/chrome/listener.js
@@ -0,0 +1,156 @@
+var windowListener = {
+ ignoreFrames:true,
+ onOpenWindow: function (aXULWindow) {
+ let aDOMWindow = aXULWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowInternal || Ci.nsIDOMWindow);
+ aDOMWindow.addEventListener("load", function () {
+ aDOMWindow.removeEventListener("load", arguments.callee, false);
+ windowListener.loadIntoWindow(aDOMWindow, aXULWindow);
+ }, false);
+ },
+ register: function () {
+ let XULWindows = Services.wm.getXULWindowEnumerator(null);
+ while (XULWindows.hasMoreElements()) {
+ let aXULWindow = XULWindows.getNext();
+ let aDOMWindow = aXULWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowInternal || Ci.nsIDOMWindow);
+ windowListener.loadIntoWindow(aDOMWindow, aXULWindow);
+ }
+ // Listen to new windows
+ Services.wm.addListener(windowListener);
+ },
+ unregister: function () {
+ // Unload from any existing windows
+ let XULWindows = Services.wm.getXULWindowEnumerator(null);
+ while (XULWindows.hasMoreElements()) {
+ let aXULWindow = XULWindows.getNext();
+ let aDOMWindow = aXULWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowInternal || Ci.nsIDOMWindow);
+ windowListener.unloadFromWindow(aDOMWindow, aXULWindow);
+ }
+ //Stop listening so future added windows dont get this attached
+ Services.wm.removeListener(windowListener);
+ },
+ loadIntoWindow: function (aDOMWindow, aXULWindow) {
+ if (!aDOMWindow) {
+ return;
+ }
+ if (aDOMWindow.gBrowser) {
+ aDOMWindow.gBrowser.addEventListener('DOMContentLoaded', listenPageLoad, false);
+ if (aDOMWindow.gBrowser.tabContainer) {
+ //start - go through all tabs in this window we just added to
+ var tabs = aDOMWindow.gBrowser.tabContainer.childNodes;
+ for (var i = 0; i < tabs.length; i++) {
+ var tabBrowser = tabs[i].linkedBrowser;
+ var win = tabBrowser.contentWindow;
+ loadIntoContentWindowAndItsFrames(win);
+ }
+ //end - go through all tabs in this window we just added to
+ } else {
+ //does not have tabContainer
+ var win = aDOMWindow.gBrowser.contentWindow;
+ loadIntoContentWindowAndItsFrames(win);
+ }
+ }
+ },
+ unloadFromWindow: function (aDOMWindow, aXULWindow) {
+ if (!aDOMWindow) {
+ return;
+ }
+ if (aDOMWindow.gBrowser) {
+ aDOMWindow.gBrowser.removeEventListener('DOMContentLoaded', listenPageLoad, false);
+ if (aDOMWindow.gBrowser.tabContainer) {
+ //has tabContainer
+ //start - go through all tabs in this window we just added to
+ var tabs = aDOMWindow.gBrowser.tabContainer.childNodes;
+ for (var i = 0; i < tabs.length; i++) {
+ Cu.reportError('DOING tab: ' + i);
+ var tabBrowser = tabs[i].linkedBrowser;
+ var win = tabBrowser.contentWindow;
+ unloadFromContentWindowAndItsFrames(win);
+ }
+ //end - go through all tabs in this window we just added to
+ } else {
+ //does not have tabContainer
+ var win = aDOMWindow.gBrowser.contentWindow;
+ unloadFromContentWindowAndItsFrames(win);
+ }
+ } else {
+ //window does not have gBrowser
+ }
+ }
+};
+/*end - windowlistener*/
+
+function loadIntoContentWindowAndItsFrames(theWin) {
+ var frames = theWin.frames;
+ var winArr = [theWin];
+ for (var j = 0; j < frames.length; j++) {
+ winArr.push(frames[j].window);
+ }
+ Cu.reportError('# of frames in tab: ' + frames.length);
+ for (var j = 0; j < winArr.length; j++) {
+ if (j == 0) {
+ Cu.reportError('**checking win: ' + j + ' location = ' + winArr[j].document.location);
+ } else {
+ Cu.reportError('**checking frame win: ' + j + ' location = ' + winArr[j].document.location);
+ }
+ var doc = winArr[j].document;
+ //START - edit below here
+
+ if (this.ignoreFrames) {
+ break;
+ }
+ //END - edit above here
+ }
+}
+
+function unloadFromContentWindowAndItsFrames(theWin) {
+ var frames = theWin.frames;
+ var winArr = [theWin];
+ for (var j = 0; j < frames.length; j++) {
+ winArr.push(frames[j].window);
+ }
+ Cu.reportError('# of frames in tab: ' + frames.length);
+ for (var j = 0; j < winArr.length; j++) {
+ if (j == 0) {
+ Cu.reportError('**checking win: ' + j + ' location = ' + winArr[j].document.location);
+ } else {
+ Cu.reportError('**checking frame win: ' + j + ' location = ' + winArr[j].document.location);
+ }
+ var doc = winArr[j].document;
+ //START - edit below here
+ if (this.ignoreFrames) {
+ break;
+ }
+ //END - edit above here
+ }
+}
+
+/**
+ Listener that observe the prefs variables
+
+ If the module list changes (new module, module deactivated/activated), the parser list is reloaded
+*/
+var PrefObserver = {
+ register: function() {
+ // First we'll need the preference services to look for preferences.
+ var prefService = Components.classes["@mozilla.org/preferences-service;1"]
+ .getService(Components.interfaces.nsIPrefService);
+
+ // For this.branch we ask for the preferences
+ this.branch = prefService.getBranch("extensions.vwof.");
+
+ // Finally add the observer.
+ this.branch.addObserver("", this, false);
+ },
+
+ unregister: function() {
+ this.branch.removeObserver("", this);
+ },
+
+ observe: function(aSubject, aTopic, aData) {
+ switch (aData) {
+ case "modules":
+ vwof.set_parsers_activation();
+ break;
+ }
+ }
+}
diff --git a/chrome/locale/en-US/browserOverlay.dtd b/chrome/locale/en-US/browserOverlay.dtd
deleted file mode 100755
index 9b759db..0000000
--- a/chrome/locale/en-US/browserOverlay.dtd
+++ /dev/null
@@ -1,3 +0,0 @@
-<!ENTITY vwof.open.label "Open Video WithOut Flash">
-<!ENTITY vwof.openMenu.accesskey "O">
-<!ENTITY vwof.openItem.accesskey "V">
diff --git a/modules/FC2.jsm b/chrome/modules/FC2.jsm
old mode 100755
new mode 100644
similarity index 91%
copy from modules/FC2.jsm
copy to chrome/modules/FC2.jsm
index 1018e14..cc218b5
--- a/modules/FC2.jsm
+++ b/chrome/modules/FC2.jsm
@@ -20,7 +20,7 @@ var parser = {
//get MD5 from video id and salt
var id_salt = id+this.SALT;
- var md5sum = vwofChrome.utils.md5(id_salt);
+ var md5sum = utils.md5(id_salt);
//get gk (signature generated by JS)
var gk = [];
@@ -38,9 +38,9 @@ var parser = {
api_video_uri = api_video_uri.replace('MIMI', md5sum);
api_video_uri = api_video_uri.replace('GK', gk.join(''));
- var data = vwofChrome.utils.get(api_video_uri).responseText;
+ var data = utils.get(api_video_uri);
//extract the video url (filepath) from the data
- var assoc_data = vwofChrome.utils.url_vars_to_array(data);
+ var assoc_data = utils.url_vars_to_array(data);
var filepath = assoc_data['filepath'];
if(!filepath)return;
diff --git a/modules/HTML5.jsm b/chrome/modules/HTML5.jsm
old mode 100755
new mode 100644
similarity index 100%
copy from modules/HTML5.jsm
copy to chrome/modules/HTML5.jsm
diff --git a/chrome/modules/Makefile.in b/chrome/modules/Makefile.in
new file mode 100644
index 0000000..23f8111
--- /dev/null
+++ b/chrome/modules/Makefile.in
@@ -0,0 +1,2 @@
+# The sources for the module files.
+modules_sources := $(wildcard $(modules_dir)/*.jsm)
diff --git a/chrome/modules/SWM.jsm b/chrome/modules/SWM.jsm
new file mode 100644
index 0000000..9b23f80
--- /dev/null
+++ b/chrome/modules/SWM.jsm
@@ -0,0 +1,105 @@
+/**
+ScreenWaveMedia module
+
+The only site where I go that uses this media provider is cinemassacre.com
+
+The video are all in RMTP format and there is only one format for each video
+
+Since it is all RMTP, the link is open in a vlc instance outside of firefox, but it's no big deal as long
+as the video can be played.
+
+There are two html layout, the "old" layout (http://cinemassacre.com/2013/07/01/avgn-bill-teds-excellent-adventure/)
+
+<div id="SWMPlayer_25823" class="SWMPlayer" style="width:640px;height:320px;">Loading Video...</div>
+<script type="text/javascript" src="http://player.screenwavemedia.com/play/jwplayer/jwplayer.js"></script>
+<script type="text/javascript" src="http://player.screenwavemedia.com/play/embed.php?id=25823"></script> <-- video data are here
+
+and the "new" layout since september 2013 (http://cinemassacre.com/2013/09/06/avgn-tiger-electronic/)
+
+<iframe src="http://player.screenwavemedia.com/play/player.php?id=Cinemassacre-52273484b87b2" frameborder="0" height="540" width="960">
+<html> ...
+
+ <div id="SWMPlayer" class="SWMPlayer">Loading Video...</div>
+ <script>
+ ...
+ jwplayer('SWMPlayer').setup({
+ 'id': 'videoPlayer',
+ 'width': '100%', 'height': '100%',
+ 'provider': 'rtmp',
+ 'streamer': 'rtmp://174.127.86.16/Cinemassacre',
+ 'flashplayer': 'http://player.screenwavemedia.com/play/jwplayer/player.swf',
+ 'file': 'Cinemassacre-52273484b87b2_high.mp4',
+ 'image': 'http://image.screenwavemedia.com/Cinemassacre-52273484b87b2_thumb_640x360.jpg', 'stretching': 'uniform',
+ </script>
+</body></html>
+</iframe>
+
+
+For both layout, the video data are in the same format, only the way to get the script content differ
+*/
+
+var parser = {
+ parse_embed: function(cw) {
+ const REGEX_IMG = /'image': '(.*\.jpg)'/;
+ var video_info = []; //player DOM element, preview image and array of videos
+
+ //for the "old" layout, outside of a frame, script tag with src
+ const XPATH_PLAYER = "//div[starts-with(@id, 'SWMPlayer')]";
+ const XPATH_SCRIPT = "//script[starts-with(@src, 'http://player.screenwavemedia.com/play/embed.php')]";
+
+ var xp_res_player = cw.document.evaluate(XPATH_PLAYER, cw.document, null, cw.XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
+ var xp_res_script = cw.document.evaluate(XPATH_SCRIPT, cw.document, null, cw.XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
+
+ while (player = xp_res_player.iterateNext()) {
+ var script = xp_res_script.iterateNext();
+ var script_content = utils.get(script.src);
+
+ var video_img = script_content.match(REGEX_IMG)[1];
+ var videos = this.parse_data(script_content); //get format, type and uri of videos
+
+ video_info.push({
+ 'player':player,
+ 'video_img':video_img,
+ 'videos': videos
+ });
+ }
+
+ //for the "new" layout, inside a frame, simple script markup
+ const XPATH_PLAYER_FRAME = "//iframe[starts-with(@src, 'http://player.screenwavemedia.com/play/player.php')]";
+ var xp_res_player_frame = cw.document.evaluate(XPATH_PLAYER_FRAME, cw.document, null, cw.XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
+
+ while (player = xp_res_player_frame.iterateNext()) {
+ var script_content = player.contentDocument.body.innerHTML;
+
+ var video_img_match = script_content.match(REGEX_IMG);
+ if(video_img_match)video_img = video_img_match[1];
+ else video_img = undefined;
+
+ var videos = this.parse_data(script_content); //get format, type and uri of videos
+
+ video_info.push({
+ 'player':player,
+ 'video_img':video_img,
+ 'videos': videos
+ });
+ }
+
+ return video_info;
+ },
+
+ /**
+ the video data are written in a script markup
+ */
+ parse_data: function(data){
+ const REGEX_STREAMER = /'streamer': '(.*)'/;
+ const REGEX_FILE = /'file': '(.*)'/;
+
+ var streamer = data.match(REGEX_STREAMER)[1];
+ var file = data.match(REGEX_FILE)[1];
+ var video_uri = streamer + '/' + file;
+
+ //only one element in the array for this module
+ var videos = [ {'quality':'medium', 'format':'rtmp', 'url':video_uri} ];
+ return videos;
+ }
+};
diff --git a/chrome/modules/ScreenWaveMedia.jsm b/chrome/modules/ScreenWaveMedia.jsm
new file mode 100644
index 0000000..71d935a
--- /dev/null
+++ b/chrome/modules/ScreenWaveMedia.jsm
@@ -0,0 +1,57 @@
+var parser = {
+ parse_embed: function(cw) {
+ var player;
+ var videos = [];
+ var video_info = [];
+ const doc = cw.document;
+ const REGEX_ID = /id=(.+)/;
+ const URL_VIDEO = 'http://video2.screenwavemedia.com/vod/VIDEO_ID_QUALITY.mp4';
+ const URL_IMAGE = 'http://image.screenwavemedia.com/VIDEO_ID_thumb_640x360.jpg';
+ const video_quality = ['audio', 'low', 'med', 'high', 'hd1'];
+ const URL_PLAYER_FRAME = 'http://player.screenwavemedia.com/play/player.php';
+ const XPATH_PLAYER_FRAME = "//iframe[starts-with(@src, '"+URL_PLAYER_FRAME+"')]"
+ const URL_PLAYER_SCRIPT = 'http://player.screenwavemedia.com/play/play.php';
+ const XPATH_PLAYER_SCRIPT = "//script[starts-with(@src, '"+URL_PLAYER_SCRIPT+"')]";
+
+ var xp_res_player_frame = doc.evaluate(XPATH_PLAYER_FRAME, doc, null,
+ cw.XPathResult.FIRST_ORDERED_NODE_TYPE,
+ null);
+
+ var node = xp_res_player_frame.singleNodeValue;
+
+ if(node){
+ player = node;
+ }
+ else{
+ var xp_res_player_script = doc.evaluate(XPATH_PLAYER_SCRIPT, doc, null,
+ cw.XPathResult.FIRST_ORDERED_NODE_TYPE,
+ null);
+
+ node = xp_res_player_script.singleNodeValue;
+ if(!node)return;
+
+ player = doc.getElementById('videoarea');
+ player.id = "swmvwof_player";
+ }
+
+ if(!node)return;
+
+ var video_id = node.src.match(REGEX_ID)[1];
+
+ for (var i=0;i<video_quality.length;i++) {
+ var url = URL_VIDEO.replace('VIDEO_ID', video_id);
+ url = url.replace("QUALITY", video_quality[i]);
+ videos.push( {'quality': video_quality[i], 'format':'mp4', 'url':url} );
+ }
+
+ var video_img = URL_IMAGE.replace('VIDEO_ID', video_id);
+
+ video_info.push({
+ 'player': player,
+ 'video_img':video_img,
+ 'videos': videos
+ });
+
+ return video_info;
+ }
+};
diff --git a/chrome/modules/blip.jsm b/chrome/modules/blip.jsm
new file mode 100644
index 0000000..b776df9
--- /dev/null
+++ b/chrome/modules/blip.jsm
@@ -0,0 +1,118 @@
+var parser = {
+ BASE_URI: 'blip.tv',
+ URL_PARAM_JSON: '?skin=json&no_wrap=1',
+
+ parse_embed: function(cw) {
+ const doc = cw.document;
+ const XPATH_PLAYER = "//iframe[starts-with(@src, 'http://blip.tv/play')]";
+ var video_info = [];
+ var player;
+ var video_img;
+
+ var xp_res_player = doc.evaluate(XPATH_PLAYER, doc,
+ null, cw.XPathResult.ORDERED_NODE_ITERATOR_TYPE,
+ null );
+
+ try{
+ while (player = xp_res_player.iterateNext()) {
+ var videos = [];
+ var encoded_file;
+ var player_doc = utils.get(player.src);
+
+ if((encoded_file = player_doc.match(/"file":"(.+?)",/)) !== null){
+ var file = decodeURIComponent(encoded_file[1]);
+ file = file.replace('rss/flash', 'posts/view');
+ var json_string = utils.get(file+this.URL_PARAM_JSON);
+ var parse_data = this.parse_json_data(json_string);
+ video_img = parse_data[0];
+ videos = parse_data[1];
+ }
+ else{
+ const URL_BASE = 'http://blip.tv/file/get/';
+
+ const REGEX_VIDEO_URI_HD = 'bliphd720 : "(.*)"';
+ const REGEX_VIDEO_URI_SD = 'blipsd : "(.*)"';
+ const REGEX_VIDEO_URI_LD = 'blipld : "(.*)"';
+ const REGEX_VIDEO_IMG = 'config\.video\.thumbnail = "(.*)"';
+
+ var video_uri_hd = player_doc.match(REGEX_VIDEO_URI_HD);
+ var video_uri_sd = player_doc.match(REGEX_VIDEO_URI_SD);
+ var video_uri_ld = player_doc.match(REGEX_VIDEO_URI_LD);
+ var video_uri_img = player_doc.match(REGEX_VIDEO_IMG);
+
+ if(video_uri_hd[1] != ""){
+ videos.push({'quality':'hd720' , 'url':URL_BASE+video_uri_hd[1]});
+ }
+ if(video_uri_sd[1] != ""){
+ videos.push({'quality':'medium', 'url':URL_BASE+video_uri_sd[1]});
+ }
+ if(video_uri_ld[1] != ""){
+ videos.push({'quality':'low' , 'url':URL_BASE+video_uri_ld[1]});
+ }
+
+ if(video_uri_img){
+ video_img = 'http:'+video_uri_img[1];
+ video_img = video_img.replace('THUMB_WIDTH', player.width);
+ video_img = video_img.replace('THUMB_HEIGHT', player.height);
+ }
+ }
+
+ video_info.push({
+ 'player': player,
+ 'video_img':video_img,
+ 'videos': videos
+ });
+ }
+ }
+ finally{
+ //in case iterateNext() throw invalidStateException
+ //because of a DOM alteration, return what was fetched
+ return video_info;
+ }
+
+ return video_info;
+ },
+
+ parse_site: function(cw) {
+ var doc = cw.document;
+ var video_info = [];
+ var player = doc.getElementById('PlayeriFrame');
+ if(!player)return;
+
+ var json_string = utils.get(doc.URL+this.URL_PARAM_JSON);
+ var parse_data = this.parse_json_data(json_string);
+ var video_img = parse_data[0];
+ var videos = parse_data[1];
+
+ video_info.push({
+ 'player': player,
+ 'video_img': video_img,
+ 'videos': videos
+ });
+
+ return video_info;
+ },
+
+ parse_json_data: function(json_string){
+ var post = JSON.parse(json_string).Post;
+
+ var videos = [];
+ for(var i=0;i<post.additionalMedia.length;i++){
+ var format = post.additionalMedia[i].primary_mime_type;
+ if(format == 'text/plain')continue;
+
+ //remove video part of the mime type for a prettier display
+ format=format.replace('video/', '');
+
+ videos.push({'format': format,
+ 'quality': post.additionalMedia[i].media_width + '/' +
+ post.additionalMedia[i].media_height,
+ 'url':post.additionalMedia[i].url}
+ );
+ }
+
+ var video_img = post.thumbnailUrl;
+
+ return [video_img, videos];
+ }
+};
diff --git a/modules/dailymotion.jsm b/chrome/modules/dailymotion.jsm
old mode 100755
new mode 100644
similarity index 100%
copy from modules/dailymotion.jsm
copy to chrome/modules/dailymotion.jsm
diff --git a/chrome/modules/dew.jsm b/chrome/modules/dew.jsm
new file mode 100644
index 0000000..b09ea55
--- /dev/null
+++ b/chrome/modules/dew.jsm
@@ -0,0 +1,20 @@
+var parser = {
+ parse_embed: function(cw) {
+ const XPATH_PLAYER = "//embed[contains(@src, 'dewplayer')]";
+ const REGEX_SOURCE = /[&\?]?son=([^&?]+)/;
+ var video_info = [];
+ var xp_res_player = cw.document.evaluate(XPATH_PLAYER, cw.document, null, cw.XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
+
+ while (player = xp_res_player.iterateNext()) {
+ var video_uri = player.src.match(REGEX_SOURCE)[1];
+
+ if(!video_uri)continue;
+ video_info.push({
+ 'player':player,
+ 'videos': [ {'quality':'medium', 'url':video_uri} ]
+ });
+ }
+
+ return video_info;
+ }
+};
diff --git a/modules/niconico.jsm b/chrome/modules/niconico.jsm
old mode 100755
new mode 100644
similarity index 92%
copy from modules/niconico.jsm
copy to chrome/modules/niconico.jsm
index 61bb763..5e3eb8b
--- a/modules/niconico.jsm
+++ b/chrome/modules/niconico.jsm
@@ -33,8 +33,8 @@ var parser = {
////get the video link from the flapi
const video_id = json_data.flashvars.videoId;
const flapi_url = 'http://flapi.nicovideo.jp/api/getflv?v='+video_id;
- const data = vwofChrome.utils.get(flapi_url).responseText;
- const assoc_data = vwofChrome.utils.url_vars_to_array(data);
+ const data = utils.get(flapi_url);
+ const assoc_data = utils.url_vars_to_array(data);
const url = decodeURIComponent(assoc_data['url']);
var videos = [ {
diff --git a/chrome/modules/springboard.jsm b/chrome/modules/springboard.jsm
new file mode 100644
index 0000000..f881418
--- /dev/null
+++ b/chrome/modules/springboard.jsm
@@ -0,0 +1,25 @@
+var parser = {
+ parse_embed: function(cw) {
+ const XPATH_PLAYER = "//iframe[starts-with(@src, 'http://cms.springboardplatform.com/embed_iframe')]";
+ const XPATH_VIDEO_URI = '/html/head/meta[@property="og:video"]/@content';
+ const XPATH_VIDEO_IMG = '/html/head/meta[@property="og:image"]/@content';
+ var video_info = [];
+ var xp_res_player = cw.document.evaluate(XPATH_PLAYER, cw.document, null, cw.XPathResult.UNORDERED_NODE_ITERATOR_TYPE, null);
+
+ while (player = xp_res_player.iterateNext()) {
+ var player_doc = player.contentDocument;
+
+ var video_uri = player_doc.evaluate(XPATH_VIDEO_URI, player_doc, null, cw.XPathResult.STRING_TYPE, null).stringValue;
+ var video_img = player_doc.evaluate(XPATH_VIDEO_IMG, player_doc, null, cw.XPathResult.STRING_TYPE, null).stringValue;
+
+ if(!video_uri)continue;
+
+ video_info.push({
+ 'player':player,
+ 'video_img':video_img,
+ 'videos': [ {'quality':'medium', 'url':video_uri} ]
+ });
+ }
+ return video_info;
+ }
+};
diff --git a/chrome/modules/twitch.jsm b/chrome/modules/twitch.jsm
new file mode 100644
index 0000000..b0277d6
--- /dev/null
+++ b/chrome/modules/twitch.jsm
@@ -0,0 +1,39 @@
+var parser = {
+ BASE_URI : 'www.twitch.tv',
+ API_GET_VIDEO:'http://usher.twitch.tv/select/CHANNEL.json?allow_source=true&nauthsig=SIG&nauth=TOKEN&type=any',
+ API_GET_TOKEN:'http://api.twitch.tv/api/channels/CHANNEL/access_token',
+
+ parse_site:function(cw) {
+ const REGEX_CHANNEL = /twitch.tv\/(\w+)/;
+ var doc = cw.document;
+ var video_info = [];
+ var channel;
+
+ //get the channel name
+ if(url_match = doc.URL.match(REGEX_CHANNEL)){
+ channel = url_match[1];
+ }
+ else{
+ throw('cannot retreive channel name of a '+this.BASE_URI+' video on '+doc.URL);
+ }
+
+ //get sig and token
+ var api_token_uri = this.API_GET_TOKEN.replace('CHANNEL', channel);
+ var str_token = vwofChrome.utils.get(api_token_uri);
+ var json_token = JSON.parse(str_token);
+
+ var sig = json_token['sig'];
+ var token = json_token['token'];
+ //token = token.replace(/"/g, '\\"');
+ token = encodeURIComponent(token);
+
+ //get video info with sig and token values
+ var api_video_uri = this.API_GET_VIDEO.replace('CHANNEL', channel);
+ api_video_uri = api_video_uri.replace('SIG', sig);
+ api_video_uri = api_video_uri.replace('TOKEN', token);
+
+ var str_video = vwofChrome.utils.get(api_video_uri);
+ alert(str_video);
+ return video_info;
+ }
+};
diff --git a/chrome/modules/ustream.jsm b/chrome/modules/ustream.jsm
new file mode 100644
index 0000000..a43b93c
--- /dev/null
+++ b/chrome/modules/ustream.jsm
@@ -0,0 +1,48 @@
+/**
+ ustream parser
+ inspired from https://github.com/piscui/ustream-to-ffmpeg
+*/
+
+var parser = {
+ BASE_URI:'www.ustream.tv',
+
+ parse_site : function(cw){
+ const XPATH_CHANNEL_ID = '/html/head/meta[@name="ustream:channel_id"]/@content';
+ const XPATH_VIDEO_IMG = '/html/head/meta[@property="og:image"]/@content';
+ const URL_AMF = 'http://cgw.ustream.tv/Viewer/getStream/1/CHANNEL_ID.amf';
+
+ var video_info = [];
+
+ var channel_id = cw.document.evaluate(XPATH_CHANNEL_ID, cw.document, null, cw.XPathResult.STRING_TYPE, null).stringValue;
+ var video_img = cw.document.evaluate(XPATH_VIDEO_IMG, cw.document, null, cw.XPathResult.STRING_TYPE, null).stringValue;
+ var video_uri = URL_AMF.replace('CHANNEL_ID', channel_id);
+
+ var data = utils.get(video_uri);
+ var videos = this.parse_data(data);
+
+ var player = cw.document.getElementsByClassName("player")[0];
+
+ video_info.push({
+ 'player':player,
+ 'video_img':video_img,
+ 'videos': videos
+ });
+
+
+ return video_info;
+ },
+
+ parse_data : function(data){
+ //const REGEX_CDNURL = /cdnUrl\W\W\S(.+?)\x00/;
+ const REGEX_LIVEHTTP = /liveHttpUrl\W\W\S(.+?)\x00/;
+
+ //var url_rtmp = data.match(REGEX_CDNURL)[1];
+ var url_http = data.match(REGEX_LIVEHTTP)[1];
+
+ var videos = [];
+ //videos.push({'format': 'rtmp', 'url': url_rtmp });
+ videos.push({'format': 'm3u8', 'url': url_http });
+
+ return videos;
+ }
+};
diff --git a/modules/youtube.jsm b/chrome/modules/youtube.jsm
old mode 100755
new mode 100644
similarity index 90%
copy from modules/youtube.jsm
copy to chrome/modules/youtube.jsm
index ad7910b..c521f21
--- a/modules/youtube.jsm
+++ b/chrome/modules/youtube.jsm
@@ -22,7 +22,7 @@ var parser = {
var player_api = doc.getElementById('player-api');
if(player_api){
player_api.setAttribute('id', 'vwof_player-api'); //prevent the player-api div to be erased by the missing plugin tv-static message
- if(vwofChrome.youtubeUtils.yt_is_wide()){
+ if(youtubeUtils.yt_is_wide()){
player_api.setAttribute("style", "margin:auto;"); //center the player
}
}
@@ -39,7 +39,7 @@ var parser = {
player_api.appendChild(player);
var api_video_uri = this.API_GET_VIDEO.replace('VIDEO_ID', id);
- var data = vwofChrome.utils.get(api_video_uri).responseText;
+ var data = utils.get(api_video_uri);
var video_data = this.parse_data(data);
video_data['player'] = player;
@@ -67,7 +67,7 @@ var parser = {
var id = player.src.match(REGEX_VIDEO_ID_IFRAME)[1];
var api_video_uri = this.API_GET_VIDEO.replace('VIDEO_ID', id);
- var data = vwofChrome.utils.get(api_video_uri).responseText;
+ var data = utils.get(api_video_uri);
var parsed_array = this.parse_data(data);
parsed_array['player'] = player;
@@ -84,7 +84,7 @@ var parser = {
*/
parse_data: function(data){
var videos = [];
- var assoc_data = vwofChrome.utils.url_vars_to_array(data);
+ var assoc_data = utils.url_vars_to_array(data);
var url_encoded_fmt_stream_map = assoc_data['url_encoded_fmt_stream_map'];
var url_decoded_fmt_stream_map = decodeURIComponent(url_encoded_fmt_stream_map);
@@ -92,7 +92,7 @@ var parser = {
var i;
for(i=0;i<arr_url_decoded_fmt_stream_map.length;i++){
- var assoc_url_decoded_fmt_stream = vwofChrome.utils.url_vars_to_array(arr_url_decoded_fmt_stream_map[i]);
+ var assoc_url_decoded_fmt_stream = utils.url_vars_to_array(arr_url_decoded_fmt_stream_map[i]);
var encoded_uri = assoc_url_decoded_fmt_stream['url'];
var decoded_uri = decodeURIComponent(encoded_uri);
decoded_uri += '&signature='+assoc_url_decoded_fmt_stream['sig']; //add the signature to the decoded url
diff --git a/chrome/content/player.js b/chrome/player.js
old mode 100755
new mode 100644
similarity index 98%
copy from chrome/content/player.js
copy to chrome/player.js
index 80e2958..809768b
--- a/chrome/content/player.js
+++ b/chrome/player.js
@@ -1,7 +1,3 @@
-if ("undefined" == typeof(vwofPlayer)) {
- var vwofPlayer = {};
-};
-
vwofPlayer = {
/**
add the player stylecheet link to the head of the document
@@ -10,7 +6,7 @@ vwofPlayer = {
var style = doc.createElement('link');
style.setAttribute('type', 'text/css');
style.setAttribute('rel', 'stylesheet');
- style.setAttribute('href', 'chrome://vwof/content/player.css');
+ style.setAttribute('href', 'chrome://vwof/skin/player.css');
style.setAttribute('id', style_id);
doc.head.appendChild(style);
},
diff --git a/chrome/prefs.js b/chrome/prefs.js
new file mode 100644
index 0000000..2764774
--- /dev/null
+++ b/chrome/prefs.js
@@ -0,0 +1,47 @@
+function getGenericPref(branch,prefName)
+{
+ switch (branch.getPrefType(prefName))
+ {
+ default:
+ case 0: return undefined; // PREF_INVALID
+ case 32: return getUCharPref(prefName,branch); // PREF_STRING
+ case 64: return branch.getIntPref(prefName); // PREF_INT
+ case 128: return branch.getBoolPref(prefName); // PREF_BOOL
+ }
+}
+
+function setGenericPref(branch,prefName,prefValue)
+{
+ switch (typeof prefValue)
+ {
+ case "string":
+ setUCharPref(prefName,prefValue,branch);
+ return;
+ case "number":
+ branch.setIntPref(prefName,prefValue);
+ return;
+ case "boolean":
+ branch.setBoolPref(prefName,prefValue);
+ return;
+ }
+}
+
+function setDefaultPref(prefBranch, prefName, prefValue)
+{
+ var defaultBranch = Services.prefs.getDefaultBranch(prefBranch);
+ setGenericPref(defaultBranch,prefName,prefValue);
+}
+
+function getUCharPref(prefName,branch) // Unicode getCharPref
+{
+ branch = branch ? branch : Services.prefs;
+ return branch.getComplexValue(prefName, Components.interfaces.nsISupportsString).data;
+}
+function setUCharPref(prefName,text,branch) // Unicode setCharPref
+{
+ var string = Components.classes["@mozilla.org/supports-string;1"]
+ .createInstance(Components.interfaces.nsISupportsString);
+ string.data = text;
+ branch = branch ? branch : Services.prefs;
+ branch.setComplexValue(prefName, Components.interfaces.nsISupportsString, string);
+}
diff --git a/chrome/prefs.xul b/chrome/prefs.xul
new file mode 100644
index 0000000..fcef025
--- /dev/null
+++ b/chrome/prefs.xul
@@ -0,0 +1,79 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
+<prefwindow id="vwofPrefWindow"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <prefpane id="vwof_pref_general" label="General">
+
+ <preferences>
+ <preference id="extensions.vwof.activate_onload"
+ name="extensions.vwof.activate_onload"
+ type="bool"/>
+ <preference id="plugins.notifyMissingFlash"
+ name="plugins.notifyMissingFlash"
+ type="bool"/>
+ <preference id="full-screen-api.approval-required"
+ name="full-screen-api.approval-required"
+ type="bool"/>
+ </preferences>
+
+ <checkbox label="Detect videos on page load"
+ preference="extensions.vwof.activate_onload"/>
+ <checkbox label="Enable missing flash plugin warnings"
+ preference="plugins.notifyMissingFlash"/>
+ <checkbox label="Enable approval message when fullscreen"
+ preference="full-screen-api.approval-required"/>
+
+ </prefpane>
+
+ <prefpane id="vwof_pref_prefered_format" label="Prefered format">
+ <preferences>
+ <preference id="extensions.vwof.prefered_quality"
+ name="extensions.vwof.prefered_quality"
+ type="string" />
+ <preference id="extensions.vwof.prefered_format"
+ name="extensions.vwof.prefered_format"
+ type="string" />
+ </preferences>
+
+ <label value="Prefered format" control="prefered_format" />
+ <menulist id="prefered_format" preference="extensions.vwof.prefered_format"
+ preference-editable="true">
+ <menupopup>
+ <menuitem label="webm" value="webm"/>
+ <menuitem label="mp4" value="mp4"/>
+ <menuitem label="avi" value="avi"/>
+ <menuitem label="flv" value="flv"/>
+ </menupopup>
+ </menulist>
+
+ <label value="Prefered quality" control="prefered_quality" />
+ <menulist id="prefered_quality" preference="extensions.vwof.prefered_quality"
+ preference-editable="true">
+ <menupopup>
+ <menuitem label="hd1080" value="hd1080"/>
+ <menuitem label="hd720" value="hd720"/>
+ <menuitem label="medium" value="medium"/>
+ <menuitem label="low" value="low"/>
+ </menupopup>
+ </menulist>
+
+ </prefpane>
+
+ <prefpane id="vwof_pref_modules" label="modules">
+ <script type="application/x-javascript" src="chrome://vwof/content/browserOverlay.js" />
+ <script type="application/x-javascript" src="chrome://vwof/content/youtube_utils.js" />
+
+ <preferences>
+ <preference id="extensions.vwof.modules" name="extensions.vwof.modules" type="string"/>
+ </preferences>
+
+ <checkbox id="vwof_yt_wide" label="YouTube theater mode"
+ oncommand="vwofChrome.youtubeUtils.toggle_yt_wide(event)"/>
+ </prefpane>
+
+ <script src="youtube_utils.js"/>
+ <script src="vwof.js"/>
+ <script src="list_modules.js"/>
+
+</prefwindow>
+
diff --git a/chrome/skin/toolbar-button.css b/chrome/skin/toolbar-button.css
deleted file mode 100755
index a475ebb..0000000
--- a/chrome/skin/toolbar-button.css
+++ /dev/null
@@ -1,14 +0,0 @@
-/* skin/toolbar-button.css */
-
-#vwof-button {
- list-style-image: url("chrome://vwof/skin/video-icon_24.png");
-}
-
-toolbar[iconsize="small"] #vwof-button {
- list-style-image: url("chrome://vwof/skin/video-icon_14.png");
-}
-
-#vwof-button:checked{
- background-color:#FF0000;
-}
-
diff --git a/chrome/skin/video-icon_14.png b/chrome/skin/video-icon_14.png
deleted file mode 100755
index d4150b6..0000000
Binary files a/chrome/skin/video-icon_14.png and /dev/null differ
diff --git a/chrome/skin/video-icon_24.png b/chrome/skin/video-icon_24.png
deleted file mode 100755
index bf273fa..0000000
Binary files a/chrome/skin/video-icon_24.png and /dev/null differ
diff --git a/chrome/content/utils.js b/chrome/utils.js
old mode 100755
new mode 100644
similarity index 89%
copy from chrome/content/utils.js
copy to chrome/utils.js
index 5d1025e..cdc8dc6
--- a/chrome/content/utils.js
+++ b/chrome/utils.js
@@ -1,7 +1,5 @@
-vwofChrome.utils = {
- /**
- needed by some parser to get the video source
- */
+var utils = {
+
get:function(uri){
const XMLHttpRequest = Components.Constructor("@mozilla.org/xmlextras/xmlhttprequest;1",
"nsIXMLHttpRequest",
@@ -9,12 +7,9 @@ vwofChrome.utils = {
let xmlhttp = XMLHttpRequest("GET", uri, false);
xmlhttp.send();
- return xmlhttp;
+ return xmlhttp.responseText;
},
- /**
- converts url vars into a js associative array
- */
url_vars_to_array: function(url){
var arr_variable = url.split('&');
var arr_assoc = {};
diff --git a/chrome/vwof.js b/chrome/vwof.js
new file mode 100644
index 0000000..e251ec4
--- /dev/null
+++ b/chrome/vwof.js
@@ -0,0 +1,89 @@
+var vwof= {
+ parsers:{}, //hash of the parsers (loaded from jsm modules)
+ parser_name:["blip", "dailymotion", "FC2", "HTML5", "niconico", "youtube", "ScreenWaveMedia"],
+
+ /**
+ Load modules listed in the extensions.vwof.modules pref variable to this.parsers hash
+ */
+ load_modules:function(){
+ for(var i=0;i<this.parser_name.length;i++){
+ let key_parser = this.parser_name[i];
+ let context = {};
+ let res = 'chrome://vwof/content/modules/'+key_parser+'.jsm';
+ Services.scriptloader.loadSubScript(res, context, "UTF-8");
+ this.parsers[key_parser] = context;
+ }
+ },
+ set_parsers_activation:function(){
+ //check in the preferences : activated a parser on page load or not
+ Components.utils.import("resource://gre/modules/Services.jsm");
+ var prefManager = Components.classes["@mozilla.org/preferences-service;1"]
+ .getService(Components.interfaces.nsIPrefBranch);
+
+ var modules_list = prefManager.getCharPref("extensions.vwof.modules");
+ var modules = JSON.parse(modules_list); //parser / value from the preferences
+
+ for(var key_parser in this.parsers){
+ var parser = this.parsers[key_parser].parser;
+
+ //if a pref is defined for this parser
+ if(modules[key_parser])
+ parser['activated'] = modules[key_parser]?true:false;
+ else
+ parser['activated'] = false;
+ }
+ },
+ getVideoInfo:function (cw) {
+ var video_info = []; // array of video_data
+ var has_parsed_site = false;
+
+ for(var key_parser in this.parsers){
+ try{
+ var parser = this.parsers[key_parser].parser;
+ if(parser['activated'] != true)continue;
+ var video_data = []; //array of video links with quality
+
+ //if the parser has a URI and it's the current location
+ if(parser.BASE_URI && cw.location.hostname == parser.BASE_URI){
+ video_data = parser.parse_site(cw);
+ has_parsed_site = true;
+ }
+ else if(parser.parse_embed){
+ video_data = parser.parse_embed(cw);
+ }
+
+ //if there is at least a video url retreived from the parser
+ if(video_data.length >= 1){
+ //set the source (name of the parser)
+ for(var i=0;i < video_data.length;i++){
+ video_data[i]['source'] = this.parsers[key_parser].name;
+ }
+
+ //concat the chunks of video(s) from this parser
+ video_info = video_info.concat(video_data);
+ }
+ }
+ catch(err){
+ Components.utils.reportError("vwof plugin, exception in "+key_parser+": "+err);
+ };
+
+ //official web sites do not embed several videos, so don't use other parsers
+ if(has_parsed_site){break;}
+ }
+
+ return video_info;
+ },
+
+ detectVideo:function(cw) {
+ var video_info = this.getVideoInfo(cw);
+
+ for (var i = 0; i < video_info.length; i++) {
+ if(video_info[i]['player']){
+ var replace_location = video_info[i]['player'];
+ var player = vwofPlayer.create_video_selector(video_info[i], cw);
+ var replace_parent = replace_location.parentNode;
+ replace_parent.replaceChild(player, replace_location);
+ }
+ }
+ }
+};
diff --git a/chrome/content/youtube_utils.js b/chrome/youtube_utils.js
old mode 100755
new mode 100644
similarity index 90%
copy from chrome/content/youtube_utils.js
copy to chrome/youtube_utils.js
index 7842b7c..c0e1f0c
--- a/chrome/content/youtube_utils.js
+++ b/chrome/youtube_utils.js
@@ -1,7 +1,4 @@
-if("undefined" == typeof(vwofChrome)){
- var vwofChrome = {};
-}
-vwofChrome.youtubeUtils = {
+var youtubeUtils = {
toggle_yt_wide:function (event){
var c = event.target.hasAttribute('checked')?1:0;
var wide;
@@ -36,7 +33,7 @@ vwofChrome.youtubeUtils = {
}
catch (errorInfo)
{
- console.error(errorInfo);
+ Components.utils.reportError(errorInfo);
}
return wide;
}
diff --git a/chrome/content/list_modules.js b/content/list_modules.js
old mode 100755
new mode 100644
similarity index 91%
rename from chrome/content/list_modules.js
rename to content/list_modules.js
index 89c55aa..9bda604
--- a/chrome/content/list_modules.js
+++ b/content/list_modules.js
@@ -1,5 +1,5 @@
var checkbox_wide = document.getElementById("vwof_yt_wide");
-var wide = vwofChrome.youtubeUtils.yt_is_wide();
+var wide = youtubeUtils.yt_is_wide();
checkbox_wide.setAttribute("checked", wide);
var prefPane = document.getElementById('vwof_pref_modules');
@@ -21,10 +21,10 @@ element_columns.appendChild(element_column_embed);
element_grid.appendChild(element_columns);
element_grid.appendChild(element_rows);
-for(var i=0;i<vwofChrome.BrowserOverlay.parser_name.length;i++){
+for(var i=0;i<vwof.parser_name.length;i++){
var element_row = document.createElement('row');
- let key_module = vwofChrome.BrowserOverlay.parser_name[i];
+ let key_module = vwof.parser_name[i];
var element_label_key = document.createElement('label');
element_label_key.setAttribute('value', key_module);
@@ -53,3 +53,4 @@ function update_module(event){
prefManager.setCharPref("extensions.vwof.modules", s_modules);
}
+
diff --git a/content/listener.js b/content/listener.js
new file mode 100644
index 0000000..4c54182
--- /dev/null
+++ b/content/listener.js
@@ -0,0 +1,144 @@
+var windowListener = {
+ ignoreFrames:true,
+ onOpenWindow: function (aXULWindow) {
+ let aDOMWindow = aXULWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowInternal || Ci.nsIDOMWindow);
+ aDOMWindow.addEventListener("load", function () {
+ aDOMWindow.removeEventListener("load", arguments.callee, false);
+ windowListener.loadIntoWindow(aDOMWindow, aXULWindow);
+ }, false);
+ },
+ register: function () {
+ let XULWindows = Services.wm.getXULWindowEnumerator(null);
+ while (XULWindows.hasMoreElements()) {
+ let aXULWindow = XULWindows.getNext();
+ let aDOMWindow = aXULWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowInternal || Ci.nsIDOMWindow);
+ windowListener.loadIntoWindow(aDOMWindow, aXULWindow);
+ }
+ // Listen to new windows
+ Services.wm.addListener(windowListener);
+ },
+ unregister: function () {
+ // Unload from any existing windows
+ let XULWindows = Services.wm.getXULWindowEnumerator(null);
+ while (XULWindows.hasMoreElements()) {
+ let aXULWindow = XULWindows.getNext();
+ let aDOMWindow = aXULWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowInternal || Ci.nsIDOMWindow);
+ windowListener.unloadFromWindow(aDOMWindow, aXULWindow);
+ }
+ //Stop listening so future added windows dont get this attached
+ Services.wm.removeListener(windowListener);
+ },
+ loadIntoWindow: function (aDOMWindow, aXULWindow) {
+ if (!aDOMWindow) {
+ return;
+ }
+ if (aDOMWindow.gBrowser) {
+ aDOMWindow.gBrowser.addEventListener('DOMContentLoaded', listenPageLoad, false);
+ if (aDOMWindow.gBrowser.tabContainer) {
+ //start - go through all tabs in this window we just added to
+ var tabs = aDOMWindow.gBrowser.tabContainer.childNodes;
+ for (var i = 0; i < tabs.length; i++) {
+ var tabBrowser = tabs[i].linkedBrowser;
+ var win = tabBrowser.contentWindow;
+ loadIntoContentWindowAndItsFrames(win);
+ }
+ //end - go through all tabs in this window we just added to
+ } else {
+ //does not have tabContainer
+ var win = aDOMWindow.gBrowser.contentWindow;
+ loadIntoContentWindowAndItsFrames(win);
+ }
+ }
+ },
+ unloadFromWindow: function (aDOMWindow, aXULWindow) {
+ if (!aDOMWindow) {
+ return;
+ }
+ if (aDOMWindow.gBrowser) {
+ aDOMWindow.gBrowser.removeEventListener('DOMContentLoaded', listenPageLoad, false);
+ if (aDOMWindow.gBrowser.tabContainer) {
+ //has tabContainer
+ //start - go through all tabs in this window we just added to
+ var tabs = aDOMWindow.gBrowser.tabContainer.childNodes;
+ for (var i = 0; i < tabs.length; i++) {
+ var tabBrowser = tabs[i].linkedBrowser;
+ var win = tabBrowser.contentWindow;
+ unloadFromContentWindowAndItsFrames(win);
+ }
+ //end - go through all tabs in this window we just added to
+ } else {
+ //does not have tabContainer
+ var win = aDOMWindow.gBrowser.contentWindow;
+ unloadFromContentWindowAndItsFrames(win);
+ }
+ } else {
+ //window does not have gBrowser
+ }
+ }
+};
+/*end - windowlistener*/
+
+function loadIntoContentWindowAndItsFrames(theWin) {
+ var frames = theWin.frames;
+ var winArr = [theWin];
+ for (var j = 0; j < frames.length; j++) {
+ winArr.push(frames[j].window);
+ }
+ for (var j = 0; j < winArr.length; j++) {
+ var doc = winArr[j].document;
+ //START - edit below here
+
+ if (this.ignoreFrames) {
+ break;
+ }
+ //END - edit above here
+ }
+}
+
+function unloadFromContentWindowAndItsFrames(theWin) {
+ var frames = theWin.frames;
+ var winArr = [theWin];
+ for (var j = 0; j < frames.length; j++) {
+ winArr.push(frames[j].window);
+ }
+
+ for (var j = 0; j < winArr.length; j++) {
+ var doc = winArr[j].document;
+ //START - edit below here
+ if (this.ignoreFrames) {
+ break;
+ }
+ //END - edit above here
+ }
+}
+
+/**
+ Listener that observe the prefs variables
+
+ If the module list changes (new module, module deactivated/activated), the parser list is reloaded
+*/
+var PrefObserver = {
+ register: function() {
+ // First we'll need the preference services to look for preferences.
+ var prefService = Components.classes["@mozilla.org/preferences-service;1"]
+ .getService(Components.interfaces.nsIPrefService);
+
+ // For this.branch we ask for the preferences
+ this.branch = prefService.getBranch("extensions.vwof.");
+
+ // Finally add the observer.
+ this.branch.addObserver("", this, false);
+ },
+
+ unregister: function() {
+ this.branch.removeObserver("", this);
+ },
+
+ observe: function(aSubject, aTopic, aData) {
+ switch (aData) {
+ case "modules":
+ vwof.set_parsers_activation();
+ break;
+ }
+ }
+}
diff --git a/modules/FC2.jsm b/content/modules/FC2.jsm
old mode 100755
new mode 100644
similarity index 91%
rename from modules/FC2.jsm
rename to content/modules/FC2.jsm
index 1018e14..cc218b5
--- a/modules/FC2.jsm
+++ b/content/modules/FC2.jsm
@@ -20,7 +20,7 @@ var parser = {
//get MD5 from video id and salt
var id_salt = id+this.SALT;
- var md5sum = vwofChrome.utils.md5(id_salt);
+ var md5sum = utils.md5(id_salt);
//get gk (signature generated by JS)
var gk = [];
@@ -38,9 +38,9 @@ var parser = {
api_video_uri = api_video_uri.replace('MIMI', md5sum);
api_video_uri = api_video_uri.replace('GK', gk.join(''));
- var data = vwofChrome.utils.get(api_video_uri).responseText;
+ var data = utils.get(api_video_uri);
//extract the video url (filepath) from the data
- var assoc_data = vwofChrome.utils.url_vars_to_array(data);
+ var assoc_data = utils.url_vars_to_array(data);
var filepath = assoc_data['filepath'];
if(!filepath)return;
diff --git a/modules/HTML5.jsm b/content/modules/HTML5.jsm
old mode 100755
new mode 100644
similarity index 100%
rename from modules/HTML5.jsm
rename to content/modules/HTML5.jsm
diff --git a/content/modules/Makefile.in b/content/modules/Makefile.in
new file mode 100644
index 0000000..23f8111
--- /dev/null
+++ b/content/modules/Makefile.in
@@ -0,0 +1,2 @@
+# The sources for the module files.
+modules_sources := $(wildcard $(modules_dir)/*.jsm)
diff --git a/content/modules/ScreenWaveMedia.jsm b/content/modules/ScreenWaveMedia.jsm
new file mode 100644
index 0000000..71d935a
--- /dev/null
+++ b/content/modules/ScreenWaveMedia.jsm
@@ -0,0 +1,57 @@
+var parser = {
+ parse_embed: function(cw) {
+ var player;
+ var videos = [];
+ var video_info = [];
+ const doc = cw.document;
+ const REGEX_ID = /id=(.+)/;
+ const URL_VIDEO = 'http://video2.screenwavemedia.com/vod/VIDEO_ID_QUALITY.mp4';
+ const URL_IMAGE = 'http://image.screenwavemedia.com/VIDEO_ID_thumb_640x360.jpg';
+ const video_quality = ['audio', 'low', 'med', 'high', 'hd1'];
+ const URL_PLAYER_FRAME = 'http://player.screenwavemedia.com/play/player.php';
+ const XPATH_PLAYER_FRAME = "//iframe[starts-with(@src, '"+URL_PLAYER_FRAME+"')]"
+ const URL_PLAYER_SCRIPT = 'http://player.screenwavemedia.com/play/play.php';
+ const XPATH_PLAYER_SCRIPT = "//script[starts-with(@src, '"+URL_PLAYER_SCRIPT+"')]";
+
+ var xp_res_player_frame = doc.evaluate(XPATH_PLAYER_FRAME, doc, null,
+ cw.XPathResult.FIRST_ORDERED_NODE_TYPE,
+ null);
+
+ var node = xp_res_player_frame.singleNodeValue;
+
+ if(node){
+ player = node;
+ }
+ else{
+ var xp_res_player_script = doc.evaluate(XPATH_PLAYER_SCRIPT, doc, null,
+ cw.XPathResult.FIRST_ORDERED_NODE_TYPE,
+ null);
+
+ node = xp_res_player_script.singleNodeValue;
+ if(!node)return;
+
+ player = doc.getElementById('videoarea');
+ player.id = "swmvwof_player";
+ }
+
+ if(!node)return;
+
+ var video_id = node.src.match(REGEX_ID)[1];
+
+ for (var i=0;i<video_quality.length;i++) {
+ var url = URL_VIDEO.replace('VIDEO_ID', video_id);
+ url = url.replace("QUALITY", video_quality[i]);
+ videos.push( {'quality': video_quality[i], 'format':'mp4', 'url':url} );
+ }
+
+ var video_img = URL_IMAGE.replace('VIDEO_ID', video_id);
+
+ video_info.push({
+ 'player': player,
+ 'video_img':video_img,
+ 'videos': videos
+ });
+
+ return video_info;
+ }
+};
diff --git a/content/modules/blip.jsm b/content/modules/blip.jsm
new file mode 100644
index 0000000..b776df9
--- /dev/null
+++ b/content/modules/blip.jsm
@@ -0,0 +1,118 @@
+var parser = {
+ BASE_URI: 'blip.tv',
+ URL_PARAM_JSON: '?skin=json&no_wrap=1',
+
+ parse_embed: function(cw) {
+ const doc = cw.document;
+ const XPATH_PLAYER = "//iframe[starts-with(@src, 'http://blip.tv/play')]";
+ var video_info = [];
+ var player;
+ var video_img;
+
+ var xp_res_player = doc.evaluate(XPATH_PLAYER, doc,
+ null, cw.XPathResult.ORDERED_NODE_ITERATOR_TYPE,
+ null );
+
+ try{
+ while (player = xp_res_player.iterateNext()) {
+ var videos = [];
+ var encoded_file;
+ var player_doc = utils.get(player.src);
+
+ if((encoded_file = player_doc.match(/"file":"(.+?)",/)) !== null){
+ var file = decodeURIComponent(encoded_file[1]);
+ file = file.replace('rss/flash', 'posts/view');
+ var json_string = utils.get(file+this.URL_PARAM_JSON);
+ var parse_data = this.parse_json_data(json_string);
+ video_img = parse_data[0];
+ videos = parse_data[1];
+ }
+ else{
+ const URL_BASE = 'http://blip.tv/file/get/';
+
+ const REGEX_VIDEO_URI_HD = 'bliphd720 : "(.*)"';
+ const REGEX_VIDEO_URI_SD = 'blipsd : "(.*)"';
+ const REGEX_VIDEO_URI_LD = 'blipld : "(.*)"';
+ const REGEX_VIDEO_IMG = 'config\.video\.thumbnail = "(.*)"';
+
+ var video_uri_hd = player_doc.match(REGEX_VIDEO_URI_HD);
+ var video_uri_sd = player_doc.match(REGEX_VIDEO_URI_SD);
+ var video_uri_ld = player_doc.match(REGEX_VIDEO_URI_LD);
+ var video_uri_img = player_doc.match(REGEX_VIDEO_IMG);
+
+ if(video_uri_hd[1] != ""){
+ videos.push({'quality':'hd720' , 'url':URL_BASE+video_uri_hd[1]});
+ }
+ if(video_uri_sd[1] != ""){
+ videos.push({'quality':'medium', 'url':URL_BASE+video_uri_sd[1]});
+ }
+ if(video_uri_ld[1] != ""){
+ videos.push({'quality':'low' , 'url':URL_BASE+video_uri_ld[1]});
+ }
+
+ if(video_uri_img){
+ video_img = 'http:'+video_uri_img[1];
+ video_img = video_img.replace('THUMB_WIDTH', player.width);
+ video_img = video_img.replace('THUMB_HEIGHT', player.height);
+ }
+ }
+
+ video_info.push({
+ 'player': player,
+ 'video_img':video_img,
+ 'videos': videos
+ });
+ }
+ }
+ finally{
+ //in case iterateNext() throw invalidStateException
+ //because of a DOM alteration, return what was fetched
+ return video_info;
+ }
+
+ return video_info;
+ },
+
+ parse_site: function(cw) {
+ var doc = cw.document;
+ var video_info = [];
+ var player = doc.getElementById('PlayeriFrame');
+ if(!player)return;
+
+ var json_string = utils.get(doc.URL+this.URL_PARAM_JSON);
+ var parse_data = this.parse_json_data(json_string);
+ var video_img = parse_data[0];
+ var videos = parse_data[1];
+
+ video_info.push({
+ 'player': player,
+ 'video_img': video_img,
+ 'videos': videos
+ });
+
+ return video_info;
+ },
+
+ parse_json_data: function(json_string){
+ var post = JSON.parse(json_string).Post;
+
+ var videos = [];
+ for(var i=0;i<post.additionalMedia.length;i++){
+ var format = post.additionalMedia[i].primary_mime_type;
+ if(format == 'text/plain')continue;
+
+ //remove video part of the mime type for a prettier display
+ format=format.replace('video/', '');
+
+ videos.push({'format': format,
+ 'quality': post.additionalMedia[i].media_width + '/' +
+ post.additionalMedia[i].media_height,
+ 'url':post.additionalMedia[i].url}
+ );
+ }
+
+ var video_img = post.thumbnailUrl;
+
+ return [video_img, videos];
+ }
+};
diff --git a/modules/dailymotion.jsm b/content/modules/dailymotion.jsm
old mode 100755
new mode 100644
similarity index 100%
rename from modules/dailymotion.jsm
rename to content/modules/dailymotion.jsm
diff --git a/modules/niconico.jsm b/content/modules/niconico.jsm
old mode 100755
new mode 100644
similarity index 92%
rename from modules/niconico.jsm
rename to content/modules/niconico.jsm
index 61bb763..5e3eb8b
--- a/modules/niconico.jsm
+++ b/content/modules/niconico.jsm
@@ -33,8 +33,8 @@ var parser = {
////get the video link from the flapi
const video_id = json_data.flashvars.videoId;
const flapi_url = 'http://flapi.nicovideo.jp/api/getflv?v='+video_id;
- const data = vwofChrome.utils.get(flapi_url).responseText;
- const assoc_data = vwofChrome.utils.url_vars_to_array(data);
+ const data = utils.get(flapi_url);
+ const assoc_data = utils.url_vars_to_array(data);
const url = decodeURIComponent(assoc_data['url']);
var videos = [ {
diff --git a/modules/youtube.jsm b/content/modules/youtube.jsm
old mode 100755
new mode 100644
similarity index 90%
rename from modules/youtube.jsm
rename to content/modules/youtube.jsm
index ad7910b..c521f21
--- a/modules/youtube.jsm
+++ b/content/modules/youtube.jsm
@@ -22,7 +22,7 @@ var parser = {
var player_api = doc.getElementById('player-api');
if(player_api){
player_api.setAttribute('id', 'vwof_player-api'); //prevent the player-api div to be erased by the missing plugin tv-static message
- if(vwofChrome.youtubeUtils.yt_is_wide()){
+ if(youtubeUtils.yt_is_wide()){
player_api.setAttribute("style", "margin:auto;"); //center the player
}
}
@@ -39,7 +39,7 @@ var parser = {
player_api.appendChild(player);
var api_video_uri = this.API_GET_VIDEO.replace('VIDEO_ID', id);
- var data = vwofChrome.utils.get(api_video_uri).responseText;
+ var data = utils.get(api_video_uri);
var video_data = this.parse_data(data);
video_data['player'] = player;
@@ -67,7 +67,7 @@ var parser = {
var id = player.src.match(REGEX_VIDEO_ID_IFRAME)[1];
var api_video_uri = this.API_GET_VIDEO.replace('VIDEO_ID', id);
- var data = vwofChrome.utils.get(api_video_uri).responseText;
+ var data = utils.get(api_video_uri);
var parsed_array = this.parse_data(data);
parsed_array['player'] = player;
@@ -84,7 +84,7 @@ var parser = {
*/
parse_data: function(data){
var videos = [];
- var assoc_data = vwofChrome.utils.url_vars_to_array(data);
+ var assoc_data = utils.url_vars_to_array(data);
var url_encoded_fmt_stream_map = assoc_data['url_encoded_fmt_stream_map'];
var url_decoded_fmt_stream_map = decodeURIComponent(url_encoded_fmt_stream_map);
@@ -92,7 +92,7 @@ var parser = {
var i;
for(i=0;i<arr_url_decoded_fmt_stream_map.length;i++){
- var assoc_url_decoded_fmt_stream = vwofChrome.utils.url_vars_to_array(arr_url_decoded_fmt_stream_map[i]);
+ var assoc_url_decoded_fmt_stream = utils.url_vars_to_array(arr_url_decoded_fmt_stream_map[i]);
var encoded_uri = assoc_url_decoded_fmt_stream['url'];
var decoded_uri = decodeURIComponent(encoded_uri);
decoded_uri += '&signature='+assoc_url_decoded_fmt_stream['sig']; //add the signature to the decoded url
diff --git a/chrome/content/player.js b/content/player.js
old mode 100755
new mode 100644
similarity index 98%
rename from chrome/content/player.js
rename to content/player.js
index 80e2958..809768b
--- a/chrome/content/player.js
+++ b/content/player.js
@@ -1,7 +1,3 @@
-if ("undefined" == typeof(vwofPlayer)) {
- var vwofPlayer = {};
-};
-
vwofPlayer = {
/**
add the player stylecheet link to the head of the document
@@ -10,7 +6,7 @@ vwofPlayer = {
var style = doc.createElement('link');
style.setAttribute('type', 'text/css');
style.setAttribute('rel', 'stylesheet');
- style.setAttribute('href', 'chrome://vwof/content/player.css');
+ style.setAttribute('href', 'chrome://vwof/skin/player.css');
style.setAttribute('id', style_id);
doc.head.appendChild(style);
},
diff --git a/content/prefs.js b/content/prefs.js
new file mode 100644
index 0000000..2764774
--- /dev/null
+++ b/content/prefs.js
@@ -0,0 +1,47 @@
+function getGenericPref(branch,prefName)
+{
+ switch (branch.getPrefType(prefName))
+ {
+ default:
+ case 0: return undefined; // PREF_INVALID
+ case 32: return getUCharPref(prefName,branch); // PREF_STRING
+ case 64: return branch.getIntPref(prefName); // PREF_INT
+ case 128: return branch.getBoolPref(prefName); // PREF_BOOL
+ }
+}
+
+function setGenericPref(branch,prefName,prefValue)
+{
+ switch (typeof prefValue)
+ {
+ case "string":
+ setUCharPref(prefName,prefValue,branch);
+ return;
+ case "number":
+ branch.setIntPref(prefName,prefValue);
+ return;
+ case "boolean":
+ branch.setBoolPref(prefName,prefValue);
+ return;
+ }
+}
+
+function setDefaultPref(prefBranch, prefName, prefValue)
+{
+ var defaultBranch = Services.prefs.getDefaultBranch(prefBranch);
+ setGenericPref(defaultBranch,prefName,prefValue);
+}
+
+function getUCharPref(prefName,branch) // Unicode getCharPref
+{
+ branch = branch ? branch : Services.prefs;
+ return branch.getComplexValue(prefName, Components.interfaces.nsISupportsString).data;
+}
+function setUCharPref(prefName,text,branch) // Unicode setCharPref
+{
+ var string = Components.classes["@mozilla.org/supports-string;1"]
+ .createInstance(Components.interfaces.nsISupportsString);
+ string.data = text;
+ branch = branch ? branch : Services.prefs;
+ branch.setComplexValue(prefName, Components.interfaces.nsISupportsString, string);
+}
diff --git a/content/prefs.xul b/content/prefs.xul
new file mode 100644
index 0000000..fcef025
--- /dev/null
+++ b/content/prefs.xul
@@ -0,0 +1,79 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
+<prefwindow id="vwofPrefWindow"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <prefpane id="vwof_pref_general" label="General">
+
+ <preferences>
+ <preference id="extensions.vwof.activate_onload"
+ name="extensions.vwof.activate_onload"
+ type="bool"/>
+ <preference id="plugins.notifyMissingFlash"
+ name="plugins.notifyMissingFlash"
+ type="bool"/>
+ <preference id="full-screen-api.approval-required"
+ name="full-screen-api.approval-required"
+ type="bool"/>
+ </preferences>
+
+ <checkbox label="Detect videos on page load"
+ preference="extensions.vwof.activate_onload"/>
+ <checkbox label="Enable missing flash plugin warnings"
+ preference="plugins.notifyMissingFlash"/>
+ <checkbox label="Enable approval message when fullscreen"
+ preference="full-screen-api.approval-required"/>
+
+ </prefpane>
+
+ <prefpane id="vwof_pref_prefered_format" label="Prefered format">
+ <preferences>
+ <preference id="extensions.vwof.prefered_quality"
+ name="extensions.vwof.prefered_quality"
+ type="string" />
+ <preference id="extensions.vwof.prefered_format"
+ name="extensions.vwof.prefered_format"
+ type="string" />
+ </preferences>
+
+ <label value="Prefered format" control="prefered_format" />
+ <menulist id="prefered_format" preference="extensions.vwof.prefered_format"
+ preference-editable="true">
+ <menupopup>
+ <menuitem label="webm" value="webm"/>
+ <menuitem label="mp4" value="mp4"/>
+ <menuitem label="avi" value="avi"/>
+ <menuitem label="flv" value="flv"/>
+ </menupopup>
+ </menulist>
+
+ <label value="Prefered quality" control="prefered_quality" />
+ <menulist id="prefered_quality" preference="extensions.vwof.prefered_quality"
+ preference-editable="true">
+ <menupopup>
+ <menuitem label="hd1080" value="hd1080"/>
+ <menuitem label="hd720" value="hd720"/>
+ <menuitem label="medium" value="medium"/>
+ <menuitem label="low" value="low"/>
+ </menupopup>
+ </menulist>
+
+ </prefpane>
+
+ <prefpane id="vwof_pref_modules" label="modules">
+ <script type="application/x-javascript" src="chrome://vwof/content/browserOverlay.js" />
+ <script type="application/x-javascript" src="chrome://vwof/content/youtube_utils.js" />
+
+ <preferences>
+ <preference id="extensions.vwof.modules" name="extensions.vwof.modules" type="string"/>
+ </preferences>
+
+ <checkbox id="vwof_yt_wide" label="YouTube theater mode"
+ oncommand="vwofChrome.youtubeUtils.toggle_yt_wide(event)"/>
+ </prefpane>
+
+ <script src="youtube_utils.js"/>
+ <script src="vwof.js"/>
+ <script src="list_modules.js"/>
+
+</prefwindow>
+
diff --git a/chrome/content/utils.js b/content/utils.js
old mode 100755
new mode 100644
similarity index 89%
rename from chrome/content/utils.js
rename to content/utils.js
index 5d1025e..cdc8dc6
--- a/chrome/content/utils.js
+++ b/content/utils.js
@@ -1,7 +1,5 @@
-vwofChrome.utils = {
- /**
- needed by some parser to get the video source
- */
+var utils = {
+
get:function(uri){
const XMLHttpRequest = Components.Constructor("@mozilla.org/xmlextras/xmlhttprequest;1",
"nsIXMLHttpRequest",
@@ -9,12 +7,9 @@ vwofChrome.utils = {
let xmlhttp = XMLHttpRequest("GET", uri, false);
xmlhttp.send();
- return xmlhttp;
+ return xmlhttp.responseText;
},
- /**
- converts url vars into a js associative array
- */
url_vars_to_array: function(url){
var arr_variable = url.split('&');
var arr_assoc = {};
diff --git a/content/vwof.js b/content/vwof.js
new file mode 100644
index 0000000..e251ec4
--- /dev/null
+++ b/content/vwof.js
@@ -0,0 +1,89 @@
+var vwof= {
+ parsers:{}, //hash of the parsers (loaded from jsm modules)
+ parser_name:["blip", "dailymotion", "FC2", "HTML5", "niconico", "youtube", "ScreenWaveMedia"],
+
+ /**
+ Load modules listed in the extensions.vwof.modules pref variable to this.parsers hash
+ */
+ load_modules:function(){
+ for(var i=0;i<this.parser_name.length;i++){
+ let key_parser = this.parser_name[i];
+ let context = {};
+ let res = 'chrome://vwof/content/modules/'+key_parser+'.jsm';
+ Services.scriptloader.loadSubScript(res, context, "UTF-8");
+ this.parsers[key_parser] = context;
+ }
+ },
+ set_parsers_activation:function(){
+ //check in the preferences : activated a parser on page load or not
+ Components.utils.import("resource://gre/modules/Services.jsm");
+ var prefManager = Components.classes["@mozilla.org/preferences-service;1"]
+ .getService(Components.interfaces.nsIPrefBranch);
+
+ var modules_list = prefManager.getCharPref("extensions.vwof.modules");
+ var modules = JSON.parse(modules_list); //parser / value from the preferences
+
+ for(var key_parser in this.parsers){
+ var parser = this.parsers[key_parser].parser;
+
+ //if a pref is defined for this parser
+ if(modules[key_parser])
+ parser['activated'] = modules[key_parser]?true:false;
+ else
+ parser['activated'] = false;
+ }
+ },
+ getVideoInfo:function (cw) {
+ var video_info = []; // array of video_data
+ var has_parsed_site = false;
+
+ for(var key_parser in this.parsers){
+ try{
+ var parser = this.parsers[key_parser].parser;
+ if(parser['activated'] != true)continue;
+ var video_data = []; //array of video links with quality
+
+ //if the parser has a URI and it's the current location
+ if(parser.BASE_URI && cw.location.hostname == parser.BASE_URI){
+ video_data = parser.parse_site(cw);
+ has_parsed_site = true;
+ }
+ else if(parser.parse_embed){
+ video_data = parser.parse_embed(cw);
+ }
+
+ //if there is at least a video url retreived from the parser
+ if(video_data.length >= 1){
+ //set the source (name of the parser)
+ for(var i=0;i < video_data.length;i++){
+ video_data[i]['source'] = this.parsers[key_parser].name;
+ }
+
+ //concat the chunks of video(s) from this parser
+ video_info = video_info.concat(video_data);
+ }
+ }
+ catch(err){
+ Components.utils.reportError("vwof plugin, exception in "+key_parser+": "+err);
+ };
+
+ //official web sites do not embed several videos, so don't use other parsers
+ if(has_parsed_site){break;}
+ }
+
+ return video_info;
+ },
+
+ detectVideo:function(cw) {
+ var video_info = this.getVideoInfo(cw);
+
+ for (var i = 0; i < video_info.length; i++) {
+ if(video_info[i]['player']){
+ var replace_location = video_info[i]['player'];
+ var player = vwofPlayer.create_video_selector(video_info[i], cw);
+ var replace_parent = replace_location.parentNode;
+ replace_parent.replaceChild(player, replace_location);
+ }
+ }
+ }
+};
diff --git a/chrome/content/youtube_utils.js b/content/youtube_utils.js
old mode 100755
new mode 100644
similarity index 90%
rename from chrome/content/youtube_utils.js
rename to content/youtube_utils.js
index 7842b7c..c0e1f0c
--- a/chrome/content/youtube_utils.js
+++ b/content/youtube_utils.js
@@ -1,7 +1,4 @@
-if("undefined" == typeof(vwofChrome)){
- var vwofChrome = {};
-}
-vwofChrome.youtubeUtils = {
+var youtubeUtils = {
toggle_yt_wide:function (event){
var c = event.target.hasAttribute('checked')?1:0;
var wide;
@@ -36,7 +33,7 @@ vwofChrome.youtubeUtils = {
}
catch (errorInfo)
{
- console.error(errorInfo);
+ Components.utils.reportError(errorInfo);
}
return wide;
}
diff --git a/defaults/preferences/vwof.js b/defaults/preferences/vwof.js
old mode 100755
new mode 100644
index ab25570..4090ad2
--- a/defaults/preferences/vwof.js
+++ b/defaults/preferences/vwof.js
@@ -1,4 +1,3 @@
-pref("extensions.vwof.activate_onload", true);
pref("extensions.vwof.prefered_quality", 'medium');
pref("extensions.vwof.prefered_format", 'webm');
-pref("extensions.vwof.modules", '{"HTML5":1, "blip":1, "youtube":1, "dailymotion":1, "niconico":1, "FC2":1}');
+pref("extensions.vwof.modules", '{"HTML5":1, "springboard":1, "blip":1, "youtube":1, "dew":1, "SWM":1, "dailymotion":1, "ustream":1, "niconico":1, "FC2":1}');
diff --git a/install.rdf b/install.rdf
index fa36e99..6de29d7 100755
--- a/install.rdf
+++ b/install.rdf
@@ -1,25 +1,45 @@
<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+ xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description about="urn:mozilla:install-manifest">
+
+ <!-- The id of the extension. -->
<em:id>vwof at drev.com</em:id>
+
+ <!-- A version string identifying the version of the add-on. -->
+ <em:version>2.0.2</em:version>
+
+ <!-- The name of the add-on; intended for display in the UI. -->
<em:name>Video WithOut Flash</em:name>
+
+ <!-- A short description to display in the user interface. -->
<em:description>Watch videos without flash</em:description>
- <em:version>1.5.1</em:version>
- <em:creator>Drevet Olivier</em:creator>
- <em:homepageURL>http://olivier.drevet.free.fr</em:homepageURL>
- <em:type>2</em:type>
- <em:optionsURL>chrome://vwof/content/prefs.xul</em:optionsURL>
- <!-- Mozilla Firefox -->
+ <!-- The name of the developer to display in the user interface. -->
+ <em:creator>DREVET Olivier</em:creator>
+
+ <!-- A link to the add-on home page to display in the user interface. -->
+ <em:homepageURL>http://mozilla.org</em:homepageURL>
+
+ <!-- Target Application this extension can install into,
+ with minimum and maximum supported versions. -->
<em:targetApplication>
<Description>
+ <!-- Mozilla Firefox -->
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
- <em:minVersion>3.0</em:minVersion>
- <em:maxVersion>33.0</em:maxVersion>
+ <em:minVersion>27.0</em:minVersion>
+ <em:maxVersion>34.0</em:maxVersion>
</Description>
</em:targetApplication>
+
+ <!-- An integer value representing the type of add-on. -->
+ <em:type>2</em:type> <!-- Extensions -->
+
+ <!-- Tells the application whether the extension is boot-strappable. -->
+ <em:bootstrap>true</em:bootstrap>
+
+ <em:optionsURL>chrome://vwof/content/prefs.xul</em:optionsURL>
</Description>
</RDF>
diff --git a/locale/en-US/strings.dtd b/locale/en-US/strings.dtd
new file mode 100644
index 0000000..83ebffb
--- /dev/null
+++ b/locale/en-US/strings.dtd
@@ -0,0 +1 @@
+<!ENTITY VideoUI.label "Open in a new tab">
diff --git a/locale/en-US/strings.properties b/locale/en-US/strings.properties
new file mode 100644
index 0000000..139c356
--- /dev/null
+++ b/locale/en-US/strings.properties
@@ -0,0 +1,3 @@
+Video.label=vwof
+Video.tooltip=Watch videos without flash
+Video.commandkey=W
diff --git a/modules/blip.jsm b/modules/blip.jsm
deleted file mode 100755
index f1d3137..0000000
--- a/modules/blip.jsm
+++ /dev/null
@@ -1,111 +0,0 @@
-var parser = {
- BASE_URI: 'blip.tv',
- URL_PARAM_JSON: '?skin=json&no_wrap=1',
-
- parse_embed: function(cw) {
- var doc = cw.document;
- const XPATH_PLAYER = "//iframe[starts-with(@src, 'http://blip.tv/play')]";
- var video_info = [];
- var player;
- var video_img;
-
- var xp_res_player = doc.evaluate(XPATH_PLAYER, doc,
- null, cw.XPathResult.UNORDERED_NODE_ITERATOR_TYPE,
- null );
-
- while (player = xp_res_player.iterateNext()) {
- var videos = [];
- var encoded_file;
- var player_doc = vwofChrome.utils.get(player.src).responseText;
-
- if((encoded_file = player_doc.match(/"file":"(.+?)",/)) !== null){
- var file = decodeURIComponent(encoded_file[1]);
- file = file.replace('rss/flash', 'posts/view');
- var json_string = vwofChrome.utils.get(file+this.URL_PARAM_JSON).responseText;
- var parse_data = this.parse_json_data(json_string);
- video_img = parse_data[0];
- videos = parse_data[1];
- }
- else{
- const URL_BASE = 'http://blip.tv/file/get/';
-
- const REGEX_VIDEO_URI_HD = 'bliphd720 : "(.*)"';
- const REGEX_VIDEO_URI_SD = 'blipsd : "(.*)"';
- const REGEX_VIDEO_URI_LD = 'blipld : "(.*)"';
- const REGEX_VIDEO_IMG = 'config\.video\.thumbnail = "(.*)"';
-
- var video_uri_hd = player_doc.match(REGEX_VIDEO_URI_HD);
- var video_uri_sd = player_doc.match(REGEX_VIDEO_URI_SD);
- var video_uri_ld = player_doc.match(REGEX_VIDEO_URI_LD);
- var video_uri_img = player_doc.match(REGEX_VIDEO_IMG);
-
- if(video_uri_hd[1] != ""){
- videos.push({'quality':'hd720' , 'url':URL_BASE+video_uri_hd[1]});
- }
- if(video_uri_sd[1] != ""){
- videos.push({'quality':'medium', 'url':URL_BASE+video_uri_sd[1]});
- }
- if(video_uri_ld[1] != ""){
- videos.push({'quality':'low' , 'url':URL_BASE+video_uri_ld[1]});
- }
-
- if(video_uri_img){
- video_img = 'http:'+video_uri_img[1];
- video_img = video_img.replace('THUMB_WIDTH', player.width);
- video_img = video_img.replace('THUMB_HEIGHT', player.height);
- }
- }
-
- video_info.push({
- 'player': player,
- 'video_img':video_img,
- 'videos': videos
- });
- }
-
- return video_info;
- },
-
- parse_site: function(cw) {
- var doc = cw.document;
- var video_info = [];
- var player = doc.getElementById('PlayeriFrame');
- if(!player)return;
-
- var json_string = vwofChrome.utils.get(doc.URL+this.URL_PARAM_JSON).responseText;
- var parse_data = this.parse_json_data(json_string);
- var video_img = parse_data[0];
- var videos = parse_data[1];
-
- video_info.push({
- 'player': player,
- 'video_img': video_img,
- 'videos': videos
- });
-
- return video_info;
- },
-
- parse_json_data: function(json_string){
- var post = JSON.parse(json_string).Post;
-
- var videos = [];
- for(var i=0;i<post.additionalMedia.length;i++){
- var format = post.additionalMedia[i].primary_mime_type;
- if(format == 'text/plain')continue;
-
- //remove video part of the mime type for a prettier display
- format=format.replace('video/', '');
-
- videos.push({'format': format,
- 'quality': post.additionalMedia[i].media_width + '/' +
- post.additionalMedia[i].media_height,
- 'url':post.additionalMedia[i].url}
- );
- }
-
- var video_img = post.thumbnailUrl;
-
- return [video_img, videos];
- }
-};
diff --git a/chrome/content/player.css b/skin/player.css
old mode 100755
new mode 100644
similarity index 96%
rename from chrome/content/player.css
rename to skin/player.css
index 41d2ae3..0135922
--- a/chrome/content/player.css
+++ b/skin/player.css
@@ -7,7 +7,7 @@
background-size: 100%;
background-repeat: no-repeat;
background-size: contain;
- background-position: center top;
+ background-position: center top;
display:block;
cursor:pointer;
z-index:1;
diff --git a/chrome/skin/video-icon.png b/skin/video-icon.png
old mode 100755
new mode 100644
similarity index 100%
rename from chrome/skin/video-icon.png
rename to skin/video-icon.png
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-mozext/video-without-flash.git
More information about the Pkg-mozext-commits
mailing list