There are 25 previous versions of this script.
// ==UserScript==
// @name Facebook Video
// @namespace sizzlemctwizzle
// @description Adds links to download or convert videos with Zamzar.com, and provides code to embed your videos in other sites.
// @version 2.2.3
// @require http://sizzlemctwizzle.com/updater.php?id=11992
// @include http://*.facebook.com/*
// ==/UserScript==
// Copyleft Michael Medley <medleymind@gmail.com>, All Wrongs Reserved
function get_values(swfid) {
// Get the Video url
values = new Array();
if (unsafeWindow[swfid].getVariable('highqual_src')) { // Get High Quality if available
src = unsafeWindow[swfid].getVariable('highqual_src');
unsafeWindow[swfid].addVariable("video_src", unsafeWindow[swfid].getVariable('highqual_src'));
} else { // Default to Low Quality if unavailable
src = unsafeWindow[swfid].getVariable('video_src');
}
values[0] = decodeURIComponent(src);
values[1] = "http://www.zamzar.com/url/?u=" + src;
return values;
}
// Smart XPath Function
function $x(x, t, r) {
if (t && t.nodeType)
var h = r, r = t, t = h;
var d = r ? r.ownerDocument || r : r = document, p;
switch (t) {
case 1:
p = 'numberValue';
break;
case 2:
p = 'stringValue';
break;
case 3:
p = 'booleanValue';
break;
case 8: case 9:
p = 'singleNodeValue';
break;
default:
return d.evaluate(x, r, null, t || 6, null);
}
return d.evaluate(x, r, null, t, null)[p];
}
// Element creation function by Avg and JoeSimmons
function create(A, B, C) {
if (!B)
A = document.createTextNode(A);
else {
A = document.createElement(A);
for (var b in B) {
if (b.indexOf("on") == 0)
A.addEventListener(b.substring(2), B[b], false);
else if (b == "style")
A.setAttribute(b, B[b]);
else
A[b] = B[b];
}
if (C)
for(var i = 0, len = C.length; i<len; i++)
A.appendChild(C[i]);
}
return A;
}
// Optional shortcut functions I like
var $x1 = function(x, r) { return $x(x, 9, r) },
$xb = function(x, r) { return $x(x, 3, r) };
// A robust and universal forEach
function forEach(lst, cb) {
if (lst.snapshotItem) {
var i = 0, len = lst.snapshotLength;
while (i < len)
cb(lst.snapshotItem(i), i++, lst);
}
else if (lst.iterateNext) {
var item;
while (item = lst.iterateNext())
cb(item, lst);
}
else if (lst.forEach)
lst.forEach(cb);
else if (typeof lst.length != 'undefined' && typeof lst === 'object')
Array.forEach(lst, cb);
else if (typeof lst === 'object')
for (var i in lst) cb(lst[i], i, lst);
else
return false;
}
if (typeof GM_addStyle === 'undefined') GM_addStyle = function(css) {
var head = document.getElementsByTagName('head')[0], style = document.createElement('style');
if (!head) {return}
style.type = 'text/css';
try {style.innerHTML = css}
catch(x) {style.innerText = css}
head.appendChild(style);
};
function $(element) { return document.getElementById(element); }
function insertAfter(node, after) { after.parentNode.insertBefore(node, after.nextSibling);}
// Get the actual Facebook url
function realUrl() {
if (window.location.hash.match(/\.php/)) {
return 'http://'+window.location.host+window.location.hash.split('#')[1];
} else if (window.location.href.indexOf('#') != -1) {
return window.location.hash.split('#')[0];
} else {
return window.location.href;
}
}
// GM_addStyle if not available
if (typeof GM_addStyle === 'undefined') GM_addStyle = function(css) {
var head = document.getElementsByTagName('head')[0], style = document.createElement('style');
if (!head) {return}
style.type = 'text/css';
try {style.innerHTML = css}
catch(x) {style.innerText = css}
head.appendChild(style);
};
// Get the Emebd Code
function get_code(swfid, callback) {
if (!code[swfid]) {
//params += "&post_form_id="+unsafeWindow.Env["post_form_id"]+"&__a=1&post_form_id_source=AsyncRequest&nctr[id]="+unsafeWindow.Env["nctrlid"]+'&fb_dtsg='+unsafeWindow.Env["fb_dtsg"]+'&nctr[ct]='+unsafeWindow.presence.pageLoadTime;
width[swfid] = unsafeWindow[swfid].getVariable('stage_width');
height[swfid] = unsafeWindow[swfid].getVariable('stage_height');
code[swfid] = '<object width="'+width[swfid]+'" height="'+height[swfid]+'" ><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://www.facebook.com/v/'+unsafeWindow[swfid].getVariable('video_id')+'" /><embed src="http://www.facebook.com/v/'+unsafeWindow[swfid].getVariable('video_id')+'" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="'+width[swfid]+'" height="'+height[swfid]+'"></embed></object>';
}
callback();
}
// Add elements to a video page
function add_elements(swfid, values) {
var embed, pubdiv;
if (embed = $x1('//a[contains(@onclick, "motion_show_embed_video_dialog")]'))
embed.className += " hidden_elem";
// Public Links
pubdiv = create('div',
{id:'public_link_photo'},
[create('Show people this video by sending them this public link: '),
create(realUrl())]);
// Append Elements
($('main_column')) ? insertAfter(pubdiv, $('main_column').parentNode) : void(0);
var ul = document.evaluate('//ul[@class="actionspro"]', document, null, 9, null).singleNodeValue;
// Embed Link
ul.appendChild(create('li',
{className:'actionspro_li'},
[create('a',
{
onclick:
function (e) {
show_code(swfid);
e.preventDefault();
},
href:'#',
textContent:'Embed this Video',
className:'actionspro_a'})]));
// Wizard Link
ul.appendChild(create('li',
{className:'actionspro_li'},
[create('a',
{
onclick:
function (e) {
run_wizard(swfid);
e.preventDefault();
},
href:'#',
textContent:'Customize Code',
className:'actionspro_a'})]));
// Download Link
ul.appendChild(create('li',
{className:'actionspro_li'},
[create('a',
{
id:"download_" + swfid,
href:values[0],
textContent:'Download Video',
className:'actionspro_a'})]));
// Convert Link
ul.appendChild(create('li',
{className:'actionspro_li'},
[create('a',
{
id:"convert_" + swfid,
href:values[1],
textContent:'Convert Video',
className:'actionspro_a'})]));
}
// Run the script if video posted on site besides a video page: feeds, walls, and messages
function posted_videos(swfid, values) {
actions = document.getElementById("actions_"+swfid);
actions.innerHTML = '<a href="' + values[0] + '" id="download_' + swfid + '">Download Video</a> | <a href="' + values[1] + '" id="convert_' + swfid + '">Convert Video</a>';
actions.setAttribute('class', 'fb_vid_actions');
}
function show_code(swfid) {
get_code(swfid, function() {
$('independent').style.display = 'block';
$('independent').innerHTML = '<div style="top: 125px;" class="generic_dialog"><div style="width: 487px;" class="generic_dialog_popup"><div class="pop_content popcontent_advanced" id="pop_content"><h2 class="dialog_title"><span>Embed this video</span></h2><div class="dialog_content"><div class="dialog_body"><div class="embed_description">You can use this code to display this video on any site on the web.The video will respect Facebook privacy settings.</div><br><div>Embed code:<input size="40" class="code_block" onclick="this.focus(); this.select();" id="" name="" value=\''+code[swfid]+'\' type="text"></div></div><div class="dialog_buttons"><input class="inputsubmit" name="ok" value="Okay" onclick="document.getElementById(\'independent\').style.display = \'none\';" type="button"></div></div></div></div>';
});
}
function run_wizard(swfid) {
get_code(swfid, function() {
// Embed Wizard
$('independent').style.display = 'block';
wizard_html = '<div style="top: 125px;" class="generic_dialog"><div style="width: 487px;" class="generic_dialog_popup"><div class="pop_content popcontent_advanced" id="pop_content"><h2 class="dialog_title"><span>Customize Embed Code</span></h2><div class="dialog_content"><div class="dialog_body"><div id="embed_options" style="padding:20px;"><p>'+
'<form id="custom_'+swfid+'"><table><tr><td><label>Width</lable></td><td><input type="text" id="width_'+swfid+'" class="code_block" size="15" value="'+width[swfid]+'" /></td></tr>'+
'<tr><td><label>Height</lable></td><td><input type="text" id="height_'+swfid+'" class="code_block" size="15" value="'+height[swfid]+'" /></td></tr></table></form></p></div>\n'+
'<div class="dialog_buttons"><input class="inputsubmit" value="Update" id="update_'+swfid+'" type="button" onclick="document.getElementById(\'independent\').style.display = \'none\';" /></div></div></div></div>';
$('independent').innerHTML = wizard_html;
$("width_"+swfid).addEventListener('blur',function () {
$("height_"+swfid).value = Math.round(($("width_"+swfid).value/width[swfid])*height[swfid]);
},false);
$("height_"+swfid).addEventListener('blur',function () {
$("width_"+swfid).value = Math.round(($("height_"+swfid).value/height[swfid])*width[swfid]);
},false);
$("update_"+swfid).addEventListener('click',function () {
update_video(swfid);
},false);
});
}
// Show the effect of the video customizer in the page
function update_video(swfid) {
new_width = $("width_"+swfid).value;
new_height = $("height_"+swfid).value;
code[swfid] = code[swfid].replace(new RegExp('width="'+width[swfid]+'"', 'g'), 'width="'+new_width+'"').replace(new RegExp('height="'+height[swfid]+'"', 'g'), 'height="'+new_height+'"');
width[swfid] = new_width;
height[swfid] = new_height;
$(swfid+"_holder").innerHTML = code[swfid];
}
// Locate Videos
function find_videos() {
document.body.removeEventListener('DOMNodeInserted', find_videos, false);
forEach($x('//div[@class="fb_video_holder"] | //div[@class="mvp_holder"]'),
function (video) {
if (!video.getAttribute('mod')) {
// Is it a holder or an embed object?
if (video.className == "fb_video_holder") {
swfid = video.getAttribute('id').split('_holder')[0];
} else if (video.getElementsByTagName('embed')[0]) {
swfid = video.getElementsByTagName('embed')[0].getAttribute('id');
video.setAttribute('id', swfid+"_holder");
}
if (realUrl().match('/video/') == null) { // Posted Video
div = document.createElement('div');
div.setAttribute('id', "actions_"+swfid);
insertAfter(div, video.parentNode.parentNode);
if (unsafeWindow[swfid]) posted_videos(swfid, get_values(swfid));
} else if ($("video_actions")) { // Video Page
$("video_actions").setAttribute('id', "actions_"+swfid);
if (unsafeWindow[swfid]) add_elements(swfid, get_values(swfid));
}
video.setAttribute('mod', "done");
} // Modifications have already been made
});
}
// Style I stole from Facebook
style = '\n.code_block {\n'+
'font-size:12px;\n' +
'background:#f7f7f7;\n' +
'width: 190px;\n' +
'border:1px solid #ccc;\n' +
'color:#555;\n' +
'}\n\n' +
'#public_link_photo {\n' +
'clear: both;\n' +
'color: #333;\n' +
'font-size: 9px;\n' +
'padding: 5px 5px;\n' +
'text-align: center;\n' +
'margin: 10px 0px 0px 0px;\n' +
'background: #f7f7f7;\n' +
'border-top: 1px solid #D8DFEA;\n' +
'}\n\n' +
'#public_link_photo span {\n' +
'color: black;\n' +
'display: block;\n' +
'font-size: 11px;\n' +
'}\n' +
'.fb_vid_actions { background-color: rgb(236, 239, 245);\n' +
'padding: 5px;\n' +
'text-align: center;\n' +
'display:block;\n' +
'float:none;\n' +
'margin-top: 10px;\n' +
'}\n' +
'#independent { display:none;\n' +
'z-index:10000;\n' +
'position: fixed;\n' +
'}\n\n';
// This is triggered by Facebook whenever the page changes
function watchforchange() {
$('content').removeEventListener('DOMNodeInserted', watchforchange, false);
setTimeout(function () {
if ($xb('//div[@mod]')) {
$('independent').style.display = 'none';
}
find_videos();
$('content').addEventListener('DOMNodeInserted', watchforchange, false);
}, 500);
}
// Wait for the body element to exist
var checker=setInterval(function(){
if($('content')) {
clearInterval(checker);
var ourpopup = document.createElement('div');
ourpopup.id = 'independent';
ourpopup.className = 'generic_dialog video_embed_dialog pop_dialog';
GM_addStyle(style);
if(typeof unsafeWindow==='undefined') unsafeWindow = window;
document.body.appendChild(ourpopup);
code = {};
width = {};
height = {};
watchforchange();
}
},200);
