mx pak1 ?
b a c k g r o u n d . j s \ 1a3 c o n t e n t _ s c r i p t . j s PB ֚ d e f . j s o n N n r&" i c o n s \ i c o n _ 1 6 . p n g #J i c o n s \ i c o n _ 3 2 . p n g _ U i c o n s \ i c o n _ 4 8 . p n g & s e r v i c e . h t m a (function(){
//
if (typeof require != 'undefined' && typeof module != 'undefined' && module.id == "vkopt/background"){
this.mozilla_jetpack = true;
this.jetpack_lib_path = module.uri.match(/^(.+)\//)[1];
this.window = false;
this.navigator = false;
this.Chrome = require("chrome");
this.Promise = require("./promise").Promise;
this.pageMod = require("sdk/page-mod");
this.self = require("sdk/self");
this.XMLHttpRequest = require("sdk/net/xhr").XMLHttpRequest;
this.Cc=Chrome.Cc;
this.Ci=Chrome.Ci;
this.Cu=Chrome.Cu;
this.scope = {};
Cu.import('resource://gre/modules/devtools/Console.jsm', scope); // console import for Firefox Jetpack
Cu.import(jetpack_lib_path+'/Timer.jsm', scope); // оказывается у некоторых браузеров в этом модуле нет setInterval и т.д, т.ч тянем копию нормального
Cu.import("resource://gre/modules/Downloads.jsm", scope);
Cu.import("resource://gre/modules/Task.jsm", scope);
this.console = scope.console;
this.setTimeout = scope.setTimeout;
this.clearTimeout = scope.clearTimeout;
this.setInterval = scope.setInterval;
this.clearInterval = scope.clearInterval;
this.Task = scope.Task;
this.Downloads = scope.Downloads;
console.log('vkopt jetpack inited',!!setTimeout);
}
//
if (typeof console == 'undefined' || !(console || {}).log || !(console || {}).info){
this.console = {
dummy: true,
log:function(){},
info:function(){},
error:function(){}
};
}
var ex_loader, ext_api;
ex_loader = {
type:'internal', // internal|beta|online
base_path: 'http://vkopt.net/upd/',
config_url:'http://vkopt.net/upd/upd/config.json',
scripts_path:'http://vkopt.net/upd/scripts/',
beta_path: 'https://raw.githubusercontent.com/VkOpt/VkOpt/master/source/',
mark:'vkopt_loader',
packed_scripts:[
{
"in_frames":1,
"run_at":0,
"files":[
"vkopt.js",
"vk_face.js",
"vk_lib.js",
"vk_main.js",
"vk_media.js",
"vk_page.js",
"vk_resources.js",
"vk_settings.js",
"vk_skinman.js",
"vk_txtedit.js",
"vk_users.js",
"vklang.js"
],
"domain":"vkontakte\\.ru|vk\\.com",
"exclude":"|notifier\\.php|im_frame\\.php|about:blank|i",
"api_enabled":true
},
{
"files":["vk_lib.js"],
"domain":"vkontakte\\.ru|vk\\.com|vk\\.me|userapi\\.com",
"exclude":"|notifier\\.php|im_frame\\.php|about:blank|i"
}
],
config:[ //Default config; example; overwritten;
{
"in_frames":1, // 0 or null - execute in all; 1 - exclude frames; 2 - only in frames; 3 - disable scripts
"run_at":0, //0 - start or 1 - dom_content_loaded
"files":[ //Scripts list
//"script1.js",
//"script2.js"
],
"domain":"example\\.com",
"exclude":"|notifier\.php|im_frame\.php|about:blank|i", // RegEx "|pattern|flags" for excluding urls
"api_enabled":true
}
],
update_time: 10*60*1000, //update scripts each 4 hours
moz_strorage_id:"http://vkopt.loader.storage",
browsers:{
mozilla:(function(){try{return Components.interfaces.nsIObserverService!=null} catch(e){return false} })(),
mozilla_jetpack: (typeof require != 'undefined' && typeof module != 'undefined' && module.id == "vkopt/background"),
opera: window && window.opera && opera.extension,
chrome: window && window.chrome && chrome.extension,
safari: window && window.safari && safari.extension,
maxthon: (function(){try{return window.external.mxGetRuntime!=null} catch(e){return false} })() //without try{}catch it fail script on Firefox
},
get_script_path:function(filename){
var spath='';
if (filename.match(/^https?:\/\//)) return filename;
var b = ex_loader.browsers;
switch (ex_loader.type){
case 'internal': //
if (b.opera) spath='scripts/'+filename;
else if (b.chrome) spath=chrome.extension.getURL('scripts/'+filename);
else if (b.safari) spath=safari.extension.baseURI+'scripts/'+filename;
//else if (b.mozilla_jetpack) spath = 'resource://vkopt-at-vkopt-dot-net/vkopt/data/scripts/' + filename;
else if (b.mozilla_jetpack ) spath = 'resource://vkopt_jetpack/' + filename;
else if (b.mozilla) spath = 'resource://vkopt/' + filename;
break;
case 'beta':
spath= (ex_loader.beta_path.match(/^https?:\/\//)?'':ex_loader.base_path)+ex_loader.beta_path+filename;
break;
case 'online':
spath=(ex_loader.scripts_path.match(/^https?:\/\//)?'':ex_loader.base_path)+ex_loader.scripts_path+filename;
break;
default:
spath=(ex_loader.scripts_path.match(/^https?:\/\//)?'':ex_loader.base_path)+ex_loader.scripts_path+filename;
}
//console.log(filename,spath);
return spath;
//var src=(filename.match(/https?:\/\//))?filename:spath+filename;
//filename:ex_loader.base_path+ex_loader.scripts_path+filename
},
init:function(){
var b = ex_loader.browsers;
if (b.mozilla_jetpack){
console.log('vkopt init, is mozilla: ',b.mozilla,', is mozilla_jetpack:',b.mozilla_jetpack);
}
if (ex_loader.type=='internal' && b.maxthon){ // MAXTHON
ex_loader.type='online'; // Maxthon 4 doesn't support inject scripts from internal resources
}
ex_loader.init_config();
if (b.opera){ // OPERA
opera.extension.onconnect = function(event) {
ext_api.ready=true;
event.source.postMessage({act:'connected'});
};
opera.extension.onmessage = function(event) {
var data = event.data;
if (data.act=='get_scripts'){
ex_loader.get_scripts(data.url,function(files,api_allowed){
event.source.postMessage({files:files, api_enabled:api_allowed, __key:data.__key});
},data.in_frame);
}
var SendResponse=function(msg){
msg.__key = data.__key;
msg._req=data._req;
event.source.postMessage(msg);
};
ext_api.message_handler(data,SendResponse);
};
} else if (b.chrome){ // CHROME
ext_api.ready=true;
chrome.extension.onRequest.addListener(function(request, sender, sendResponse) {
// request.url - contain url
if (request.act=='get_scripts' && request.url){
ex_loader.get_scripts(request.url,function(files,api_allowed){
//console.log({url: request.url, inframe: request.in_frame, files:files});
sendResponse({files:files, api_enabled:api_allowed, __key:request.__key});
},request.in_frame);
return;
}
// FOR API
var SendResp=function(data){
data.__key = request.__key;
data._req= request._req;
sendResponse(data);
};
ext_api.message_handler(request,SendResp);
});
} else if(b.safari){ // SAFARI
safari.application.addEventListener("message", function(e) {
// e.message.url - contain url
if (e.name === "get_scripts"){
ex_loader.get_scripts(e.message.url,function(files,api_allowed){
e.target.page.dispatchMessage("scripts", {files:files, api_enabled:api_allowed, __key:e.message.__key});
},e.message.in_frame);
}
var SendResponse=function(msg){
msg.__key = e.message.__key;
msg._req= e.message._req;
e.target.page.dispatchMessage('extension_api',msg);
};
ext_api.message_handler(e.message,SendResponse);
}, false);
ext_api.ready=true;
} else if (b.maxthon){ // MAXTHON
var rt = window.external.mxGetRuntime();
rt.listen('get_scripts', function(data){
ex_loader.get_scripts(data.url,function(files,api_allowed){
rt.post('scripts',{files:files, api_enabled:api_allowed, __key:data.__key});
},data.in_frame);
});
//console.log('Init api listeners');
rt = window.external.mxGetRuntime();
rt.listen('extension_bg_api', function(data){
var SendResponse=function(msg){
msg.__key = data.__key;
msg._req= data._req;
rt.post('extension_api',msg);
};
ext_api.message_handler(data,SendResponse);
});
ext_api.ready=true;
} else if (b.mozilla_jetpack){ // MOZILLA JETPACK
console.log('init pageMod');
pageMod.PageMod({
include: /.*/,
exclude: /.*notifier\.php|.*im_frame\.php/,
contentScriptFile: [self.data.url("content_script.js")],
contentScriptOptions: {qwe:123},
contentScriptWhen: "start",
onAttach: function (worker) {
//worker.port.emit("init", {});
console.log('onAttach');
worker.port.on("get_scripts", function (data) {
console.log('on get_scripts');
ex_loader.get_scripts(data.url,function(files,api_allowed){
console.log('send get_scripts response');
worker.port.emit("scripts", {files:files, api_enabled:api_allowed, __key:data.__key});
},data.in_frame);
});
worker.port.on('extension_bg_api', function(data){
var SendResponse=function(msg){
msg.__key = data.__key;
msg._req= data._req;
worker.port.emit('extension_api',msg);
};
ext_api.message_handler(data,SendResponse);
});
ext_api.ready=true;
}
});
} else if (b.mozilla){ // MOZILLA
ex_loader.moz_ldr(function(doc,win){
var bg={
get_scripts:ex_loader.get_scripts,
postMessage:function(data,callback){
var SendResponse=function(msg){
msg.__key = data.__key;
msg._req= data._req;
callback(msg);
};
ext_api.message_handler(data,SendResponse,{win:win,doc:doc,mozilla:1});
}
};
vkopt_ldr_init_content_script(win, doc, bg);
});
}
ex_loader._upd_interval = setInterval(function(){ //Run update checker
//ex_loader.update_config();
ex_loader.init_config();
},ex_loader.update_time);
},
deinit:function(){
clearInterval(_upd_interval);
},
moz_ldr:function(callback){
if (ex_loader.browsers.mozilla_jetpack) // Firefox Jetpack
callback(document, document.defaultView);
else {
var srv = {
observe: function (aSubject, aTopic, aData) {
switch (aTopic) {
case 'document-element-inserted':
var doc = aSubject;
if (null === doc.location) break;
var win = doc.defaultView;
callback(doc, win);
break;
}
}
};
var observerService = Components.classes['@mozilla.org/observer-service;1']
.getService(Components.interfaces.nsIObserverService);
observerService.addObserver(srv, 'document-element-inserted', false);
}
},
is_packed_available:function(){
return !((window.external && window.external.mxGetRuntime) || ex_loader.online_update); // MAXTHON
},
is_allow_run:function(in_frames,doc,in_frame){
in_frames = in_frames || 0;
var inframe=(in_frame!=null)?in_frame:((doc || document).defaultView.parent != (doc || document).defaultView);
switch (in_frames){ // 0 or null - execute in all; 1 - exclude frames; 2 - only in frames; 3 - disable scripts
case 0:
return true; // include all
case 1:
return inframe?false:true; // exclude frames
case 2:
return inframe?true:false; // only in frames
case 3:
return false; // disable scripts
}
return true;
},
update_all:function(callback){
ex_loader.set('scripts_config_hash',Math.random());
ex_loader.update_config(function(){ex_loader.init_config(callback);},true);
},
get_scripts:function(url,callback,in_frame){
var api_allowed = false;
var domain=url;
if (url=='about:blank'){
callback([]);
return;
}
if (domain.indexOf('/')!=-1) domain=domain.split('/')[2];
console.info('ext_bg: get_scripts ',domain);
var data=ex_loader.config;//ex_loader.packed_scripts
var scripts=[];
for (var i=0; i0 && !data[i].in_frames){//0 or null - execute in all; 1 - exclude frames; 2 - only in frames
scripts[z][1]=data[i].in_frames;
}
}
}
if (add)
scripts.push([src,data[i].in_frames,data[i].files[j], (data[i].run_at || 0),0]);
}
}
if (scripts.length>1) console.info('ext_bg: get_scripts scr:',scripts,' url:'+url);
//console.log('scripts:',scripts);
var result=[];
var idx=0;
var load_next=function(){
//console.error('ext_bg: ldr',idx,'/',scripts.length);
if (idx>=scripts.length) {
if (scripts.length>1) console.info('ext_bg: get_scripts scr res:',result,' url:'+url);
callback(result, api_allowed);
return;
}
ex_loader.get_script_content(scripts[idx][0],function(script){
scripts[idx][4]=(script==scripts[idx][0]);
scripts[idx][0]=script;
result.push(scripts[idx]);
idx++;
load_next();
});
};
load_next();
},
update_config:function(callback,clear){
if (ex_loader.type=='internal'){
callback();
return;
}
ex_loader.load((ex_loader.config_url.match(/^https?:\/\//)?'':ex_loader.base_path)+ex_loader.config_url+'?rand='+Math.random(),function(script){
if (!script) return;
if (clear) ex_loader.clear();
var ts=ex_loader.time();
ex_loader.set('scripts_config',ts+script);//store script and timesamp
callback();
});
},
init_config:function(callback){
var cur_ts=ex_loader.time();
var ts=0;
if (ex_loader.type=='internal'){
ex_loader.config=ex_loader.packed_scripts;
return;
}
var content=ex_loader.get('scripts_config');
var old_hash=ex_loader.get('scripts_config_hash');
if (content){
content=String(content);
ts=parseInt(content.substr(0,String(cur_ts).length));//parse script download time
content=content.substr(String(cur_ts).length);//parse script content
if (content=='') return; // next call maybe from setInterval in ex_loader.init();
try{
var data=JSON.parse(content);
var hash=String(data.shift());
ex_loader.set('scripts_config_hash',hash);
ex_loader.config=data;
}catch(e){
ex_loader.error('config_parse_error. waiting '+ex_loader.update_time+'ms for reloading...');
setTimeout(function(){
ex_loader.update_config(function(){ex_loader.init_config(callback);});
},ex_loader.update_time);
return;
}
if (old_hash!=hash){
setTimeout(function(){
var scripts=[];
for (var i=0; i=scripts.length){
if (callback) callback();
return;
}
ex_loader.update_script(scripts[idx++],load_next);
};
load_next();
},5);
}
if (cur_ts - ts > ex_loader.update_time) setTimeout(function(){ex_loader.update_config(ex_loader.init_config);},10);// update if script date expired
} else {
ex_loader.update_config(function(){ex_loader.init_config(callback)});
}
},
time:function() { return Math.round(new Date().getTime());},
error:function(s){console.log(s);},
load:function(path,callback){
var req = new XMLHttpRequest();
req.open('GET', path, true);
req.onreadystatechange = function(){
if (req.readyState == 4) {
if (!req.responseText) ex_loader.error('ERROR: Can\'t read ' + path);
//console.log('script_content:',path,{txt:req.responseText,req:req});
callback(req.status==200 || !path.match(/^https?:\/\//)?req.responseText:null,req);
}
};
req.send();
//if (!req.responseText) ex_loader.error('ERROR: Can\'t read ' + path);
//return req.status==200?req.responseText:null;
},
get:function(key){
try{
return ext_api.utils.ls.getItem(key);
} catch(e){
console.error('ls.getItem error key:"'+key+'" ', e);
}
},
set:function(key,value){
ext_api.utils.ls.setItem(key, value);
},
clear:function(){
ext_api.utils.ls.clear();
},
update_script:function(name,callback){
ex_loader.load(name+'?rand='+Math.random(),function(script){
if (!script) return;
var ts=ex_loader.time();
ex_loader.set(name.split('/').pop(),ts+script);//store script and timesamp
callback();
});
},
scripts_cache:{},
get_script_content:function(name,callback){
//console.log('get_script_content:',name);
var cur_ts=ex_loader.time();
var ts=0;
var key=name.split('/').pop();
var content=ex_loader.get(key);
if (content && name.match(/https?:\/\//)){
content=String(content);
ts=parseInt(content.substr(0,String(cur_ts).length));//parse script download time
content=content.substr(String(cur_ts).length);//parse script content
//if (ts-cur_ts > ex_loader.update_time) setTimeout(function(){ex_loader.update_script(name)},10);// update if script date expired
} else {
if (name.match(/https?:\/\//)){
ex_loader.update_script(name,function(){
ex_loader.get_script_content(name,function(content){
callback(content);
});
});
} else {
if (window.opera && opera.extension){
if (!ex_loader.scripts_cache[key]){
ex_loader.load(name,function(content){
ex_loader.scripts_cache[key]=content;
callback(content);
})
} else {
callback(ex_loader.scripts_cache[key]);
}
} else {
callback(name);
}
}
return;
}
callback(content);
}
};
var _ua = navigator ? navigator.userAgent.toLowerCase() : '';
var browser = {
version: (_ua.match( /.+(?:me|ox|on|rv|it|era|opr|ie)[\/: ]([\d.]+)/ ) || [0,'0'])[1],
opera: (/opera/i.test(_ua) || /opr/i.test(_ua)),
msie: (/msie/i.test(_ua) && !/opera/i.test(_ua) || /trident\//i.test(_ua)),
msie6: (/msie 6/i.test(_ua) && !/opera/i.test(_ua)),
msie7: (/msie 7/i.test(_ua) && !/opera/i.test(_ua)),
msie8: (/msie 8/i.test(_ua) && !/opera/i.test(_ua)),
msie9: (/msie 9/i.test(_ua) && !/opera/i.test(_ua)),
mozilla: /firefox/i.test(_ua),
chrome: /chrome/i.test(_ua),
yabrowser: /yabrowser/i.test(_ua),
safari: (!(/chrome/i.test(_ua)) && /webkit|safari|khtml/i.test(_ua)),
iphone: /iphone/i.test(_ua),
ipod: /ipod/i.test(_ua),
iphone4: /iphone.*OS 4/i.test(_ua),
ipod4: /ipod.*OS 4/i.test(_ua),
ipad: /ipad/i.test(_ua),
android: /android/i.test(_ua),
bada: /bada/i.test(_ua),
mobile: /iphone|ipod|ipad|opera mini|opera mobi|iemobile|android/i.test(_ua),
msie_mobile: /iemobile/i.test(_ua),
safari_mobile: /iphone|ipod|ipad/i.test(_ua),
opera_mobile: /opera mini|opera mobi/i.test(_ua),
opera_mini: /opera mini/i.test(_ua),
mac: /mac/i.test(_ua)
};
ext_api={
ready:false,
store_val_prefix: 'custval_',
message_handler:function(data,send_response,obj){
obj = obj || {};
console.log('BG_GET:',data,send_response);
switch(data.act){
case 'check_ext':
send_response({act:'get_response'});
break;
case 'get':
ext_api.get(data.url,function(t,status){
send_response({act:'GET_response', response:t});
});
break;
case 'post':
ext_api.post(data.url,data.params,function(t,status){
send_response({act:'POST_response', response:t});
});
break;
case 'head':
ext_api.head(data.url,function(headers,status){
send_response({act:'POST_response', response:headers});
});
break;
case 'ajax':
ext_api.ajax(data.options,function(r){
/*
r.text is xhr.responseText;
r.headers is xhr.getAllResponseHeaders();
r.status is xhr.status;
OR
r.error
*/
send_response({act:'AJAX_response', response:r});
});
break;
case 'storage_get':
var prefix = data.reserved_access_allowed ? '' : ext_api.store_val_prefix;
if (data.keys){
var vals={};
for (var i=0; i-1)
return false;
if (/\.(js|css)$/.test(key))
return false;
return true;
},
ajax:function(options,callback){
/*
options={
url
method: POST | GET | HEAD
data : POST data
params: GET params
headers: if headers['Content-type']=='multipart/form-data' use data as Uint8Array
}
*/
if (!options.url || (options.url || '').replace(/^\s+|\s+$/g, '') == '') {
var response = {};
response.text = '';
response.headers = '';
response.status = 0;
response.error = 'No URL';
callback(response);
return;
}
var serialize = function (obj) {
var pairs = [];
for (var key in obj) {
pairs.push(encodeURIComponent(key)
+ '=' + encodeURIComponent(obj[key]));
}
return pairs.join('&');
};
var isEmptyObject = function (obj) {
for (var key in obj) return false;
return true;
};
var xhr = new XMLHttpRequest(),
//callback = callback || this.noop,
method = options.method || 'GET',
params = serialize(options.params || {}),
headers = options.headers || {},
data = options.data || null,
url = options.url || '',
responseType = options.responseType || '',
contentType = headers['Content-type'] || 'application/x-www-form-urlencoded';
if (!headers['Content-type'])
headers['Content-type'] = contentType;
if (data && (typeof data == 'object') && isEmptyObject(data)) data = null;
if (data && (typeof data == 'object') && Object.prototype.toString.call(data) !== '[object Array]') data = serialize(data);
if (~contentType.indexOf('multipart/form-data') && method == 'POST' && data && data.length) {
var buffer = new Uint8Array(data.length);
for (var i = 0; i < data.length; i++) {
buffer[i] = data[i];
}
data = buffer.buffer;
}
if (params)
url += ~url.indexOf('?') ? '&' + params : '?' + params;
try {
xhr.open(method, url, true);
for (var i in headers) {
xhr.setRequestHeader(i, headers[i]);
}
xhr.responseType = responseType;
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
var response = {};
if (!responseType || responseType == 'text') response.text = xhr.responseText;
response.headers = xhr.getAllResponseHeaders();
response.status = xhr.status;
response.raw = (responseType == 'arraybuffer' ? [].slice.call(new Uint8Array(xhr.response)) : xhr.response);
callback(response);
}
};
xhr.send(data);
} catch (e) {
console.log('XHR ERROR', e);
callback({
error: e
});
}
},
get:function(url,params,callback){
if (!callback){
callback=params;
params=null;
}
ext_api.ajax({url:url, params:params, method:'GET'},function(r){
callback(r.text,r.status);
})
},
post:function(url,params,callback){
ext_api.ajax({url:url, data:params, method:'POST'},function(r){
callback(r.text,r.status);
})
},
head:function(url, callback){
ext_api.ajax({url:url, method:'HEAD'},function(r){
callback(r.headers,r.status);
})
},
/*download_chr:function(url,name,progress_callback){
var req = new XMLHttpRequest();
req.open("GET", url, true);
req.responseType = "blob";
req.onprogress=function(evt){
if (evt.lengthComputable){
if (progress_callback)
progress_callback(evt.loaded,evt.total)
//var percentComplete = (evt.loaded / evt.total)*100;
}
};
req.onload = function(oEvent) {
var res = req.response;
var blob = new Blob([res], {type:req.getResponseHeader('Content-Type')});
url = window.URL.createObjectURL(blob);
var a = document.createElement("a");
document.body.appendChild(a);
a.style = "display: none";
a.href = url;
a.download = name;
a.click();
window.URL.revokeObjectURL(url);
};
req.send();
return req;
},*/
download:function(url, title, win, fileType, aShouldBypassCache){ // ONLY MOZILLA
if (ex_loader.browsers.mozilla_jetpack) { // Firefox Jetpack
// Показ диалогового окна выбора пути для сохранения файла
var nsIFilePicker = Ci.nsIFilePicker;
var fp = Cc["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
var window = require("sdk/window/utils").getMostRecentBrowserWindow();
fp.init(window, "Save As", nsIFilePicker.modeSave);
fp.defaultString = title;
var fileType = title.substr(title.lastIndexOf(".") + 1, 3);
fp.appendFilter(fileType, "*." + fileType);
var rv = fp.show();
if (rv == nsIFilePicker.returnOK || rv == nsIFilePicker.returnReplace) {
// Добавление закачки в менеджер закачек
Task.spawn(function () {
///////////////////////
if (!Downloads.getList) {
return Promise.reject(Error('downloader.js -> get -> module is not implimented'));
}
return Promise.all([
Downloads.createDownload({
source: url,
target: fp.file
}),
Downloads.getList(Downloads.PUBLIC)
]).then(function (args) {
var dl = args[0],
list = args[1];
console.log('download then:', arguments);
list.add(dl);
dl.start();
return dl;
});
///////////////////////
/*
try {
let list = yield Downloads.getList(Downloads.ALL);
let download = yield Downloads.createDownload({
source : url,
target : fp.file
});
yield list.add(download);
yield download.start();
} catch (e) {
console.error(e);
}*/
}).then(null, Cu.reportError);
}
} else {
function getDownloadFile(defaultString, fileType) {
var nsIFilePicker = Ci.nsIFilePicker//Components.interfaces.nsIFilePicker;
var fp = /*Components.classes*/Cc["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
fp.init(window, "Save As", nsIFilePicker.modeSave);
try {
var urlExt = defaultString.substr(defaultString.lastIndexOf(".") + 1, 3);
if (urlExt != fileType) defaultString += "." + fileType
} catch (ex) {
}
fp.defaultString = defaultString;
fp.appendFilter(fileType, "*." + fileType);
var rv = fp.show();
if (rv == nsIFilePicker.returnOK || rv == nsIFilePicker.returnReplace) {
var file = fp.file;
//var path = fp.file.path;
return file;
}
return null;
}
if (!fileType)
fileType = url.substr(url.lastIndexOf(".") + 1, 3);
var file = getDownloadFile(title, fileType);
var persist = /*Components.classes*/Cc['@mozilla.org/embedding/browser/nsWebBrowserPersist;1'].createInstance(/*Components.interfaces*/Ci.nsIWebBrowserPersist);
var ios = /*Components.classes*/Cc['@mozilla.org/network/io-service;1'].getService(/*Components.interfaces*/Ci.nsIIOService);
var uri = ios.newURI(url, null, null);
var fileURL = ios.newFileURI(file);
persist = makeWebBrowserPersist();
const nsIWBP = /*Components.interfaces*/Ci.nsIWebBrowserPersist;
const flags = nsIWBP.PERSIST_FLAGS_REPLACE_EXISTING_FILES;
if (win && "undefined" != typeof(PrivateBrowsingUtils) && PrivateBrowsingUtils.privacyContextFromWindow) {
var privacyContext = PrivateBrowsingUtils.privacyContextFromWindow(win);
var isPrivate = privacyContext.usePrivateBrowsing;
} else {
// older than Firefox 19 or couldn't get window.
var privacyContext = null;
var isPrivate = false;
}
persist.persistFlags = flags;
if (aShouldBypassCache) {
persist.persistFlags |= nsIWBP.PERSIST_FLAGS_BYPASS_CACHE;
}
persist.persistFlags |= nsIWBP.PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION;
persist.persistFlags |= nsIWBP.PERSIST_FLAGS_DONT_CHANGE_FILENAMES;
var tr = /*Components.classes*/Cc["@mozilla.org/transfer;1"].createInstance(/*Components.interfaces*/Ci.nsITransfer);
tr.init(uri, fileURL, "", null, null, null, persist, isPrivate);
persist.progressListener = tr;
if (browser.version < 36)
persist.saveURI(uri, null, null, null, null, fileURL, privacyContext);
else // В новых FF добавлен четвертый параметр aReferrerPolicy
persist.saveURI(uri, null, null, null, null, null, fileURL, privacyContext);
}
},
utils:{
ls:null,
init_ls:function(){
if (ex_loader.browsers.mozilla || ex_loader.browsers.mozilla_jetpack){
var url = ex_loader.moz_strorage_id;
if (ex_loader.browsers.mozilla_jetpack){
var ios = Cc["@mozilla.org/network/io-service;1"]
.getService(Ci.nsIIOService);
var ssm = Cc["@mozilla.org/scriptsecuritymanager;1"]
.getService(Ci.nsIScriptSecurityManager);
var dsm = Cc["@mozilla.org/dom/storagemanager;1"]
.getService(Ci.nsIDOMStorageManager);
} else {
var ios = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
var ssm = Components.classes["@mozilla.org/scriptsecuritymanager;1"]
.getService(Components.interfaces.nsIScriptSecurityManager);
var dsm = Components.classes["@mozilla.org/dom/storagemanager;1"]
.getService(Components.interfaces.nsIDOMStorageManager);
}
var uri = ios.newURI(url, "", null);
var principal = ssm.getCodebasePrincipal(uri);
var storage = dsm.getLocalStorageForPrincipal(principal, "");
ext_api.utils.ls = storage;
} else
ext_api.utils.ls = localStorage;
},
chrome_init: function(){
var download_file_names={};
chrome.webRequest.onBeforeRequest.addListener(
function(details) {
//console.log('onBeforeRequest:',details);
var url=details.url.match(/^(.+)[&\?]\/(.+\.[a-z0-9]+)/);
if (url){
download_file_names['name'+details.requestId]=decodeURIComponent(url[2]);
return {redirectUrl: url[1]};
}
},
{urls: ["*://*.vk.me/*","*://*.userapi.me/*","*://*.vk-cdn.net/*"]},["blocking"]
);
chrome.webRequest.onHeadersReceived.addListener(
function(details) {
//console.log('onHeadersReceived:',details);
if (download_file_names['name'+details.requestId]){
var found = false;
for (var i = 0; i < details.responseHeaders.length; ++i) {
if (details.responseHeaders[i].name === 'Content-Disposition') {
details.responseHeaders[i].value = 'attachment; filename="'+download_file_names['name'+details.requestId]+'"';
found = true;
break;
} //Content-Disposition: attachment; filename=\"1.png\""
}
if (!found) details.responseHeaders.push({
name: 'Content-Disposition',
value: 'attachment; filename="'+download_file_names['name'+details.requestId]+'"'
});
return {
responseHeaders: details.responseHeaders
};
}
},
{urls: ["*://*.vk.me/*","*://*.userapi.me/*","*://*.vk-cdn.net/*"]}, ["responseHeaders","blocking"]
);
}
}
};
/*
ex_loader.init();
ext_api.utils.init_ls();
*/
ext_api.utils.init_ls.apply(this);
ex_loader.init.apply(this);
if (browser.chrome && !(window.external && window.external.mxGetRuntime))
ext_api.utils.chrome_init()
})();// ==UserScript==
// @include *.*
// ==/UserScript==
(function(){
var ext_browser={
mozilla:(function(){try{return Components.interfaces.nsIObserverService!=null} catch(e){return false} })(),
mozilla_jetpack: typeof self != 'undefined' && self.port && self.port.emit && self.port.on,
opera: window.opera && opera.extension,
chrome: window.chrome && chrome.extension,
safari: window.safari && safari.self,
maxthon: (function(){try{return window.external.mxGetRuntime!=null} catch(e){return false} })() //without try{}catch it fail script on Firefox
};
function init_content_script(win,doc,bg){
win = win || window;
doc = doc || document;
bg = bg || {};
var api_enabled = false;
var ex_ldr={
mark:'vkopt_loader',
__key:(Math.round(Math.random()*10000000)).toString(35),
init:function(){
ex_ldr.get_scripts(function(data){
var obj=JSON.parse(win.localStorage['ldr_disabled_libs'] || "{}");
var run_at_start=[];
var run_content_loaded=[];
if (data.length){
ex_ldr.inj_script("window._ext_ldr_"+ex_ldr.mark+"=true;");
}
for (var i=0; i0){
callback(data.files);
}
if (data.act=='connected'){
opera.extension.postMessage({act:'get_scripts', url:doc.location.href,in_frame:ex_ldr.is_in_frame(doc), __key:ex_ldr.__key});
console.log('ext_content: opera.extension.postMessage get_scripts');
}
if (data.api_enabled) api_enabled = true;
ex_api.ready=true;
if (data.__key==ex_ldr.__key){
ex_api.message_handler(data);
}
ex_api.post_message=function(msg){
msg=ex_api.prepare_data(msg);
opera.extension.postMessage(msg);
return msg;
}
},false);
} else if (ext_browser.chrome){ // CHROMIUM
chrome.extension.sendRequest({act:'get_scripts', url:doc.location.href,in_frame:ex_ldr.is_in_frame(doc), __key:ex_ldr.__key}, function(data) {
if (data.__key==ex_ldr.__key && data.files && data.files.length>0){
if (data.api_enabled)
api_enabled = true;
callback(data.files);
}
});
//*
ex_api.ready=true;
ex_api.post_message=function(msg){
msg=ex_api.prepare_data(msg);
chrome.extension.sendRequest(msg, function(data) {
if (data.__key==ex_ldr.__key){
ex_api.message_handler(data);
}
});
return msg;
}
} else if (ext_browser.safari){
ex_api.ready=true;
safari.self.addEventListener("message", function(e) { // SAFARI
if (e.message.__key==ex_ldr.__key && e.message.files && e.message.files.length>0){
if (e.message.api_enabled)
api_enabled = true;
callback(e.message.files);
}
if (e.message.__key==ex_ldr.__key){
ex_api.message_handler(e.message);
}
}, false);
safari.self.tab.dispatchMessage("get_scripts",{url:doc.location.href,in_frame:ex_ldr.is_in_frame(doc), __key:ex_ldr.__key});
ex_api.post_message=function(msg){
msg=ex_api.prepare_data(msg);
safari.self.tab.dispatchMessage('extension_api',msg);
return msg;
}
} else if (ext_browser.maxthon){ // MAXTHON
var rt = window.external.mxGetRuntime();
rt.post('get_scripts',{url:doc.location.href,in_frame:ex_ldr.is_in_frame(doc), __key:ex_ldr.__key});
rt.listen('scripts', function(data){
if (data.__key==ex_ldr.__key && data.files && data.files.length>0){
//console.log('scripts on '+doc.location.href,data.files);
if (data.api_enabled)
api_enabled = true;
callback(data.files);
}
});
ex_api.post_message=function(msg){
msg=ex_api.prepare_data(msg);
rt.post('extension_bg_api',msg);
return msg;
};
rt.listen('extension_api', function(data){
if (data.__key==ex_ldr.__key){
ex_api.message_handler(data);
}
});
ex_api.ready=true;
} else if (ext_browser.mozilla_jetpack){
self.port.on("scripts",function (data) {
//alert('on content script\n'+data.__key+'\n'+ex_ldr.__key+'\n'+data.files.length);
if (data.__key==ex_ldr.__key && data.files && data.files.length>0){
if (data.api_enabled)
api_enabled = true;
callback(data.files);
}
});
var get_scr = function(data) {
self.port.emit("get_scripts", {url:doc.location.href,in_frame:ex_ldr.is_in_frame(doc), __key:ex_ldr.__key});
}
get_scr();
// изначально первое сообщение не доходило в background, из-за этого 'init' запрос был добавлен
// (вероятно глюк ночной сборки, либо onAttach срабатывал после отсылки сообщения).
//self.port.on("init",get_scr);
ex_api.post_message=function(msg){
msg=ex_api.prepare_data(msg);
self.port.emit('extension_bg_api',msg);
return msg;
};
self.port.on('extension_api', function(data){
if (data.__key==ex_ldr.__key){
ex_api.message_handler(data);
}
});
ex_api.ready=true;
} else { //if (ext_browser.mozilla) // MOZILLA
bg.get_scripts(doc.location.href,function(files, api_allowed){
if (files && files.length>0){
//console.log('scripts on '+doc.location.href,data.files);
if (api_allowed)
api_enabled = true;
callback(files);
}
},ex_ldr.is_in_frame(doc));
ex_api.post_message=function(msg){
msg=ex_api.prepare_data(msg);
setTimeout(function(){
bg.postMessage(msg,function(data){
if (data.__key==ex_ldr.__key){
ex_api.message_handler(data);
}
});
},1);
return msg;
}
}
},
is_in_frame:function(doc){
return ((doc || document).defaultView.parent != (doc || document).defaultView);
},
is_allow_run:function(in_frames,doc){
in_frames = in_frames || 0;
var inframe=((doc || document).defaultView.parent != (doc || document).defaultView);
switch (in_frames){ // 0 or null - execute in all; 1 - exclude frames; 2 - only in frames; 3 - disable scripts
case 0:
return true; // include all
case 1:
return !inframe; // exclude frames
case 2:
return !!inframe; // only in frames
case 3:
return false; // disable scripts
}
return true;
},
inj_script:function(script,info,by_src){
var ext=(info || ".js").split('.').pop();
switch(ext){
case 'js':
if (ext_browser.opera) win.eval(script);
else { /*if (ext_browser.chrome || ext_browser.safari || ext_browser.maxthon)*/
var js = doc.createElement('script');
js.type = 'text/javascript';
js.charset = 'UTF-8';
if (!by_src)
js.innerHTML=script;
else
js.src=script;
js.setAttribute(ex_ldr.mark,info);
doc.getElementsByTagName('head')[0].appendChild(js);
}
break;
case 'css':
if (by_src){
var cssNode = document.createElement('link');
cssNode.type = 'text/css';
cssNode.rel = 'stylesheet';
cssNode.setAttribute(ex_ldr.mark,info);
cssNode.href = script;
doc.getElementsByTagName("head")[0].appendChild(cssNode);
} else {
var styleElement = doc.createElement("style");
styleElement.type = "text/css";
styleElement.setAttribute(ex_ldr.mark,info);
styleElement.appendChild(doc.createTextNode(script));
doc.getElementsByTagName("head")[0].appendChild(styleElement);
}
break;
}
},
init_keys:function(){
var done=function(){
informer.show(ex_ldr.mark+" scripts updated",2000,doc);
};
var keyhandler = function(e){
if (!e){ e = event; }
if (e.altKey && e.ctrlKey){
switch (e.keyCode){
case 85: /*case 1075: case 1043: case 117://alert("Alt+Ctrl+U"); */
ex_api.req({act:'update_scripts'},function(){
done();
});
informer.show(ex_ldr.mark+" run update scripts
(Alt+Ctrl+U)",2000,doc);
ex_ldr.inj_script("console.log('"+ex_ldr.mark+" run update scripts (Alt+Ctrl+U)');");
break;
}
}
};
if (doc.addEventListener){
doc.addEventListener('keydown', keyhandler, false);
} else if (doc.attachEvent){
doc.attachEvent('keydown', keyhandler);
} else {
doc.onkeydown = keyhandler;
}
}
};
var informer={
delay:2000,
show:function(msg,delay,doc){
delay = delay || informer.delay;
doc = doc || document;
var div=doc.createElement('div');
div.setAttribute('style','position:fixed; z-index:10000; background:rgba(0,0,0,0.7); color:#FFF; padding:10px; width:200px; left:-250px; border-radius:0 15px 15px 0; bottom:5px; box-shadow:0 0 5px #000; text-shadow:0 -1px #000; -webkit-transition: all 200ms linear;-moz-transition: all 200ms linear;-o-transition: all 200ms linear; transition: all 200ms linear;font-family: "tahoma", "arial", "verdana", sans-serif, "Lucida Sans"; font-size: 11px;');
console.log('informer',msg);
div.innerHTML=msg;
var a=doc.createElement('div');
a.innerHTML='×';
a.setAttribute('style','cursor:pointer; float:right; padding:0px 3px; line-height:16px;font-size: 8pt; font-weight:bold; background:rgba(0,0,0,0.5); border-radius:3px;');
div.insertBefore(a,div.firstChild);
doc.body.appendChild(div);
var old_left=div.style.left;
var visible=true;
var hide=function(){
if (!visible) return;
visible=false;
div.style.left=old_left;
setTimeout(function(){div.parentNode.removeChild(div);},400);
};
a.onclick=hide;
setTimeout(function(){div.style.left='0px';},1);
setTimeout(function(){
hide();
},delay);
}
};
// win.postMessage({act:'get',url:'http://vkopt.net/download'},"*")
var ex_msg={
init:function(handler){
if (!doc.head){
setTimeout(function(){
ex_msg.init(handler);
},10)
return;
}
if (typeof CustomEvent != 'undefined'){
win.addEventListener('vkopt_messaging_request', function(e) {
handler(e.detail,function(data){
var data_obj = {data:data}
var response = new CustomEvent("vkopt_messaging_response",{detail:data_obj});
win.dispatchEvent(response);
});
});
} else {
doc.addEventListener("vkopt_messaging_request", function(event) {
var node = event.target;
if (!node || node.nodeType != Node.TEXT_NODE)
return;
var _doc = node.ownerDocument;
handler(JSON.parse(node.nodeValue), function(response) {
node.nodeValue = JSON.stringify(response);
var event = _doc.createEvent("HTMLEvents");
event.initEvent("vkopt_messaging_response", true, false);
return node.dispatchEvent(event);
});
}, false, true);
}
}
}
var ex_api={
__key:(Math.round(Math.random()*10000000)).toString(35),
ready:false,
callbacks:{},
cid:1,
prepare_data:function(msg){
msg = msg || {};
msg.__key=ex_ldr.__key;
msg._req=ex_api.cid++;
return msg
},
post_message:function(data){console.log("can't post message to bg process",data)},
init:function(win){
win = win || window;
ex_msg.init(ex_api.on_message);
//win.addEventListener("message", ex_api.on_message,false);
},
message_handler:function(data){
data = data || {};
if (data && data._req && ex_api.callbacks['cb_'+data._req]){
ex_api.callbacks['cb_'+data._req](data);
} else {
if (data._req) console.log('Response from bg:',data);
}
},
on_message:function(e,send_response){ // FOR PAGE <-> CONTENT SCRIPT
var res = e.data;
//console.log('msg_get:',res);
if (!res.act || res.mark!=ex_ldr.mark) return;
switch (res.act){
case 'get':
case 'post':
case 'head':
case 'ajax':
case 'storage_get':
case 'storage_set':
case 'storage_keys':
case 'storage_delete':
case 'storage_clear':
case 'download':
case 'check_ext':
//case 'update_scripts':
ex_api.req(res,function(data, sub){
//win.postMessage(JSON.parse(JSON.stringify({response:data,sub:sub})),"*");
send_response(JSON.parse(JSON.stringify({response:data,sub:sub})));
});
break;
}
},
req:function(data,callback){
var data=ex_api.post_message(data);
if (!api_enabled)
return true;
data._sub = data._sub || {};
var cid=data._req;
if (callback){
ex_api.callbacks['cb_'+cid]=function(response){
callback(response,data._sub);
//alert('RESPONSE!\n'+response+'\n+data._sub);
if (!response._prevent_remove_cb)
delete ex_api.callbacks['cb_'+cid];
}
}
//console.log('REQ_ID: '+data._req);
}
};
ex_ldr.init();
ex_ldr.init_keys(); // TODO: disable if no need
ex_api.init(win);
//win.ex_api=ex_api;
}
if (ext_browser.opera || ext_browser.chrome || ext_browser.safari || ext_browser.maxthon || ext_browser.mozilla_jetpack){
init_content_script(window, document);
}
// in Mozilla browsers "init_content_script" called from background.js
vkopt_ldr_init_content_script=init_content_script;
/*
in injected scripts:
api ready check
crossdomain requests
*/
})();
[{
"type": "extension",
"frameworkVersion": "1.0.6",
"version": "2.3.3.0",
"guid": "{458D9EF6-7F82-4E4A-9D1C-DCCD956E5583}",
"name": "VkOpt",
"title": {
"ru-ru": "VkOpt",
"en": "VkOpt",
},
'description' : {
'en' : 'Extend functional of vk.com',
'ru-ru' : 'Расширение функционала социальной сети Вконтакте (vk.com)'
},
'author': {
'name': 'KiberInfinity'
},
'permissions': {
'httpRequest': ['*.vkopt.net', 'vkopt.net', '*.googlecode.com','*.*'],
'notifications': true
},
'service': {
'main': 'service.htm',
'debug': false
},
"actions": [{
"type": "script",
"entryPoints": ["doc_start"],
"include": ["*"],
"js": ["content_script.js"],
"includeFrames": true
}]
}]PNG
IHDR a pHYs
OiCCPPhotoshop ICC profile xڝSgTS=BKKoR RB&*! J!QEEȠQ,
!{kּ>H3Q5B.@
$p d!s# ~<<+" x M0B\t8K @zB @F&S