Created
April 21, 2018 16:02
-
-
Save lekhnath/fe3388d7a5880c5c96f9b1b16b5ea8d2 to your computer and use it in GitHub Desktop.
save from net
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // ==UserScript== | |
| // @name SaveFrom.net helper | |
| // @namespace http://savefrom.net/ | |
| // @version 2.70 | |
| // @date 2014-07-12 | |
| // @author Magicbit, Inc | |
| // @description Youtube Downloader: all in one script to get Vimeo, Facebook, Dailymotion videos for free | |
| // @homepage http://savefrom.net/user.php?helper=userjs | |
| // @icon http://savefrom.net/img/extension/icon_16.png | |
| // @icon64 http://savefrom.net/img/extension/icon_64.png | |
| // @updateURL https://sf-addon.com/helper/chrome/helper.meta.js | |
| // @downloadURL https://sf-addon.com/helper/chrome/helper.user.js | |
| // @include http://* | |
| // @include https://* | |
| // @exclude *://google.*/* | |
| // @exclude *://*.google.*/* | |
| // @exclude *://acidtests.org/* | |
| // @exclude *://*.acidtests.org/* | |
| // @run-at document-end | |
| // @grant GM_setValue | |
| // @grant GM_getValue | |
| // @grant GM_xmlhttpRequest | |
| // @grant GM_info | |
| // @grant GM_openInTab | |
| // @grant GM_registerMenuCommand | |
| // @grant GM_unregisterMenuCommand | |
| // @grant GM_notification | |
| // @grant GM_download | |
| // ==/UserScript== | |
| (function(){ | |
| if(!window.GM_getValue) | |
| return; | |
| if(window.sessionStorage) { | |
| sessionStorage['savefrom-helper-userjs'] = '1'; | |
| } | |
| var chrome, _menu, _options, _background, SaveFrom_Utils, _moduleHosts, _modules; | |
| ///////////////////////////////////////////////// | |
| // CHROME | |
| chrome = { | |
| app: { | |
| getDetails: function(){ | |
| if(GM_info && GM_info.script) | |
| return GM_info.script; | |
| return {}; | |
| } | |
| }, | |
| browserAction: { | |
| setIcon: function(icon){}, | |
| setTitle: function(title){}, | |
| }, | |
| tabs: { | |
| getSelected: function(winId, cb){ | |
| cb({ | |
| id: 1, | |
| url: location.href | |
| }); | |
| }, | |
| query: function(queryInfo, cb){ | |
| cb([]); | |
| }, | |
| create: function(options){ | |
| GM_openInTab(options.url, { | |
| active: options.selected || options.active, | |
| insert: true | |
| }); | |
| }, | |
| sendRequest: function(id, request, callback){ | |
| if(!chrome.extension.moduleRequestHandler) | |
| return; | |
| chrome.extension.moduleRequestHandler(request, {}, callback); | |
| }, | |
| onRemoved: { | |
| addListener: function(){} | |
| } | |
| }, | |
| extension: { | |
| requestHandler: null, | |
| moduleRequestHandler: null, | |
| onRequest: { | |
| addListener: function(cb){ | |
| if(!chrome.extension.requestHandler) | |
| { | |
| chrome.extension.requestHandler = cb; | |
| return; | |
| } | |
| chrome.extension.moduleRequestHandler = cb; | |
| } | |
| }, | |
| sendRequest: function(request, callback) | |
| { | |
| if(!chrome.extension.requestHandler) | |
| { | |
| callback(); | |
| return; | |
| } | |
| var sender = { | |
| moduleName: request.moduleName, | |
| tab: { | |
| id: 1, | |
| url: location.href | |
| } | |
| }; | |
| chrome.extension.requestHandler(request, sender, callback); | |
| } | |
| }, | |
| i18n: { | |
| lang: 'en', | |
| messages: {en: {}}, | |
| detectUserLanguage: function() | |
| { | |
| var lang = window.navigator.userLanguage || window.navigator.language; | |
| if(lang && this.messages[lang]) | |
| this.lang = lang; | |
| return this.lang; | |
| }, | |
| getMessage: function(msg_id) | |
| { | |
| var m = this.messages[this.lang]; | |
| if(m && m[msg_id] && m[msg_id].message) | |
| return m[msg_id].message; | |
| return ''; | |
| }, | |
| translate: function(parent) | |
| { | |
| parent = parent || document; | |
| var e_list = parent.querySelectorAll('*[data-i18n]'); | |
| for(var i = 0, len = e_list.length; i < len; i++) | |
| { | |
| var el = e_list[i]; | |
| el.innerText = chrome.i18n.getMessage(el.dataset.i18n); | |
| } | |
| } | |
| }, | |
| downloads: { | |
| download: function(options, cb) { | |
| if (!window.GM_download) { | |
| return; | |
| } | |
| var gm_options = {}; | |
| gm_options.url = options.url; | |
| gm_options.name = options.filename; | |
| gm_options.headers = options.headers; | |
| gm_options.saveAs = !!(options.saveAs); | |
| gm_options.onload = function() { | |
| cb(true); | |
| }; | |
| gm_options.onerror = cb; | |
| GM_download(gm_options); | |
| } | |
| } | |
| }; | |
| ///////////////////////////////////////////////// | |
| // MENU | |
| _menu = { | |
| activeDataAttr: 'data-sfh-active', | |
| id: 'sfh--ujs-menu', | |
| tooltipId: 'sfh--ujs-menu-tooltip', | |
| enabled: true, | |
| active: false, | |
| hover: false, | |
| title: '', | |
| items: [], | |
| shakeTimer: 0, | |
| shakeInterval: 10000, | |
| menu: null, | |
| icon: null, | |
| style: { | |
| menu: { | |
| initial: { | |
| background: '#fff', | |
| borderStyle: 'solid', | |
| borderWidth: '2px 0 2px 2px', | |
| borderRadius: '5px 0 0 5px', | |
| display: 'none', | |
| boxSizing: 'content-box', | |
| font: '13px/18px Arial,Helvetica,sans-serif', | |
| width: 'auto', | |
| height: 'auto', | |
| padding: 0, | |
| margin: 0, | |
| overflow: 'visible', | |
| position: 'fixed', | |
| top: '50px', | |
| right: '0', | |
| textAlign: 'left', | |
| WebkitTransition: 'all 0.2s', | |
| transition: 'all 0.2s', | |
| zIndex: 99999, | |
| cursor: 'pointer' | |
| }, | |
| enabled: { | |
| borderColor: '#8dc50b' | |
| }, | |
| disabled: { | |
| borderColor: '#d0d0d0' | |
| }, | |
| tag: { | |
| display: 'block', | |
| width: '10px', | |
| height: '20px', | |
| overflow: 'hidden', | |
| opacity: 0.5 | |
| }, | |
| tagHover: { | |
| width: '20px', | |
| opacity: 0.8 | |
| }, | |
| active: { | |
| width: 'auto', | |
| height: 'auto', | |
| overflow: 'visible', | |
| opacity: 0.9 | |
| } | |
| }, | |
| icon: { | |
| initial: { | |
| display: 'inline-block', | |
| boxSizing: 'content-box', | |
| backgroundPosition: '50% 50%', | |
| backgroundRepeat: 'no-repeat', | |
| width: '16px', | |
| height: '16px', | |
| margin: 0, | |
| padding: '2px', | |
| overflow: 'hidden', | |
| verticalAlign: 'middle' | |
| }, | |
| enabled: { | |
| backgroundImage: 'url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAA3XAAAN1wFCKJt4AAACOklEQVQ4y42TTWgTURSFz3sv00maJqVWg6LiD7VUdGERQQnoQlS6sStxVVBULE0XoiDFjejChaC4qCCIKBQE0U1XpYoLFX9AXLbVVhR/UInGTjKZeTOTee+6aKdO2iAeuJvDd8+73MtjRIRIT2ud5d3GdOsLdP0150VEyLN3LGIiPxGHPE8RDEApAkCLAuboiInE45ArwxIAhKHWWhPiFYak40zdBCMzazpyy9btcsuoIAcEUktuIB0HVUASScAtozIu8n3F359e9m36+j4BAHa1erzqTB7mjK0HAE8qaVB9QOBBAoDt2tvKzuRFIroHYIgDwEC3NWQV3YJlyZn5ADcIFOLlS+UCgGXJGavoFga6rSEAYPErRLozsXqqOUtddfsp4+2Rrd82L2YTDz53nDST2Q1ps42STZlmVdMrBGvmQa1SBwqe5c8qB+8Kg//0Att1/Fnme5WPbHgq026qpjEh2A4A4Ew4XBh2GHor615KJH9oVctoUmkAUIpe+yLoYUSECw8zufZ2MWoYfCf+Q7WaflUqqd7z++3iwg4ujadXpVr4fcPk+X82+/q5rOpD5w4435cs8cwoW7s8mxoxTb6nUbPv6ye/KrLvSi99ibwlVzh9m23M5MwbqTTfF/elox/ZRb//6lH6EPcbnnHwJutsaRPX0q2iBwCcshqrzqpTwydoejHbMAAABq+zLSLDLgOAsunscIEmGnELAYwxBoABEABMAKm9x7AdAB7fwhsAEoAPQM397rnGP/fQK/eKCl8BAAAAAElFTkSuQmCC)' | |
| }, | |
| disabled: { | |
| backgroundImage: 'url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAKT2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVNnVFPpFj333vRCS4iAlEtvUhUIIFJCi4AUkSYqIQkQSoghodkVUcERRUUEG8igiAOOjoCMFVEsDIoK2AfkIaKOg6OIisr74Xuja9a89+bN/rXXPues852zzwfACAyWSDNRNYAMqUIeEeCDx8TG4eQuQIEKJHAAEAizZCFz/SMBAPh+PDwrIsAHvgABeNMLCADATZvAMByH/w/qQplcAYCEAcB0kThLCIAUAEB6jkKmAEBGAYCdmCZTAKAEAGDLY2LjAFAtAGAnf+bTAICd+Jl7AQBblCEVAaCRACATZYhEAGg7AKzPVopFAFgwABRmS8Q5ANgtADBJV2ZIALC3AMDOEAuyAAgMADBRiIUpAAR7AGDIIyN4AISZABRG8lc88SuuEOcqAAB4mbI8uSQ5RYFbCC1xB1dXLh4ozkkXKxQ2YQJhmkAuwnmZGTKBNA/g88wAAKCRFRHgg/P9eM4Ors7ONo62Dl8t6r8G/yJiYuP+5c+rcEAAAOF0ftH+LC+zGoA7BoBt/qIl7gRoXgugdfeLZrIPQLUAoOnaV/Nw+H48PEWhkLnZ2eXk5NhKxEJbYcpXff5nwl/AV/1s+X48/Pf14L7iJIEyXYFHBPjgwsz0TKUcz5IJhGLc5o9H/LcL//wd0yLESWK5WCoU41EScY5EmozzMqUiiUKSKcUl0v9k4t8s+wM+3zUAsGo+AXuRLahdYwP2SycQWHTA4vcAAPK7b8HUKAgDgGiD4c93/+8//UegJQCAZkmScQAAXkQkLlTKsz/HCAAARKCBKrBBG/TBGCzABhzBBdzBC/xgNoRCJMTCQhBCCmSAHHJgKayCQiiGzbAdKmAv1EAdNMBRaIaTcA4uwlW4Dj1wD/phCJ7BKLyBCQRByAgTYSHaiAFiilgjjggXmYX4IcFIBBKLJCDJiBRRIkuRNUgxUopUIFVIHfI9cgI5h1xGupE7yAAygvyGvEcxlIGyUT3UDLVDuag3GoRGogvQZHQxmo8WoJvQcrQaPYw2oefQq2gP2o8+Q8cwwOgYBzPEbDAuxsNCsTgsCZNjy7EirAyrxhqwVqwDu4n1Y8+xdwQSgUXACTYEd0IgYR5BSFhMWE7YSKggHCQ0EdoJNwkDhFHCJyKTqEu0JroR+cQYYjIxh1hILCPWEo8TLxB7iEPENyQSiUMyJ7mQAkmxpFTSEtJG0m5SI+ksqZs0SBojk8naZGuyBzmULCAryIXkneTD5DPkG+Qh8lsKnWJAcaT4U+IoUspqShnlEOU05QZlmDJBVaOaUt2ooVQRNY9aQq2htlKvUYeoEzR1mjnNgxZJS6WtopXTGmgXaPdpr+h0uhHdlR5Ol9BX0svpR+iX6AP0dwwNhhWDx4hnKBmbGAcYZxl3GK+YTKYZ04sZx1QwNzHrmOeZD5lvVVgqtip8FZHKCpVKlSaVGyovVKmqpqreqgtV81XLVI+pXlN9rkZVM1PjqQnUlqtVqp1Q61MbU2epO6iHqmeob1Q/pH5Z/YkGWcNMw09DpFGgsV/jvMYgC2MZs3gsIWsNq4Z1gTXEJrHN2Xx2KruY/R27iz2qqaE5QzNKM1ezUvOUZj8H45hx+Jx0TgnnKKeX836K3hTvKeIpG6Y0TLkxZVxrqpaXllirSKtRq0frvTau7aedpr1Fu1n7gQ5Bx0onXCdHZ4/OBZ3nU9lT3acKpxZNPTr1ri6qa6UbobtEd79up+6Ynr5egJ5Mb6feeb3n+hx9L/1U/W36p/VHDFgGswwkBtsMzhg8xTVxbzwdL8fb8VFDXcNAQ6VhlWGX4YSRudE8o9VGjUYPjGnGXOMk423GbcajJgYmISZLTepN7ppSTbmmKaY7TDtMx83MzaLN1pk1mz0x1zLnm+eb15vft2BaeFostqi2uGVJsuRaplnutrxuhVo5WaVYVVpds0atna0l1rutu6cRp7lOk06rntZnw7Dxtsm2qbcZsOXYBtuutm22fWFnYhdnt8Wuw+6TvZN9un2N/T0HDYfZDqsdWh1+c7RyFDpWOt6azpzuP33F9JbpL2dYzxDP2DPjthPLKcRpnVOb00dnF2e5c4PziIuJS4LLLpc+Lpsbxt3IveRKdPVxXeF60vWdm7Obwu2o26/uNu5p7ofcn8w0nymeWTNz0MPIQ+BR5dE/C5+VMGvfrH5PQ0+BZ7XnIy9jL5FXrdewt6V3qvdh7xc+9j5yn+M+4zw33jLeWV/MN8C3yLfLT8Nvnl+F30N/I/9k/3r/0QCngCUBZwOJgUGBWwL7+Hp8Ib+OPzrbZfay2e1BjKC5QRVBj4KtguXBrSFoyOyQrSH355jOkc5pDoVQfujW0Adh5mGLw34MJ4WHhVeGP45wiFga0TGXNXfR3ENz30T6RJZE3ptnMU85ry1KNSo+qi5qPNo3ujS6P8YuZlnM1VidWElsSxw5LiquNm5svt/87fOH4p3iC+N7F5gvyF1weaHOwvSFpxapLhIsOpZATIhOOJTwQRAqqBaMJfITdyWOCnnCHcJnIi/RNtGI2ENcKh5O8kgqTXqS7JG8NXkkxTOlLOW5hCepkLxMDUzdmzqeFpp2IG0yPTq9MYOSkZBxQqohTZO2Z+pn5mZ2y6xlhbL+xW6Lty8elQfJa7OQrAVZLQq2QqboVFoo1yoHsmdlV2a/zYnKOZarnivN7cyzytuQN5zvn//tEsIS4ZK2pYZLVy0dWOa9rGo5sjxxedsK4xUFK4ZWBqw8uIq2Km3VT6vtV5eufr0mek1rgV7ByoLBtQFr6wtVCuWFfevc1+1dT1gvWd+1YfqGnRs+FYmKrhTbF5cVf9go3HjlG4dvyr+Z3JS0qavEuWTPZtJm6ebeLZ5bDpaql+aXDm4N2dq0Dd9WtO319kXbL5fNKNu7g7ZDuaO/PLi8ZafJzs07P1SkVPRU+lQ27tLdtWHX+G7R7ht7vPY07NXbW7z3/T7JvttVAVVN1WbVZftJ+7P3P66Jqun4lvttXa1ObXHtxwPSA/0HIw6217nU1R3SPVRSj9Yr60cOxx++/p3vdy0NNg1VjZzG4iNwRHnk6fcJ3/ceDTradox7rOEH0x92HWcdL2pCmvKaRptTmvtbYlu6T8w+0dbq3nr8R9sfD5w0PFl5SvNUyWna6YLTk2fyz4ydlZ19fi753GDborZ752PO32oPb++6EHTh0kX/i+c7vDvOXPK4dPKy2+UTV7hXmq86X23qdOo8/pPTT8e7nLuarrlca7nuer21e2b36RueN87d9L158Rb/1tWeOT3dvfN6b/fF9/XfFt1+cif9zsu72Xcn7q28T7xf9EDtQdlD3YfVP1v+3Njv3H9qwHeg89HcR/cGhYPP/pH1jw9DBY+Zj8uGDYbrnjg+OTniP3L96fynQ89kzyaeF/6i/suuFxYvfvjV69fO0ZjRoZfyl5O/bXyl/erA6xmv28bCxh6+yXgzMV70VvvtwXfcdx3vo98PT+R8IH8o/2j5sfVT0Kf7kxmTk/8EA5jz/GMzLdsAAAAgY0hSTQAAeiUAAICDAAD5/wAAgOkAAHUwAADqYAAAOpgAABdvkl/FRgAAAiNJREFUeNqMkj+oUlEcx7/nHu/V7lMTxaghqIgoWpIQisCmhjfloDS9QQgMHkpTODc2hS45OQRB6GCLb2hqiAIJpzB6UUhDkqi34/17rtfTonI1ifeDs/zO5/eB8/0dwhjDqjRN+xOLxU4bhiGwVUIIhMNhsmJW/YAfsm1bAIDnedgl8DM7BYZhjAHAdd0FpVTy383n84Wf2RD0er3L8Xj8tq7rDAAcx7EopXtbAgsAdF1ng8HgYDKZfEilUt8CADCbzR7quv5AkqQLAGBZlhUMBjcEjuOsBDcYY0+FEK8BVCQAyGQylel0eqhp2vHynSbnHP5j27a5DPp4Op0eZjKZCgAQ/xZW1e12++Fw+Kq/p+v6l3Q6fW2bDfT7/aKiKBdDoZBQFEX1PC9JCJE45xsgIUQaDoevKKUjzrlp2zbhnP8gnU4nIcvyEaU0vQQNSZJmnued9QsopcPFYhERQuwtV911XXefMMbQbDbPJJPJN7Is38IJynXdj6PR6H4+n/+9zqDdbp9TVbWpKMqd/w1zzt+bppnPZrO//gmx0WicTyQSL0Oh0N1dw7ZtvxuPxweFQuHnOpvtLdTr9UuxWOyFqqr3/H3TNN9qmvaoWCx+3wh31xprtdqVaDT6PBKJ7C8/2hFj7HGpVPq6ze4UAEC1Wr0uy/KzZWhPyuXy513cWhCNRgkAAoACCAI4lcvlbgJAq9X6BMAC4ADwAAjGmACAvwMAXX8khNE72VIAAAAASUVORK5CYII=)' | |
| }, | |
| tag: {padding: '2px'}, | |
| active: {padding: '5px'} | |
| }, | |
| title: { | |
| display: 'inline-block', | |
| font: 'bold 13px/18px Arial,Helvetica,sans-serif', | |
| lineHeight: '26px', | |
| margin: 0, | |
| padding: 0, | |
| textAlign: 'left', | |
| verticalAlign: 'middle' | |
| }, | |
| itemsBox: { | |
| display: 'block', | |
| margin: 0, | |
| padding: 0 | |
| }, | |
| item: { | |
| color: '#000', | |
| backgroundColor: '#fff', | |
| border: 'none', | |
| boxSizing: 'content-box', | |
| font: 'normal 13px/18px Arial,Helvetica,sans-serif', | |
| margin: '2px', | |
| padding: '2px 3px', | |
| position: 'relative', | |
| whiteSpace: 'nowrap', | |
| textAlign: 'left', | |
| cursor: 'pointer' | |
| }, | |
| itemHover: { | |
| backgroundColor: '#f9f9f9', | |
| border: '1px solid #d0d0d0', | |
| borderRadius: '3px', | |
| padding: '1px 2px' | |
| }, | |
| itemSep: { | |
| backgroundColor: '#d0d0d0', | |
| border: 'none', | |
| borderRadius: 0, | |
| boxSizing: 'content-box', | |
| height: '1px', | |
| lineHeight: '1px', | |
| margin: '5px', | |
| padding: '0', | |
| cursor: 'default' | |
| } | |
| }, | |
| addItem: function(id, title, fn) | |
| { | |
| if(!title) | |
| title = '-'; | |
| return this.items.push({id: id, title: title, fn: fn}); | |
| }, | |
| resetItems: function() | |
| { | |
| this.items = []; | |
| }, | |
| setTitle: function(title, version) | |
| { | |
| this.title = title; | |
| if(version) | |
| this.title += ' ' + version; | |
| }, | |
| create: function(enabled){ | |
| if(this.menu || !document.body) | |
| return; | |
| if(!this.items) | |
| return; | |
| var _this = this; | |
| var menu = document.createElement('div'); | |
| menu.addEventListener('mouseover', function(){ | |
| if(!_this.active) | |
| { | |
| _this.hover = true; | |
| _this.setElementsStyle('tagHover'); | |
| } | |
| }); | |
| menu.addEventListener('mouseout', function(){ | |
| if(!_this.active) | |
| { | |
| _this.hover = false; | |
| _this.setElementsStyle('tag'); | |
| } | |
| }); | |
| var icon = document.createElement('div'); | |
| icon.title = this.title; | |
| icon.addEventListener('click', function(event){ | |
| event.preventDefault(); | |
| event.stopPropagation(); | |
| if(event.button === 0) | |
| { | |
| _this.toggleMenuItems(); | |
| } | |
| else if(event.button == 2) | |
| { | |
| _this.remove(); | |
| } | |
| return false; | |
| }, false); | |
| icon.addEventListener('contextmenu', function(event){ | |
| event.preventDefault(); | |
| event.stopPropagation(); | |
| _this.remove(); | |
| return false; | |
| }, false); | |
| this.icon = menu.appendChild(icon); | |
| this.menu = document.body.appendChild(menu); | |
| this.setElementsStyle('initial'); | |
| this.setEnabled(enabled); | |
| this.showTag(); | |
| if(this.isNewUser()) | |
| { | |
| this.shakeTimer = setTimeout(function(){_this.shakeTag();}, this.shakeInterval); | |
| } | |
| }, | |
| setStyle: function(element, style) | |
| { | |
| if(this[element] && this.style[element] && this.style[element][style]) | |
| SaveFrom_Utils.setStyle(this[element], this.style[element][style]); | |
| }, | |
| setElementsStyle: function(style) | |
| { | |
| if(!style) | |
| return; | |
| var elements = ['menu', 'icon']; | |
| for(var i = 0; i < elements.length; i++) | |
| this.setStyle(elements[i], style); | |
| }, | |
| setEnabled: function(enabled) | |
| { | |
| this.enabled = enabled; | |
| this.setElementsStyle(this.enabled ? 'enabled' : 'disabled'); | |
| }, | |
| showTag: function() | |
| { | |
| this.setElementsStyle('tag'); | |
| }, | |
| toggleMenuItems: function() | |
| { | |
| return _menu.active ? _menu.hideMenuItems() : _menu.showMenuItems(); | |
| }, | |
| remove: function() | |
| { | |
| if(_menu.menu) | |
| _menu.menu.parentNode.removeChild(_menu.menu); | |
| _menu.removeTooltip(); | |
| }, | |
| showMenuItems: function() | |
| { | |
| if(this.active) | |
| return; | |
| this.removeActiveItems(); | |
| var title = this.createTitle(); | |
| if(title) | |
| this.menu.appendChild(title); | |
| var items = this.createItems(); | |
| if(items) | |
| this.menu.appendChild(items); | |
| this.active = true; | |
| this.setElementsStyle('active'); | |
| document.addEventListener('click', this.onDocumentClick, false); | |
| document.addEventListener('keydown', this.onDocumentKeyDown, false); | |
| if(this.isNewUser()) | |
| { | |
| GM_setValue('newUser', '0'); | |
| this.showTooltip(); | |
| } | |
| }, | |
| hideMenuItems: function() | |
| { | |
| this.removeTooltip(); | |
| this.removeActiveItems(); | |
| document.removeEventListener('click', this.onDocumentClick, false); | |
| document.removeEventListener('keydown', this.onDocumentKeyDown, false); | |
| this.active = false; | |
| this.showTag(); | |
| }, | |
| onDocumentClick: function(event) | |
| { | |
| var node = event.target; | |
| if(node != _menu.menu && !SaveFrom_Utils.isParent(node, _menu.menu)) | |
| { | |
| _menu.hideMenuItems(); | |
| } | |
| }, | |
| onDocumentKeyDown: function(event) | |
| { | |
| if(event.keyCode == 27) | |
| { | |
| _menu.hideMenuItems(); | |
| } | |
| }, | |
| removeActiveItems: function() | |
| { | |
| var e = null; | |
| while(e = this.menu.querySelector('div[' + this.activeDataAttr + ']')) | |
| { | |
| e.parentNode.removeChild(e); | |
| } | |
| }, | |
| createTitle: function() | |
| { | |
| var _this = this; | |
| if(!this.title) | |
| return null; | |
| var title = document.createElement('div'); | |
| title.innerHTML = this.title; | |
| title.setAttribute(this.activeDataAttr, '1'); | |
| SaveFrom_Utils.setStyle(title, this.style.title); | |
| title.addEventListener('click', function(event){ | |
| if(event.button === 0) | |
| { | |
| event.preventDefault(); | |
| event.stopPropagation(); | |
| _this.toggleMenuItems(); | |
| return false; | |
| } | |
| }); | |
| return title; | |
| }, | |
| createItems: function() | |
| { | |
| if(!this.items) | |
| return; | |
| var box = document.createElement('div'); | |
| box.setAttribute(this.activeDataAttr, '1'); | |
| SaveFrom_Utils.setStyle(box, this.style.itemsBox); | |
| for(var i = 0; i < this.items.length; i++) | |
| { | |
| this.createItem(this.items[i], box); | |
| } | |
| return box; | |
| }, | |
| createItem: function(data, parent) | |
| { | |
| var _this = this, | |
| item = document.createElement('div'); | |
| if(!data.title || data.title == '-') | |
| { | |
| SaveFrom_Utils.setStyle(item, this.style.itemSep); | |
| } | |
| else if(data.fn) | |
| { | |
| item.innerHTML = data.title; | |
| SaveFrom_Utils.setStyle(item, this.style.item); | |
| item.addEventListener('mouseover', function(){ | |
| SaveFrom_Utils.setStyle(this, _this.style.itemHover); | |
| }); | |
| item.addEventListener('mouseout', function(){ | |
| SaveFrom_Utils.setStyle(this, _this.style.item); | |
| }); | |
| item.addEventListener('click', function(event){ | |
| if(event.button === 0) | |
| { | |
| event.preventDefault(); | |
| event.stopPropagation(); | |
| _this.hideMenuItems(); | |
| data.fn(data.id, data.title); | |
| return false; | |
| } | |
| }); | |
| } | |
| parent.appendChild(item); | |
| }, | |
| isNewUser: function() | |
| { | |
| return GM_getValue('newUser') == '1'; | |
| }, | |
| shakeTag: function() | |
| { | |
| clearTimeout(this.shakeTag); | |
| if(!this.enabled || this.active || !this.isNewUser()) | |
| return; | |
| if(this.hover) | |
| { | |
| this.shakeTimer = setTimeout(function(){_menu.shakeTag();}, _menu.shakeInterval); | |
| return; | |
| } | |
| var style = 'tagHover', counter = 0; | |
| function step() | |
| { | |
| SaveFrom_Utils.setStyle(_menu.menu, _menu.style.menu[style]); | |
| style = (style == 'tagHover') ? 'tag' : 'tagHover'; | |
| if(counter++ < 3) | |
| { | |
| setTimeout(step, 100); | |
| return; | |
| } | |
| _menu.shakeTimer = setTimeout(function(){_menu.shakeTag();}, _menu.shakeInterval); | |
| } | |
| step(); | |
| }, | |
| removeTooltip: function() | |
| { | |
| var e = document.getElementById(this.tooltipId); | |
| if(e) | |
| e.parentNode.removeChild(e); | |
| }, | |
| showTooltip: function() | |
| { | |
| var menuSize = SaveFrom_Utils.getSize(this.menu); | |
| var t = document.createElement('div'); | |
| t.id = this.tooltipId; | |
| SaveFrom_Utils.setStyle(t, { | |
| border: 'none', | |
| display: 'block', | |
| boxSizing: 'content-box', | |
| width: '280px', | |
| height: 'auto', | |
| padding: 0, | |
| margin: 0, | |
| overflow: 'visible', | |
| position: 'fixed', | |
| top: '50px', | |
| right: menuSize.width + 10 + 'px', | |
| WebkitTransition: 'all 0.2s', | |
| transition: 'all 0.2s', | |
| zIndex: 99999, | |
| opacity: 0 | |
| }); | |
| var cnt = document.createElement('div'); | |
| cnt.innerHTML = chrome.i18n.getMessage("menuTooltip"); | |
| SaveFrom_Utils.setStyle(cnt, { | |
| color: '#000', | |
| background: '#fdeca6', | |
| border: '1px solid #b3a77d', | |
| borderRadius: '5px', | |
| display: 'block', | |
| boxSizing: 'content-box', | |
| font: '13px/18px Arial,Helvetica,sans-serif', | |
| padding: '10px', | |
| margin: 0, | |
| position: 'relative', | |
| textAlign: 'left' | |
| }); | |
| var arrow = document.createElement('div'); | |
| SaveFrom_Utils.setStyle(arrow, { | |
| background: '#fdeca6', | |
| borderRight: '1px solid #b3a77d', | |
| borderBottom: '1px solid #b3a77d', | |
| boxSizing: 'content-box', | |
| position: 'absolute', | |
| top: '10px', | |
| right: '-7px', | |
| width: '10px', | |
| height: '10px', | |
| WebkitTransform: 'rotate(-45deg)' | |
| }); | |
| cnt.appendChild(arrow); | |
| t.appendChild(cnt); | |
| document.body.appendChild(t); | |
| t.style.opacity = '0.9'; | |
| } | |
| }; | |
| ///////////////////////////////////////////////// | |
| // OPTIONS | |
| _options = { | |
| classPrefix: 'sfh--', | |
| dataAttr: 'data-sfh-option', | |
| html: 'PHN0eWxlIHR5cGU9InRleHQvY3NzIj4KLnNmaC0tb3B0aW9uc3tiYWNrZ3JvdW5kLWNvbG9yOiNmZmY7Ym9yZGVyOm5vbmU7Zm9udDoxM3B4LzEgQXJpYWwsSGVsdmV0aWNhLHNhbnMtc2VyaWY7d2lkdGg6NTgwcHg7bWFyZ2luOjA7cGFkZGluZzo5cHg7dGV4dC1hbGlnbjpsZWZ0fS5zZmgtLW9wdGlvbnMgLnNmaC0tdGl0bGV7Zm9udC1zaXplOjEuM2VtO21hcmdpbjowIDAgMS4zZW0gMH0KLnNmaC0tb3B0aW9ucyBmb3Jte21hcmdpbjowO3BhZGRpbmc6MH0KLnNmaC0tb3B0aW9ucyBsYWJlbHtkaXNwbGF5OmJsb2NrO21hcmdpbjouMmVtIDA7cGFkZGluZzowO3RleHQtYWxpZ246bGVmdH0KLnNmaC0tb3B0aW9ucyAuc2ZoLS1pbmxpbmUtY29udGVudCBsYWJlbHtkaXNwbGF5OmlubGluZS1ibG9jazttYXJnaW4tbGVmdDoxMHB4fQouc2ZoLS1vcHRpb25zIC5zZmgtLWZsZWZ0e2Zsb2F0OmxlZnR9Ci5zZmgtLW9wdGlvbnMgLnNmaC0tZmwtY29sdW1ue2Zsb2F0OmxlZnQ7bWFyZ2luLXJpZ2h0OjIwcHh9Ci5zZmgtLW9wdGlvbnMgLnNmaC0tY2xlYXJ7Y2xlYXI6Ym90aDtoZWlnaHQ6MDtmb250LXNpemU6MDtsaW5lLWhlaWdodDowfQouc2ZoLS1vcHRpb25zIC5zZmgtLWJsb2Nre2JvcmRlci10b3A6MXB4IHNvbGlkICNkZmUxZTg7cGFkZGluZzoxLjVlbSAwIDAgMDttYXJnaW46MS41ZW0gMCAwIDA7bWluLXdpZHRoOjE2MHB4fQouc2ZoLS1vcHRpb25zIC5zZmgtLWJsb2NrLXRpdGxle2ZvbnQtd2VpZ2h0OmJvbGQ7bWFyZ2luLWJvdHRvbTouNWVtfQouc2ZoLS1vcHRpb25zIC5zZmgtLW1vZHVsZXtmb250LXdlaWdodDpib2xkO21hcmdpbi10b3A6MWVtfS5zZmgtLW9wdGlvbnMgLnNmaC0tbW9kdWxlOmZpcnN0LWNoaWxke21hcmdpbi10b3A6MH0KLnNmaC0tb3B0aW9ucyAuc2ZoLS1tb2R1bGVfb3B0aW9uc3tmb250LXNpemU6LjllbTtmb250LXdlaWdodDpub3JtYWw7bWFyZ2luLWxlZnQ6MmVtfQoKPC9zdHlsZT4KPGRpdiBjbGFzcz0ic2ZoLS1vcHRpb25zIj4KICA8ZGl2IGNsYXNzPSJzZmgtLXRpdGxlIiBkYXRhLWkxOG49Im9wdGlvbnNUaXRsZSI+U2F2ZUZyb20ubmV0IEhlbHBlciAtIFByZWZlcmVuY2VzPC9kaXY+CgogIDxmb3JtPgogICAgPGRpdiBjbGFzcz0ic2ZoLS1ibG9jayI+CiAgICAgIDxkaXYgZGF0YS1pMThuPSJvcHRpb25zSGFuZGxlTGlua3MiIGNsYXNzPSJzZmgtLWJsb2NrLXRpdGxlIj5IYW5kbGUgbGlua3M8L2Rpdj4KICAgICAgPGxhYmVsPjxpbnB1dCB0eXBlPSJjaGVja2JveCIgZGF0YS1zZmgtb3B0aW9uPSJsbUZpbGVIb3N0aW5nIiBjaGVja2VkPSIxIj4mbmJzcDs8c3BhbiBkYXRhLWkxOG49Im9wdGlvbnNGaWxlSG9zdGluZ3MiPlRvIGZpbGVob3N0aW5nczwvc3Bhbj48L2xhYmVsPgogICAgICA8bGFiZWw+PGlucHV0IHR5cGU9ImNoZWNrYm94IiBkYXRhLXNmaC1vcHRpb249ImxtTWVkaWFIb3N0aW5nIiBjaGVja2VkPSIxIj4mbmJzcDs8c3BhbiBkYXRhLWkxOG49Im9wdGlvbnNNZWRpYUhvc3RpbmdzIj5UbyBtZWRpYWhvc3RpbmdzPC9zcGFuPjwvbGFiZWw+CiAgICA8L2Rpdj4KCiAgICA8ZGl2IGNsYXNzPSJzZmgtLWJsb2NrIj4KICAgICAgPGRpdiBkYXRhLWkxOG49Im9wdGlvbnNNb2R1bGVzIiBjbGFzcz0ic2ZoLS1ibG9jay10aXRsZSI+TW9kdWxlczwvZGl2PgogICAgICA8ZGl2IGNsYXNzPSJzZmgtLXlvdXR1YmVfYm94IiBjbGFzcz0ic2ZoLS1tb2R1bGUiPjxsYWJlbD48aW5wdXQgdHlwZT0iY2hlY2tib3giIGRhdGEtc2ZoLW9wdGlvbj0ibW9kdWxlWW91dHViZSIgY2hlY2tlZD0iMSI+Jm5ic3A7PHNwYW4gZGF0YS1pMThuPSJvcHRpb25zWW91dHViZSI+WW91VHViZTwvc3Bhbj48L2xhYmVsPgogICAgICAgIDxkaXYgY2xhc3M9InNmaC0tbW9kdWxlX29wdGlvbnMiPgogICAgICAgICAgPGRpdiBjbGFzcz0ic2ZoLS1mbC1jb2x1bW4iPjxzcGFuIGRhdGEtaTE4bj0ib3B0aW9uc1lUSGlkZUxpbmtzIj5IaWRlIGxpbmtzPC9zcGFuPjo8L2Rpdj4KICAgICAgICAgIDxkaXYgY2xhc3M9InNmaC0tZmxlZnQgc2ZoLS1pbmxpbmUtY29udGVudCI+CiAgICAgICAgICAgIDxsYWJlbD48aW5wdXQgdHlwZT0iY2hlY2tib3giIGRhdGEtc2ZoLW9wdGlvbj0ieXRIaWRlRkxWIiBjaGVja2VkPSIwIj4mbmJzcDtGTFY8L2xhYmVsPgogICAgICAgICAgICA8bGFiZWw+PGlucHV0IHR5cGU9ImNoZWNrYm94IiBkYXRhLXNmaC1vcHRpb249Inl0SGlkZU1QNCIgY2hlY2tlZD0iMCI+Jm5ic3A7TVA0PC9sYWJlbD4KICAgICAgICAgICAgPGxhYmVsPjxpbnB1dCB0eXBlPSJjaGVja2JveCIgZGF0YS1zZmgtb3B0aW9uPSJ5dEhpZGVXZWJNIiBjaGVja2VkPSIxIj4mbmJzcDtXZWJNPC9sYWJlbD4KICAgICAgICAgICAgPGJyPgogICAgICAgICAgICA8bGFiZWw+PGlucHV0IHR5cGU9ImNoZWNrYm94IiBkYXRhLXNmaC1vcHRpb249Inl0SGlkZTNHUCIgY2hlY2tlZD0iMSI+Jm5ic3A7M0dQPC9sYWJlbD4KICAgICAgICAgICAgPGxhYmVsPjxpbnB1dCB0eXBlPSJjaGVja2JveCIgZGF0YS1zZmgtb3B0aW9uPSJ5dEhpZGUzRCIgY2hlY2tlZD0iMSI+Jm5ic3A7M0Q8L2xhYmVsPgogICAgICAgICAgICA8bGFiZWw+PGlucHV0IHR5cGU9ImNoZWNrYm94IiBkYXRhLXNmaC1vcHRpb249Inl0SGlkZU1QNE5vQXVkaW8iIGNoZWNrZWQ9IjEiPiZuYnNwO01QNCZuYnNwOyhubyZuYnNwO2F1ZGlvKTwvbGFiZWw+CiAgICAgICAgICAgIDxsYWJlbD48aW5wdXQgdHlwZT0iY2hlY2tib3giIGRhdGEtc2ZoLW9wdGlvbj0ieXRIaWRlQXVkaW9fTVA0IiBjaGVja2VkPSIxIj4mbmJzcDtBdWRpbzwvbGFiZWw+CiAgICAgICAgICA8L2Rpdj4KICAgICAgICAgIDxkaXYgY2xhc3M9InNmaC0tY2xlYXIiPjwvZGl2PgogICAgICAgIDwvZGl2PgogICAgICA8L2Rpdj4KCiAgICAgIDxkaXYgY2xhc3M9InNmaC0tbW9kdWxlIj48bGFiZWw+PGlucHV0IHR5cGU9ImNoZWNrYm94IiBkYXRhLXNmaC1vcHRpb249Im1vZHVsZURhaWx5bW90aW9uIiBjaGVja2VkPSIxIj4mbmJzcDs8c3BhbiBkYXRhLWkxOG49Im9wdGlvbnNEYWlseW1vdGlvbiI+RGFpbHltb3Rpb248L3NwYW4+PC9sYWJlbD48L2Rpdj4KCiAgICAgIDxkaXYgY2xhc3M9InNmaC0tbW9kdWxlIj48bGFiZWw+PGlucHV0IHR5cGU9ImNoZWNrYm94IiBkYXRhLXNmaC1vcHRpb249Im1vZHVsZVZpbWVvIiBjaGVja2VkPSIxIj4mbmJzcDs8c3BhbiBkYXRhLWkxOG49Im9wdGlvbnNWaW1lbyI+VmltZW88L3NwYW4+PC9sYWJlbD48L2Rpdj4KCiAgICAgIDxkaXYgY2xhc3M9InNmaC0tbW9kdWxlIj48bGFiZWw+PGlucHV0IHR5cGU9ImNoZWNrYm94IiBkYXRhLXNmaC1vcHRpb249Im1vZHVsZUZhY2Vib29rIiBjaGVja2VkPSIxIj4mbmJzcDs8c3BhbiBkYXRhLWkxOG49Im9wdGlvbnNGYWNlYm9vayI+RmFjZWJvb2s8L3NwYW4+PC9sYWJlbD48L2Rpdj4KCiAgICAgIDxkaXYgY2xhc3M9InNmaC0tbW9kdWxlIj48bGFiZWw+PGlucHV0IHR5cGU9ImNoZWNrYm94IiBkYXRhLXNmaC1vcHRpb249Im1vZHVsZVNvdW5kY2xvdWQiIGNoZWNrZWQ9IjEiPiZuYnNwOzxzcGFuIGRhdGEtaTE4bj0ib3B0aW9uc1NvdW5kY2xvdWQiPlNvdW5kQ2xvdWQ8L3NwYW4+PC9sYWJlbD48L2Rpdj4KCiAgICAgIDxkaXYgY2xhc3M9InNmaC0tbW9kdWxlIj48bGFiZWw+PGlucHV0IHR5cGU9ImNoZWNrYm94IiBkYXRhLXNmaC1vcHRpb249Im1vZHVsZVZrb250YWt0ZSIgY2hlY2tlZD0iMSI+Jm5ic3A7PHNwYW4gZGF0YS1pMThuPSJvcHRpb25zVmtvbnRha3RlIj5WSzwvc3Bhbj48L2xhYmVsPgogICAgICAgIDxkaXYgY2xhc3M9InNmaC0tbW9kdWxlX29wdGlvbnMiPjxsYWJlbD48aW5wdXQgdHlwZT0iY2hlY2tib3giIGRhdGEtc2ZoLW9wdGlvbj0idmtTaG93Qml0cmF0ZSIgY2hlY2tlZD0iMCI+Jm5ic3A7PHNwYW4gZGF0YS1pMThuPSJvcHRpb25zQml0cmF0ZSI+U2hvdyBiaXRyYXRlIGluc3RhbnRseTwvc3Bhbj48L2xhYmVsPjwvZGl2PgogICAgICA8L2Rpdj4KCiAgICAgIDxkaXYgY2xhc3M9InNmaC0tbW9kdWxlIj48bGFiZWw+PGlucHV0IHR5cGU9ImNoZWNrYm94IiBkYXRhLXNmaC1vcHRpb249Im1vZHVsZU9kbm9rbGFzc25pa2kiIGNoZWNrZWQ9IjEiPiZuYnNwOzxzcGFuIGRhdGEtaTE4bj0ib3B0aW9uc09kbm9rbGFzc25pa2kiPk9kbm9rbGFzc25pa2k8L3NwYW4+PC9sYWJlbD48L2Rpdj4KICAgIDwvZGl2PgogICAgPGRpdiBjbGFzcz0ic2ZoLS1jbGVhciI+PC9kaXY+CiAgPC9mb3JtPgo8L2Rpdj4=', | |
| init: function() | |
| { | |
| var _this = this, | |
| parent = document.querySelector('.sfh--options'); | |
| if(!parent) | |
| return; | |
| chrome.i18n.translate(parent); | |
| if(GM_getValue('lite') == '1') | |
| this.hideBlock('youtube_box', true); | |
| var c = parent.querySelectorAll('form input[type="checkbox"]'); | |
| for(var i = 0; i < c.length; i++) | |
| { | |
| var name = c[i].getAttribute(this.dataAttr); | |
| if(name && GM_getValue(name)) | |
| { | |
| c[i].checked = (GM_getValue(name) == '0') ? false : true; | |
| c[i].addEventListener('change', function onCbChange(event){ | |
| var e = event.target, name = e.getAttribute(_this.dataAttr); | |
| GM_setValue(name, e.checked ? '1' : '0'); | |
| }, false); | |
| } | |
| } | |
| }, | |
| hideBlock: function(name, hide) | |
| { | |
| var node = document.querySelector('.' + this.classPrefix + name); | |
| if(node) | |
| node.style.display = hide ? 'none' : ''; | |
| }, | |
| show: function() | |
| { | |
| SaveFrom_Utils.popupDiv(atob(this.html), null, 640, 600); | |
| this.init(); | |
| } | |
| }; | |
| ///////////////////////////////////////////////// | |
| // BACKGROUND | |
| _background = function(){ | |
| var infoPageActive = true; | |
| var helper = getHelperName(); | |
| GM_setValue('helper', helper); | |
| var lite = (helper == 'chromelite'); | |
| GM_setValue('lite', lite ? '1' : '0'); | |
| // default preferences | |
| var default_preferences = { | |
| version: 0, | |
| enable: 1, | |
| newUser: 1, | |
| lmFileHosting: 1, | |
| lmMediaHosting: 1, | |
| moduleYoutube: 1, | |
| moduleDailymotion: 1, | |
| moduleVimeo: 1, | |
| moduleFacebook: 1, | |
| moduleSoundcloud: 1, | |
| moduleVkontakte: 1, | |
| moduleOdnoklassniki: 1, | |
| moduleShowDownloadInfo: 1, | |
| ytHideFLV: 0, | |
| ytHideMP4: 0, | |
| ytHideWebM: 1, | |
| ytHide3GP: 1, | |
| ytHide3D: 1, | |
| ytHideMP4NoAudio: 1, | |
| ytHideAudio_MP4: 1, | |
| vkShowBitrate: 0 | |
| }; | |
| var pref_names = { | |
| youtube: 'moduleYoutube', | |
| dailymotion: 'moduleDailymotion', | |
| vimeo: 'moduleVimeo', | |
| facebook: 'moduleFacebook', | |
| soundcloud: 'moduleSoundcloud', | |
| vk: 'moduleVkontakte', | |
| odnoklassniki: 'moduleOdnoklassniki' | |
| }; | |
| var menuCommands = [ | |
| { | |
| id: 'downloadFromCurrentPage', | |
| command: downloadFromCurrentPage, | |
| modules: ['lm', 'youtube', 'soundcloud', 'dailymotion'] | |
| }, | |
| { | |
| id: '', | |
| modules: ['lm', 'youtube', 'soundcloud', 'dailymotion'] | |
| }, | |
| { | |
| id: 'updateLinks', | |
| notify: 'updateLinksNotification', | |
| modules: ['vk', 'odnoklassniki', 'facebook', 'lm'] | |
| }, | |
| { | |
| id: 'downloadMP3Files', | |
| modules: ['vk'] | |
| }, | |
| { | |
| id: 'downloadPlaylist', | |
| modules: ['vk'] | |
| }, | |
| { | |
| id: 'downloadPhotos', | |
| modules: ['vk'] | |
| }, | |
| { | |
| id: '', | |
| modules: ['vk', 'odnoklassniki', 'facebook', 'lm'] | |
| }, | |
| { | |
| id: 'showOptions', | |
| command: showOptions, | |
| always: true | |
| }, | |
| { | |
| id: 'reportBug', | |
| command: reportBug, | |
| always: true | |
| }, | |
| { | |
| id: '', | |
| always: true | |
| }, | |
| { | |
| id: 'disable', | |
| command: enableExtension, | |
| always: true | |
| } | |
| ]; | |
| // localStorage == widget.preferences | |
| for (var k in default_preferences) | |
| { | |
| if(GM_getValue(k) === undefined) | |
| GM_setValue(k, default_preferences[k]); // set default preference | |
| } | |
| function registerModuleMenuCommand(params, enabled) | |
| { | |
| if(!params.id) | |
| { | |
| // separator | |
| _menu.addItem(); | |
| return; | |
| } | |
| var strId = params.id; | |
| if(!enabled && params.id == 'disable') | |
| strId = 'menuEnable'; | |
| var name = chrome.i18n.getMessage(strId); | |
| if(!name) | |
| return; | |
| if(params.command) | |
| { | |
| GM_registerMenuCommand(name, params.command); | |
| _menu.addItem(params.id, name, params.command); | |
| return; | |
| } | |
| var fn = function(){ | |
| chrome.tabs.sendRequest(1, {action: params.id}); | |
| if(params.notify) | |
| GM_notification(chrome.i18n.getMessage(params.notify), null, null, null, 3000); | |
| }; | |
| GM_registerMenuCommand(name, fn); | |
| _menu.addItem(params.id, name, fn); | |
| } | |
| function registerMenuCommands(moduleName, enabled) | |
| { | |
| _menu.resetItems(); | |
| for(var i = 0; i < menuCommands.length; i++) | |
| { | |
| var item = menuCommands[i]; | |
| if(item.gmId) | |
| { | |
| continue; | |
| GM_unregisterMenuCommand(item.gmId); | |
| } | |
| if(enabled || item.always) | |
| { | |
| if(!item.modules || item.modules.indexOf(moduleName) > -1) | |
| { | |
| menuCommands[i].gmId = registerModuleMenuCommand(item, enabled); | |
| } | |
| } | |
| } | |
| } | |
| // modules[tab.id] = moduleName | |
| var modules = {}; | |
| chrome.tabs.onRemoved.addListener(function(tabId){ | |
| if (tabId in modules) | |
| delete modules[tabId]; | |
| }); | |
| // routes[action] = handler | |
| // handler - function(request, sender) { | |
| // ... code ... | |
| // return response; | |
| // } | |
| var routes = { | |
| initModule: function (request, sender, callback) | |
| { | |
| var response = {}; | |
| var extEnable = GM_getValue('enable') == '1'; | |
| var moduleName = request.moduleName; | |
| response.name = moduleName; | |
| if (sender.tab) | |
| { | |
| sender.tab.id = 1; | |
| response.moduleEnable = true; | |
| var info = chrome.app.getDetails(); | |
| response.version = info.version; | |
| if(!request.frame) | |
| { | |
| modules[sender.tab.id] = moduleName; | |
| } | |
| response.helper = helper; | |
| response.lite = lite; | |
| response.downloads = false; //(window.GM_download !== undefined); | |
| response.moduleShowDownloadInfo = GM_getValue('moduleShowDownloadInfo') == '1'; | |
| if(moduleName != 'savefrom') | |
| { | |
| response.ytHideFLV = GM_getValue('ytHideFLV'); | |
| response.ytHideMP4 = GM_getValue('ytHideMP4'); | |
| response.ytHideWebM = GM_getValue('ytHideWebM'); | |
| response.ytHide3GP = GM_getValue('ytHide3GP'); | |
| response.ytHide3D = GM_getValue('ytHide3D'); | |
| response.ytHideMP4NoAudio = GM_getValue('ytHideMP4NoAudio'); | |
| response.ytHideAudio_MP4 = GM_getValue('ytHideAudio_MP4'); | |
| if (moduleName == 'lm') | |
| { | |
| response.moduleEnable &= GM_getValue('lmFileHosting') == '1' | |
| || GM_getValue('lmMediaHosting') == '1'; | |
| response.lmMediaHosting = GM_getValue('lmMediaHosting'); | |
| response.lmFileHosting = GM_getValue('lmFileHosting'); | |
| } | |
| else | |
| { | |
| response.moduleEnable &= GM_getValue(pref_names[moduleName]) == '1'; | |
| if(moduleName == 'vk') | |
| { | |
| response.vkShowBitrate = GM_getValue('vkShowBitrate'); | |
| } | |
| } | |
| } | |
| if(!request.frame) | |
| { | |
| registerMenuCommands(request.moduleName, extEnable); | |
| if(response.moduleEnable || moduleName == 'savefrom') | |
| { | |
| _menu.setTitle(chrome.i18n.getMessage('extName'), info.version); | |
| _menu.create(extEnable); | |
| } | |
| } | |
| response.moduleEnable &= extEnable; | |
| } | |
| callback(response); | |
| userTrack(); | |
| }, | |
| hideDownloadInfo: function(request, sender){ | |
| GM_setValue('moduleShowDownloadInfo', '0'); | |
| }, | |
| getVimeoLinks: function (request, sender, callback) | |
| { | |
| function callback_links(links, title, thumb) | |
| { | |
| var response = { | |
| action: request.action, | |
| extVideoId: request.extVideoId, | |
| links: links, | |
| title: title, | |
| thumb: thumb | |
| }; | |
| callback(response); | |
| } | |
| getVimeoLinks(request.extVideoId, callback_links); | |
| }, | |
| getVKLinks: function (request, sender, callback) | |
| { | |
| function callback_links(vid, links, title, duration, thumb, data, embed) | |
| { | |
| if(embed) | |
| { | |
| embed.origRequest = request; | |
| routes[embed.action](embed, sender, callback); | |
| return; | |
| } | |
| var response = { | |
| action: request.action, | |
| extVideoId: vid ? vid : request.extVideoId, | |
| links: links, | |
| title: title, | |
| duration: duration, | |
| thumb: thumb, | |
| data: data, | |
| checkLinks: null | |
| }; | |
| if(request.checkLinks && links && links.length > 0) | |
| { | |
| checkVkLinks(links, function(checkUrl, isValid, status){ | |
| response.checkLinks = isValid; | |
| callback(response); | |
| }); | |
| return; | |
| } | |
| callback(response); | |
| } | |
| getVKLinks(request.extVideoId, callback_links); | |
| }, | |
| getYoutubeLinks: function (request, sender, callback) | |
| { | |
| function callback_links(links, title, subtitles, duration) | |
| { | |
| var response = { | |
| action: request.action, | |
| extVideoId: request.extVideoId, | |
| links: links, | |
| title: title, | |
| subtitles: subtitles, | |
| duration: duration, | |
| checkLinks: null | |
| }; | |
| if(request.checkLinks && links) | |
| { | |
| checkYoutubeLinks(links, function(checkUrl, isValid, status){ | |
| response.checkLinks = isValid; | |
| callback(response); | |
| }); | |
| return; | |
| } | |
| callback(response); | |
| } | |
| getYoutubeLinks(sender.tab.url, request.extVideoId, request.checkSubtitles, callback_links); | |
| }, | |
| getOdnoklassnikiLinks: function (request, sender, callback) | |
| { | |
| function callback_links(links) | |
| { | |
| var response = { | |
| action: request.action, | |
| extVideoId: request.extVideoId, | |
| links: links, | |
| title: request.title | |
| }; | |
| callback(response); | |
| } | |
| getOdnoklassnikiLinks(request.extVideoId, callback_links); | |
| }, | |
| getOdnoklassnikiAudioLinks: function (request, sender, callback) | |
| { | |
| function callback_links(data) | |
| { | |
| var response = { | |
| action: request.action, | |
| trackId: request.trackId, | |
| jsessionId: request.jsessionId, | |
| data: data | |
| }; | |
| callback(response); | |
| } | |
| getOdnoklassnikiAudioLinks(sender.tab.url, request.trackId, request.jsessionId, callback_links); | |
| }, | |
| getDailymotionLinks: function (request, sender, callback) | |
| { | |
| function callback_links(data) | |
| { | |
| if (!data) { | |
| data = {}; | |
| } | |
| var response = { | |
| action: request.action, | |
| extVideoId: request.extVideoId, | |
| links: data.links, | |
| title: data.title, | |
| duration: data.duration, | |
| thumb: data.thumb | |
| }; | |
| callback(response); | |
| } | |
| getDailymotionLinks(request.extVideoId, callback_links) | |
| }, | |
| getSoundcloudTrackInfo: function (request, sender, callback) | |
| { | |
| function callback_links(data, isValid) | |
| { | |
| var response = { | |
| action: request.action, | |
| trackUrl: request.trackUrl, | |
| client_id: request.client_id, | |
| data: data, | |
| checkLinks: isValid | |
| }; | |
| callback(response); | |
| } | |
| getSoundcloudTrackInfo(request.trackUrl, request.client_id, callback_links); | |
| }, | |
| getFileSize: function (request, sender, callback) | |
| { | |
| getFileSize(request.url, callback); | |
| }, | |
| downloadFile: function(request, sender, callback) | |
| { | |
| function callback_info(id) | |
| { | |
| var response = { | |
| options: request.options, | |
| id: id | |
| }; | |
| callback(response); | |
| } | |
| downloadFile(request.options, callback_info); | |
| } | |
| }; | |
| // content scripts dispatcher | |
| chrome.extension.onRequest.addListener(function(request, sender, callback){ | |
| //console.log('dispatcher', request, sender, callback); | |
| routes[request.action](request, sender, callback); | |
| }); | |
| function getHelperName() | |
| { | |
| var info = chrome.app.getDetails(); | |
| if(info && info.name && info.name.search(/\s+lite/i) > -1) | |
| return 'chromelite'; | |
| if(navigator && navigator.userAgent) | |
| { | |
| if(navigator.userAgent.search(/YaBrowser\/\d+\.\d+/i) > -1) | |
| return 'yabrowser'; | |
| if(navigator.userAgent.search(/OPR\/\d+\.\d+/i) > -1) | |
| return 'opera-chromium'; | |
| } | |
| return 'chrome'; | |
| } | |
| // actions from menu | |
| function enableExtension() | |
| { | |
| // toggle extension status | |
| var enabled = GM_getValue('enable') == '1'; | |
| enabled = !enabled; | |
| GM_setValue('enable', enabled ? '1' : '0'); | |
| _menu.setEnabled(enabled); | |
| registerMenuCommands(modules[1], enabled); | |
| setButtonParams(); | |
| } | |
| function downloadFromCurrentPage() | |
| { | |
| chrome.tabs.getSelected(null, function(tab) | |
| { | |
| var url = 'http://savefrom.net/?url=' + encodeURIComponent(tab.url) + | |
| '&utm_source=' + helper + '&utm_medium=extensions&utm_campaign=bookmarklet'; | |
| chrome.tabs.create({url: url, selected: true}); | |
| }); | |
| } | |
| function installFullVersion() | |
| { | |
| var url = 'http://savefrom.net/user.php?helper=1' + | |
| '&utm_source=' + helper + '&utm_medium=extensions&utm_campaign=get_full_version'; | |
| chrome.tabs.create({url: url, selected: true}); | |
| } | |
| function showOptions() | |
| { | |
| _options.show(); | |
| } | |
| function reportBug() | |
| { | |
| var url = 'http://savefrom.userecho.com/forum/20869-/'; | |
| if(chrome.i18n.getMessage("lang") == 'ru') | |
| url = 'http://savefrom.userecho.com/forum/19523-/'; | |
| chrome.tabs.create({url: url, selected: true}); | |
| } | |
| // tab actions | |
| /* | |
| var tabActions = ['updateLinks', 'downloadPlaylist', 'downloadMP3Files', 'downloadPhotos']; | |
| function tabAction(request, tab) | |
| { | |
| if (tab) | |
| { | |
| chrome.tabs.sendRequest(tab.id, request); | |
| } | |
| else | |
| { | |
| chrome.tabs.getSelected(null, function(tab){ | |
| chrome.tabs.sendRequest(tab.id, request); | |
| }); | |
| } | |
| } | |
| function createAction(name, tab) | |
| { | |
| return function(){ | |
| tabAction({action: name}, tab); | |
| }; | |
| } | |
| for (var i = 0; i < tabActions.length; i++) | |
| { | |
| var actionName = tabActions[i]; | |
| window[actionName] = createAction(actionName); | |
| } | |
| */ | |
| // --------- | |
| //setButtonParams(); | |
| if(GM_getValue('enable') != '0') | |
| checkVersion(); | |
| function setButtonParams() | |
| { | |
| var icon = {path: 'images/icon_18.png'}; | |
| var title = {title: chrome.i18n.getMessage("titleDefault")}; | |
| if(GM_getValue('enable') == '0') | |
| { | |
| title.title = chrome.i18n.getMessage("titleDesabled"); | |
| icon.path = 'images/icon_disabled_18.png'; | |
| } | |
| chrome.browserAction.setIcon(icon); | |
| chrome.browserAction.setTitle(title); | |
| } | |
| function fixPref(pref) | |
| { | |
| for(i = 0; i < pref.length; i++) | |
| { | |
| if(GM_getValue(pref[i].name) != pref[i].check) | |
| GM_setValue(pref[i].name, pref[i].def); | |
| } | |
| } | |
| function checkVersion() | |
| { | |
| var url = '', | |
| info = chrome.app.getDetails(); | |
| if(!GM_getValue('version') || GM_getValue('version') == '0') | |
| { | |
| // first run | |
| url = 'http://savefrom.net/user.php?helper=userjs;firstrun'; | |
| } | |
| else if(GM_getValue('version') != info.version) | |
| { | |
| // update | |
| //url = 'http://savefrom.net/user.php?helper=userjs;update'; | |
| } | |
| if(url) | |
| { | |
| GM_setValue('version', info.version); | |
| return; | |
| if(!infoPageActive) | |
| { | |
| chrome.tabs.create({url: url, selected: false, active: false}); | |
| } | |
| else | |
| { | |
| chrome.tabs.query({url: '*://legal.yandex.com.tr/*'}, function(tabs) { | |
| var active = tabs.length == 0; | |
| chrome.tabs.query({url: '*://legal.yandex.ru/*'}, function(tabs) { | |
| active = active && tabs.length == 0; | |
| chrome.tabs.create({url: url, selected: active, active: active}); | |
| }); | |
| }); | |
| } | |
| } | |
| } | |
| function sendRequest(url, callback, method, referer, post, cookie, header) | |
| { | |
| method = method ? method : ((post) ? 'POST' : 'GET'); | |
| var headers = {}; | |
| if(referer) | |
| headers['Referer'] = referer; | |
| if(cookie) | |
| headers['Cookie'] = cookie; | |
| if(post) | |
| { | |
| headers['Content-type'] = 'application/x-www-form-urlencoded'; | |
| headers['Content-Length'] = post.length; | |
| } | |
| if(header) | |
| { | |
| for(var i = 0; i < header.length; i++) | |
| { | |
| headers[header[i][0]] = header[i][1]; | |
| } | |
| } | |
| function cb(r) | |
| { | |
| r.getResponseHeader = function(header){ | |
| if(!r.responseHeaders) | |
| return ''; | |
| var re = new RegExp("(?:^|[\\r\\n])" + header + ":\\s*(.+)(?:[\\r\\n]|$)", "im"); | |
| var m = r.responseHeaders.match(re); | |
| if(m && m.length > 1) | |
| return m[1]; | |
| return ''; | |
| } | |
| callback(r); | |
| } | |
| GM_xmlhttpRequest({ | |
| method: method, | |
| url: url, | |
| data: post ? post : '', | |
| headers: headers, | |
| onload: cb, | |
| onerror: cb, | |
| ontimeout: cb | |
| }); | |
| } | |
| function getFileSize(url, callback, referer, cookie, header) | |
| { | |
| sendRequest(url, function(req){ | |
| var response = { | |
| fileSize: 0, | |
| fileType: '', | |
| status: req.status | |
| }; | |
| if (req.status == 200 || req.status == 206) | |
| { | |
| var s = req.getResponseHeader('Content-Length'); | |
| if(s) | |
| { | |
| s = parseInt(s); | |
| if(!isNaN(s)) | |
| response.fileSize = s; | |
| } | |
| var t = req.getResponseHeader('Content-Type'); | |
| if(t) | |
| response.fileType = t; | |
| } | |
| callback(response); | |
| }, 'HEAD', referer, null, cookie, header); | |
| } | |
| function downloadFile(options, callback) | |
| { | |
| if(chrome.downloads) | |
| return chrome.downloads.download(options, callback); | |
| callback(); | |
| } | |
| function getVimeoLinks(videoId, callback) | |
| { | |
| getVimeoNoEmbedLinks(videoId, function(links, title, thumb){ | |
| if(links) | |
| { | |
| callback(links, title, thumb); | |
| return; | |
| } | |
| getVimeoEmbedLinks(videoId, callback); | |
| }); | |
| } | |
| function getVimeoEmbedLinks(videoId, callback) | |
| { | |
| sendRequest('http://player.vimeo.com/video/' + videoId, function(r){ | |
| if(r.status == 200 && r.responseText) | |
| { | |
| var config = r.responseText.match(/,c\s*=\s*(\{[\s\S]+?\})\s*;/i); | |
| if(config && config.length > 1) | |
| { | |
| config = config[1]; | |
| var data = getVimeoDataFromConfig(config); | |
| if(data && data.links) | |
| { | |
| callback(data.links, data.title, data.thumb); | |
| return; | |
| } | |
| } | |
| } | |
| callback(null, '', ''); | |
| }); | |
| } | |
| function getVimeoNoEmbedLinks(videoId, callback) | |
| { | |
| sendRequest('http://vimeo.com/' + videoId, function(r){ | |
| if(r.status == 200 && r.responseText) | |
| { | |
| var configUrl = r.responseText.match( | |
| /data-config-url=[\"']([^\s\"'\<\>]+)/i); | |
| if(configUrl && configUrl.length > 1) | |
| { | |
| configUrl = configUrl[1].replace(/&/ig, '&'); | |
| sendRequest(configUrl, function(r){ | |
| if(r.status == 200 && r.responseText) | |
| { | |
| var data = getVimeoDataFromConfig(r.responseText); | |
| if(data && data.links) | |
| { | |
| callback(data.links, data.title, data.thumb); | |
| return; | |
| } | |
| } | |
| callback(null, '', ''); | |
| }); | |
| return; | |
| } | |
| } | |
| callback(null, '', ''); | |
| }); | |
| } | |
| function getVimeoDataFromConfig(config) | |
| { | |
| config = config.replace(/(\{|,)\s*(\w+)\s*:/ig, '$1"$2":'). | |
| replace(/(:\s+)\'/g, '$1"').replace(/\'([,\]\}])/g, '"$1'); | |
| try | |
| { | |
| config = JSON.parse(config); | |
| } | |
| catch(err) | |
| { | |
| return null; | |
| } | |
| if(!config || !config.request || !config.video || | |
| !config.request.files || !config.request.files.codecs.length) | |
| { | |
| return null; | |
| } | |
| var r = config.request, v = config.video, data = {}; | |
| data.title = v.title ? v.title : ''; | |
| if(v.thumbs) | |
| { | |
| for(i in v.thumbs) | |
| { | |
| data.thumb = v.thumbs[i]; | |
| break; | |
| } | |
| } | |
| data.links = []; | |
| var codecs = r.files.codecs; | |
| for(var k = 0; k < codecs.length; k++) | |
| { | |
| var files = r.files[codecs[k]]; | |
| if(files) | |
| { | |
| for(var i in files) | |
| { | |
| var name = i.length <= 3 ? i.toUpperCase() : | |
| ucfirst(i.toLowerCase()); | |
| var ext = files[i].url.match(/\.(\w{2,4})(?:\?|#|$)/i); | |
| if(ext && ext.length > 1) | |
| ext = ext[1].toLowerCase(); | |
| else | |
| ext = 'mp4'; | |
| data.links.push({ | |
| url: files[i].url, | |
| name: name, | |
| type: ext, | |
| ext: ext.toUpperCase() | |
| }); | |
| } | |
| } | |
| } | |
| return data; | |
| } | |
| function getVkFlvLink(v) | |
| { | |
| if(v.host.search(/^https?:\/\//i) != -1) | |
| { | |
| if(v.host.charAt(v.host.length - 1) != '/') | |
| v.host += '/'; | |
| if(v.host.search(/^https?:\/\/cs\d+\./i) != -1) | |
| return v.host + 'u' + v.uid + '/videos/' + v.vtag + '.flv'; | |
| return v.host + 'assets/video/' + v.vtag + v.vkid + '.vk.flv'; | |
| } | |
| if(v.host.search(/\D/) == -1) | |
| return 'http://cs' + v.host + '.' + 'vk.com/u' + v.uid + '/videos/' + v.vtag + '.flv'; | |
| return 'http://' + v.host + '/assets/video/' + v.vtag + v.vkid + '.vk.flv'; | |
| } | |
| function getVkMp4Link(v, q) | |
| { | |
| if(q == 240 && v.no_flv == 0) | |
| return getVkFlvLink(v); | |
| if(v.host.search(/^https?:\/\//i) != -1) | |
| { | |
| if(v.host.charAt(v.host.length - 1) != '/') | |
| v.host += '/'; | |
| return v.host + 'u' + v.uid + '/videos/' + v.vtag + '.' + q + '.mp4'; | |
| } | |
| return 'http://cs' + v.host + '.' + 'vk.com/u' + v.uid + '/videos/' + v.vtag + '.' + q + '.mp4'; | |
| } | |
| function getVkVideoLinks(v) | |
| { | |
| if(!v || !v.host || !v.vtag || (!v.vkid && !v.uid)) | |
| return null; | |
| if(typeof(v.host) != 'string' && v.host.toString) | |
| v.host = v.host.toString(); | |
| v.host = v.host.replace(/\\\//g, '/'); | |
| if(v.hd > 0 && (!v.hd_def || v.hd > v.hd_def)) | |
| v.hd_def = v.hd; | |
| var links = []; | |
| if(v.hd_def <= 0 && v.no_flv == 0) | |
| { | |
| links.push({ | |
| url: getVkFlvLink(v), | |
| name: 'FLV', | |
| subname: '', | |
| type: 'flv' | |
| }); | |
| } | |
| else | |
| { | |
| links.push({ | |
| url: getVkMp4Link(v, 240), | |
| name: (v.no_flv == 0) ? 'FLV' : 'MP4', | |
| subname: '', | |
| type: (v.no_flv == 0) ? 'flv' : 'mp4' | |
| }); | |
| if(v.hd_def > 0) | |
| { | |
| links.push({ | |
| url: getVkMp4Link(v, 360), | |
| name: 'MP4', | |
| subname: '360', | |
| type: 'mp4' | |
| }); | |
| if(v.hd_def > 1) | |
| { | |
| links.push({ | |
| url: getVkMp4Link(v, 480), | |
| name: 'MP4', | |
| subname: '480', | |
| type: 'mp4' | |
| }); | |
| if(v.hd_def > 2) | |
| { | |
| links.push({ | |
| url: getVkMp4Link(v, 720), | |
| name: 'MP4', | |
| subname: '720', | |
| type: 'mp4' | |
| }); | |
| } | |
| } | |
| } | |
| } | |
| return links; | |
| } | |
| function getVKLinks(videoId, callback) | |
| { | |
| var links = [], title = videoId, duration = '', thumb = '', data = null, embed = null; | |
| var vid = videoId; | |
| if(vid.search(/^video-?\d+_\d+/i) == -1) | |
| { | |
| var oid = '', id = ''; | |
| var m = vid.match(/(?:^|&)oid=(-?\d+)/i); | |
| if(m && m.length > 1) | |
| oid = m[1]; | |
| m = vid.match(/(?:^|&)id=(-?\d+)/i); | |
| if(m && m.length > 1) | |
| id = m[1]; | |
| vid = ''; | |
| if(oid && id) | |
| vid = 'video' + oid + '_' + id; | |
| } | |
| if(!vid) | |
| { | |
| callback(vid, links, title); | |
| return; | |
| } | |
| title = vid; | |
| var url = 'http://vk.com/' + vid; | |
| sendRequest(url, function(r){ | |
| try | |
| { | |
| if(r.status == 200 && r.responseText) | |
| { | |
| var json = r.responseText | |
| .replace(/\{[a-zA-Z_\-\.]+\}/ig, '') | |
| .match(/var vars\s*=\s*(\{[^\}]+\})/i); | |
| if(json) | |
| { | |
| try | |
| { | |
| json = json[1]; | |
| if(json.search(/^\{\s*\\\"/) > -1) | |
| json = json.replace(/\\\"/g, '"'); | |
| json = JSON.parse(json); | |
| if(json) | |
| { | |
| data = json; | |
| links = getVkVideoLinks(json); | |
| if(json.md_title) | |
| title = json.md_title; | |
| if(json.thumb) | |
| thumb = json.thumb; | |
| else if(json.jpg) | |
| thumb = json.jpg; | |
| if(thumb && thumb.search(/\\\//) > -1) | |
| thumb = thumb.replace(/\\\//g, '/'); | |
| } | |
| } | |
| catch(err){} | |
| } | |
| else | |
| { | |
| var frame = r.responseText.match(/<iframe[^>]+>/ig), m; | |
| if(frame) | |
| { | |
| for(var i=0, l=frame.length; i<l; i++) | |
| { | |
| if(m = frame[i].match(/youtube.com\\?\/embed\\?\/([\w\-]+)/i)) | |
| { | |
| embed = { | |
| action: 'getYoutubeLinks', | |
| extVideoId: m[1] | |
| }; | |
| break; | |
| } | |
| if(m = frame[i].match(/vimeo.com\\?\/video\\?\/(\d+)/i)) | |
| { | |
| embed = { | |
| action: 'getVimeoLinks', | |
| extVideoId: m[1] | |
| }; | |
| break; | |
| } | |
| } | |
| } | |
| if (embed === null) { | |
| var ajaxPreload = r.responseText.lastIndexOf('ajax.preload'); | |
| if (ajaxPreload !== -1) { | |
| var data = r.responseText.substr(ajaxPreload); | |
| var dmId = data.match(/url: '(?:[\w\\/]+.)?dailymotion.com(?:\\\/swf)?\\\/video\\\/([\w\d]+)\??/); | |
| if (dmId) { | |
| embed = { | |
| action: 'getDailymotionLinks', | |
| extVideoId: dmId[1] | |
| } | |
| } | |
| } | |
| } | |
| } | |
| var dur = r.responseText.match(/(['"]?)duration\1\s*:\s*(\d+)/i); | |
| if(dur) | |
| { | |
| duration = dur[2]; | |
| } | |
| } | |
| } | |
| finally | |
| { | |
| callback(vid, links, title, duration, thumb, data, embed); | |
| } | |
| }); | |
| } | |
| function checkVkLinks(links, callback) | |
| { | |
| var checkUrl = ''; | |
| if(links && links.length > 0) | |
| { | |
| if(links[0].type == 'mp4') | |
| checkUrl = links[0].url; | |
| else if(links.length > 1) | |
| checkUrl = links[1].url; | |
| else | |
| checkUrl = links[0].url; | |
| } | |
| if(checkUrl) | |
| { | |
| getFileSize(checkUrl, function(r){ | |
| var isValid = (r.status >= 400) ? false : true; | |
| callback(checkUrl, isValid, r.status); | |
| }); | |
| return; | |
| } | |
| callback(); | |
| } | |
| function getYoutubeLinks(eurl, videoId, checkSubtitles, callback_) { | |
| var links = null, title = '', duration = ''; | |
| eurl = encodeURIComponent(eurl); | |
| var url = 'http://www.youtube.com/get_video_info?video_id=' + videoId + | |
| '&asv=3&eurl=' + eurl + '&el=info&sts=15956'; | |
| var cookies = 'VISITOR_INFO1_LIVE=; PREF=; GEO=; use_hitbox='; | |
| var embed = true; | |
| var callback = function(links, title, subtitles, duration) { | |
| if(links || !embed) | |
| { | |
| callback_(links, title, subtitles, duration); | |
| } | |
| else | |
| { | |
| embed = false; | |
| url = 'http://www.youtube.com/watch?v=' + videoId; | |
| sendRequest(url, getYoutubeLinks_, '', url, '', cookies); | |
| } | |
| }; | |
| sendRequest(url, getYoutubeLinks_, '', url, '', cookies); | |
| function getYoutubeLinks_(r) { | |
| var cb = function() { | |
| if(checkSubtitles) | |
| { | |
| checkYoutubeSubtitles(videoId, function(subtitles){ | |
| callback(links, title, subtitles, duration); | |
| }); | |
| } | |
| else | |
| callback(links, title, null, duration); | |
| }; | |
| if (r.status !== 200 || !r.responseText) { | |
| return cb(); | |
| } | |
| var dashUrl; | |
| try { | |
| var getParam = function(str, param, number) { | |
| var re = new RegExp('(?:^|&)' + param + '=([^\\s\\&\\"]+)', 'i'); | |
| if(!embed) | |
| { | |
| re = new RegExp('\\"' + param + '\\"\\s*:\\s*\\"([^\\"]+)\\"', 'i'); | |
| if(number) | |
| re = new RegExp('\\"' + param + '\\"\\s*:\\s*\\"?(\\d+)', 'i'); | |
| } | |
| var m = str.match(re); | |
| if(m && m.length > 1) | |
| { | |
| if(embed) | |
| return decodeURIComponent(m[1]); | |
| var json = '{"v": "' + m[1] + '"}'; | |
| var obj = JSON.parse(json); | |
| if(obj && obj.v) | |
| return obj.v; | |
| } | |
| return ''; | |
| }; | |
| var baseUrl = '', | |
| adaptiveFmts = getParam(r.responseText, 'adaptive_fmts'), | |
| title = getParam(r.responseText, 'title'), | |
| length_seconds = getParam(r.responseText, 'length_seconds', true), | |
| fmtMap = getParam(r.responseText, '(?:fmt_url_map|url_encoded_fmt_stream_map)'); | |
| dashUrl = getParam(r.responseText, 'dashmpd'); | |
| if(!embed) | |
| fmtMap = fmtMap.split('\\u0026').join('&'); | |
| if(fmtMap.search(/url%3dhttp/i) > -1) | |
| fmtMap = decodeURIComponent(fmtMap); | |
| var titleParam = ''; | |
| if(title) | |
| { | |
| title = title.replace(/\+/g, '%20'); | |
| title = decodeURIComponent(title). | |
| replace(/[\x2F\x5C\x3A\x7C]/g, '-'). | |
| replace(/[\x2A\x3F]/g, ''). | |
| replace(/\x22/g, '\''). | |
| replace(/\x3C/g, '('). | |
| replace(/\x3E/g, ')'). | |
| replace(/(?:^\s+)|(?:\s+$)/g, ''); | |
| titleParam = '&title=' + encodeURIComponent(title); | |
| } | |
| if(length_seconds) | |
| duration = length_seconds; | |
| var lks = parseYoutubeFmtMap(fmtMap, titleParam, baseUrl); | |
| if(adaptiveFmts) | |
| { | |
| var adaptive_links = parseYoutubeFmtMap(adaptiveFmts, titleParam, baseUrl); | |
| for (var i in adaptive_links) { | |
| if(!lks[i]) | |
| lks[i] = adaptive_links[i]; | |
| } | |
| } | |
| // Deprecated | |
| // findYoutubeAvailableLinks(lks, baseUrl, dashUrl, adaptiveFmts, titleParam); | |
| if(lks) | |
| links = lks; | |
| } | |
| finally { | |
| getYouTubeDashLinks(links, dashUrl, function(_links) { | |
| if (_links) { | |
| links = _links; | |
| } | |
| cb(); | |
| }); | |
| } | |
| } | |
| } | |
| var getYouTubeDashLinks = (function() { | |
| var parseDash = function(xml, links, cb) { | |
| var parser = new DOMParser(); | |
| var xmlDoc = parser.parseFromString(xml,"text/xml"); | |
| var elList = xmlDoc.querySelectorAll('Representation'); | |
| if (!links) { | |
| links = {}; | |
| } | |
| for (var i = 0, el; el = elList[i]; i++) { | |
| var itag = el.id; | |
| if (links[itag] !== undefined) { | |
| continue; | |
| } | |
| var baseurl = el.querySelector('BaseURL'); | |
| if (baseurl === null) { | |
| continue; | |
| } | |
| var url = baseurl.textContent; | |
| links[itag] = url; | |
| } | |
| cb(links); | |
| }; | |
| var _getDashLinks = function(links, dashmpd, cb) { | |
| if (!dashmpd) { | |
| return cb(); | |
| } | |
| var signature_pos = dashmpd.indexOf('signature'); | |
| if (signature_pos === -1) { | |
| var s_pos = dashmpd.indexOf('/s/'); | |
| if (s_pos === -1) { | |
| return cb(); | |
| } | |
| s_pos += 3; | |
| var s_end = dashmpd.indexOf('/', s_pos); | |
| if (s_end === -1) { | |
| s_end = dashmpd.length; | |
| } | |
| var s = dashmpd.substr( s_pos, s_end - s_pos ); | |
| var signature = youtubeSignatureDecipher(s); | |
| if (signature === s) { | |
| return cb(); | |
| } | |
| dashmpd = dashmpd.substr(0, s_pos - 2) + 'signature/' + signature + dashmpd.substr(s_end); | |
| } | |
| sendRequest(dashmpd, function(r) { | |
| if(r.status !== 200) { | |
| return cb(); | |
| } | |
| parseDash(r.responseText, links, cb); | |
| }); | |
| }; | |
| return _getDashLinks; | |
| })(); | |
| function youtubeSignatureDecipher(sig) | |
| { | |
| function swap(a, b) | |
| { | |
| var t = a[0]; | |
| a[0] = a[b % a.length]; | |
| a[b] = t; | |
| } | |
| var s = sig.split(''); | |
| swap(s, 43); | |
| swap(s, 2); | |
| swap(s, 54); | |
| s = s.reverse(); | |
| swap(s, 8); | |
| s = s.slice(1); | |
| return s.join(''); | |
| } | |
| function checkYoutubeLinks(links, callback) | |
| { | |
| var checkUrl = ''; | |
| var checkItags = ['18', '34', '35'], checkUrl = ''; | |
| for(var i = 0; i < checkItags.length; i++) | |
| { | |
| if(links[checkItags[i]]) | |
| { | |
| checkUrl = links[checkItags[i]]; | |
| break; | |
| } | |
| } | |
| if(checkUrl) | |
| { | |
| getFileSize(checkUrl, function(r){ | |
| var isValid = (r.status >= 400) ? false : true; | |
| callback(checkUrl, isValid, r.status); | |
| }); | |
| return; | |
| } | |
| callback(); | |
| } | |
| function findYoutubeAvailableLinks(links, baseUrl, dashUrl, adaptiveFmts, titleParam) | |
| { | |
| if(!baseUrl || !dashUrl || !adaptiveFmts) | |
| return; | |
| var dashQuery = getYoutubeDashQuery(dashUrl); | |
| if(!dashQuery) | |
| return; | |
| var itags = getYoutubeAdaptiveFtmItags(adaptiveFmts); | |
| if(!itags) | |
| return; | |
| var map = { | |
| '133': ['5'], // 240 | |
| '134': ['34', '18', '43'], // 360 | |
| '135': ['35', '44'], // 480 | |
| '136': ['22', '45'], // 720 | |
| '137': ['37', '46'], // 1080 | |
| '138': ['38'] // 4k | |
| }; | |
| for(var i = 0; i < itags.length; i++) | |
| { | |
| if(map[itags[i]]) | |
| { | |
| for(var j = 0; j < map[itags[i]].length; j++) | |
| { | |
| var itag = map[itags[i]][j]; | |
| if(!links[itag]) | |
| { | |
| links[itag] = baseUrl + dashQuery + '&itag=' + itag + titleParam; | |
| } | |
| } | |
| } | |
| } | |
| } | |
| function parseYoutubeFmtMap(fmtMap, titleParam, baseUrl) | |
| { | |
| if(!fmtMap) | |
| return; | |
| var l = {}; | |
| fmtMap = fmtMap.split(','); | |
| for(var i = 0; i < fmtMap.length; ++i) | |
| { | |
| var query = parseQuery(fmtMap[i]); | |
| if(query.url) | |
| { | |
| query.url = decodeURIComponent(query.url); | |
| if(query.url.search(/(\?|&)sig(nature)?=/i) == -1) | |
| { | |
| if(query.sig) | |
| query.url += '&signature=' + query.sig; | |
| else if(query.signature) | |
| query.url += '&signature=' + query.signature; | |
| else if(query.s) | |
| query.url += '&signature=' + youtubeSignatureDecipher(query.s); | |
| } | |
| if(query.url.search(/(\?|&)itag=/i) == -1) | |
| { | |
| if(query.itag) | |
| query.url += '&itag=' + query.itag; | |
| } | |
| var fmt = query.url.match(/(?:\?|&)itag=(\d+)/i); | |
| if(fmt && fmt.length > 1) | |
| { | |
| fmt = fmt[1]; | |
| query.url = query.url.replace(/(\?|&)sig=/i, '$1signature='). | |
| replace(/\\u0026/ig, '&').replace(/\\\//g, '/'); | |
| l[fmt] = query.url; | |
| if(titleParam) | |
| l[fmt] += titleParam; | |
| if(!baseUrl) | |
| { | |
| var m = query.url.match(/^(https?:\/\/[^\?]+\?)/); | |
| if(m && m.length > 1) | |
| baseUrl = m[1]; | |
| } | |
| } | |
| } | |
| } | |
| return l; | |
| } | |
| function getYoutubeDashQuery(dashUrl) | |
| { | |
| if(!dashUrl) | |
| return ''; | |
| var u = dashUrl.replace(/^.+\/api\/manifest\/dash\//i, ''); | |
| if(u == dashUrl) | |
| return ''; | |
| u = u.split('/'); | |
| if(!u || u.length < 2) | |
| return ''; | |
| var query = {}; | |
| for(var i = 0; i < u.length - 1; i += 2) | |
| { | |
| if(u[i] != 'itag') | |
| { | |
| u[i] = decodeURIComponent(u[i]); | |
| u[i + 1] = decodeURIComponent(u[i + 1]); | |
| if(u[i] == 's') | |
| { | |
| u[i] = 'signature'; | |
| u[i + 1] = youtubeSignatureDecipher(u[i + 1]); | |
| } | |
| else if(u[i] == 'sig') | |
| { | |
| u[i] = 'signature'; | |
| } | |
| else if(u[i] == 'sparams' && u[i + 1].search(/(^|,|%2C)itag(^|,|%2C)/i)) | |
| { | |
| return ''; | |
| } | |
| query[u[i]] = u[i + 1]; | |
| } | |
| } | |
| if(!query.signature) | |
| return ''; | |
| query.ratebypass = 'yes'; | |
| return getQueryString(query); | |
| } | |
| function getYoutubeAdaptiveFtmItags(adaptiveFmts) | |
| { | |
| if(!adaptiveFmts) | |
| return; | |
| var itags = []; | |
| adaptiveFmts = adaptiveFmts.split('\\u0026').join('&'); | |
| u = adaptiveFmts.split(','); | |
| for(var i = 0; i < u.length; ++i) | |
| { | |
| var q = parseQuery(u[i]); | |
| var itag = 0; | |
| if(q.url) | |
| { | |
| q.url = decodeURIComponent(q.url); | |
| var m = q.url.match(/(?:\?|&)itag=(\d+)/i); | |
| if(m && m.length > 1) | |
| itag = m[1]; | |
| } | |
| if(!itag && q.itag) | |
| itag = q.itag; | |
| if(itag) | |
| itags.push(itag); | |
| } | |
| return itags; | |
| } | |
| function checkYoutubeSubtitles(videoId, callback) | |
| { | |
| var url = 'http://video.google.com/timedtext?hl=en&v=' + videoId + | |
| '&type=list&tlangs=1'; | |
| sendRequest(url, function(r){ | |
| var result = false; | |
| if(r.status == 200 && r.responseXML) | |
| { | |
| var doc = r.responseXML; | |
| if(doc.getElementsByTagName && | |
| (doc.getElementsByTagName('TARGET').length || doc.getElementsByTagName('TRACK').length)) | |
| { | |
| result = true; | |
| } | |
| } | |
| callback(result); | |
| }); | |
| } | |
| function getOdnoklassnikiLinks(extVideoId, callback) | |
| { | |
| if(!extVideoId) | |
| { | |
| callback(null); | |
| return; | |
| } | |
| var url = 'http://in.video.mail.ru/cgi-bin/video/oklite?eid=' + extVideoId; | |
| sendRequest(url, function(r){ | |
| if(r.status == 200 && r.responseText) | |
| { | |
| var u = 'http://www.okcontent.video.mail.ru/media/'; | |
| var host = r.responseText.match(/\$vcontentHost=([^\s\"'\<\>]+)/i); | |
| if(host && host.length > 1) | |
| u = 'http://' + host[1] + '/media/'; | |
| u += extVideoId; | |
| var links = []; | |
| links.push({ | |
| url: u + '-v.mp4', | |
| name: 'SD', | |
| ext: 'FLV' | |
| }); | |
| if(r.responseText.search(/\$HDexist=1/i) > -1) | |
| { | |
| links.push({ | |
| url: u + '-hv.mp4', | |
| name: 'HD', | |
| ext: 'MP4' | |
| }); | |
| } | |
| if(links) | |
| { | |
| callback(links); | |
| return; | |
| } | |
| } | |
| callback(null); | |
| }, '', url); | |
| } | |
| function getOdnoklassnikiAudioLinks(pageUrl, trackId, jsessionId, callback) | |
| { | |
| if(!trackId || !jsessionId) | |
| { | |
| callback(null); | |
| return; | |
| } | |
| var url = 'http://wmf1.odnoklassniki.ru/play;jsessionid=' + jsessionId + | |
| '?tid=' + trackId + '&'; | |
| sendRequest(url, function(r){ | |
| var data = null; | |
| if(r.status == 200 && r.responseText) | |
| { | |
| data = JSON.parse(r.responseText); | |
| } | |
| callback(data); | |
| }, '', url); | |
| } | |
| function getSoundcloudTrackInfo(trackUrl, client_id, callback) | |
| { | |
| if(!trackUrl || !client_id) | |
| { | |
| callback(null); | |
| return; | |
| } | |
| var url = 'http://api.soundcloud.com/resolve.json?url=' + trackUrl + | |
| '&client_id=' + client_id; | |
| sendRequest(url, function(r){ | |
| var data = null; | |
| if(r.status < 400 && r.responseText) | |
| { | |
| var data = JSON.parse(r.responseText); | |
| if(!data) | |
| data = r.responseText; | |
| } | |
| checkSoundcloudLinks(data, client_id, callback); | |
| }, '', url); | |
| } | |
| function checkSoundcloudLinks(data, client_id, cb) { | |
| if (!data) { | |
| return cb(); | |
| } | |
| var info = data; | |
| if(info.kind !== 'track' && info.tracks && info.tracks.length === 1) | |
| info = info.tracks[0]; | |
| if(info.kind === 'track' && info.stream_url) { | |
| validateSoundcloudTrackUrl(info.stream_url, client_id, function (isValid) { | |
| cb(data, isValid); | |
| }); | |
| return; | |
| } | |
| if (info.tracks) { | |
| validateSoundcloudTrackUrl(info.tracks[0].stream_url, client_id, function(isValid) { | |
| cb(data, isValid); | |
| }); | |
| return; | |
| } | |
| return cb(data); | |
| } | |
| function validateSoundcloudTrackUrl(url, client_id, cb) { | |
| url += (url.indexOf('?') === -1) ? '?' : '&'; | |
| url += 'client_id=' + client_id; | |
| sendRequest(url, function(r) { | |
| cb(r.status === 200); | |
| }, 'HEAD'); | |
| } | |
| var getDailymotionLinks = (function() { | |
| var readLink = function(url) { | |
| url = url.replace(/\\\//g, '/'); | |
| url = url.replace(/\@\@[\w\-]+$/, ''); | |
| var size = ''; | |
| var t = url.match(/\/cdn\/\w+\-(\d+x\d+)\//i); | |
| if(t && t.length > 1) | |
| { | |
| size = t[1]; | |
| } | |
| else | |
| { | |
| t = url.match(/\D(\d+x\d+)\D/i); | |
| if(t && t.length > 1) | |
| { | |
| size = t[1]; | |
| } | |
| } | |
| var ext = 'FLV'; | |
| t = url.match(/\.(\w{1,6})(?:$|\?)/); | |
| if(t && t.length > 1) | |
| { | |
| ext = t[1].toUpperCase(); | |
| } | |
| if(size !== '80x60') | |
| { | |
| var height = parseInt(size.split('x').slice(-1)[0]); | |
| return {url: url, name: ext+' '+height, ext: ext, info_url: '', height: height}; | |
| } | |
| }; | |
| var getLinks = function(text, cb) | |
| { | |
| var about = {}; | |
| var links = []; | |
| var info = text.match(/(?:var|,)\s*info\s*=\s*\{(.*?)\}\s*(?:;|,\s*\w+\s*=)/i); | |
| if(!info || info.length < 2) { | |
| return cb(); | |
| } | |
| info = info[1]; | |
| try { | |
| info = JSON.parse('{' + info + '}'); | |
| if(!info) { | |
| return cb(); | |
| } | |
| about.title = info.title; | |
| about.duration = info.duration; | |
| about.thumb = info.thumbnail_medium_url; | |
| for(var i in info) | |
| { | |
| if (!info.hasOwnProperty(i)) { | |
| continue; | |
| } | |
| if (!info[i]) { | |
| continue; | |
| } | |
| if(info[i].search(/^https?:\/\/[^\s\"]+\.(mp4|flv)(\?|$)/) > -1) | |
| { | |
| var link = readLink(info[i]); | |
| if (link !== undefined) { | |
| links.push(link); | |
| } | |
| } | |
| } | |
| } catch(e){} | |
| if (links.length > 0) { | |
| about.links = links; | |
| } | |
| cb(about); | |
| }; | |
| var getEmbedVideoInfo = function (id, callback) { | |
| var url = "http://www.dailymotion.com/embed/video/" + id; | |
| sendRequest(url, function(r) { | |
| if(r.status !== 200) { | |
| return callback(); | |
| } | |
| getLinks(r.responseText, callback); | |
| }); | |
| }; | |
| return getEmbedVideoInfo; | |
| })(); | |
| function parseQuery(query) | |
| { | |
| var k = {}; | |
| var re = /[?&]?([^=]+)(?:=([^&]*))?/g; | |
| while(m = re.exec(query)) | |
| { | |
| if(m[1] && m[2]) | |
| k[m[1]] = m[2]; | |
| else if(m[1]) | |
| k[m[1]] = ''; | |
| }; | |
| return k; | |
| } | |
| function getQueryString(query, key_prefix, key_suffix) | |
| { | |
| if(!query || typeof(query) != 'object') | |
| return ''; | |
| if(key_prefix === undefined) | |
| key_prefix = ''; | |
| if(key_suffix === undefined) | |
| key_suffix = ''; | |
| var str = ''; | |
| for(key in query) | |
| { | |
| if(str.length) | |
| str += '&'; | |
| if(query[key] instanceof Object) | |
| { | |
| if(!key_prefix) | |
| key_prefix = ''; | |
| if(!key_suffix) | |
| key_suffix = ''; | |
| str += getQueryString(query[key], key_prefix + key + "[", "]" + key_suffix); | |
| } | |
| else | |
| str += key_prefix + escape(key) + key_suffix + '=' + escape(query[key]); | |
| } | |
| return str; | |
| } | |
| function ucfirst(str) | |
| { | |
| if(str.length) | |
| str = str.charAt(0).toUpperCase() + str.slice(1); | |
| return str; | |
| } | |
| function userTrack() { | |
| var now = Date.now(); | |
| if (GM_getValue('trackTime') > now) { | |
| return; | |
| } | |
| GM_setValue('trackTime', now + 86400000); | |
| dblCheck(function() { | |
| sendScreenViewStats('init'); | |
| }); | |
| } | |
| function dblCheck(cb) { | |
| var dblTrack = GM_getValue('dblTrack'); | |
| var dataList = (dblTrack)?dblTrack.split(','):''; | |
| var now = Date.now(); | |
| if (dataList && dataList[1] > now) { | |
| return; | |
| } | |
| var uuid = generateUuid(); | |
| var expire = now + 60000; | |
| GM_setValue('dblTrack', uuid+','+expire); | |
| setTimeout(function() { | |
| var dblTrack = GM_getValue('dblTrack'); | |
| var dataList = (dblTrack)?dblTrack.split(','):''; | |
| if (dataList[0] !== uuid) { | |
| return; | |
| } | |
| cb(); | |
| }, 5000); | |
| } | |
| function sendScreenViewStats(screenName) { | |
| var params = { | |
| an: 'helper', | |
| aid: 'userjs-' + helper, | |
| av: chrome.app.getDetails().version, | |
| t: 'screenview', | |
| cd: screenName | |
| }; | |
| sendStatsInfo(params); | |
| } | |
| function sendStatsInfo(params) { | |
| if(!params.t) | |
| return; | |
| var def = { | |
| v: 1, | |
| tid: 'UA-7055055-5', | |
| cid: getUuid(), | |
| //ul: chrome.i18n.getMessage("lang") | |
| }; | |
| for (var i in def) { | |
| if(!params[i]) | |
| params[i] = def[i]; | |
| } | |
| sendRequest('https://www.google-analytics.com/collect', | |
| function(r){}, 'POST', '', | |
| getQueryString(params) | |
| ); | |
| } | |
| function getUuid() { | |
| var uuid = GM_getValue('uuid'); | |
| if (uuid) { | |
| return uuid; | |
| } | |
| uuid = generateUuid(); | |
| GM_setValue('uuid', uuid); | |
| return uuid; | |
| } | |
| function generateUuid() | |
| { | |
| return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { | |
| var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8); | |
| return v.toString(16); | |
| }); | |
| } | |
| fixPref([ | |
| {name: 'button', check: '0', def: '1'}, | |
| {name: 'moduleVimeo', check: '0', def: '1'}, | |
| {name: 'moduleFacebook', check: '0', def: '1'}, | |
| {name: 'moduleSoundcloud', check: '0', def: '1'}, | |
| {name: 'ytHideFLV', check: '1', def: '0'}, | |
| {name: 'ytHideMP4', check: '1', def: '0'}, | |
| {name: 'ytHideWebM', check: '0', def: '1'}, | |
| {name: 'ytHide3GP', check: '0', def: '1'}, | |
| {name: 'ytHide3D', check: '0', def: '1'}, | |
| {name: 'ytHideMP4NoAudio', check: '0', def: '1'}, | |
| {name: 'ytHideAudio_MP4', check: '0', def: '1'}, | |
| {name: 'vkShowBitrate', check: '1', def: '0'} | |
| ]); | |
| }; | |
| ///////////////////////////////////////////////// | |
| // UTILS | |
| SaveFrom_Utils = { | |
| downloadParam: 'sfh--download', | |
| prefs: {}, | |
| initModule: function(name, callback) | |
| { | |
| var request = { | |
| action: 'initModule', | |
| moduleName: name, | |
| frame: (window.top != window.self) | |
| }; | |
| callback = callback || function(){}; | |
| chrome.extension.sendRequest(request, callback); | |
| }, | |
| runModule: function(response, module) | |
| { | |
| if (!response) | |
| return; | |
| this.prefs = response; | |
| //console.log('moduleEnable', response.moduleEnable, module) | |
| if(response.name == 'savefrom') | |
| module.run(); | |
| else if (response.moduleEnable) | |
| module.run(); | |
| }, | |
| trim: function(str) | |
| { | |
| return str.replace(/^\s+|\s+$/g, ''); | |
| }, | |
| nextSibling: function(obj) | |
| { | |
| var next = obj; | |
| do | |
| { | |
| next = next.nextSibling; | |
| if(next) | |
| { | |
| if(next.nodeType == 1) | |
| return next; | |
| if(next.nodeType == 9) | |
| break; | |
| } | |
| } | |
| while(next); | |
| return null; | |
| }, | |
| setStyle: function(node, style) | |
| { | |
| if(!node || !style) | |
| return; | |
| for(var i in style) | |
| node.style[i] = style[i]; | |
| }, | |
| getStyle: function(node, property) | |
| { | |
| var s = undefined; | |
| if(!node) | |
| return undefined; | |
| if(node.currentStyle) | |
| { | |
| property = property.replace(/-(w)/g, function(s, m){return m.toUpperCase()}); | |
| return node.currentStyle[property]; | |
| } | |
| if(window.getComputedStyle) | |
| return window.getComputedStyle(node, null).getPropertyValue(property); | |
| return undefined; | |
| }, | |
| addStyleRules: function(selector, rules) | |
| { | |
| var style = document.getElementById('savefrom-styles'); | |
| if(!style) | |
| { | |
| style = document.createElement('style') | |
| style.id = 'savefrom-styles'; | |
| // maybe need for safari | |
| //style.appendChild(document.createTextNode("")); | |
| var s = document.querySelector('head style'); | |
| if(s) | |
| // allow to override our styles | |
| s.parentNode.insertBefore(style, s); | |
| else | |
| document.querySelector('head').appendChild(style); | |
| } | |
| if(typeof(rules) == 'object') { | |
| var r = []; | |
| for(var i in rules) | |
| r.push(i + ':' + rules[i]); | |
| rules = r.join(';'); | |
| } | |
| style.sheet.addRule(selector, rules); | |
| }, | |
| getPosition: function(node) | |
| { | |
| var box = node.getBoundingClientRect(); | |
| return { | |
| top: Math.round(box.top + window.pageYOffset), | |
| left: Math.round(box.left + window.pageXOffset) | |
| } | |
| }, | |
| getSize: function(node) | |
| { | |
| return {width: node.offsetWidth, height: node.offsetHeight}; | |
| }, | |
| getMatchFirst: function(str, re) | |
| { | |
| var m = str.match(re); | |
| if(m && m.length > 1) | |
| return m[1]; | |
| return ''; | |
| }, | |
| getElementByIds: function(ids) | |
| { | |
| for(var i = 0; i < ids.length; i++) | |
| { | |
| var node = document.getElementById(ids[i]); | |
| if(node) | |
| return node; | |
| } | |
| return null; | |
| }, | |
| hasClass: function(node, name) | |
| { | |
| if(!node || !node.className || name == '') | |
| return false; | |
| if(node.className == name) | |
| return true; | |
| var re = new RegExp("(^|\\s+)" + name + "(\\s+|$)"); | |
| if(node.className.search(re) != -1) | |
| return true; | |
| return false; | |
| }, | |
| addClass: function(node, name) | |
| { | |
| if(!this.hasClass(node, name)) | |
| { | |
| var c = node.className; | |
| if(c) | |
| node.className = c + ' ' + name; | |
| else | |
| node.className = name; | |
| } | |
| }, | |
| removeClass: function(node, name) | |
| { | |
| if(!this.hasClass(node, name)) | |
| return; | |
| var re = new RegExp("(^|\\s+)" + name + "(\\s+|$)"); | |
| node.className = node.className.replace(re, function(t, s1, s2){ | |
| if(s1 && s2) | |
| return ' '; | |
| return ''; | |
| }); | |
| }, | |
| matchesSelector: function(node, selector) | |
| { | |
| if(node.matchesSelector) | |
| return node.matchesSelector(selector); | |
| if(node.webkitMatchesSelector) | |
| return node.webkitMatchesSelector(selector); | |
| var nodes = node.parentNode.querySelectorAll(selector); | |
| for(var i = 0; i < nodes.length; ++i) | |
| { | |
| if(nodes[i] == node) | |
| return true; | |
| } | |
| return false; | |
| }, | |
| getParentByClass: function(node, name) | |
| { | |
| if(!node || name == '') | |
| return false; | |
| if(typeof(name) == 'object' && name.length > 0) | |
| { | |
| for(var parent = node; parent; parent = parent.parentNode) | |
| { | |
| for(var i = 0; i < name.length; i++) | |
| { | |
| if(this.hasClass(parent, name[i])) | |
| return parent; | |
| } | |
| } | |
| } | |
| else | |
| { | |
| for(var parent = node; parent; parent = parent.parentNode) | |
| { | |
| if(this.hasClass(parent, name)) | |
| return parent; | |
| } | |
| } | |
| return null; | |
| }, | |
| isParent: function(node, testParent) | |
| { | |
| for(var parent = node; parent; parent = parent.parentNode) | |
| { | |
| if (parent == testParent) | |
| return true; | |
| } | |
| return false; | |
| }, | |
| emptyNode: function(node) | |
| { | |
| while(node.firstChild) | |
| node.removeChild(node.firstChild); | |
| }, | |
| download: function(filename, url, options, callback, iframe) | |
| { | |
| if(!url) | |
| return false; | |
| filename = filename || this.getFileName(url); | |
| if(!filename) | |
| return false; | |
| if (!this.prefs || !this.prefs.downloads) { | |
| if (iframe && this.downloadCheckProtocol(url)) { | |
| var src = this.getMatchFirst(url, /(^https?:\/\/[^\/]+)/); | |
| if(src == location.protocol + '//' + location.host) { | |
| var a = document.createElement('a'); | |
| a.href = url; | |
| a.download = filename; | |
| document.body.appendChild(a); | |
| this.click(a); | |
| setTimeout(function(){ | |
| a.parentNode.removeChild(a); | |
| }, 100); | |
| } | |
| else { | |
| var params = {url: url, filename: filename}; | |
| params = encodeURIComponent(JSON.stringify(params)); | |
| src += '/404?#' + this.downloadParam + '=' + params; | |
| var f = document.createElement('iframe'); | |
| f.src = src; | |
| this.setStyle(f, { | |
| width: 0, | |
| height: 0, | |
| overflow: 'hidden' | |
| }); | |
| document.body.appendChild(f); | |
| setTimeout(function(){ | |
| f.parentNode.removeChild(f); | |
| }, 3000); | |
| } | |
| return true; | |
| } | |
| return false; | |
| } | |
| var params = options || {}; | |
| params.url = url; | |
| params.filename = filename; | |
| var request = { | |
| action: 'downloadFile', | |
| options: params | |
| }; | |
| callback = callback || function(){}; | |
| chrome.extension.sendRequest(request, callback); | |
| return true; | |
| }, | |
| downloadCheckProtocol: function(url) { | |
| if(location.protocol == 'http:') { | |
| return true; | |
| } | |
| if(!url) { | |
| return false; | |
| } | |
| url = url.toLowerCase(); | |
| if(location.protocol == url.substr(0, location.protocol.length)) { | |
| return true; | |
| } | |
| return false; | |
| }, | |
| downloadLink: function(a, callback, iframe) | |
| { | |
| if(!a.href) | |
| return false; | |
| var filename = a.getAttribute('download'); | |
| return this.download(filename, a.href, null, callback, iframe); | |
| }, | |
| downloadOnClick: function(event, callback, iframe) | |
| { | |
| var _this = SaveFrom_Utils; | |
| var node = event.target; | |
| if(node.tagName != 'A') | |
| node = node.parentNode; | |
| if ( !(_this.prefs && _this.prefs.downloads) && | |
| !(iframe && node.href && _this.downloadCheckProtocol(node.href)) ) { | |
| return; | |
| } | |
| if(event.button == 2) | |
| return; | |
| event.preventDefault(); | |
| event.stopPropagation(); | |
| _this.downloadLink(node, callback, iframe); | |
| }, | |
| click: function(node, ctrlKey, altKey, shiftKey, button) | |
| { | |
| if(!node) | |
| return; | |
| if(!ctrlKey) | |
| ctrlKey = false; | |
| if(!altKey) | |
| altKey = false; | |
| if(!shiftKey) | |
| shiftKey = false; | |
| if(!button) | |
| button = 0; | |
| var e = document.createEvent("MouseEvents"); | |
| e.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, | |
| ctrlKey, altKey, shiftKey, false, button, null); | |
| node.dispatchEvent(e); | |
| }, | |
| parseQuery: function(query) | |
| { | |
| var k = new Array(); | |
| var re = /[?&]?([^=]+)(?:=([^&]*))?/g; | |
| while(m = re.exec(query)) | |
| { | |
| if(m[1] && m[2]) | |
| k[m[1]] = m[2]; | |
| else if(m[1]) | |
| k[m[1]] = ''; | |
| }; | |
| return k; | |
| }, | |
| getQueryString: function(query, key_prefix, key_suffix) | |
| { | |
| if(!query || typeof(query) != 'object') | |
| return ''; | |
| if(key_prefix === undefined) | |
| key_prefix = ''; | |
| if(key_suffix === undefined) | |
| key_suffix = ''; | |
| var str = ''; | |
| for(key in query) | |
| { | |
| if(str.length) | |
| str += '&'; | |
| if(query[key] instanceof Object) | |
| { | |
| if(!key_prefix) | |
| key_prefix = ''; | |
| if(!key_suffix) | |
| key_suffix = ''; | |
| str += getQueryString(query[key], key_prefix + key + "[", "]" + key_suffix); | |
| } | |
| else | |
| str += key_prefix + escape(key) + key_suffix + '=' + escape(query[key]); | |
| } | |
| return str; | |
| }, | |
| md5: function(str) | |
| { | |
| // http://kevin.vanzonneveld.net | |
| // + original by: Webtoolkit.info (http://www.webtoolkit.info/) | |
| // + namespaced by: Michael White (http://getsprink.com) | |
| // + tweaked by: Jack | |
| // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) | |
| // + input by: Brett Zamir (http://brett-zamir.me) | |
| // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) | |
| // - depends on: utf8_encode | |
| // * example 1: md5('Kevin van Zonneveld'); | |
| // * returns 1: '6e658d4bfcb59cc13f96c14450ac40b9' | |
| var xl; | |
| var rotateLeft = function (lValue, iShiftBits) { | |
| return (lValue << iShiftBits) | (lValue >>> (32 - iShiftBits)); | |
| }; | |
| var addUnsigned = function (lX, lY) { | |
| var lX4, lY4, lX8, lY8, lResult; | |
| lX8 = (lX & 0x80000000); | |
| lY8 = (lY & 0x80000000); | |
| lX4 = (lX & 0x40000000); | |
| lY4 = (lY & 0x40000000); | |
| lResult = (lX & 0x3FFFFFFF) + (lY & 0x3FFFFFFF); | |
| if (lX4 & lY4) { | |
| return (lResult ^ 0x80000000 ^ lX8 ^ lY8); | |
| } | |
| if (lX4 | lY4) { | |
| if (lResult & 0x40000000) { | |
| return (lResult ^ 0xC0000000 ^ lX8 ^ lY8); | |
| } else { | |
| return (lResult ^ 0x40000000 ^ lX8 ^ lY8); | |
| } | |
| } else { | |
| return (lResult ^ lX8 ^ lY8); | |
| } | |
| }; | |
| var _F = function (x, y, z) { | |
| return (x & y) | ((~x) & z); | |
| }; | |
| var _G = function (x, y, z) { | |
| return (x & z) | (y & (~z)); | |
| }; | |
| var _H = function (x, y, z) { | |
| return (x ^ y ^ z); | |
| }; | |
| var _I = function (x, y, z) { | |
| return (y ^ (x | (~z))); | |
| }; | |
| var _FF = function (a, b, c, d, x, s, ac) { | |
| a = addUnsigned(a, addUnsigned(addUnsigned(_F(b, c, d), x), ac)); | |
| return addUnsigned(rotateLeft(a, s), b); | |
| }; | |
| var _GG = function (a, b, c, d, x, s, ac) { | |
| a = addUnsigned(a, addUnsigned(addUnsigned(_G(b, c, d), x), ac)); | |
| return addUnsigned(rotateLeft(a, s), b); | |
| }; | |
| var _HH = function (a, b, c, d, x, s, ac) { | |
| a = addUnsigned(a, addUnsigned(addUnsigned(_H(b, c, d), x), ac)); | |
| return addUnsigned(rotateLeft(a, s), b); | |
| }; | |
| var _II = function (a, b, c, d, x, s, ac) { | |
| a = addUnsigned(a, addUnsigned(addUnsigned(_I(b, c, d), x), ac)); | |
| return addUnsigned(rotateLeft(a, s), b); | |
| }; | |
| var convertToWordArray = function (str) { | |
| var lWordCount; | |
| var lMessageLength = str.length; | |
| var lNumberOfWords_temp1 = lMessageLength + 8; | |
| var lNumberOfWords_temp2 = (lNumberOfWords_temp1 - (lNumberOfWords_temp1 % 64)) / 64; | |
| var lNumberOfWords = (lNumberOfWords_temp2 + 1) * 16; | |
| var lWordArray = new Array(lNumberOfWords - 1); | |
| var lBytePosition = 0; | |
| var lByteCount = 0; | |
| while (lByteCount < lMessageLength) { | |
| lWordCount = (lByteCount - (lByteCount % 4)) / 4; | |
| lBytePosition = (lByteCount % 4) * 8; | |
| lWordArray[lWordCount] = (lWordArray[lWordCount] | (str.charCodeAt(lByteCount) << lBytePosition)); | |
| lByteCount++; | |
| } | |
| lWordCount = (lByteCount - (lByteCount % 4)) / 4; | |
| lBytePosition = (lByteCount % 4) * 8; | |
| lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80 << lBytePosition); | |
| lWordArray[lNumberOfWords - 2] = lMessageLength << 3; | |
| lWordArray[lNumberOfWords - 1] = lMessageLength >>> 29; | |
| return lWordArray; | |
| }; | |
| var wordToHex = function (lValue) { | |
| var wordToHexValue = "", | |
| wordToHexValue_temp = "", | |
| lByte, lCount; | |
| for (lCount = 0; lCount <= 3; lCount++) { | |
| lByte = (lValue >>> (lCount * 8)) & 255; | |
| wordToHexValue_temp = "0" + lByte.toString(16); | |
| wordToHexValue = wordToHexValue + wordToHexValue_temp.substr(wordToHexValue_temp.length - 2, 2); | |
| } | |
| return wordToHexValue; | |
| }; | |
| var x = [], | |
| k, AA, BB, CC, DD, a, b, c, d, S11 = 7, | |
| S12 = 12, | |
| S13 = 17, | |
| S14 = 22, | |
| S21 = 5, | |
| S22 = 9, | |
| S23 = 14, | |
| S24 = 20, | |
| S31 = 4, | |
| S32 = 11, | |
| S33 = 16, | |
| S34 = 23, | |
| S41 = 6, | |
| S42 = 10, | |
| S43 = 15, | |
| S44 = 21; | |
| //str = this.utf8_encode(str); | |
| x = convertToWordArray(str); | |
| a = 0x67452301; | |
| b = 0xEFCDAB89; | |
| c = 0x98BADCFE; | |
| d = 0x10325476; | |
| xl = x.length; | |
| for (k = 0; k < xl; k += 16) { | |
| AA = a; | |
| BB = b; | |
| CC = c; | |
| DD = d; | |
| a = _FF(a, b, c, d, x[k + 0], S11, 0xD76AA478); | |
| d = _FF(d, a, b, c, x[k + 1], S12, 0xE8C7B756); | |
| c = _FF(c, d, a, b, x[k + 2], S13, 0x242070DB); | |
| b = _FF(b, c, d, a, x[k + 3], S14, 0xC1BDCEEE); | |
| a = _FF(a, b, c, d, x[k + 4], S11, 0xF57C0FAF); | |
| d = _FF(d, a, b, c, x[k + 5], S12, 0x4787C62A); | |
| c = _FF(c, d, a, b, x[k + 6], S13, 0xA8304613); | |
| b = _FF(b, c, d, a, x[k + 7], S14, 0xFD469501); | |
| a = _FF(a, b, c, d, x[k + 8], S11, 0x698098D8); | |
| d = _FF(d, a, b, c, x[k + 9], S12, 0x8B44F7AF); | |
| c = _FF(c, d, a, b, x[k + 10], S13, 0xFFFF5BB1); | |
| b = _FF(b, c, d, a, x[k + 11], S14, 0x895CD7BE); | |
| a = _FF(a, b, c, d, x[k + 12], S11, 0x6B901122); | |
| d = _FF(d, a, b, c, x[k + 13], S12, 0xFD987193); | |
| c = _FF(c, d, a, b, x[k + 14], S13, 0xA679438E); | |
| b = _FF(b, c, d, a, x[k + 15], S14, 0x49B40821); | |
| a = _GG(a, b, c, d, x[k + 1], S21, 0xF61E2562); | |
| d = _GG(d, a, b, c, x[k + 6], S22, 0xC040B340); | |
| c = _GG(c, d, a, b, x[k + 11], S23, 0x265E5A51); | |
| b = _GG(b, c, d, a, x[k + 0], S24, 0xE9B6C7AA); | |
| a = _GG(a, b, c, d, x[k + 5], S21, 0xD62F105D); | |
| d = _GG(d, a, b, c, x[k + 10], S22, 0x2441453); | |
| c = _GG(c, d, a, b, x[k + 15], S23, 0xD8A1E681); | |
| b = _GG(b, c, d, a, x[k + 4], S24, 0xE7D3FBC8); | |
| a = _GG(a, b, c, d, x[k + 9], S21, 0x21E1CDE6); | |
| d = _GG(d, a, b, c, x[k + 14], S22, 0xC33707D6); | |
| c = _GG(c, d, a, b, x[k + 3], S23, 0xF4D50D87); | |
| b = _GG(b, c, d, a, x[k + 8], S24, 0x455A14ED); | |
| a = _GG(a, b, c, d, x[k + 13], S21, 0xA9E3E905); | |
| d = _GG(d, a, b, c, x[k + 2], S22, 0xFCEFA3F8); | |
| c = _GG(c, d, a, b, x[k + 7], S23, 0x676F02D9); | |
| b = _GG(b, c, d, a, x[k + 12], S24, 0x8D2A4C8A); | |
| a = _HH(a, b, c, d, x[k + 5], S31, 0xFFFA3942); | |
| d = _HH(d, a, b, c, x[k + 8], S32, 0x8771F681); | |
| c = _HH(c, d, a, b, x[k + 11], S33, 0x6D9D6122); | |
| b = _HH(b, c, d, a, x[k + 14], S34, 0xFDE5380C); | |
| a = _HH(a, b, c, d, x[k + 1], S31, 0xA4BEEA44); | |
| d = _HH(d, a, b, c, x[k + 4], S32, 0x4BDECFA9); | |
| c = _HH(c, d, a, b, x[k + 7], S33, 0xF6BB4B60); | |
| b = _HH(b, c, d, a, x[k + 10], S34, 0xBEBFBC70); | |
| a = _HH(a, b, c, d, x[k + 13], S31, 0x289B7EC6); | |
| d = _HH(d, a, b, c, x[k + 0], S32, 0xEAA127FA); | |
| c = _HH(c, d, a, b, x[k + 3], S33, 0xD4EF3085); | |
| b = _HH(b, c, d, a, x[k + 6], S34, 0x4881D05); | |
| a = _HH(a, b, c, d, x[k + 9], S31, 0xD9D4D039); | |
| d = _HH(d, a, b, c, x[k + 12], S32, 0xE6DB99E5); | |
| c = _HH(c, d, a, b, x[k + 15], S33, 0x1FA27CF8); | |
| b = _HH(b, c, d, a, x[k + 2], S34, 0xC4AC5665); | |
| a = _II(a, b, c, d, x[k + 0], S41, 0xF4292244); | |
| d = _II(d, a, b, c, x[k + 7], S42, 0x432AFF97); | |
| c = _II(c, d, a, b, x[k + 14], S43, 0xAB9423A7); | |
| b = _II(b, c, d, a, x[k + 5], S44, 0xFC93A039); | |
| a = _II(a, b, c, d, x[k + 12], S41, 0x655B59C3); | |
| d = _II(d, a, b, c, x[k + 3], S42, 0x8F0CCC92); | |
| c = _II(c, d, a, b, x[k + 10], S43, 0xFFEFF47D); | |
| b = _II(b, c, d, a, x[k + 1], S44, 0x85845DD1); | |
| a = _II(a, b, c, d, x[k + 8], S41, 0x6FA87E4F); | |
| d = _II(d, a, b, c, x[k + 15], S42, 0xFE2CE6E0); | |
| c = _II(c, d, a, b, x[k + 6], S43, 0xA3014314); | |
| b = _II(b, c, d, a, x[k + 13], S44, 0x4E0811A1); | |
| a = _II(a, b, c, d, x[k + 4], S41, 0xF7537E82); | |
| d = _II(d, a, b, c, x[k + 11], S42, 0xBD3AF235); | |
| c = _II(c, d, a, b, x[k + 2], S43, 0x2AD7D2BB); | |
| b = _II(b, c, d, a, x[k + 9], S44, 0xEB86D391); | |
| a = addUnsigned(a, AA); | |
| b = addUnsigned(b, BB); | |
| c = addUnsigned(c, CC); | |
| d = addUnsigned(d, DD); | |
| } | |
| var temp = wordToHex(a) + wordToHex(b) + wordToHex(c) + wordToHex(d); | |
| return temp.toLowerCase(); | |
| }, | |
| decodeHTML: function(html) | |
| { | |
| var d = document.createElement('div'); | |
| d.innerHTML = html.replace(/</g, '<'). | |
| replace(/\>/g, '>'). | |
| replace(/\"/g, '"'); | |
| var res = d.textContent ? d.textContent : d.innerText; | |
| d.innerHTML = ''; | |
| return SaveFrom_Utils.decodeUnicodeEscapeSequence(res); | |
| }, | |
| decodeUnicodeEscapeSequence: function(text) | |
| { | |
| return text.replace(/\\u([0-9a-f]{4})/g, function(s, m){ | |
| m = parseInt(m, 16); | |
| if(!isNaN(m)) | |
| { | |
| return String.fromCharCode(m); | |
| } | |
| }); | |
| }, | |
| getFileExtension: function(str, def) | |
| { | |
| var ext = this.getMatchFirst(str, /\.([a-z0-9]{3,4})(\?|$)/i); | |
| if(ext) | |
| return ext.toLowerCase(); | |
| return (def ? def : ''); | |
| }, | |
| getFileName: function(url) | |
| { | |
| var filename = this.getMatchFirst(url, /\/([^\?#\/]+\.[a-z\d]{2,6})(?:\?|#|$)/i); | |
| if(!filename) | |
| return filename; | |
| return this.fileName.modify(filename); | |
| }, | |
| getTopLevelDomain: function(domain) | |
| { | |
| if(!domain) | |
| return ''; | |
| if(!domain.match(/^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,6}/)) | |
| return domain; | |
| var a = domain.split('.'); | |
| var l = a.length; | |
| if(l == 2) | |
| return domain; | |
| return (a[l - 2] + '.' + a[l - 1]); | |
| }, | |
| dateToObj: function(ts, leadingZero) | |
| { | |
| var d = (ts === null || ts === undefined) ? new Date() : new Date(ts); | |
| if(leadingZero === undefined) | |
| leadingZero = true; | |
| var res = { | |
| year: d.getFullYear(), | |
| month: (d.getMonth() + 1), | |
| day: d.getDate(), | |
| hour: d.getHours(), | |
| min: d.getMinutes(), | |
| sec: d.getSeconds() | |
| }; | |
| if(leadingZero) | |
| { | |
| for(var i in res) | |
| { | |
| if(res[i].toString().length == 1) | |
| res[i] = '0' + res[i]; | |
| } | |
| } | |
| return res; | |
| }, | |
| utf8Encode: function(str) | |
| { | |
| str = str.replace(/\r\n/g,"\n"); | |
| var res = ""; | |
| for (var n = 0; n < str.length; n++) | |
| { | |
| var c = str.charCodeAt(n); | |
| if (c < 128) | |
| res += String.fromCharCode(c); | |
| else if((c > 127) && (c < 2048)) | |
| { | |
| res += String.fromCharCode((c >> 6) | 192); | |
| res += String.fromCharCode((c & 63) | 128); | |
| } | |
| else | |
| { | |
| res += String.fromCharCode((c >> 12) | 224); | |
| res += String.fromCharCode(((c >> 6) & 63) | 128); | |
| res += String.fromCharCode((c & 63) | 128); | |
| } | |
| } | |
| return res; | |
| }, | |
| utf8ToWindows1251: function(str) | |
| { | |
| var res = '', i = 0, c = c1 = c2 = 0; | |
| var a = { | |
| 208: { | |
| 160: 208, 144: 192, 145: 193, 146: 194, | |
| 147: 195, 148: 196, 149: 197, 129: 168, | |
| 150: 198, 151: 199, 152: 200, 153: 201, | |
| 154: 202, 155: 203, 156: 204, 157: 205, | |
| 158: 206, 159: 207, 161: 209, 162: 210, | |
| 163: 211, 164: 212, 165: 213, 166: 214, | |
| 167: 215, 168: 216, 169: 217, 170: 218, | |
| 171: 219, 172: 220, 173: 221, 174: 222, | |
| 175: 223, 176: 224, 177: 225, 178: 226, | |
| 179: 227, 180: 228, 181: 229, 182: 230, | |
| 183: 231, 184: 232, 185: 233, 186: 234, | |
| 187: 235, 188: 236, 189: 237, 190: 238, | |
| 191: 239 | |
| }, | |
| 209: { | |
| 145: 184, 128: 240, 129: 241, 130: 242, | |
| 131: 243, 132: 244, 133: 245, 134: 246, | |
| 135: 247, 136: 248, 137: 249, 138: 250, | |
| 139: 251, 140: 252, 141: 253, 142: 254, | |
| 143: 255 | |
| } | |
| }; | |
| while(i < str.length) | |
| { | |
| c = str.charCodeAt(i); | |
| if(c < 128) | |
| { | |
| res += String.fromCharCode(c); | |
| i++; | |
| } | |
| else if((c > 191) && (c < 224)) | |
| { | |
| if(c == 208 || c == 209) | |
| { | |
| c2 = str.charCodeAt(i + 1); | |
| if(a[c][c2]) | |
| res += String.fromCharCode(a[c][c2]); | |
| else | |
| res += '?'; | |
| } | |
| else | |
| res += '?'; | |
| i += 2; | |
| } | |
| else | |
| { | |
| res += '?'; | |
| i += 3; | |
| } | |
| } | |
| return res; | |
| }, | |
| base64_encode: function(str) | |
| { | |
| var res = ''; | |
| var c1, c2, c3, e1, e2, e3, e4; | |
| var key = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; | |
| var i = 0; | |
| while(i < str.length) | |
| { | |
| c1 = str.charCodeAt(i++); | |
| c2 = str.charCodeAt(i++); | |
| c3 = str.charCodeAt(i++); | |
| e1 = c1 >> 2; | |
| e2 = ((c1 & 3) << 4) | (c2 >> 4); | |
| e3 = ((c2 & 15) << 2) | (c3 >> 6); | |
| e4 = c3 & 63; | |
| if(isNaN(c2)) | |
| { | |
| e3 = e4 = 64; | |
| } | |
| else if(isNaN(c3)) | |
| { | |
| e4 = 64; | |
| } | |
| res += key.charAt(e1) + key.charAt(e2) + key.charAt(e3) + key.charAt(e4); | |
| } | |
| return res; | |
| }, | |
| sizeHuman: function(size, round) | |
| { | |
| if(round == undefined || round == null) | |
| round = 2; | |
| var s = size, count = 0, sign = '', unite_spec = [ | |
| chrome.i18n.getMessage('vkFileSizeByte'), | |
| chrome.i18n.getMessage('vkFileSizeKByte'), | |
| chrome.i18n.getMessage('vkFileSizeMByte'), | |
| chrome.i18n.getMessage('vkFileSizeGByte'), | |
| chrome.i18n.getMessage('vkFileSizeTByte'), | |
| ]; | |
| if(s < 0) | |
| { | |
| sign = '-'; | |
| s = Math.abs(s); | |
| } | |
| while(s >= 1000) | |
| { | |
| count++; | |
| s /= 1024; | |
| } | |
| if(round >= 0) | |
| { | |
| var m = round * 10; | |
| s = Math.round(s * m) / m; | |
| } | |
| if(count < unite_spec.length) | |
| return sign + s + ' ' + unite_spec[count]; | |
| return size; | |
| }, | |
| sendRequest: function(url, callback, method, referer, post, cookie, | |
| userAgent, header) | |
| { | |
| var req = new window.XMLHttpRequest(); | |
| if (!req) | |
| return; | |
| method = method ? method : ((post) ? 'POST' : 'GET'); | |
| //userAgent = userAgent ? userAgent : window.navigator.userAgent; | |
| req.open(method, url, true); | |
| //req.setRequestHeader('User-Agent', userAgent); | |
| if(referer) | |
| { | |
| req.setRequestHeader('Referer', referer); | |
| } | |
| if(cookie) | |
| { | |
| req.setRequestHeader('Cookie', cookie); | |
| } | |
| if (post) | |
| { | |
| req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); | |
| req.setRequestHeader("Content-Length", post.length); | |
| } | |
| if(header) | |
| { | |
| for(var i = 0; i < header.length; i++) | |
| { | |
| req.setRequestHeader(header[i][0], header[i][1]); | |
| } | |
| } | |
| req.onreadystatechange = function () | |
| { | |
| if (req.readyState != 4) | |
| return; | |
| callback(req); | |
| }; | |
| if (req.readyState == 4) | |
| { | |
| return; | |
| } | |
| if(post) | |
| req.send(post); | |
| else | |
| req.send(); | |
| }, | |
| secondsToDuration: function(seconds) | |
| { | |
| if(!seconds || isNaN(seconds)) | |
| return ''; | |
| function zfill(time) | |
| { | |
| if(time < 10) | |
| return '0' + time; | |
| return time.toString(); | |
| } | |
| var hours = Math.floor(seconds / 3600); | |
| seconds %= 3600; | |
| var minutes = Math.floor(seconds / 60); | |
| seconds %= 60; | |
| if(hours > 0) | |
| return hours + ":" + zfill(minutes) + ":" + zfill(seconds); | |
| return minutes + ":" + zfill(seconds); | |
| }, | |
| // file name | |
| fileName: { | |
| maxLength: 80, | |
| getParts: function(name) | |
| { | |
| return name.match(/^(.+)\.([a-z0-9]{1,4})$/i); | |
| }, | |
| shorten: function(name) | |
| { | |
| name = name.substr(0, this.maxLength); | |
| var nws = '\\u0030-\\u0039\\u0041-\\u005a\\u005f\\u0061-\\u007a\\u00aa\\u00b5\\u00ba\\u00c0-\\u00d6\\u00d8-\\u00f6\\u00f8-\\u021f\\u0222-\\u0233\\u0250-\\u02ad\\u0386\\u0388-\\u038a\\u038c\\u038e-\\u03a1\\u03a3-\\u03ce\\u03d0-\\u03d7\\u03da-\\u03f3\\u0400-\\u0481\\u048c-\\u04c4\\u04c7\\u04c8\\u04cb\\u04cc\\u04d0-\\u04f5\\u04f8\\u04f9\\u0531-\\u0556\\u0561-\\u0587\\u05d0-\\u05ea\\u05f0-\\u05f2\\u0621-\\u063a\\u0641-\\u064a\\u0660-\\u0669\\u0671-\\u06d3\\u06d5\\u06f0-\\u06fc\\u0710\\u0712-\\u072c\\u0780-\\u07a5\\u0905-\\u0939\\u093d\\u0950\\u0958-\\u0961\\u0966-\\u096f\\u0985-\\u098c\\u098f\\u0990\\u0993-\\u09a8\\u09aa-\\u09b0\\u09b2\\u09b6-\\u09b9\\u09dc\\u09dd\\u09df-\\u09e1\\u09e6-\\u09f1\\u0a05-\\u0a0a\\u0a0f\\u0a10\\u0a13-\\u0a28\\u0a2a-\\u0a30\\u0a32\\u0a33\\u0a35\\u0a36\\u0a38\\u0a39\\u0a59-\\u0a5c\\u0a5e\\u0a66-\\u0a6f\\u0a72-\\u0a74\\u0a85-\\u0a8b\\u0a8d\\u0a8f-\\u0a91\\u0a93-\\u0aa8\\u0aaa-\\u0ab0\\u0ab2\\u0ab3\\u0ab5-\\u0ab9\\u0abd\\u0ad0\\u0ae0\\u0ae6-\\u0aef\\u0b05-\\u0b0c\\u0b0f\\u0b10\\u0b13-\\u0b28\\u0b2a-\\u0b30\\u0b32\\u0b33\\u0b36-\\u0b39\\u0b3d\\u0b5c\\u0b5d\\u0b5f-\\u0b61\\u0b66-\\u0b6f\\u0b85-\\u0b8a\\u0b8e-\\u0b90\\u0b92-\\u0b95\\u0b99\\u0b9a\\u0b9c\\u0b9e\\u0b9f\\u0ba3\\u0ba4\\u0ba8-\\u0baa\\u0bae-\\u0bb5\\u0bb7-\\u0bb9\\u0be7-\\u0bef\\u0c05-\\u0c0c\\u0c0e-\\u0c10\\u0c12-\\u0c28\\u0c2a-\\u0c33\\u0c35-\\u0c39\\u0c60\\u0c61\\u0c66-\\u0c6f\\u0c85-\\u0c8c\\u0c8e-\\u0c90\\u0c92-\\u0ca8\\u0caa-\\u0cb3\\u0cb5-\\u0cb9\\u0cde\\u0ce0\\u0ce1\\u0ce6-\\u0cef\\u0d05-\\u0d0c\\u0d0e-\\u0d10\\u0d12-\\u0d28\\u0d2a-\\u0d39\\u0d60\\u0d61\\u0d66-\\u0d6f\\u0d85-\\u0d96\\u0d9a-\\u0db1\\u0db3-\\u0dbb\\u0dbd\\u0dc0-\\u0dc6\\u0e01-\\u0e30\\u0e32\\u0e33\\u0e40-\\u0e45\\u0e50-\\u0e59\\u0e81\\u0e82\\u0e84\\u0e87\\u0e88\\u0e8a\\u0e8d\\u0e94-\\u0e97\\u0e99-\\u0e9f\\u0ea1-\\u0ea3\\u0ea5\\u0ea7\\u0eaa\\u0eab\\u0ead-\\u0eb0\\u0eb2\\u0eb3\\u0ebd\\u0ec0-\\u0ec4\\u0ed0-\\u0ed9\\u0edc\\u0edd\\u0f00\\u0f20-\\u0f29\\u0f40-\\u0f47\\u0f49-\\u0f6a\\u0f88-\\u0f8b\\u1000-\\u1021\\u1023-\\u1027\\u1029\\u102a\\u1040-\\u1049\\u1050-\\u1055\\u10a0-\\u10c5\\u10d0-\\u10f6\\u1100-\\u1159\\u115f-\\u11a2\\u11a8-\\u11f9\\u1200-\\u1206\\u1208-\\u1246\\u1248\\u124a-\\u124d\\u1250-\\u1256\\u1258\\u125a-\\u125d\\u1260-\\u1286\\u1288\\u128a-\\u128d\\u1290-\\u12ae\\u12b0\\u12b2-\\u12b5\\u12b8-\\u12be\\u12c0\\u12c2-\\u12c5\\u12c8-\\u12ce\\u12d0-\\u12d6\\u12d8-\\u12ee\\u12f0-\\u130e\\u1310\\u1312-\\u1315\\u1318-\\u131e\\u1320-\\u1346\\u1348-\\u135a\\u1369-\\u1371\\u13a0-\\u13f4\\u1401-\\u166c\\u166f-\\u1676\\u1681-\\u169a\\u16a0-\\u16ea\\u1780-\\u17b3\\u17e0-\\u17e9\\u1810-\\u1819\\u1820-\\u1842\\u1844-\\u1877\\u1880-\\u18a8\\u1e00-\\u1e9b\\u1ea0-\\u1ef9\\u1f00-\\u1f15\\u1f18-\\u1f1d\\u1f20-\\u1f45\\u1f48-\\u1f4d\\u1f50-\\u1f57\\u1f59\\u1f5b\\u1f5d\\u1f5f-\\u1f7d\\u1f80-\\u1fb4\\u1fb6-\\u1fbc\\u1fbe\\u1fc2-\\u1fc4\\u1fc6-\\u1fcc\\u1fd0-\\u1fd3\\u1fd6-\\u1fdb\\u1fe0-\\u1fec\\u1ff2-\\u1ff4\\u1ff6-\\u1ffc\\u203f\\u2040\\u207f\\u2102\\u2107\\u210a-\\u2113\\u2115\\u2119-\\u211d\\u2124\\u2126\\u2128\\u212a-\\u212d\\u212f-\\u2131\\u2133-\\u2139\\u3006\\u3041-\\u3094\\u30a1-\\u30fb\\u3105-\\u312c\\u3131-\\u318e\\u31a0-\\u31b7\\u3400-\\u4db5\\u4e00-\\u9fa5\\ua000-\\ua48c\\uac00-\\ud7a3\\uf900-\\ufa2d\\ufb00-\\ufb06\\ufb13-\\ufb17\\ufb1d\\ufb1f-\\ufb28\\ufb2a-\\ufb36\\ufb38-\\ufb3c\\ufb3e\\ufb40\\ufb41\\ufb43\\ufb44\\ufb46-\\ufbb1\\ufbd3-\\ufd3d\\ufd50-\\ufd8f\\ufd92-\\ufdc7\\ufdf0-\\ufdfb\\ufe33\\ufe34\\ufe4d-\\ufe4f\\ufe70-\\ufe72\\ufe74\\ufe76-\\ufefc\\uff10-\\uff19\\uff21-\\uff3a\\uff3f\\uff41-\\uff5a\\uff65-\\uff6f\\uff71-\\uff9d\\uffa0-\\uffbe\\uffc2-\\uffc7\\uffca-\\uffcf\\uffd2-\\uffd7\\uffda-\\uffdc'; | |
| var re = new RegExp('^(.+)([^' + nws + ']+)[' + nws + ']+$', 'i'); | |
| return name.replace(re, function(str, m1, m2){ | |
| m1 = m1.replace(/[,_\-\.]+$/g, ''); | |
| if(m2 == ')' || m2 == ']') | |
| return m1 + m2; | |
| return m1; | |
| }); | |
| }, | |
| modify: function(name) | |
| { | |
| if(!name) | |
| return ''; | |
| name = name.replace(/^\s+|\s+$/g, ''); | |
| try | |
| { | |
| name = decodeURIComponent(name); | |
| } | |
| catch(err) | |
| { | |
| name = unescape(name); | |
| } | |
| name = SaveFrom_Utils.decodeHTML(name); | |
| name = name.replace(/\s+/g, ' ') | |
| .replace(/[\x2F\x5C\x3A\x7C]+/g, '_') | |
| .replace(/[\x2A\x3F\x22]/g, '') | |
| .replace(/\x3C/g, '(') | |
| .replace(/\x3E/g, ')') | |
| .replace(/(?:^\s+)|(?:\s+$)/g, '') | |
| .replace(/(\.|\!|\?|_|,|\-|\:|\+){2,1000}/g, '$1') | |
| .replace(/[\.,:;\/\-_\+=\x27]$/ig, ''); | |
| if(!name) | |
| return ''; | |
| if(name.length <= this.maxLength) | |
| return name; | |
| var parts = this.getParts(name); | |
| if(parts && parts.length == 3) | |
| { | |
| parts[1] = this.shorten(parts[1]); | |
| return parts[1] + '.' + parts[2]; | |
| } | |
| name = this.shorten(name); | |
| return name; | |
| } | |
| }, | |
| svg: { | |
| icon: { | |
| download: 'M 4,0 4,8 0,8 8,16 16,8 12,8 12,0 4,0 z', | |
| info: 'M 8,1.55 C 11.6,1.55 14.4,4.44 14.4,8 14.4,11.6 11.6,14.4 8,14.4 4.44,14.4 1.55,11.6 1.55,8 1.55,4.44 4.44,1.55 8,1.55 M 8,0 C 3.58,0 0,3.58 0,8 0,12.4 3.58,16 8,16 12.4,16 16,12.4 16,8 16,3.58 12.4,0 8,0 L 8,0 z M 9.16,12.3 H 6.92 V 7.01 H 9.16 V 12.3 z M 8.04,5.91 C 7.36,5.91 6.81,5.36 6.81,4.68 6.81,4 7.36,3.45 8.04,3.45 8.72,3.45 9.27,4 9.27,4.68 9.27,5.36 8.72,5.91 8.04,5.91 z', | |
| noSound: 'M 11.4,5.05 13,6.65 14.6,5.05 16,6.35 14.4,7.95 16,9.55 14.6,11 13,9.35 11.4,11 10,9.55 11.6,7.95 10,6.35 z M 8,1.75 8,14.3 4,10.5 l -4,0 0,-4.75 4,0 z' | |
| }, | |
| cache: {}, | |
| getSrc: function(icon, color) | |
| { | |
| if(!this.icon[icon]) | |
| return ''; | |
| if(!this.cache[icon]) | |
| this.cache[icon] = {}; | |
| if(!this.cache[icon][color]) | |
| { | |
| this.cache[icon][color] = window.btoa( | |
| '<?xml version="1.0" encoding="UTF-8"?>' + | |
| '<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.1" width="16" height="16" viewBox="0 0 16 16" id="svg2" xml:space="preserve">' + | |
| '<path d="' + this.icon[icon] + '" fill="' + color + '" /></svg>' | |
| ); | |
| } | |
| if(this.cache[icon][color]) | |
| return 'data:image/svg+xml;base64,' + this.cache[icon][color]; | |
| return ''; | |
| } | |
| }, | |
| appendDownloadInfo: function(parent, color, boxStyle, btnStyle) | |
| { | |
| if(!color) | |
| color = '#a0a0a0'; | |
| var info = document.createElement('span'); | |
| info.appendChild(document.createTextNode(chrome.i18n.getMessage('downloadTitle'))); | |
| this.setStyle(info, { | |
| display: 'inline-block', | |
| position: 'relative', | |
| border: '1px solid ' + color, | |
| borderRadius: '5px', | |
| fontSize: '13px', | |
| lineHeight: '17px', | |
| padding: '2px 19px 2px 5px', | |
| marginTop: '5px', | |
| opacity: 0.9 | |
| }); | |
| if(boxStyle) | |
| this.setStyle(info, boxStyle); | |
| var close = document.createElement('span'); | |
| close.innerHTML = '×'; | |
| this.setStyle(close, { | |
| color: color, | |
| width: '14px', | |
| height: '14px', | |
| fontSize: '14px', | |
| fontWeight: 'bold', | |
| lineHeight: '14px', | |
| position: 'absolute', | |
| top: 0, | |
| right: 0, | |
| overflow: 'hidden', | |
| cursor: 'pointer' | |
| }); | |
| if(btnStyle) | |
| this.setStyle(close, btnStyle); | |
| close.addEventListener('click', function(){ | |
| info.parentNode.removeChild(info); | |
| chrome.extension.sendRequest({action: 'hideDownloadInfo'}, function(){}); | |
| }, false); | |
| info.appendChild(close); | |
| parent.appendChild(info); | |
| }, | |
| appendFileSizeIcon: function(link, iconStyle, textStyle, error, noBrackets, container) | |
| { | |
| var iconColor = '#333333'; | |
| if(error) | |
| iconColor = '#ff0000'; | |
| else if(iconStyle && iconStyle.color) | |
| iconColor = iconStyle.color; | |
| var s = document.createElement('img'); | |
| s.src = SaveFrom_Utils.svg.getSrc('info', iconColor); | |
| s.title = chrome.i18n.getMessage(error ? 'getFileSizeFailTitle' : 'getFileSizeTitle'); | |
| var defIconStyle = { | |
| width: '14px', | |
| height: '14px', | |
| marginLeft: '3px', | |
| verticalAlign: 'middle', | |
| position: 'relative', | |
| top: '-1px', | |
| cursor: 'pointer' | |
| }; | |
| var defTextStyle = { | |
| fontSize: '75%', | |
| fontWeight: 'normal', | |
| marginLeft: '3px', | |
| whiteSpace: 'nowrap' | |
| }; | |
| var _this = this; | |
| this.setStyle(s, defIconStyle); | |
| if(iconStyle && typeof(iconStyle) == 'object') | |
| this.setStyle(s, iconStyle); | |
| if (container) { | |
| container.appendChild(s); | |
| } else | |
| if(link.nextSibling == null) { | |
| link.parentNode.appendChild(s); | |
| } else | |
| { | |
| link.parentNode.insertBefore(s, link.nextSibling); | |
| } | |
| s.addEventListener("click", function(event){ | |
| event.preventDefault(); | |
| event.stopPropagation(); | |
| var node = document.createElement('span'); | |
| node.innerHTML = '...'; | |
| _this.setStyle(node, defTextStyle); | |
| if(textStyle && typeof(textStyle) == 'object') | |
| _this.setStyle(node, textStyle); | |
| s.parentNode.replaceChild(node, s); | |
| var request = { | |
| action: 'getFileSize', | |
| url: link.href | |
| } | |
| chrome.extension.sendRequest(request, function(response){ | |
| if(response.fileSize == 0) | |
| { | |
| node.parentNode.removeChild(node); | |
| _this.appendFileSizeIcon(link, iconStyle, textStyle, true, noBrackets, container); | |
| } | |
| else | |
| { | |
| if(response.fileType.search(/^audio\//i) > -1) | |
| { | |
| var seconds = link.getAttribute('data-savefrom-helper-duration', false); | |
| if(seconds) | |
| { | |
| seconds = parseInt(seconds); | |
| if(!isNaN(seconds)) | |
| { | |
| var size = _this.sizeHuman(response.fileSize, 2); | |
| var bitrate = Math.floor((response.fileSize / seconds) / 125) + ' ' + | |
| chrome.i18n.getMessage('kbps'); | |
| if (noBrackets) { | |
| node.innerHTML = size + ' ~ ' + bitrate; | |
| } else { | |
| node.innerHTML = '(' + size + ' ~ ' + bitrate + ')'; | |
| } | |
| return; | |
| } | |
| } | |
| } | |
| if (noBrackets) { | |
| node.innerHTML = _this.sizeHuman(response.fileSize, 2); | |
| } else { | |
| node.innerHTML = '(' + _this.sizeHuman(response.fileSize, 2) + ')'; | |
| } | |
| node.title = response.fileType ? response.fileType : ''; | |
| } | |
| }); | |
| }, false); | |
| return s; | |
| }, | |
| appendNoSoundIcon: function(link, iconStyle) | |
| { | |
| var noSoundIconColor = '#ff0000'; | |
| if(iconStyle && iconStyle.color) | |
| noSoundIconColor = iconStyle.color; | |
| var s = document.createElement('img'); | |
| s.src = SaveFrom_Utils.svg.getSrc('noSound', noSoundIconColor); | |
| s.title = chrome.i18n.getMessage('withoutAudio'); | |
| var defIconStyle = { | |
| width: '14px', | |
| height: '14px', | |
| marginLeft: '3px', | |
| verticalAlign: 'middle', | |
| position: 'relative', | |
| top: '-1px', | |
| cursor: 'pointer' | |
| }; | |
| SaveFrom_Utils.setStyle(s, defIconStyle); | |
| if(iconStyle && typeof(iconStyle) == 'object') | |
| SaveFrom_Utils.setStyle(s, iconStyle); | |
| if(link.nextSibling == null) { | |
| if (link.parentNode === null) { | |
| link.appendChild(s); | |
| } else { | |
| link.parentNode.appendChild(s); | |
| } | |
| } else | |
| { | |
| link.parentNode.insertBefore(s, link.nextSibling); | |
| } | |
| }, | |
| video: { | |
| dataAttr: 'data-savefrom-video-visible', | |
| yt: { | |
| show3D: false, | |
| showMP4NoAudio: false, | |
| showFormat: { | |
| 'FLV': true, | |
| 'MP4': true, | |
| 'WebM': false, | |
| '3GP': false, | |
| 'Audio MP4': false, | |
| 'Audio OGG': false | |
| }, | |
| format: { | |
| 'FLV': { | |
| '5': {quality: '240p'}, | |
| '34': {quality: '360p'}, | |
| '35': {quality: '480p'} | |
| }, | |
| 'MP4': { | |
| '18': {quality: '360p'}, | |
| '22': {quality: '720p'}, | |
| '37': {quality: '1080p'}, | |
| '38': {quality: '4k'}, | |
| '82': {quality: '360p', '3d': true}, | |
| '83': {quality: '240p', '3d': true}, | |
| '84': {quality: '720p', '3d': true}, | |
| '85': {quality: '1080p', '3d': true}, | |
| '160': {quality: '144p', 'noAudio': true}, | |
| '133': {quality: '240p', 'noAudio': true}, | |
| '134': {quality: '360p', 'noAudio': true}, | |
| '135': {quality: '480p', 'noAudio': true}, | |
| '136': {quality: '720p', 'noAudio': true}, | |
| '137': {quality: '1080p', 'noAudio': true}, | |
| '264': {quality: '1440p', 'noAudio': true}, | |
| '138': {quality: '4k', 'noAudio': true} | |
| }, | |
| 'WebM': { | |
| '43': {quality: '360p'}, | |
| '44': {quality: '480p'}, | |
| '45': {quality: '720p'}, | |
| '46': {quality: '1080p'}, | |
| '242': {quality: '240p', 'noAudio': true}, | |
| '243': {quality: '360p', 'noAudio': true}, | |
| '244': {quality: '480p low', 'noAudio': true}, | |
| '245': {quality: '480p med', 'noAudio': true}, | |
| '246': {quality: '480p high', 'noAudio': true}, | |
| '247': {quality: '720p', 'noAudio': true}, | |
| '248': {quality: '1080p', 'noAudio': true}, | |
| '271': {quality: '1440p', 'noAudio': true}, | |
| '272': {quality: '4k', 'noAudio': true}, | |
| '100': {quality: '360p', '3d': true}, | |
| '101': {quality: '480p', '3d': true}, | |
| '102': {quality: '720p', '3d': true} | |
| }, | |
| '3GP': { | |
| '17': {quality: '144p'}, | |
| '36': {quality: '240p'} | |
| }, | |
| 'Audio MP4': { | |
| '139': {quality: '48', ext: 'aac', noVideo: true}, | |
| '140': {quality: '128', ext: 'aac', noVideo: true}, | |
| '141': {quality: '256', ext: 'aac', noVideo: true} | |
| }, | |
| 'Audio OGG': { | |
| '171': {quality: '128', ext: 'ogg', noVideo: true}, | |
| '172': {quality: '172', ext: 'ogg', noVideo: true} | |
| } | |
| }, | |
| excludeItag: { | |
| // MP4 | |
| '133': ['5'], // 240 | |
| '134': ['34', '18'], // 360 | |
| '135': ['35'], // 480 | |
| '136': ['22'], // 720 | |
| '137': ['37'], // 1080 | |
| //'264': [], // 1440p | |
| '138': ['38'], // 4k | |
| // WebM | |
| '243': ['43'], // 360 | |
| '244': ['44'], // 480 | |
| '247': ['45'], // 720 | |
| '248': ['46'] // 1080 | |
| }, | |
| init: function(prefs) | |
| { | |
| SaveFrom_Utils.video.yt.show3D = prefs.ytHide3D == '0' ? true : false; | |
| SaveFrom_Utils.video.yt.showMP4NoAudio = prefs.ytHideMP4NoAudio == '0' ? true : false; | |
| var show = false; | |
| for(var i in SaveFrom_Utils.video.yt.showFormat) | |
| { | |
| SaveFrom_Utils.video.yt.showFormat[i] = prefs['ytHide' + i.replace(' ', '_')] == '0' ? true : false; | |
| if(SaveFrom_Utils.video.yt.showFormat[i]) | |
| show = true; | |
| } | |
| if(!show) | |
| SaveFrom_Utils.video.yt.showFormat.FLV = true; | |
| }, | |
| filterLinks: function(links) | |
| { | |
| for(var i in this.excludeItag) | |
| { | |
| if(links[i] && this.excludeItag[i].length > 0) | |
| { | |
| for(var j = 0; j < this.excludeItag[i].length; j++) | |
| { | |
| var itag = this.excludeItag[i][j]; | |
| if(links[itag]) | |
| { | |
| delete links[i]; | |
| break; | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| show: function(links, parent, showDownloadInfo, style, videoTitle) | |
| { | |
| SaveFrom_Utils.video.yt.filterLinks(links); | |
| style = style || {}; | |
| var content = document.createElement('div'); | |
| SaveFrom_Utils.setStyle(content, { | |
| display: 'inline-block', | |
| margin: '0 auto' | |
| }); | |
| parent.appendChild(content); | |
| var box = document.createElement('div'); | |
| SaveFrom_Utils.setStyle(box, { | |
| display: 'inline-block', | |
| padding: '0 90px 0 0', | |
| position: 'relative' | |
| }); | |
| content.appendChild(box); | |
| var tbl = document.createElement('table'); | |
| SaveFrom_Utils.setStyle(tbl, { | |
| emptyCells: 'show', | |
| borderCollapse: 'collapse', | |
| margin: '0 auto', | |
| padding: '0', | |
| width: 'auto' | |
| }); | |
| box.appendChild(tbl); | |
| var hidden = false; | |
| for(var i in SaveFrom_Utils.video.yt.format) | |
| { | |
| if(SaveFrom_Utils.video.yt.append(links, i, | |
| SaveFrom_Utils.video.yt.format[i], tbl, style, videoTitle)) | |
| { | |
| hidden = true; | |
| } | |
| } | |
| for(var i in links) | |
| { | |
| if(SaveFrom_Utils.video.yt.append(links, '', null, tbl, style, videoTitle)) | |
| { | |
| hidden = true; | |
| } | |
| break; | |
| } | |
| if(!hidden) | |
| return; | |
| var more = document.createElement('span'); | |
| more.innerHTML = chrome.i18n.getMessage('more') + ' »'; | |
| SaveFrom_Utils.setStyle(more, { | |
| color: '#555', | |
| border: '1px solid #a0a0a0', | |
| borderRadius: '3px', | |
| display: 'block', | |
| fontFamily: 'Arial', | |
| fontSize: '15px', | |
| lineHeight: '17px', | |
| padding: '1px 5px', | |
| position: 'absolute', | |
| bottom: '3px', | |
| right: '0', | |
| cursor: 'pointer' | |
| }); | |
| if(style.btn && typeof(style.btn) == 'object') | |
| SaveFrom_Utils.setStyle(more, style.btn); | |
| box.appendChild(more); | |
| more.addEventListener('click', function(event){ | |
| event.preventDefault(); | |
| event.stopPropagation(); | |
| var e = parent.querySelectorAll('*[' + SaveFrom_Utils.video.dataAttr + ']'); | |
| for(var i = 0; i < e.length; i++) | |
| { | |
| var visible = e[i].getAttribute(SaveFrom_Utils.video.dataAttr, false); | |
| var display = 'none', symbol = '»'; | |
| if(visible == '0') | |
| { | |
| visible = '1'; | |
| display = ''; | |
| symbol = '«'; | |
| } | |
| else | |
| visible = '0'; | |
| e[i].style.display = display; | |
| e[i].setAttribute(SaveFrom_Utils.video.dataAttr, visible, false); | |
| this.innerHTML = chrome.i18n.getMessage('more') + ' ' + symbol; | |
| } | |
| return false; | |
| }, false); | |
| if(showDownloadInfo == '1') | |
| { | |
| var color = '#a0a0a0', a = tbl.querySelector('td a'); | |
| content.appendChild(document.createElement('br')); | |
| SaveFrom_Utils.appendDownloadInfo(content, color, null, { | |
| width: '16px', | |
| height: '16px', | |
| fontSize: '16px', | |
| lineHeight: '16px' | |
| }); | |
| } | |
| }, | |
| append: function(links, title, format, parent, style, videoTitle) | |
| { | |
| var hidden = false; | |
| var aStyle = { | |
| whiteSpace: 'nowrap' | |
| }; | |
| var sStyle = { | |
| fontSize: '75%', | |
| fontWeight: 'normal', | |
| marginLeft: '3px', | |
| whiteSpace: 'nowrap' | |
| }; | |
| var tr = document.createElement('tr'); | |
| var td = document.createElement('td'); | |
| td.appendChild(document.createTextNode(title ? title : '???')); | |
| if(!title || !SaveFrom_Utils.video.yt.showFormat[title]) | |
| { | |
| tr.setAttribute(SaveFrom_Utils.video.dataAttr, '0'); | |
| tr.style.display = 'none'; | |
| hidden = true; | |
| } | |
| SaveFrom_Utils.setStyle(td, { | |
| border: 'none', | |
| padding: '3px 15px 3px 0', | |
| textAlign: 'left', | |
| verticalAlign: 'middle' | |
| }); | |
| tr.appendChild(td); | |
| td = document.createElement('td'); | |
| SaveFrom_Utils.setStyle(td, { | |
| border: 'none', | |
| padding: '3px 0', | |
| textAlign: 'left', | |
| verticalAlign: 'middle', | |
| lineHeight: '17px' | |
| }); | |
| tr.appendChild(td); | |
| var sep = false; | |
| if(format) | |
| { | |
| for(var i in format) | |
| { | |
| if(links[i]) | |
| { | |
| if(sep) | |
| { | |
| td.lastChild.style.marginRight = '15px'; | |
| td.appendChild(document.createTextNode(' ')); | |
| } | |
| var span = document.createElement('span'); | |
| span.style.whiteSpace = 'nowrap'; | |
| var a = document.createElement('a'); | |
| a.href = links[i]; | |
| a.title = chrome.i18n.getMessage('downloadTitle'); | |
| a.innerHTML = format[i]['3d'] ? '3D' : format[i].quality; | |
| if(title === 'Audio MP4' || title === 'Audio OGG') | |
| a.innerHTML += ' ' + chrome.i18n.getMessage('kbps'); | |
| if(videoTitle) | |
| { | |
| var ext = format[i]['ext']; | |
| if(!ext) | |
| ext = title.toLowerCase(); | |
| a.setAttribute('download', SaveFrom_Utils.fileName.modify(videoTitle + '.' + ext) ); | |
| if(title == 'Audio MP4' || title == 'Audio OGG' || format[i]['noAudio']) | |
| { | |
| a.addEventListener('click', function(event){ | |
| SaveFrom_Utils.downloadOnClick(event, null, true); | |
| }, false); | |
| } | |
| } | |
| SaveFrom_Utils.setStyle(a, aStyle); | |
| if(style.link && typeof(style.link) == 'object') | |
| SaveFrom_Utils.setStyle(a, style.link); | |
| span.appendChild(a); | |
| SaveFrom_Utils.appendFileSizeIcon(a, style.fsIcon, style.fsText); | |
| if(format[i]['3d']) | |
| { | |
| if(!SaveFrom_Utils.video.yt.show3D) | |
| { | |
| hidden = true; | |
| span.setAttribute(SaveFrom_Utils.video.dataAttr, '0'); | |
| span.style.display = 'none'; | |
| } | |
| var s = document.createElement('span'); | |
| s.innerHTML = format[i].quality; | |
| SaveFrom_Utils.setStyle(s, sStyle); | |
| if(style.text && typeof(style.text) == 'object') | |
| SaveFrom_Utils.setStyle(s, style.text); | |
| a.appendChild(s); | |
| } | |
| if(format[i]['noAudio']) | |
| { | |
| if(!SaveFrom_Utils.video.yt.showMP4NoAudio) | |
| { | |
| hidden = true; | |
| span.setAttribute(SaveFrom_Utils.video.dataAttr, '0'); | |
| span.style.display = 'none'; | |
| } | |
| SaveFrom_Utils.appendNoSoundIcon(a, style ? style.noSoundIcon : false); | |
| } | |
| td.appendChild(span); | |
| sep = true; | |
| delete links[i]; | |
| } | |
| } | |
| } | |
| else | |
| { | |
| for(var i in links) | |
| { | |
| if(sep) | |
| { | |
| td.lastChild.style.marginRight = '15px'; | |
| td.appendChild(document.createTextNode(' ')); | |
| } | |
| var span = document.createElement('span'); | |
| span.style.whiteSpace = 'nowrap'; | |
| var a = document.createElement('a'); | |
| a.href = links[i]; | |
| a.title = chrome.i18n.getMessage('downloadTitle'); | |
| a.innerHTML = i; | |
| SaveFrom_Utils.setStyle(a, aStyle); | |
| if(style.link && typeof(style.link) == 'object') | |
| SaveFrom_Utils.setStyle(a, style.link); | |
| span.appendChild(a); | |
| SaveFrom_Utils.appendFileSizeIcon(a, style.fsIcon, style.fsText); | |
| td.appendChild(span); | |
| sep = true; | |
| delete links[i]; | |
| } | |
| } | |
| if (sep === false) { | |
| return; | |
| } | |
| parent.appendChild(tr); | |
| return hidden; | |
| } | |
| } | |
| }, // video | |
| playlist: { | |
| btnStyle: { | |
| display: 'block', | |
| fontWeight: 'bold', | |
| border: 'none', | |
| textDecoration: 'underline' | |
| }, | |
| getFilelistHtml: function(links) | |
| { | |
| if(!links || links.length == 0) | |
| return ''; | |
| var rows = 0; | |
| var list = ''; | |
| for(var i = 0; i < links.length; i++) | |
| { | |
| if(links[i].url) | |
| { | |
| list += links[i].url + '\r\n'; | |
| rows++; | |
| } | |
| } | |
| if(list) | |
| { | |
| if(rows < 5) | |
| rows = 5; | |
| else if(rows > 20) | |
| rows = 20; | |
| return '<b style="font-size: 125%;">' + | |
| chrome.i18n.getMessage('filelistTitle') + '</b><br>' + | |
| '<p>' + chrome.i18n.getMessage('filelistInstruction') + '</p>' + | |
| '<a href="#" class="sf__playlist" style="display:none;">' + | |
| chrome.i18n.getMessage('playlist') + '</a><br>' + | |
| '<textarea rows="' + rows + '" cols="60" style="width:100%; white-space:nowrap;">' + | |
| list + '</textarea>'; | |
| } | |
| return ''; | |
| }, | |
| popupFilelist: function(links, title, playlist, id) | |
| { | |
| var html = SaveFrom_Utils.playlist.getFilelistHtml(links); | |
| if(!html) | |
| return; | |
| var popup = SaveFrom_Utils.popupDiv(html, id); | |
| if(playlist) | |
| { | |
| var a = popup.querySelector('a.sf__playlist'); | |
| if(a) | |
| { | |
| a.addEventListener('click', function(event){ | |
| setTimeout(function(){ | |
| SaveFrom_Utils.playlist.popupPlaylist(links, title, true, id); | |
| }, 100); | |
| event.preventDefault(); | |
| return false; | |
| }, false); | |
| SaveFrom_Utils.setStyle(a, SaveFrom_Utils.playlist.btnStyle); | |
| } | |
| } | |
| }, | |
| getM3U: function(links) | |
| { | |
| var text = '#EXTM3U\r\n'; | |
| for(var i = 0; i < links.length; i++) | |
| { | |
| if(!links[i].duration) | |
| links[i].duration = '-1'; | |
| if(links[i].title || links[i].duration) | |
| { | |
| text += '#EXTINF:' + links[i].duration + ',' + | |
| links[i].title + '\r\n'; | |
| } | |
| text += links[i].url + '\r\n'; | |
| } | |
| return text; | |
| }, | |
| getPLS: function(links) | |
| { | |
| var text = '[playlist]\r\n\r\n'; | |
| for(var i = 0; i < links.length; i++) | |
| { | |
| var num = i + 1; | |
| text += 'File' + num + '=' + links[i].url + '\r\n'; | |
| if(!links[i].duration) | |
| links[i].duration = '-1'; | |
| if(links[i].title || links[i].duration) | |
| { | |
| text += 'Title' + num + '=' + links[i].title + '\r\n' + | |
| 'Length' + num + '=' + links[i].duration + '\r\n'; | |
| } | |
| text += '\r\n'; | |
| } | |
| text += 'NumberOfEntries=' + links.length + '\r\n\r\n' + | |
| 'Version=2\r\n'; | |
| return text; | |
| }, | |
| getPlaylistHtml: function(links, title) | |
| { | |
| if(!links || links.length == 0) | |
| return ''; | |
| var d = SaveFrom_Utils.dateToObj(); | |
| var dateStr = d.year + '-' + d.month + '-' + d.day + '_' + | |
| d.hour + '-' + d.min; | |
| if(!title) | |
| title = 'playlist'; | |
| title += '_' + dateStr; | |
| var html = '<b style="font-size: 125%;">' + | |
| chrome.i18n.getMessage('playlistTitle') + '</b><br>' + | |
| '<p>' + chrome.i18n.getMessage('playlistInstruction') + '</p>' + | |
| '<a href="#" class="sf__playlist" style="display:none;">' + | |
| chrome.i18n.getMessage('filelist') + '</a><br>'; | |
| var text = chrome.i18n.getMessage('download').toLowerCase(); | |
| // M3U | |
| var file = SaveFrom_Utils.playlist.getM3U(links); | |
| html += '<b>M3U</b> ' + | |
| '<a href="data:audio/x-mpegurl;charset=windows-1251;base64,' + | |
| escape(SaveFrom_Utils.base64_encode( | |
| SaveFrom_Utils.utf8ToWindows1251(SaveFrom_Utils.utf8Encode(file)))) + | |
| '" download="' + title + '.m3u">' + text + '</a>' + | |
| ' | ' + | |
| '<a href="data:audio/x-mpegurl;charset=utf-8;base64,' + | |
| escape(SaveFrom_Utils.base64_encode(SaveFrom_Utils.utf8Encode(file))) + | |
| '" download="' + title + '_utf8.m3u">' + text + ' UTF-8</a>' + | |
| '<br><br><textarea rows="6" cols="60" style="width:100%;white-space:nowrap;">' + | |
| file + '</textarea><br><br> <br>'; | |
| // PLS | |
| file = SaveFrom_Utils.playlist.getPLS(links); | |
| html += '<b>PLS</b> ' + | |
| '<a href="data:audio/x-scpls;charset=windows-1251;base64,' + | |
| escape(SaveFrom_Utils.base64_encode( | |
| SaveFrom_Utils.utf8ToWindows1251(SaveFrom_Utils.utf8Encode(file)))) + | |
| '" download="' + title + '.pls">' + text + '</a>' + | |
| ' | ' + | |
| '<a href="data:audio/x-scpls;charset=utf-8;base64,' + | |
| escape(SaveFrom_Utils.base64_encode(SaveFrom_Utils.utf8Encode(file))) + | |
| '" download="' + title + '_utf8.pls">' + text + ' UTF-8</a>' + | |
| '<br><br><textarea rows="6" cols="60" style="width:100%;white-space:nowrap;">' + | |
| file + '</textarea>'; | |
| return html; | |
| }, | |
| popupPlaylist: function(links, title, filelist, id) | |
| { | |
| var html = SaveFrom_Utils.playlist.getPlaylistHtml(links, title); | |
| if(!html) | |
| return; | |
| var popup = SaveFrom_Utils.popupDiv(html, id); | |
| if(filelist) | |
| { | |
| var a = popup.querySelector('a.sf__playlist'); | |
| if(a) | |
| { | |
| a.addEventListener('click', function(event){ | |
| setTimeout(function(){ | |
| SaveFrom_Utils.playlist.popupFilelist(links, title, true, id); | |
| }, 100); | |
| event.preventDefault(); | |
| return false; | |
| }, false); | |
| SaveFrom_Utils.setStyle(a, SaveFrom_Utils.playlist.btnStyle); | |
| } | |
| } | |
| } | |
| }, | |
| popupDiv: function(html, id, maxWidth, maxHeight, onClose) | |
| { | |
| if(!id) | |
| id = 'savefrom_popup_box'; | |
| if(!maxWidth) | |
| maxWidth = 580; | |
| if(!maxHeight) | |
| maxHeight = 520; | |
| var d = document.getElementById(id); | |
| if(d) | |
| d.parentNode.removeChild(d); | |
| d = document.createElement('div'); | |
| d.id = id; | |
| SaveFrom_Utils.setStyle(d, { | |
| zIndex: '9999', | |
| display: 'block', | |
| 'float': 'none', | |
| position: 'fixed', | |
| left: '-10000px', | |
| top: '-10000px', | |
| margin: '0', | |
| padding: '0', | |
| opacity: '0.0', | |
| color: '#000', | |
| background: '#fff', | |
| border: '3px solid #c0cad5', | |
| borderRadius: '7px', | |
| overflow: 'auto' | |
| }); | |
| var cnt = document.createElement('div'); | |
| SaveFrom_Utils.setStyle(cnt, { | |
| display: 'block', | |
| 'float': 'none', | |
| position: 'relative', | |
| overflow: 'auto', | |
| margin: '0', | |
| padding: '10px 15px' | |
| }); | |
| cnt.innerHTML = html; | |
| var btn = document.createElement('img'); | |
| btn.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAWUlEQVQ4y2NgGHHAH4j1sYjrQ+WIAvFA/B+I36MZpg8V+w9VQ9Al/5EwzDBkQ2AYr8uwaXiPQ0yfkKuwGUayIYQMI8kQqhlEFa9RLbCpFv1US5BUzSLDBAAARN9OlWGGF8kAAAAASUVORK5CYII='; | |
| btn.alt = 'x'; | |
| btn.width = 18; | |
| btn.height = 18; | |
| SaveFrom_Utils.setStyle(btn, { | |
| position: 'absolute', | |
| top: '10px', | |
| right: '15px', | |
| opacity: '0.5', | |
| cursor: 'pointer' | |
| }); | |
| btn.addEventListener('mouseover', function(){ | |
| this.style.opacity = '0.9'; | |
| },false); | |
| btn.addEventListener('mouseout', function(){ | |
| this.style.opacity = '0.5'; | |
| }, false); | |
| btn.addEventListener('click', function(){ | |
| cnt.style.display = 'none'; | |
| setTimeout(function(){d.parentNode.removeChild(d);}, 100); | |
| if (onClose) { | |
| onClose(); | |
| } | |
| return false; | |
| }, false); | |
| cnt.appendChild(btn); | |
| d.appendChild(cnt); | |
| document.body.appendChild(d); | |
| if(d.offsetWidth > maxWidth) | |
| d.style.width = maxWidth + 'px'; | |
| if(d.offsetHeight > maxHeight) | |
| { | |
| d.style.height = maxHeight + 'px'; | |
| d.style.width = (maxWidth + 20) + 'px'; | |
| } | |
| var l = Math.floor((window.innerWidth - d.offsetWidth) / 2.0); | |
| var t = Math.floor((window.innerHeight - d.offsetHeight) / 2.0); | |
| SaveFrom_Utils.setStyle(d, { | |
| top: t + 'px', | |
| left: l + 'px', | |
| opacity: '1.0' | |
| }); | |
| document.addEventListener('click', function(event){ | |
| var node = event.target; | |
| if(node != d && !SaveFrom_Utils.isParent(node, d)) | |
| { | |
| cnt.style.display = 'none'; | |
| setTimeout(function(){if(d.parentNode){d.parentNode.removeChild(d);}}, 100); | |
| document.removeEventListener('click', arguments.callee, false); | |
| if (onClose) { | |
| onClose(); | |
| } | |
| } | |
| }, false); | |
| return d; | |
| }, | |
| // row - used for hide tooltip on mouseout | |
| // because node can dissaper from DOM before mouseout raised | |
| showTooltip: function(node, text, row, style) | |
| { | |
| if(!node) | |
| return; | |
| var tooltip = document.querySelector('.savefrom-tooltip'); | |
| if(!tooltip) | |
| { | |
| tooltip = document.createElement('div'); | |
| tooltip.className = 'savefrom-tooltip'; | |
| SaveFrom_Utils.setStyle(tooltip, { | |
| 'position': 'absolute', | |
| 'opacity': 0, | |
| 'zIndex': -1 | |
| }); | |
| if (style) { | |
| SaveFrom_Utils.setStyle(tooltip, style); | |
| } | |
| } | |
| tooltip.innerHTML = text; | |
| if(tooltip.lastNode && tooltip.lastNode === node) | |
| { | |
| fixPosition(); | |
| return; | |
| } | |
| if(tooltip.lastNode) | |
| { | |
| tooltip.lastNode.removeEventListener('mouseout', hide); | |
| tooltip.lastNode.removeEventListener('mousemove', fixPosition); | |
| tooltip.lastRow && tooltip.lastRow.removeEventListener('mouseout', hide); | |
| } | |
| tooltip.lastNode = node; | |
| row && (tooltip.lastRow = row); | |
| node.addEventListener('mouseout', hide, false); | |
| node.addEventListener('mousemove', fixPosition, false); | |
| row && row.addEventListener('mouseout', hide, false); | |
| document.body.appendChild(tooltip); | |
| fixPosition(); | |
| function fixPosition() { | |
| var p = SaveFrom_Utils.getPosition(node), | |
| s = SaveFrom_Utils.getSize(tooltip); | |
| if(p.top == 0 && p.left == 0) | |
| return; | |
| p.top = p.top - s.height - 10; | |
| p.left = p.left - s.width / 2 + SaveFrom_Utils.getSize(node).width / 2; | |
| p.left = Math.min(p.left, document.body.clientWidth + document.body.scrollLeft - s.width); | |
| if(p.top < document.body.scrollTop) | |
| p.top = p.top + s.height + SaveFrom_Utils.getSize(node).height + 20; | |
| p.top += 'px'; | |
| p.left += 'px'; | |
| // show | |
| p.zIndex = 9999; | |
| p.opacity = 1; | |
| SaveFrom_Utils.setStyle(tooltip, p); | |
| } | |
| function hide() { | |
| if(tooltip.parentNode) | |
| document.body.removeChild(tooltip); | |
| tooltip.lastNode = null; | |
| tooltip.lastRow = null; | |
| SaveFrom_Utils.setStyle(tooltip, { | |
| zIndex: -1, | |
| opacity: 0 | |
| }); | |
| node.removeEventListener('mouseout', hide); | |
| node.removeEventListener('mousemove', fixPosition); | |
| row && row.removeEventListener('mouseout', hide); | |
| } | |
| }, | |
| embedDownloader: { | |
| dataAttr: 'data-savefrom-get-links', | |
| dataIdAttr: 'data-savefrom-container-id', | |
| containerClass: 'savefrom-links-container', | |
| linkClass: 'savefrom-link', | |
| panel: null, | |
| lastLink: null, | |
| style: null, | |
| hostings: { | |
| 'youtube': { | |
| re: [ | |
| /^https?:\/\/(?:[a-z]+\.)?youtube\.com\/(?:#!?\/)?watch\?.*v=([\w\-]+)/i, | |
| /^https?:\/\/(?:[a-z0-9]+\.)?youtube\.com\/(?:embed|v)\/([\w\-]+)/i, | |
| /^https?:\/\/(?:[a-z]+\.)?youtu\.be\/([\w\-]+)/i, | |
| ], | |
| action: 'getYoutubeLinks', | |
| prepareLinks: function(links) { | |
| var ret = [], | |
| format = SaveFrom_Utils.video.yt.format; | |
| for(var i in format) | |
| { | |
| for(var n in format[i]) | |
| { | |
| if(links[n]) | |
| { | |
| var type = i; | |
| if(format[i][n].ext) | |
| type = format[i][n].ext; | |
| ret.push({ | |
| name: i + ' ' + format[i][n].quality + (format[i][n]['3d'] ? ' (3d)' : '') + | |
| ( (i === 'Audio MP4' || i === 'Audio OGG') ? (' ' + chrome.i18n.getMessage('kbps')) : ''), | |
| type: type, | |
| url: links[n], | |
| noSound: format[i][n].noAudio | |
| }); | |
| } | |
| } | |
| } | |
| return ret; | |
| } | |
| }, | |
| 'vimeo': { | |
| re: [ | |
| /^https?:\/\/(?:[\w\-]+\.)?vimeo\.com\/(?:\w+\#)?(\d+)/i, | |
| /^https?:\/\/player\.vimeo\.com\/video\/(\d+)/i | |
| ], | |
| action: 'getVimeoLinks', | |
| prepareLinks: function(links) { | |
| return links.map(function(link) { | |
| var ext = link.ext; | |
| if(!ext) | |
| { | |
| ext = 'MP4'; | |
| if(link.url.search(/\.flv($|\?)/i) != -1) | |
| ext = 'FLV'; | |
| } | |
| link.name = link.name ? link.name : ext; | |
| link.type = link.type ? link.type : ext; | |
| link.ext = ext; | |
| return link; | |
| }); | |
| } | |
| }, | |
| 'vk': { | |
| re: [ | |
| /^https?:\/\/(?:[\w\-]+\.)?(?:vk\.com|vkontakte\.ru)\/(?:[^\/]+\/)*(?:[\w\-]+\?.*z=)?(video-?\d+_-?\d+\?list=[0-9a-z]+|video-?\d+_-?\d+)/i, | |
| /^https?:\/\/(?:[\w\-]+\.)?(?:vk\.com|vkontakte\.ru)\/video_ext\.php\?(.+)/i | |
| ], | |
| action: 'getVKLinks' | |
| }, | |
| 'dailymotion': { | |
| re: [ | |
| /^http:\/\/dai\.ly\/([a-z0-9]+)_?/i, | |
| /^https?:\/\/(?:[\w]+\.)?dailymotion\.com(?:\/embed)?\/video\/([a-z0-9]+)_?/i | |
| ], | |
| action: 'getDailymotionLinks' | |
| } | |
| }, | |
| init: function(style) | |
| { | |
| this.style = style; | |
| if(this.panel) { | |
| SaveFrom_Utils.popupMenu.removePanel(); | |
| } | |
| this.panel = null; | |
| this.lastLink = null; | |
| var links = document.querySelectorAll('a[' + this.dataAttr + ']'), | |
| i, l = links.length; | |
| for(i = 0; i < l; i++) | |
| { | |
| if(['savefrom.net', 'sf-addon.com'].indexOf( | |
| SaveFrom_Utils.getTopLevelDomain(links[i].hostname)) > -1) | |
| { | |
| links[i].removeEventListener('click', this.onClick); | |
| links[i].addEventListener('click', this.onClick, false); | |
| } | |
| } | |
| // hide menu on click outside them | |
| // process dinamically added links | |
| document.body.removeEventListener('click', this.onBodyClick); | |
| document.body.addEventListener('click', this.onBodyClick, true); | |
| }, | |
| checkUrl: function(url) | |
| { | |
| for(var h in this.hostings) | |
| { | |
| var params = this.hostings[h], | |
| l = params.re.length; | |
| for(var i = 0; i < l; i++) | |
| { | |
| var match = url.match(params.re[i]); | |
| if(match) | |
| { | |
| return { | |
| hosting: h, | |
| action: params.action, | |
| extVideoId: match[1] | |
| }; | |
| } | |
| } | |
| } | |
| return null; | |
| }, | |
| onClick: function(event, a) | |
| { | |
| var _this = SaveFrom_Utils.embedDownloader; | |
| if(!a) | |
| { | |
| a = event.target; | |
| while(a.parentNode) { | |
| if(a.nodeName === 'A') | |
| break; | |
| a = a.parentNode; | |
| } | |
| if(!a) | |
| return; | |
| } | |
| var href = a.getAttribute('data-savefrom-get-links'); | |
| if(!href) | |
| return; | |
| if(event.button !== 0 || event.ctrlKey || event.shiftKey) | |
| return; | |
| if(_this.lastLink === a && _this.panel && _this.panel.style.display != 'none') | |
| { | |
| _this.lastLink = null; | |
| _this.panel.style.display = 'none'; | |
| event.preventDefault(); | |
| event.stopPropagation(); | |
| return; | |
| } | |
| _this.lastLink = a; | |
| var data = _this.checkUrl(href); | |
| if(!data) | |
| return; | |
| event.preventDefault(); | |
| event.stopPropagation(); | |
| var request = { | |
| action: data.action, | |
| extVideoId: data.extVideoId | |
| }; | |
| chrome.extension.sendRequest(request, function(response) { | |
| var hosting = data.hosting; | |
| if(response.action != request.action) | |
| { | |
| var map = { | |
| 'getYoutubeLinks': 'youtube', | |
| 'getVimeoLinks': 'vimeo', | |
| 'getDailymotionLinks': 'dailymotion' | |
| }; | |
| hosting = map[response.action]; | |
| } | |
| if(response.links) | |
| _this.showLinks(response.links, response.title, a, hosting); | |
| else | |
| _this.showLinks(chrome.i18n.getMessage('noLinksFound'), null, a); | |
| }); | |
| _this.showLinks(chrome.i18n.getMessage('download') + ' ...', null, a); | |
| return false; | |
| }, | |
| onBodyClick: function(event) | |
| { | |
| var _this = SaveFrom_Utils.embedDownloader; | |
| if(!_this.panel || _this.panel.style.display == 'none') | |
| { | |
| var node = event.target; | |
| while(node.parentNode) { | |
| if(node.tagName === 'A') | |
| break; | |
| node = node.parentNode; | |
| } | |
| // dinamic links | |
| if(node.nodeName === 'A' && node.hasAttribute(_this.dataAttr) && | |
| ['savefrom.net', 'sf-addon.com'].indexOf(SaveFrom_Utils.getTopLevelDomain(node.hostname)) > -1) | |
| { | |
| return _this.onClick(event, node); | |
| } | |
| return; | |
| } | |
| node = event.target; | |
| while(node.parentNode) { | |
| if(node === _this.panel) | |
| return; | |
| node = node.parentNode; | |
| } | |
| _this.lastLink = null; | |
| _this.panel.style.display = 'none'; | |
| }, | |
| hidePanel: function() | |
| { | |
| if(this.panel) | |
| this.panel.style.display = 'none'; | |
| }, | |
| createMenu: function(links, title, a, hname) { | |
| var menuLinks = []; | |
| if (typeof links === 'string') { | |
| menuLinks = links; | |
| } else | |
| if (SaveFrom_Utils.popupMenu.prepareLinks[hname] !== undefined) { | |
| menuLinks = SaveFrom_Utils.popupMenu.prepareLinks[hname](links, title, SaveFrom_Utils); | |
| } | |
| SaveFrom_Utils.popupMenu.create({ | |
| links: menuLinks, | |
| button: a, | |
| popupId: undefined, | |
| document: document, | |
| sfUtils: SaveFrom_Utils, | |
| showFileSize: true, | |
| containerClass: this.containerClass, | |
| linkClass: this.linkClass, | |
| style: { | |
| popup: (this.style)?this.style.container:undefined, | |
| item: (this.style)?this.style.link:undefined | |
| } | |
| }); | |
| this.panel = SaveFrom_Utils.popupMenu.popup; | |
| }, | |
| showLinks: function(links, title, a, hname) | |
| { | |
| var panel, id = a.getAttribute(this.dataIdAttr); | |
| if(id) | |
| panel = document.getElementById(id); | |
| if(!panel) | |
| { | |
| this.createMenu(links, title, a, hname); | |
| return; | |
| } | |
| else if(this.panel) | |
| { | |
| this.panel.style.display = 'none'; | |
| } | |
| if(typeof(links) == 'string') | |
| { | |
| panel.innerHTML = links; | |
| } | |
| else if(!links || links.length == 0) | |
| { | |
| panel.innerHTML = chrome.i18n.getMessage('noLinksFound'); | |
| } | |
| else | |
| { | |
| // append links | |
| if(hname && this.hostings[hname] && this.hostings[hname].prepareLinks) | |
| links = this.hostings[hname].prepareLinks(links); | |
| panel.innerHTML = ''; | |
| for(var i = 0; i < links.length; i++) | |
| { | |
| if(links[i].url && links[i].name) | |
| { | |
| var a = document.createElement('a'); | |
| a.href = links[i].url; | |
| a.title = chrome.i18n.getMessage('downloadTitle'); | |
| a.appendChild(document.createTextNode(links[i].name)); | |
| var span = document.createElement('span'); | |
| span.className = this.linkClass; | |
| span.appendChild(a); | |
| panel.appendChild(span); | |
| SaveFrom_Utils.appendFileSizeIcon(a); | |
| if(links[i].noSound) | |
| SaveFrom_Utils.appendNoSoundIcon(a); | |
| if(title && !links[i].noTitle && links[i].type) | |
| { | |
| a.setAttribute('download', SaveFrom_Utils.fileName.modify( | |
| title + '.' + links[i].type.toLowerCase())); | |
| a.addEventListener('click', SaveFrom_Utils.downloadOnClick, false); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| popupMenu: { | |
| popupId: 'sf_popupMenu', | |
| popup: undefined, | |
| popupStyle: undefined, | |
| dataArrtVisible: 'data-isVisible', | |
| createBadge: function(qulity, options) { | |
| var document = options.document; | |
| var container = document.createElement('div'); | |
| options.sfUtils.setStyle(container, { | |
| display: 'inline-block', | |
| lineHeight: '18px', | |
| width: '19px', | |
| height: '17px', | |
| color: '#fff', | |
| fontSize: '12px', | |
| borderRadius: '2px', | |
| verticalAlign: 'middle', | |
| textAlign: 'center', | |
| paddingRight: '2px', | |
| fontWeight: 'bolder', | |
| marginLeft: '3px' | |
| }); | |
| if (qulity === '1080p' || qulity === '1440p' || qulity === '720p' || qulity === '720' || qulity === '1080') { | |
| container.textContent = 'HD'; | |
| container.style.backgroundColor = '#505050'; | |
| container.style.paddingRight = '1px'; | |
| } else | |
| if (qulity === '4k') { | |
| container.textContent = 'HD'; | |
| container.style.paddingRight = '1px'; | |
| container.style.backgroundColor = 'rgb(247, 180, 6)'; | |
| } | |
| return container; | |
| }, | |
| createPopupItem: function(listItem, options) { | |
| var document = options.document; | |
| var _this = SaveFrom_Utils.popupMenu; | |
| var href; | |
| if (typeof listItem === 'string') { | |
| href = listItem; | |
| } else { | |
| href = listItem.href; | |
| } | |
| if (href === '-') { | |
| var line = document.createElement('div'); | |
| options.sfUtils.setStyle(line, { | |
| display: 'block', | |
| margin: '1px 0', | |
| borderTop: '1px solid rgb(214, 214, 214)' | |
| }); | |
| return {el: line}; | |
| } | |
| var itemContainer = document.createElement( (href === '-text-') ? 'div' : 'a' ); | |
| if (options.linkClass) { | |
| itemContainer.classList.add(options.linkClass); | |
| } | |
| var itemContainerStyle = { | |
| display: 'block', | |
| padding: '0 5px', | |
| textDecoration: 'none', | |
| whiteSpace: 'nowrap', | |
| overflow: 'hidden' | |
| }; | |
| if (listItem.isHidden) { | |
| itemContainer.setAttribute(_this.dataArrtVisible, '0'); | |
| itemContainerStyle.display = 'none'; | |
| } | |
| options.sfUtils.setStyle(itemContainer, itemContainerStyle); | |
| if (href === '-text-') { | |
| return {el: itemContainer}; | |
| } | |
| itemContainer.href = href; | |
| if (href === '#') { | |
| return {el: itemContainer}; | |
| } | |
| itemContainer.title = chrome.i18n.getMessage('downloadTitle'); | |
| if (listItem.title && listItem.format) { | |
| var ext = listItem.ext; | |
| if(!ext) { | |
| ext = listItem.format.toLowerCase(); | |
| } | |
| itemContainer.setAttribute('download', SaveFrom_Utils.fileName.modify(listItem.title + '.' + ext) ); | |
| if (listItem.forceDownload) { | |
| itemContainer.addEventListener('click', function(event){ | |
| options.sfUtils.downloadOnClick(event, null, listItem.useIframe || false ); | |
| }, false); | |
| } | |
| } | |
| var titleContainer = document.createElement('span'); | |
| options.sfUtils.setStyle(titleContainer, { | |
| cssFloat: 'left' | |
| }); | |
| titleContainer.textContent = (listItem['3d'] ? '3D ':'') + (listItem.format ? listItem.format : '???') + (listItem.quality?' '+listItem.quality:''); | |
| if (['4k', '1440p', '1080p', '720p', '720', '1080'].indexOf( String(listItem.quality) ) !== -1) { | |
| titleContainer.appendChild(_this.createBadge( String(listItem.quality), options)); | |
| } | |
| itemContainer.appendChild(titleContainer); | |
| var infoConteiner = document.createElement('span'); | |
| options.sfUtils.setStyle(infoConteiner, { | |
| cssFloat: 'right', | |
| lineHeight: '22px', | |
| height: '22px' | |
| }); | |
| var sizeIconStyle = { | |
| top: '5px', | |
| verticalAlign: 'top' | |
| }; | |
| var sizeIconTextStyle = { | |
| marginLeft: 0 | |
| }; | |
| if (listItem.noAudio) { | |
| options.sfUtils.appendNoSoundIcon(infoConteiner, sizeIconStyle); | |
| } | |
| options.sfUtils.appendFileSizeIcon(itemContainer, sizeIconStyle, sizeIconTextStyle, undefined, true, infoConteiner); | |
| itemContainer.appendChild(infoConteiner); | |
| return {el: itemContainer, sizeIcon: infoConteiner.lastChild, prop: listItem}; | |
| }, | |
| sortMenuItems: function(list) { | |
| var formatPriority = ['Audio OGG','Audio MP4','3GP','WebM','FLV','MP4']; | |
| var strQuality = { | |
| Mobile: 280, | |
| SD: 360, | |
| HD: 720, | |
| '480p low': 478, | |
| '480p med': 479, | |
| '480p high': 480 | |
| }; | |
| var sizePriority = {}; | |
| var bitratePriority = []; | |
| var defList = []; | |
| var audioList = []; | |
| var muteList = []; | |
| var _3dList = []; | |
| var unkList = []; | |
| list.forEach(function(item) { | |
| var prop = item.prop; | |
| if (!prop.format) { | |
| unkList.push(item); | |
| return 1; | |
| } | |
| if (!prop.noVideo) { | |
| var size = strQuality[prop.quality] || -1; | |
| if (size === -1) { | |
| if (String(prop.quality).substr(-1) === 'k') { | |
| size = parseInt(prop.quality) * 1000; | |
| } else { | |
| size = parseInt(prop.quality); | |
| } | |
| } | |
| sizePriority[prop.quality] = size; | |
| if (prop.noAudio) { | |
| muteList.push(item); | |
| } else | |
| if (prop['3d']) { | |
| _3dList.push(item); | |
| } else { | |
| defList.push(item); | |
| } | |
| } else { | |
| bitratePriority[prop.quality] = parseInt(prop.quality); | |
| audioList.push(item); | |
| } | |
| }); | |
| var sizeCompare = function(a, b) { | |
| return sizePriority[a.quality] > sizePriority[b.quality]? -1 : sizePriority[a.quality] === sizePriority[b.quality]? 0 : 1; | |
| }; | |
| var bitrateCompare = function(a, b) { | |
| return bitratePriority[a.quality] > bitratePriority[b.quality]? -1 : (bitratePriority[a.quality] === bitratePriority[b.quality])? 0 : 1; | |
| }; | |
| var formatCompare = function(a, b) { | |
| if (a.noVideo && b.noVideo) { | |
| return bitrateCompare(a, b); | |
| } | |
| if (a.noVideo) { | |
| return 1; | |
| } | |
| if (b.noVideo) { | |
| return -1; | |
| } | |
| return formatPriority.indexOf(a.format) > formatPriority.indexOf(b.format)? -1 : formatPriority.indexOf(a.format) === formatPriority.indexOf(b.format)? 0 : 1; | |
| }; | |
| var compare = function(aa, bb) { | |
| var a = aa.prop; | |
| var b = bb.prop; | |
| var size = sizeCompare(a, b); | |
| if (size !== 0) { | |
| return size; | |
| } | |
| return formatCompare(a, b); | |
| }; | |
| defList.sort(compare); | |
| _3dList.sort(compare); | |
| audioList.sort(compare); | |
| muteList.sort(compare); | |
| return defList.concat(_3dList, audioList, muteList, unkList); | |
| }, | |
| removePanel: function() { | |
| this.popup.parentNode.removeChild(this.popup); | |
| this.popupStyle.parentNode.removeChild(this.popupStyle); | |
| this.popup = undefined; | |
| this.popupStyle = undefined; | |
| }, | |
| create: function(options) { | |
| var document = options.document; | |
| var button = options.button; | |
| var links = options.links; | |
| var _this = SaveFrom_Utils.popupMenu; | |
| if(_this.popup) { | |
| _this.removePanel(); | |
| } | |
| var popupContainer = _this.popup = document.createElement('div'); | |
| var containerSelector = '#'+_this.popupId; | |
| if (options.popupId) { | |
| containerSelector = '#'+options.popupId; | |
| popupContainer.id = options.popupId; | |
| } else | |
| if (options.containerClass) { | |
| containerSelector = '.'+options.containerClass; | |
| popupContainer.classList.add(options.containerClass); | |
| } else { | |
| popupContainer.id = _this.popupId; | |
| } | |
| var popupContainerStyle = { | |
| display: 'block', | |
| position: 'absolute', | |
| minHeight: '24px', | |
| cursor: 'default', | |
| textAlign: 'left', | |
| whiteSpace: 'nowrap', | |
| fontFamily: 'arial, sans-serif' | |
| }; | |
| var pos = SaveFrom_Utils.getPosition(button), | |
| size = SaveFrom_Utils.getSize(button); | |
| popupContainerStyle.top = (pos.top + size.height) + 'px'; | |
| popupContainerStyle.left = pos.left + 'px'; | |
| options.sfUtils.setStyle(popupContainer, popupContainerStyle); | |
| var popupCustomContainerStyle = { | |
| 'background-color': '#fff', | |
| 'z-index': '9999', | |
| 'box-shadow': '0 2px 10px 0 rgba(0,0,0,0.2)', | |
| border: '1px solid #ccc', | |
| 'border-radius': '4px', | |
| 'font-size': '12px', | |
| 'font-weight': 'bold', | |
| 'min-width': '190px' | |
| }; | |
| if (options.style && options.style.popup) { | |
| for (var key in options.style.popup) { | |
| var value = options.style.popup[key]; | |
| popupCustomContainerStyle[key] = value; | |
| } | |
| } | |
| options.sfUtils.addStyleRules(containerSelector, popupCustomContainerStyle); | |
| var itemCustomStyle = { | |
| 'line-height': '24px', | |
| color: '#3D3D3D' | |
| }; | |
| if (options.style && options.style.item) { | |
| for (var key in options.style.item) { | |
| var value = options.style.item[key]; | |
| itemCustomStyle[key] = value; | |
| } | |
| } | |
| options.sfUtils.addStyleRules(containerSelector+' '+( (options.linkClass)?'.'+options.linkClass:'a' ), itemCustomStyle); | |
| popupContainer.addEventListener('click', function(e) { | |
| e.stopPropagation(); | |
| }); | |
| popupContainer.addEventListener('mouseover', function(e) { | |
| e.stopPropagation(); | |
| }); | |
| popupContainer.addEventListener('mouseup', function(e) { | |
| e.stopPropagation(); | |
| }); | |
| popupContainer.addEventListener('mousedown', function(e) { | |
| e.stopPropagation(); | |
| }); | |
| popupContainer.addEventListener('mouseout', function(e) { | |
| e.stopPropagation(); | |
| }); | |
| var waitGetList = []; | |
| if(typeof(links) === 'string') { | |
| var loadingItem = _this.createPopupItem('-text-', options).el; | |
| loadingItem.textContent = links; | |
| popupContainer.appendChild( loadingItem ); | |
| } else { | |
| while (popupContainer.firstChild !== null) { | |
| popupContainer.removeChild(popupContainer.firstChild); | |
| } | |
| var items = []; | |
| links.forEach(function(link) { | |
| items.push(_this.createPopupItem(link, options)); | |
| }); | |
| if (items.length === 0) { | |
| var emptyItem = _this.createPopupItem('-text-', options).el; | |
| emptyItem.textContent = chrome.i18n.getMessage('noLinksFound'); | |
| popupContainer.appendChild( emptyItem ); | |
| } | |
| var hiddenList = []; | |
| items = _this.sortMenuItems(items); | |
| items.forEach(function(item) { | |
| if (item.prop.isHidden) { | |
| hiddenList.push(item.el); | |
| return 1; | |
| } | |
| popupContainer.appendChild(item.el); | |
| if (options.showFileSize) { | |
| waitGetList.push(item.sizeIcon); | |
| } | |
| }); | |
| if (hiddenList.length > 0) { | |
| var scrollListItemCount = 8; | |
| if (hiddenList.length > scrollListItemCount) { | |
| var scrollContainer = document.createElement('div'); | |
| scrollContainer.setAttribute(_this.dataArrtVisible, 0); | |
| scrollContainer.addEventListener('wheel', function(e) { | |
| if (e.wheelDeltaY > 0 && this.scrollTop === 0) { | |
| e.preventDefault(); | |
| } else | |
| if (e.wheelDeltaY < 0 && this.scrollHeight - (this.offsetHeight + this.scrollTop) <= 0) { | |
| e.preventDefault(); | |
| } | |
| }); | |
| var hasTopShadow = false; | |
| scrollContainer.addEventListener('scroll', function(e) { | |
| if (this.scrollTop !== 0) { | |
| if (hasTopShadow) { | |
| return; | |
| } | |
| hasTopShadow = true; | |
| this.style.boxShadow = 'rgba(0, 0, 0, 0.40) -2px 1px 2px 0px inset'; | |
| } else { | |
| if (!hasTopShadow) { | |
| return; | |
| } | |
| hasTopShadow = false; | |
| this.style.boxShadow = ''; | |
| } | |
| }); | |
| options.sfUtils.setStyle(scrollContainer, { | |
| maxHeight: (scrollListItemCount * 24)+'px', | |
| overflowY: 'scroll', | |
| display: 'none' | |
| }); | |
| hiddenList.forEach(function (item) { | |
| scrollContainer.appendChild(item); | |
| }); | |
| popupContainer.appendChild(scrollContainer); | |
| } else { | |
| hiddenList.forEach(function (item) { | |
| popupContainer.appendChild(item); | |
| }); | |
| } | |
| var moreItem = _this.createPopupItem('#', options).el; | |
| moreItem.textContent = chrome.i18n.getMessage('more') + ' ' + String.fromCharCode(187);//171 //160 - space | |
| moreItem.setAttribute('data-visible', 0); | |
| moreItem.addEventListener('click', function(e) { | |
| e.preventDefault(); | |
| var state = this.getAttribute('data-visible'); | |
| var symbol; | |
| if (state > 0) { | |
| state--; | |
| symbol = 187; | |
| } else { | |
| state++; | |
| symbol = 171; | |
| } | |
| this.textContent = chrome.i18n.getMessage('more') + ' ' + String.fromCharCode(symbol); | |
| moreItem.setAttribute('data-visible', state); | |
| var itemList = this.parentNode.querySelectorAll('*[' + _this.dataArrtVisible + ']'); | |
| for (var i = 0, item; item = itemList[i]; i++) { | |
| if (state === 1) { | |
| item.style.display = 'block'; | |
| } else { | |
| item.style.display = 'none'; | |
| } | |
| item.setAttribute( _this.dataArrtVisible, state); | |
| } | |
| }); | |
| var separator = _this.createPopupItem('-', options).el; | |
| popupContainer.appendChild(separator); | |
| popupContainer.appendChild(moreItem); | |
| } | |
| } | |
| var hoverBgColor = '#2F8AFF'; | |
| var hoverTextColor = '#fff'; | |
| if (options.style && options.style.hover) { | |
| hoverBgColor = options.style.hover.backgroundColor || hoverBgColor; | |
| hoverTextColor = options.style.hover.color || hoverTextColor; | |
| } | |
| var styleEl = _this.popupStyle = document.createElement('style'); | |
| styleEl.textContent = containerSelector + ' a:hover'+ | |
| '{'+ | |
| 'background-color: '+hoverBgColor+';'+ | |
| 'color: '+hoverTextColor+';'+ | |
| '}'+ | |
| containerSelector + ' > a:first-child'+ | |
| '{'+ | |
| 'border-top-left-radius: 4px;'+ | |
| 'border-top-right-radius: 4px;'+ | |
| '}'+ | |
| containerSelector + ' > a:last-child'+ | |
| '{'+ | |
| 'border-bottom-left-radius: 4px;'+ | |
| 'border-bottom-right-radius: 4px;'+ | |
| '}'; | |
| document.body.appendChild(styleEl); | |
| document.body.appendChild(popupContainer); | |
| setTimeout(function() { | |
| waitGetList.forEach(function(icon) { | |
| var event = new CustomEvent("click"); | |
| icon.dispatchEvent(event); | |
| }); | |
| }, 100); | |
| }, | |
| prepareLinks: { | |
| youtube: function(links, title, sfUtils) { | |
| var sfUtilsYt = sfUtils.video.yt; | |
| sfUtilsYt.init(sfUtils.prefs); | |
| var titleAttr = ''; | |
| if (title) { | |
| titleAttr = '&title=' + encodeURIComponent(title); | |
| for (var key in links) { | |
| links[key] += titleAttr; | |
| } | |
| } | |
| sfUtilsYt.filterLinks(links); | |
| var menuLinks = []; | |
| var popupLink; | |
| for (var format in sfUtilsYt.format) { | |
| var formatList = sfUtilsYt.format[format]; | |
| for (var itag in formatList) { | |
| if (links[itag] === undefined) { | |
| continue; | |
| } | |
| var prop = formatList[itag]; | |
| var isHidden = false; | |
| if (!sfUtilsYt.showFormat[format]) { | |
| isHidden = true; | |
| } | |
| if (prop['3d'] && !sfUtilsYt.show3D) { | |
| isHidden = true; | |
| } | |
| if (prop.noAudio && !sfUtilsYt.showMP4NoAudio) { | |
| isHidden = true; | |
| } | |
| popupLink = { href: links[itag], isHidden: isHidden, title: title, format: format }; | |
| for (var pItem in prop) { | |
| popupLink[pItem] = prop[pItem]; | |
| } | |
| if(format == 'Audio MP4' || format == 'Audio OGG' || prop.noAudio) { | |
| popupLink.forceDownload = true; | |
| } | |
| menuLinks.push(popupLink); | |
| delete links[itag]; | |
| } | |
| } | |
| for (var itag in links) { | |
| popupLink = { href: links[itag], isHidden: true, title: title, quality: itag }; | |
| menuLinks.push(popupLink); | |
| delete links[itag]; | |
| } | |
| return menuLinks; | |
| }, | |
| vimeo: function(links, title) { | |
| var menuLinks = []; | |
| var popupLink; | |
| links.forEach(function(link) { | |
| var ext = link.ext; | |
| if(!ext) | |
| { | |
| ext = 'MP4'; | |
| if(link.url.search(/\.flv($|\?)/i) != -1) | |
| ext = 'FLV'; | |
| } | |
| var quality = link.name ? link.name : ext; | |
| var format = link.type ? link.type : ext; | |
| format = format.toUpperCase(); | |
| popupLink = { href: link.url, title: title, ext: ext, format: format, quality: quality, forceDownload: true, useIframe: true }; | |
| menuLinks.push(popupLink); | |
| }); | |
| return menuLinks; | |
| }, | |
| vk: function(links, title) { | |
| var menuLinks = []; | |
| var popupLink; | |
| links.forEach(function(link) { | |
| var ext = link.name|| link.ext; | |
| var format = (ext)?ext.toUpperCase():''; | |
| var quality = (link.subname)?link.subname:''; | |
| popupLink = { href: link.url, title: title, ext: ext, format: format, quality: quality, forceDownload: true, useIframe: true }; | |
| menuLinks.push(popupLink); | |
| }); | |
| return menuLinks; | |
| }, | |
| dailymotion: function(links, title) { | |
| var menuLinks = []; | |
| var popupLink; | |
| links.forEach(function(link) { | |
| var format = link.ext; | |
| var quality = (link.height)?link.height:''; | |
| popupLink = { href: link.url, title: title, ext: format, format: format, quality: quality, forceDownload: true }; | |
| menuLinks.push(popupLink); | |
| }); | |
| return menuLinks; | |
| } | |
| } | |
| } | |
| }; | |
| (function(){ | |
| if (window.self == window.top || !location.hash) { | |
| return; | |
| } | |
| var params = location.hash.match(/sfh--download=([^\s\&]+)/i); | |
| if (!params) { | |
| return; | |
| } | |
| params = JSON.parse(decodeURIComponent(params[1])); | |
| if (!params.url || !params.filename) { | |
| return; | |
| } | |
| var a = document.createElement('a'); | |
| a.href = params.url; | |
| a.download = params.filename; | |
| a.appendChild(document.body); | |
| var event = document.createEvent('MouseEvents'); | |
| event.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, | |
| false, false, false, false, 0, null); | |
| a.dispatchEvent(event); | |
| })(); | |
| ///////////////////////////////////////////////// | |
| // MODULE | |
| _moduleHosts = { | |
| 'dailymotion.com': 'dailymotion', | |
| 'facebook.com': 'facebook', | |
| 'odnoklassniki.ru': 'odnoklassniki', | |
| 'ok.ru': 'odnoklassniki', | |
| 'savefrom.net': 'savefrom', | |
| 'soundcloud.com': 'soundcloud', | |
| 'vimeo.com': 'vimeo', | |
| 'vk.com': 'vk', | |
| 'vkontakte.ru': 'vk', | |
| 'youtube.com': 'youtube' | |
| }; | |
| _modules = {}; | |
| _modules.dailymotion = function(){ | |
| var iframe = false; | |
| if(window.top != window.self) | |
| { | |
| var m = location.href.match(/\/embed\/([\w\-]+)/i); | |
| if(m && m.length > 1) | |
| { | |
| iframe = true; | |
| } | |
| else | |
| { | |
| return; | |
| } | |
| } | |
| window.savefrom__lm = {}; | |
| var moduleName = 'dailymotion', | |
| prefs = {}; | |
| var dailymotion = { | |
| embed: null, | |
| title: '', | |
| styleIndex: 0, | |
| btnId: 'sf__download_btn', | |
| panelId: 'sf__download_panel', | |
| result: null, | |
| popupIsShow: false, | |
| hashChangeTimer: undefined, | |
| run: function() | |
| { | |
| if (iframe) { | |
| dailymotion.appendIframeButtons(); | |
| return; | |
| } | |
| var btnBox = dailymotion.insertBtn(); | |
| if (!btnBox) { | |
| var count = 0, timer = setInterval(function(){ | |
| count++; | |
| btnBox = dailymotion.insertBtn(); | |
| if(count > 5 || btnBox) | |
| clearInterval(timer); | |
| }, 1000); | |
| } | |
| clearInterval(dailymotion.hashChangeTimer); | |
| var loc = document.location.href; | |
| dailymotion.hashChangeTimer = setInterval(function(){ | |
| if(document.location.href === loc) { | |
| return; | |
| } | |
| loc = document.location.href; | |
| var exBtn = document.getElementById(dailymotion.btnId); | |
| if (!exBtn) { | |
| dailymotion.insertBtn(); | |
| } else { | |
| setTimeout(function () { | |
| var exBtn = document.getElementById(dailymotion.btnId); | |
| if (!exBtn) { | |
| dailymotion.insertBtn(); | |
| } | |
| }, 1500); | |
| } | |
| }, 1000); | |
| }, | |
| insertBtn: function() { | |
| var btnBox = dailymotion.getButtonBox(); | |
| if(btnBox) | |
| { | |
| if(dailymotion.styleIndex === 2) { | |
| dailymotion.showLinks(btnBox, SaveFrom_Utils.getParentByClass(btnBox, 'row')); | |
| } else { | |
| dailymotion.showLinks(btnBox); | |
| } | |
| } | |
| return btnBox; | |
| }, | |
| appendIframeButtons: function() | |
| { | |
| var p = undefined, | |
| b = document.createElement('div'), | |
| a = document.createElement('a'), | |
| panel = document.createElement('div'); | |
| a.href = '#'; | |
| a.textContent = chrome.i18n.getMessage('download').toLowerCase(); | |
| SaveFrom_Utils.setStyle(a, { | |
| display: 'inline-block', | |
| color: 'rgba(255,255,255,.9)', | |
| textDecoration: 'none', | |
| padding: '5px 10px' | |
| }); | |
| b.appendChild(a); | |
| SaveFrom_Utils.setStyle(b, { | |
| background: 'rgba(0, 0, 0, .4)', | |
| border: '1px solid rgba(255,255,255,.5)', | |
| borderRadius: '4px', | |
| fontFamily: 'Arial,Helvetica,sans-serif', | |
| fontSize: '13px', | |
| lineHeight: 'normal', | |
| position: 'absolute', | |
| top: '5px', | |
| left: '5px', | |
| padding: 0, | |
| margin: 0, | |
| zIndex: 99999 | |
| }); | |
| panel.id = dailymotion.panelId; | |
| SaveFrom_Utils.setStyle(panel, { | |
| color: '#fff', | |
| background: 'rgba(0,0,0,0.7)', | |
| textAlign: 'center', | |
| border: 0, | |
| display: 'none', | |
| fontFamily: 'Arial,Helvetica,sans-serif', | |
| fontSize: '13px', | |
| fontWeight: 'normal', | |
| lineHeight: 'normal', | |
| position: 'absolute', | |
| top: 0, | |
| left: 0, | |
| right: 0, | |
| margin: 0, | |
| padding: '3px', | |
| zIndex: 99990 | |
| }); | |
| dailymotion.btnBox = document.createElement('div'); | |
| dailymotion.btnBox.style.display = 'none'; | |
| dailymotion.btnBox.appendChild(b); | |
| dailymotion.btnBox.appendChild(panel); | |
| document.removeEventListener('mouseover', dailymotion.onExtPlayerOver, false); | |
| document.removeEventListener('mouseout', dailymotion.onExtPlayerOver, false); | |
| document.addEventListener('mouseover', dailymotion.onExtPlayerOver, false); | |
| document.addEventListener('mouseout', dailymotion.onExtPlayerOver, false); | |
| a.addEventListener('click', dailymotion.fetchIframeLinks, false); | |
| a.addEventListener('click', dailymotion.toggleIframePanel, false); | |
| document.body.appendChild(dailymotion.btnBox); | |
| }, | |
| onExtPlayerOver: function(event) | |
| { | |
| if(event.type == 'mouseover') | |
| { | |
| if(dailymotion.btnBox.style.display == 'none') | |
| dailymotion.btnBox.style.display = 'block'; | |
| } | |
| else if(event.type == 'mouseout') | |
| { | |
| dailymotion.btnBox.style.display = 'none'; | |
| } | |
| }, | |
| fetchIframeLinks: function(e) { | |
| var a = this; | |
| var button = e.target; | |
| if(!dailymotion.result) | |
| { | |
| dailymotion.getLinks(document.body.innerHTML, function(links) { | |
| if (links && links.length > 0) { | |
| dailymotion.result = dailymotion.handleLinks(links); | |
| dailymotion.fillIframePanelInfo(dailymotion.result); | |
| return; | |
| } | |
| dailymotion.getEmbedVideoInfo(function(links){ | |
| if(links && links.length > 0) { | |
| dailymotion.result = dailymotion.handleLinks(links); | |
| dailymotion.fillIframePanelInfo(dailymotion.result); | |
| } else { | |
| dailymotion.result = true; | |
| dailymotion.fillIframePanelInfo(null); | |
| } | |
| }); | |
| }); | |
| } | |
| button.removeEventListener('click', dailymotion.fetchIframeLinks, false); | |
| e.preventDefault(); | |
| e.stopPropagation(); | |
| return false; | |
| }, | |
| toggleIframePanel: function(e) | |
| { | |
| e.preventDefault(); | |
| e.stopPropagation(); | |
| var panel = document.getElementById(dailymotion.panelId); | |
| if(panel) | |
| { | |
| panel.style.display = (panel.style.display == 'none') ? '' : 'none'; | |
| } | |
| }, | |
| getButtonBox: function() | |
| { | |
| var parent; | |
| var linkContainer = document.getElementById('container_player_main'); | |
| if (linkContainer) { | |
| parent = SaveFrom_Utils.getParentByClass(linkContainer, 'pl_user_featured'); | |
| if (parent) { | |
| var container = parent.querySelector('#js-featured-card-counter'); | |
| if (container) { | |
| dailymotion.styleIndex = 3; | |
| return container; | |
| } | |
| } | |
| } | |
| linkContainer = document.getElementById('main_player'); | |
| if (linkContainer) { | |
| parent = document.getElementById('player_tools'); | |
| if (parent) { | |
| var container = parent.querySelector('#dmpi_video_tools'); | |
| if (container) { | |
| container = container.firstChild; | |
| if (container) { | |
| dailymotion.styleIndex = 4; | |
| return container; | |
| } | |
| } | |
| } | |
| } | |
| var btnBox = document.getElementById('sd_video_tools'); | |
| if(btnBox) { | |
| if (btnBox.tagName !== 'UL') { | |
| return; | |
| } | |
| return btnBox; | |
| } | |
| btnBox = document.querySelector('div.pl_video_infos .sd_user_subscribe'); | |
| if (btnBox) { | |
| dailymotion.styleIndex = 2; | |
| return btnBox; | |
| } | |
| parent = document.querySelector('.video_infos'); | |
| if(parent) | |
| { | |
| var box = document.createElement('div'); | |
| btnBox = document.createElement('ul'); | |
| btnBox.style.textAlign = 'right'; | |
| box.appendChild(btnBox); | |
| parent.appendChild(box); | |
| dailymotion.styleIndex = 1; | |
| return btnBox; | |
| } | |
| return null; | |
| }, | |
| hidePopup: function(e) { | |
| if (dailymotion.popupIsShow === false) { | |
| return; | |
| } | |
| if (e !== undefined) { | |
| SaveFrom_Utils.embedDownloader.onBodyClick(e); | |
| } else { | |
| SaveFrom_Utils.embedDownloader.hidePanel(); | |
| SaveFrom_Utils.embedDownloader.lastLink = null; | |
| } | |
| dailymotion.popupIsShow = SaveFrom_Utils.embedDownloader.lastLink !== null; | |
| if ( dailymotion.popupIsShow === false ) { | |
| document.removeEventListener('click', dailymotion.hidePopup, true); | |
| } | |
| }, | |
| showLinks: function(btnBox, panelParent) | |
| { | |
| var panel = dailymotion.createPanel(); | |
| if(btnBox) | |
| { | |
| if (dailymotion.styleIndex === 3 || dailymotion.styleIndex === 4) { | |
| var a = document.createElement('a'); | |
| a.id = dailymotion.btnId; | |
| a.href = '#'; | |
| if (dailymotion.styleIndex === 3) { | |
| a.textContent = chrome.i18n.getMessage('download'); | |
| a.classList.add('btn'); | |
| a.style.padding = '1px 6px'; | |
| a.style.cssFloat = 'left'; | |
| var icon = document.createElement('img'); | |
| icon.src = SaveFrom_Utils.svg.getSrc('download', '#808080'); | |
| icon.title = chrome.i18n.getMessage('download'); | |
| SaveFrom_Utils.setStyle(icon, { | |
| width: '12px', | |
| height: '12px', | |
| verticalAlign: 'middle', | |
| opacity: '0.9', | |
| marginLeft: '3px' | |
| }); | |
| a.appendChild(icon); | |
| } else { | |
| a.style.backgroundImage = 'url('+SaveFrom_Utils.svg.getSrc('download', '#808080')+')'; | |
| a.style.backgroundSize = '12px'; | |
| a.classList.add('btn'); | |
| a.title = chrome.i18n.getMessage('download'); | |
| SaveFrom_Utils.setStyle(a, { | |
| display: 'inline-block', | |
| height: '25px', | |
| backgroundPosition: 'center', | |
| backgroundRepeat: 'no-repeat' | |
| }); | |
| } | |
| a.addEventListener('click', function(e) { | |
| e.preventDefault(); | |
| var video_obj, id; | |
| if (dailymotion.styleIndex === 3) { | |
| video_obj = document.getElementById('container_player_main'); | |
| var param = video_obj.querySelector('param[name="flashvars"]'); | |
| if (param) { | |
| var data = param.getAttribute('value') || ''; | |
| var fragment = decodeURIComponent(data.substr(data.indexOf('media_id'), 100)); | |
| var pos = fragment.indexOf(','); | |
| var pos2 = fragment.indexOf(':') + 2; | |
| id = fragment.substr(pos2, pos - pos2 - 1); | |
| this.setAttribute('data-savefrom-get-links', document.location.protocol+'//dailymotion.com/video/' + id); | |
| } else { | |
| var iframe = video_obj; | |
| this.setAttribute('data-savefrom-get-links', iframe.getAttribute('src')); | |
| } | |
| } else | |
| if (dailymotion.styleIndex === 4) { | |
| var linkId = btnBox.querySelector('a[data-video-xid]'); | |
| if (linkId) { | |
| id = linkId.getAttribute('data-video-xid'); | |
| } else { | |
| id = undefined; | |
| } | |
| this.setAttribute('data-savefrom-get-links', document.location.protocol+'//dailymotion.com/video/' + id); | |
| } | |
| dailymotion.popupIsShow = true; | |
| SaveFrom_Utils.embedDownloader.onClick(e); | |
| document.removeEventListener('click', dailymotion.hidePopup, true); | |
| document.addEventListener('click', dailymotion.hidePopup, true); | |
| }); | |
| if(dailymotion.styleIndex === 4) { | |
| btnBox.appendChild(a); | |
| } else { | |
| btnBox.insertBefore(a, btnBox.firstChild); | |
| } | |
| return; | |
| } | |
| panel.style.display = 'none'; | |
| panel.style.textAlign = 'center'; | |
| if(panelParent) { | |
| panelParent.parentNode.insertBefore(panel, SaveFrom_Utils.nextSibling(panelParent)); | |
| } else { | |
| btnBox.parentNode.insertBefore(panel, SaveFrom_Utils.nextSibling(btnBox)); | |
| } | |
| if(dailymotion.styleIndex === 2) | |
| { | |
| var li = a = document.createElement('div'); | |
| a.id = dailymotion.btnId; | |
| a.className = 'button'; | |
| a.style.height = '22px'; | |
| a.style.padding = '0 5px'; | |
| } | |
| else | |
| { | |
| var li = document.createElement('li'); | |
| var a = document.createElement('a'); | |
| a.id = dailymotion.btnId; | |
| a.className = 'dmco_simplelink button linkable'; | |
| a.style.fontWeight = 'bold'; | |
| a.href = '#'; | |
| a.textContent = chrome.i18n.getMessage('download'); | |
| li.appendChild(a); | |
| } | |
| if(dailymotion.styleIndex > 0) | |
| { | |
| var icon = document.createElement('img'); | |
| icon.src = SaveFrom_Utils.svg.getSrc('download', '#808080'); | |
| icon.title = chrome.i18n.getMessage('download'); | |
| SaveFrom_Utils.setStyle(icon, { | |
| width: '12px', | |
| height: '12px', | |
| verticalAlign: 'middle', | |
| opacity: '0.9' | |
| }); | |
| a.appendChild(icon); | |
| a.appendChild(document.createTextNode(' ' + | |
| chrome.i18n.getMessage('download'))); | |
| } | |
| a.addEventListener('click', function(event){ | |
| var a = this; | |
| if(!dailymotion.result) | |
| { | |
| var video = []; //dailymotion.getVideoInfo(); | |
| if(video && video.length > 0) | |
| { | |
| dailymotion.result = dailymotion.handleLinks(video); | |
| if(dailymotion.result) | |
| dailymotion.fillPanelInfo(dailymotion.result); | |
| } | |
| else | |
| { | |
| dailymotion.getEmbedVideoInfo(function(links){ | |
| if(links && links.length > 0) | |
| { | |
| dailymotion.result = dailymotion.handleLinks(links); | |
| dailymotion.fillPanelInfo(dailymotion.result); | |
| } | |
| else | |
| { | |
| dailymotion.result = true; | |
| dailymotion.fillPanelInfo(null); | |
| } | |
| }); | |
| } | |
| } | |
| panel.style.display = (panel.style.display == 'none') ? '' : 'none'; | |
| event.preventDefault(); | |
| event.stopPropagation(); | |
| return false; | |
| }, false); | |
| btnBox.appendChild(li); | |
| } | |
| else | |
| { | |
| if(dailymotion.embed) | |
| dailymotion.embed.parentNode.parentNode.parentNode.appendChild(panel); | |
| else | |
| document.body.insertBefore(panel, document.body.firstChild); | |
| } | |
| }, | |
| createPanel: function() | |
| { | |
| var p = document.createElement('div'); | |
| p.id = dailymotion.panelId; | |
| p.style.background = '#fff'; | |
| p.style.fontSize = '17px'; | |
| p.style.padding = '5px 0'; | |
| p.appendChild(document.createTextNode(chrome.i18n.getMessage('download') + ': ')); | |
| return p; | |
| }, | |
| fillPanelInfo: function(result) | |
| { | |
| var p = document.getElementById(dailymotion.panelId); | |
| if(!p) | |
| return; | |
| SaveFrom_Utils.emptyNode(p); | |
| p.appendChild(document.createTextNode(chrome.i18n.getMessage('download') + ': ')); | |
| if(!result || !result.length) | |
| { | |
| p.appendChild(document.createTextNode(chrome.i18n.getMessage('noLinksFound'))); | |
| return; | |
| } | |
| var sStyle = { | |
| fontSize: '75%', | |
| fontWeight: 'normal', | |
| marginLeft: '3px', | |
| whiteSpace: 'nowrap' | |
| }; | |
| var fsIconStyle = {}; | |
| var fsTextStyle = { | |
| position: 'relative', | |
| top: '-1px' | |
| }; | |
| var color = '', sep = false; | |
| for(var i = 0; i < result.length; i++) | |
| { | |
| if(sep) | |
| p.appendChild(document.createTextNode(' ')); | |
| var a = document.createElement('a'); | |
| a.href = result[i][0]; | |
| a.title = chrome.i18n.getMessage('downloadTitle'); | |
| if(dailymotion.title) | |
| { | |
| a.setAttribute('download', SaveFrom_Utils.fileName.modify( | |
| dailymotion.title + '.' + result[i][2].toLowerCase())); | |
| a.addEventListener('click', SaveFrom_Utils.downloadOnClick, false); | |
| } | |
| a.innerHTML = result[i][2]; | |
| a.style.margin = '0 0 0 10px'; | |
| if(result[i][1]) | |
| { | |
| var s = document.createElement('span'); | |
| s.innerHTML = result[i][1]; | |
| SaveFrom_Utils.setStyle(s, sStyle); | |
| a.appendChild(s); | |
| } | |
| p.appendChild(a); | |
| sep = true; | |
| SaveFrom_Utils.appendFileSizeIcon(a, fsIconStyle, fsTextStyle); | |
| if(!color) | |
| color = SaveFrom_Utils.getStyle(a, 'color'); | |
| } | |
| if(result.length > 0) | |
| { | |
| if(prefs.moduleShowDownloadInfo == '1') | |
| { | |
| if(!color) | |
| color = 'blue'; | |
| p.appendChild(document.createElement('br')); | |
| SaveFrom_Utils.appendDownloadInfo(p, color, null, { | |
| width: '16px', | |
| height: '16px', | |
| fontSize: '16px', | |
| lineHeight: '16px' | |
| }); | |
| } | |
| } | |
| }, | |
| fillIframePanelInfo: function(result) | |
| { | |
| var p = document.getElementById(dailymotion.panelId); | |
| if(!p) | |
| return; | |
| SaveFrom_Utils.emptyNode(p); | |
| if(!result || !result.length) | |
| { | |
| p.appendChild(document.createTextNode(chrome.i18n.getMessage('noLinksFound'))); | |
| p.style.paddingTop = '11px'; | |
| p.style.paddingBottom = '11px'; | |
| return; | |
| } | |
| var sStyle = { | |
| fontSize: '75%', | |
| fontWeight: 'normal', | |
| marginLeft: '3px', | |
| whiteSpace: 'nowrap', | |
| color: '#fff' | |
| }; | |
| var fsIconStyle = { | |
| color: '#fff', | |
| opacity: 0.5 | |
| }; | |
| var fsTextStyle = { | |
| position: 'relative', | |
| top: '-1px' | |
| }; | |
| var item = document.createElement('div'); | |
| item.style.marginTop = '8px'; | |
| item.style.marginBottom = '8px'; | |
| item.style.paddingLeft = '70px'; | |
| item.style.paddingRight = '70px'; | |
| p.appendChild(item); | |
| var color = '', sep = false; | |
| for(var i = 0; i < result.length; i++) | |
| { | |
| if(sep) | |
| item.appendChild(document.createTextNode(' ')); | |
| var a = document.createElement('a'); | |
| a.href = result[i][0]; | |
| a.title = chrome.i18n.getMessage('downloadTitle'); | |
| if(dailymotion.title) | |
| { | |
| a.setAttribute('download', SaveFrom_Utils.fileName.modify( | |
| dailymotion.title + '.' + result[i][2].toLowerCase())); | |
| a.addEventListener('click', SaveFrom_Utils.downloadOnClick, false); | |
| } | |
| a.innerHTML = result[i][2]; | |
| a.style.margin = '0 0 0 10px'; | |
| a.style.color = '#fff'; | |
| if(result[i][1]) | |
| { | |
| var s = document.createElement('span'); | |
| s.innerHTML = result[i][1]; | |
| SaveFrom_Utils.setStyle(s, sStyle); | |
| a.appendChild(s); | |
| } | |
| item.appendChild(a); | |
| sep = true; | |
| SaveFrom_Utils.appendFileSizeIcon(a, fsIconStyle, fsTextStyle); | |
| if(!color) | |
| color = SaveFrom_Utils.getStyle(a, 'color'); | |
| } | |
| if(result.length > 0) | |
| { | |
| if(prefs.moduleShowDownloadInfo == '1') | |
| { | |
| if(!color) | |
| color = 'blue'; | |
| SaveFrom_Utils.appendDownloadInfo(p, color, null, { | |
| width: '16px', | |
| height: '16px', | |
| fontSize: '16px', | |
| lineHeight: '16px' | |
| }); | |
| } | |
| } | |
| }, | |
| handleLinks: function(video) | |
| { | |
| var result = new Array(); | |
| var links = null; | |
| if(typeof(video) == 'object') | |
| links = video; | |
| else | |
| links = video.split('||'); | |
| if(links && links.length > 0) | |
| { | |
| for(var i = 0; i < links.length; i++) | |
| { | |
| links[i] = links[i].replace(/\\\//g, '/'); | |
| links[i] = links[i].replace(/\@\@[\w\-]+$/, ''); | |
| var size = ''; | |
| var t = links[i].match(/\/cdn\/\w+\-(\d+x\d+)\//i); | |
| if(t && t.length > 1) | |
| { | |
| size = t[1]; | |
| } | |
| else | |
| { | |
| t = links[i].match(/\D(\d+x\d+)\D/i); | |
| if(t && t.length > 1) | |
| { | |
| size = t[1]; | |
| } | |
| } | |
| var ext = 'FLV'; | |
| var t = links[i].match(/\.(\w{1,6})(?:$|\?)/); | |
| if(t && t.length > 1) | |
| { | |
| ext = t[1].toUpperCase(); | |
| } | |
| if(size !== '80x60') | |
| { | |
| var height = parseInt(size.split('x').slice(-1)[0]); | |
| result.push([links[i], height, ext]); | |
| } | |
| } | |
| } | |
| if(!result) | |
| { | |
| return null; | |
| } | |
| var sort = function(a, b){ | |
| a = parseInt(a[1]); | |
| a = isNaN(a) ? 0 : a; | |
| b = parseInt(b[1]); | |
| b = isNaN(b) ? 0 : b; | |
| return a - b; | |
| }; | |
| result.sort(sort); | |
| return result; | |
| }, | |
| getVideoInfo: function() | |
| { | |
| var e = document.querySelectorAll('param[name="flashvars"]'); | |
| for(var i = 0; i < e.length; i++) | |
| { | |
| var fv = e[i].getAttribute('value', false); | |
| if(fv) | |
| { | |
| var video = fv.match(/(?:^|&)video=([^\s\"\'\&]+)/i); | |
| if(video && video.length > 1) | |
| { | |
| embed = e[i]; | |
| return decodeURIComponent(video[1]); | |
| } | |
| else | |
| { | |
| var sequence = fv.match(/(?:^|&)sequence=([^\s\"\'\&]+)/i); | |
| if(sequence && sequence.length > 1) | |
| { | |
| var data = decodeURIComponent(sequence[1]); | |
| if(data) | |
| { | |
| links = []; | |
| var p = ['ldURL', 'sdURL', 'hqURL', 'hdURL', 'hd\\d+URL']; | |
| for(var j = 0; j < p.length; j++) | |
| { | |
| var re = new RegExp("[\\x22\\x27]" + p[j] + "[\\x22\\x27]\s*:\s*[\\x22\\x27]([^\\s\\x22\\x27]+)", "ig"); | |
| while(l = re.exec(data)) | |
| { | |
| if(l && l.length > 1) | |
| links.push(l[1]); | |
| } | |
| } | |
| if(links) | |
| { | |
| var t = data.match(/videoTitle=([^\s\"\'&]+)/i); | |
| if(t && t.length > 1) | |
| t[1] = decodeURIComponent(t[1]); | |
| else | |
| { | |
| data = data.replace(/\\\"/g, '"').replace(/'/g, '''); | |
| t = data.match(/[\"']videoTitle[\"']\s*:\s*[\"']([^\s\"']+)/i); | |
| } | |
| if(t && t.length > 1) | |
| { | |
| var videoTitle = t[1].replace(/\\u([\da-f]{4})/g, function(p1, p2){ | |
| p2 = p2.replace(/^0+/, ''); | |
| return String.fromCharCode(parseInt(p2, '16')); | |
| }); | |
| dailymotion.title = videoTitle.replace(/\+/ig, ' '); | |
| } | |
| embed = e[i]; | |
| return links; | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| var e = document.querySelectorAll('dm_widget_videoplayer'); | |
| if(e) | |
| { | |
| for(var i = 0; i < e.length; i++) | |
| { | |
| if(e[i].innerHTML) | |
| { | |
| var fv = e[i].innerHTML.match(/flashvars=[\"\']([^\s\"\']+)/i); | |
| if(fv && fv.length > 1) | |
| { | |
| fv = fv[1]; | |
| var video = fv.match(/(?:^|&)video=([^\s\"\'\&]+)/i); | |
| if(video && video.length > 1) | |
| { | |
| embed = e[i]; | |
| return decodeURIComponent(video[1]); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| var video = document.body.innerHTML.match(/\(\s*[\"\']video[\"\']\s*,\s*[\"\']([^\s\"\'\<\>]+)/i); | |
| if(video && video.length > 1) | |
| { | |
| return decodeURIComponent(video[1]); | |
| } | |
| return ''; | |
| }, | |
| getLinks: function(text, cb) | |
| { | |
| var links = []; | |
| var info = SaveFrom_Utils.getMatchFirst(text, | |
| /(?:var|,)\s*info\s*=\s*\{(.*?)\}\s*(?:;|,\s*\w+\s*=)/i); | |
| if(!info) { | |
| return cb(); | |
| } | |
| try | |
| { | |
| info = JSON.parse('{' + info + '}'); | |
| if(info) | |
| { | |
| dailymotion.title = info.title; | |
| for(var i in info) | |
| { | |
| if (!info.hasOwnProperty(i)) { | |
| continue; | |
| } | |
| if (!info[i]) { | |
| continue; | |
| } | |
| if(info[i].search(/^https?:\/\/[^\s\"]+\.(mp4|flv)(\?|$)/) > -1) | |
| { | |
| links.push(info[i]); | |
| } | |
| } | |
| } | |
| } | |
| catch(e){} | |
| cb(links); | |
| }, | |
| getEmbedVideoInfo: function(callback) | |
| { | |
| if(window.location.pathname) | |
| { | |
| var url = window.location.pathname; | |
| if (!iframe) { | |
| url = "/embed" + url; | |
| } | |
| SaveFrom_Utils.sendRequest(url, function(r){ | |
| if(r.status !== 200) { | |
| return callback(); | |
| } | |
| dailymotion.getLinks(r.responseText, callback); | |
| }); | |
| return; | |
| } | |
| callback(); | |
| } | |
| }; | |
| SaveFrom_Utils.initModule(moduleName, function(response) { | |
| //console.log('dailymotion', response); | |
| prefs = response; | |
| SaveFrom_Utils.runModule(response, dailymotion); | |
| }); | |
| }; | |
| _modules.facebook = function(){ | |
| if(window.top != window.self) | |
| return; | |
| window.savefrom__lm = {}; | |
| var moduleName = 'facebook', | |
| prefs = {}; | |
| // actions | |
| chrome.extension.onRequest.addListener(function(request, sender, callback){ | |
| switch(request.action) | |
| { | |
| case 'updateLinks': | |
| fb.updateLinks(); | |
| break; | |
| } | |
| }); | |
| var fb = { | |
| className: 'savefrom_fb_download', | |
| timer: 0, | |
| run: function() | |
| { | |
| var _this = this; | |
| window.clearInterval(this.timer); | |
| this.updateLinks(); | |
| var loc = document.location.href; | |
| this.timer = window.setInterval(function(){ | |
| if(document.location.href != loc) | |
| { | |
| loc = document.location.href; | |
| _this.updateLinks(); | |
| } | |
| }, 1000); | |
| }, | |
| updateLinks: function() | |
| { | |
| this.removeDownloadLinks(), | |
| video.showLinks(); | |
| externalMedia.run(); | |
| SaveFrom_Utils.addStyleRules('.' + SaveFrom_Utils.embedDownloader.linkClass + ' img', { | |
| opacity: '.5' | |
| }); | |
| SaveFrom_Utils.embedDownloader.init(); | |
| }, | |
| removeDownloadLinks: function() | |
| { | |
| var selector = 'a.' + this.className + | |
| ',div.' + this.className + | |
| ',span.' + this.className; | |
| var e = document.querySelectorAll(selector); | |
| for(var i = e.length-1; i >= 0; i--) | |
| e[i].parentNode.removeChild(e[i]); | |
| } | |
| }; | |
| var externalMedia = { | |
| linkAttr: 'data-savefrom-ed', | |
| timer: 0, | |
| lastLink: null, | |
| re: [ | |
| /https?:\/\/(?:[a-z]+\.)?youtube\.com\/(?:#!?\/)?watch\?[^\s\"\'\<\>]*v=([\w\-]+)/i, | |
| /https?:\/\/(?:[a-z0-9]+\.)?youtube\.com\/(?:embed|v)\/([\w\-]+)/i, | |
| /https?:\/\/(?:[a-z]+\.)?youtu\.be\/([\w\-]+)/i, | |
| /https?:\/\/(?:[\w\-]+\.)?vimeo\.com\/(\d+)(?:\?|$)/i, | |
| ], | |
| thumbnail: { | |
| youtube: { | |
| re: [/ytimg\.com(?:\/|%2F)vi(?:\/|%2F)([\w\-]+)(?:\/|%2F)/i], | |
| url: 'http://www.youtube.com/watch?v={vid}' | |
| } | |
| }, | |
| run: function() | |
| { | |
| document.removeEventListener('mouseenter', this.onLinkHover, true); | |
| document.addEventListener('mouseenter', this.onLinkHover, true); | |
| document.removeEventListener('mouseleave', this.onLinkHover, true); | |
| document.addEventListener('mouseleave', this.onLinkHover, true); | |
| }, | |
| onLinkHover: function(event) | |
| { | |
| var link = event.target; | |
| if(link.tagName != 'A') | |
| return; | |
| var attr = link.getAttribute(externalMedia.linkAttr); | |
| if(event.type == 'mouseenter') | |
| { | |
| if(attr) | |
| { | |
| window.clearTimeout(externalMedia.timer); | |
| return; | |
| } | |
| if(externalMedia.handle(link)) | |
| { | |
| if(externalMedia.lastLink && externalMedia.lastLink != link) | |
| externalMedia.removeBtn(externalMedia.lastLink); | |
| SaveFrom_Utils.embedDownloader.hidePanel(); | |
| externalMedia.lastLink = link; | |
| } | |
| return; | |
| } | |
| if(attr) | |
| { | |
| window.clearTimeout(externalMedia.timer); | |
| externalMedia.timer = window.setTimeout(function(){externalMedia.removeBtn(link);}, 1500); | |
| } | |
| }, | |
| removeBtn: function(link) | |
| { | |
| if(!link || typeof(link) != 'object') | |
| return; | |
| var btn = link.querySelector('.' + fb.className); | |
| if(btn) | |
| { | |
| btn.parentNode.removeAttribute(this.linkAttr); | |
| btn.parentNode.removeChild(btn); | |
| } | |
| link.removeAttribute(this.linkAttr); | |
| if(link == this.lastLink) | |
| this.lastLink = null; | |
| }, | |
| checkUrl: function(url, retry) | |
| { | |
| if(!retry && url.search(/https?:\/\/([\w\-]+\.)?facebook\.com\/l\.php/i) > -1) | |
| { | |
| return this.checkUrl(decodeURIComponent(url), true); | |
| } | |
| for(var i = 0, l = this.re.length; i < l; i++) | |
| { | |
| var m = url.match(this.re[i]); | |
| if(m && m.length > 0) | |
| return m[0]; | |
| } | |
| }, | |
| handle: function(link) | |
| { | |
| var img = link.querySelector('img'); | |
| if(img) | |
| { | |
| var parent = img.parentNode; | |
| if(img.src && SaveFrom_Utils.getStyle(parent, 'position') == 'relative') | |
| { | |
| var ajaxify = link.getAttribute('ajaxify'); | |
| if(ajaxify && ajaxify.search(/\/flash\/expand_inline/i) > -1) | |
| { | |
| var url = this.getThumbnailUrl(img.src); | |
| if(url) | |
| { | |
| return this.createButton(url, parent, link, { | |
| display: 'block', | |
| position: 'absolute', | |
| bottom: '3px', | |
| right: '3px', | |
| zIndex: 9999, | |
| margin: 0, | |
| width: '16px', | |
| height: '16px' | |
| }, { | |
| display: 'block' | |
| }); | |
| } | |
| } | |
| else if(this.checkUrl(link.href)) | |
| { | |
| return this.createButton(link.href, parent, link, { | |
| display: 'block', | |
| position: 'absolute', | |
| bottom: '3px', | |
| right: '3px', | |
| zIndex: 9999, | |
| margin: 0, | |
| width: '16px', | |
| height: '16px' | |
| }, { | |
| display: 'block' | |
| }); | |
| } | |
| } | |
| return false; | |
| } | |
| return this.createButton(link.href, link, link); | |
| }, | |
| getThumbnailUrl: function(url) | |
| { | |
| for(var i in this.thumbnail) | |
| { | |
| for(var j = 0; j < this.thumbnail[i].re.length; j++) | |
| { | |
| var vid = SaveFrom_Utils.getMatchFirst(url, this.thumbnail[i].re[j]); | |
| if(vid) | |
| return this.thumbnail[i].url.replace(/\{vid\}/ig, vid); | |
| } | |
| } | |
| return ''; | |
| }, | |
| createButton: function(url, parent, link, styleParent, styleIcon) | |
| { | |
| url = this.checkUrl(url); | |
| if(!url) | |
| return false; | |
| var btn = document.createElement('a'); | |
| btn.className = fb.className; | |
| btn.href = 'http://savefrom.net/?url=' + encodeURIComponent(url); | |
| btn.setAttribute(SaveFrom_Utils.embedDownloader.dataAttr, url); | |
| SaveFrom_Utils.setStyle(btn, { | |
| marginLeft: '7px', | |
| verticalAlign: 'middle' | |
| }); | |
| if(styleParent) | |
| SaveFrom_Utils.setStyle(btn, styleParent); | |
| var icon = document.createElement('img'); | |
| icon.className = 'icon'; | |
| icon.src = SaveFrom_Utils.svg.getSrc('download', '#a2db16'); | |
| SaveFrom_Utils.setStyle(icon, { | |
| display: 'inline-block', | |
| width: '16px', | |
| height: '16px', | |
| verticalAlign: 'middle', | |
| //opacity: '0.9', | |
| cursor: 'pointer' | |
| }); | |
| if(styleIcon) | |
| SaveFrom_Utils.setStyle(icon, styleIcon); | |
| btn.appendChild(icon); | |
| link.setAttribute(this.linkAttr, '1'); | |
| parent.appendChild(btn); | |
| return true; | |
| } | |
| }; | |
| var video = { | |
| getParent: function() | |
| { | |
| return document.querySelector('.videoStage'); | |
| }, | |
| getLinks: function(parent, callback) | |
| { | |
| var count = 0, _this = this; | |
| var func = function(){ | |
| var embed = parent.querySelector('embed'); | |
| if(embed) | |
| { | |
| callback.call(_this, _this.getLinksFromEmbed(embed)); | |
| return; | |
| } | |
| var video = parent.querySelector('video'); | |
| if(video) | |
| { | |
| callback.call(_this, _this.getLinksFromVideo(video)); | |
| return; | |
| } | |
| count++; | |
| if(count > 10) | |
| callback.call(_this, null); | |
| window.setTimeout(func, 1000); | |
| }; | |
| setTimeout(func, 1000); | |
| }, | |
| getLinksFromEmbed: function(embed) | |
| { | |
| if(!embed) | |
| return null; | |
| var fv = embed.getAttribute('flashvars'); | |
| if(!fv) | |
| return null; | |
| var params = SaveFrom_Utils.getMatchFirst(fv, /params=([^\s&]+)/i); | |
| if(!params) | |
| return null; | |
| params = decodeURIComponent(params); | |
| params = JSON.parse(params); | |
| if(!params || !params.video_data) | |
| return null; | |
| var links = {}; | |
| for(var i = 0; i < params.video_data.length; i++) | |
| { | |
| if(params.video_data[i].sd_src) | |
| links[params.video_data[i].sd_src] = 'SD'; | |
| if(params.video_data[i].hd_src) | |
| links[params.video_data[i].hd_src] = 'HD'; | |
| } | |
| return links; | |
| }, | |
| getLinksFromVideo: function(video) | |
| { | |
| if(!video) | |
| return null; | |
| var links = {}; | |
| if(video.src) | |
| { | |
| var ext = SaveFrom_Utils.getFileExtension(video.src, 'mp4'); | |
| links[video.src] = ext.toUpperCase(); | |
| } | |
| var src = video.querySelectorAll('source'); | |
| if(src && src.length > 0) | |
| { | |
| for(var i = 0; i < src.length; i++) | |
| { | |
| var ext = SaveFrom_Utils.getFileExtension(src[i].src, 'mp4'); | |
| links[src[i].src] = ext.toUpperCase(); | |
| } | |
| } | |
| return links; | |
| }, | |
| showLinks: function() | |
| { | |
| var parent = this.getParent(); | |
| if(!parent) | |
| return; | |
| var _this = this; | |
| var links = this.getLinks(parent, function(links){ | |
| _this.appendLinks(links, parent); | |
| }); | |
| }, | |
| getFileName: function(url) | |
| { | |
| var name = SaveFrom_Utils.getFileName(url); | |
| if(name) | |
| return name; | |
| var d = SaveFrom_Utils.dateToObj(); | |
| var dateStr = d.year + '-' + d.month + '-' + d.day + '_' + | |
| d.hour + '-' + d.min; | |
| return 'facebook_' + dateStr + '.' + | |
| SaveFrom_Utils.getFileExtension(url, 'mp4'); | |
| }, | |
| appendLinks: function(links, parent) | |
| { | |
| if(!links) | |
| return; | |
| var box = SaveFrom_Utils.getElementByIds(['fbPhotoPageMediaInfo', | |
| 'fbPhotoSnowliftMediaTitle']); | |
| if(!box || box.querySelector('.' + fb.className)) | |
| return; | |
| var panel = document.createElement('div'); | |
| panel.className = fb.className; | |
| panel.style.fontWeight = 'bold'; | |
| panel.appendChild(document.createTextNode(chrome.i18n.getMessage('download') + ': ')); | |
| var found = false; | |
| for(var i in links) | |
| { | |
| if(found) | |
| panel.appendChild(document.createTextNode('|')); | |
| found = true; | |
| var a = document.createElement('a'); | |
| a.href = i; | |
| a.target = '_blank'; | |
| a.className = fb.className; | |
| a.innerHTML = links[i]; | |
| a.title = chrome.i18n.getMessage('downloadTitle'); | |
| a.setAttribute('download', this.getFileName(i)); | |
| a.addEventListener('click', SaveFrom_Utils.downloadOnClick, false); | |
| a.style.marginLeft = '5px'; | |
| a.style.marginRight = '5px'; | |
| panel.appendChild(a); | |
| } | |
| if(!found) | |
| panel.appendChild(document.createTextNode(chrome.i18n.getMessage('noLinksFound'))); | |
| if(box.id == 'fbPhotoSnowliftMediaTitle') | |
| { | |
| panel.style.display = 'inline'; | |
| panel.style.marginRight = '20px'; | |
| panel.style.lineHeight = '33px'; | |
| box.insertBefore(panel, box.firstChild); | |
| } | |
| else | |
| { | |
| box.appendChild(panel); | |
| } | |
| } | |
| }; | |
| SaveFrom_Utils.initModule(moduleName, function(response) { | |
| //console.log('facebook', response); | |
| prefs = response; | |
| SaveFrom_Utils.runModule(response, fb); | |
| }); | |
| }; | |
| _modules.odnoklassniki = function(){ | |
| if(window.top != window.self) | |
| return; | |
| window.savefrom__lm = {}; | |
| var moduleName = 'odnoklassniki', | |
| prefs = {}; | |
| function showVideoLinks(id, response) | |
| { | |
| //console.log('ok showVideoLinks', response); | |
| var parent = document.getElementById(id); | |
| video.show(response.links, response.title, parent, video.style, response.action); | |
| } | |
| // actions | |
| chrome.extension.onRequest.addListener(function(request, sender, callback){ | |
| switch(request.action) | |
| { | |
| case 'updateLinks': | |
| updateLinks(); | |
| break; | |
| case 'downloadMP3Files': | |
| audio.showListOfAudioFiles(false); | |
| break; | |
| case 'downloadPlaylist': | |
| audio.showListOfAudioFiles(true); | |
| break; | |
| } | |
| }); | |
| var downloadLinkClassName = 'savefrom_ok_download'; | |
| var titleTimer = 0; | |
| function updateLinks() | |
| { | |
| removeDownloadLinks(); | |
| audio.showLinks(); | |
| video.showLinks(); | |
| } | |
| function createTextLink(href, text, blank) { | |
| if(blank == undefined) | |
| blank = true; | |
| var a = document.createElement('a'); | |
| a.href = href; | |
| a.className = downloadLinkClassName; | |
| a.innerHTML = text; | |
| if(blank) | |
| a.setAttribute('target', '_blank', false); | |
| return a; | |
| } | |
| function removeDownloadLinks() | |
| { | |
| var selector = '.' + downloadLinkClassName; | |
| var e = document.querySelectorAll(selector); | |
| for(var i = e.length-1; i >= 0; i--) | |
| e[i].parentNode.removeChild(e[i]); | |
| } | |
| /////////////////////////////////////////////////////////////////// | |
| // AUDIO | |
| var audio = { | |
| downloadIdPrefix: 'savefrom_ok_audio_download_', | |
| infoIdPrefix: 'savefrom_ok_audio_info_', | |
| lastRow: null, | |
| lastRowCandidate: null, | |
| timer: 0, | |
| jsessionId: '', | |
| scriptNode: null, | |
| cache: {}, | |
| ajaxTimer: {}, | |
| showRowElements: function(row, show, force) | |
| { | |
| if(!row) | |
| return; | |
| var node = row.querySelectorAll('div.' + downloadLinkClassName); | |
| if(show && (!node || node.length == 0)) | |
| { | |
| if(!audio.showRowLinks(row)) | |
| return; | |
| node = row.querySelectorAll('div.' + downloadLinkClassName); | |
| } | |
| if(node && node.length > 0) | |
| { | |
| var d = show ? '' : 'none'; | |
| for(var i = 0; i < node.length; i++) | |
| { | |
| node[i].style.display = d; | |
| } | |
| } | |
| }, | |
| getNodeTrackId: function(node) | |
| { | |
| var query = node.getAttribute('data-query'); | |
| if(query) | |
| { | |
| try | |
| { | |
| query = JSON.parse(query); | |
| if(query && query.trackId) | |
| return query.trackId; | |
| } | |
| catch(Err) | |
| { | |
| return null; | |
| } | |
| } | |
| return null; | |
| }, | |
| getTrackId: function(parent) | |
| { | |
| if(!parent) | |
| return null; | |
| var trackId = audio.getNodeTrackId(parent); | |
| if(trackId) | |
| { | |
| var links = {}; | |
| links[trackId] = parent; | |
| return links; | |
| } | |
| var id = parent.id; | |
| if(id) | |
| { | |
| id = SaveFrom_Utils.getMatchFirst(id, /^\w+_(\d+)$/i); | |
| if(id) | |
| { | |
| var links = {}; | |
| links[id] = parent; | |
| return links; | |
| } | |
| } | |
| return null; | |
| }, | |
| showRowLinks: function(row) | |
| { | |
| var links = audio.getTrackId(row); | |
| for(var i in links) | |
| { | |
| if(audio.handleRow(i, links[i])) | |
| return true; | |
| } | |
| return false; | |
| }, | |
| showLinks: function() | |
| { | |
| if(audio.scriptNode && audio.scriptNode.parentNode) | |
| { | |
| audio.scriptNode.parentNode.removeChild(audio.scriptNode); | |
| audio.scriptNode = null; | |
| } | |
| var s = document.createElement('script'); | |
| s.text = '(function(){\ | |
| if(window.pageCtx && window.pageCtx.jsessionId)\ | |
| {\ | |
| document.body.setAttribute(\'data-ok-jsession-id\', window.pageCtx.jsessionId);\ | |
| }\ | |
| })();'; | |
| document.body.appendChild(s); | |
| audio.scriptNode = s; | |
| var jsessionId = document.body.getAttribute('data-ok-jsession-id'); | |
| if(!jsessionId) | |
| return; | |
| audio.jsessionId = jsessionId; | |
| audio.cache = {}; | |
| for(var i in audio.ajaxTimer) | |
| window.clearTimeout(audio.ajaxTimer[i]); | |
| audio.ajaxTimer = {}; | |
| document.removeEventListener('mouseover', audio.onMouseOver, false); | |
| document.removeEventListener('mouseout', audio.onMouseOut, false); | |
| document.addEventListener('mouseover', audio.onMouseOver, false); | |
| document.addEventListener('mouseout', audio.onMouseOut, false); | |
| }, | |
| getLink: function(trackId) | |
| { | |
| if(!trackId || !audio.jsessionId) | |
| return; | |
| audio.ajaxTimer[trackId] = window.setTimeout(function(){ | |
| delete audio.ajaxTimer[trackId]; | |
| audio.deleteLink(trackId); | |
| }, 30000); | |
| chrome.extension.sendRequest({ | |
| action: 'getOdnoklassnikiAudioLinks', | |
| trackId: trackId, | |
| jsessionId: audio.jsessionId | |
| }, function(response){ | |
| audio.setLink(response.trackId, response.data); | |
| }); | |
| }, | |
| onMouseOver: function(event) | |
| { | |
| var node = event.target; | |
| var row = SaveFrom_Utils.getParentByClass(node, ['m_portal_track', 'm_c_tr', 'mus-tr_i']); | |
| if(row) | |
| { | |
| audio.lastRowCandidate = row; | |
| window.clearTimeout(audio.timer); | |
| if(audio.lastRow == row) | |
| return; | |
| audio.timer = window.setTimeout(function(){ | |
| audio.showRowElements(audio.lastRow, false); | |
| audio.lastRow = row; | |
| audio.lastRowCandidate = null; | |
| audio.showRowElements(audio.lastRow, true); | |
| }, 250); | |
| } | |
| }, | |
| onMouseOut: function(event) | |
| { | |
| if(!audio.lastRow && !audio.lastRowCandidate) | |
| return; | |
| var node = event.target; | |
| if(SaveFrom_Utils.isParent(node, audio.lastRow) || | |
| SaveFrom_Utils.isParent(node, audio.lastRowCandidate)) | |
| { | |
| window.clearTimeout(audio.timer); | |
| audio.timer = window.setTimeout(function(){ | |
| audio.showRowElements(audio.lastRow, false); | |
| audio.lastRow = null; | |
| audio.lastRowCandidate = null; | |
| }, 1000); | |
| } | |
| }, | |
| handleRow: function(trackId, row) | |
| { | |
| if(!trackId || !row) | |
| return false; | |
| var parent = row; | |
| parent.style.position = 'relative'; | |
| var duration = row.querySelector('.m_c_duration, .m_portal_duration'); | |
| var box = document.createElement('div'); | |
| box.className = downloadLinkClassName; | |
| SaveFrom_Utils.setStyle(box, { | |
| color: '#fff', | |
| background: '#46aa19', | |
| border: '1px solid #337d12', | |
| borderRadius: '3px', | |
| padding: '1px 5px', | |
| position: 'absolute', | |
| right: '40px', | |
| top: '50%', | |
| lineHeight: '15px', | |
| opacity: 0, | |
| zIndex: 9999, | |
| cursor: 'pointer' | |
| }); | |
| box.addEventListener('click', audio.onBoxClick, false); | |
| var title = audio.getTitle(trackId, row); | |
| var link1 = createTextLink('#', '...'); | |
| link1.id = audio.downloadIdPrefix + trackId; | |
| link1.title = chrome.i18n.getMessage('downloadTitle'); | |
| if(duration) | |
| { | |
| link1.setAttribute('data-savefrom-helper-duration', | |
| audio.secondsFromDurationNode(duration)); | |
| } | |
| if(title) | |
| { | |
| title += '.mp3'; | |
| link1.setAttribute('download', SaveFrom_Utils.fileName.modify(title)); | |
| } | |
| SaveFrom_Utils.setStyle(link1, { | |
| color: '#fff', | |
| fontWeight: 'normal' | |
| }); | |
| link1.addEventListener('click', audio.onDownloadLinkClick, false); | |
| box.appendChild(link1); | |
| parent.appendChild(box); | |
| if(audio.cache[trackId]) | |
| audio.setLinkFromCache(trackId, link1); | |
| else | |
| audio.getLink(trackId); | |
| box.style.marginTop = '-' + (box.offsetHeight / 2) + 'px'; | |
| box.style.opacity = '1'; | |
| var close = document.createElement('span'); | |
| close.innerHTML = '×'; | |
| close.title = chrome.i18n.getMessage('close'); | |
| SaveFrom_Utils.setStyle(close, { | |
| color: '#fff', | |
| fontFamily: 'Tahoma,Helvetica,sans-serif', | |
| fontSize: '15px', | |
| marginLeft: '7px', | |
| opacity: '.7', | |
| cursor: 'pointer' | |
| }); | |
| close.addEventListener('click', audio.onCloseBtnClick, false); | |
| box.appendChild(close); | |
| return true; | |
| }, | |
| onBoxClick: function(event) | |
| { | |
| event.preventDefault(); | |
| event.stopPropagation(); | |
| var a = this.querySelector('a.' + downloadLinkClassName); | |
| if(a) | |
| { | |
| SaveFrom_Utils.click(a, event.ctrlKey, event.altKey, event.shiftKey, event.button); | |
| return false; | |
| } | |
| this.style.display = 'none'; | |
| return false; | |
| }, | |
| onDownloadLinkClick: function(event) | |
| { | |
| if(event.button == 2) | |
| return false; | |
| event.stopPropagation(); | |
| if(this.href == '#') | |
| { | |
| event.preventDefault(); | |
| return false; | |
| } | |
| SaveFrom_Utils.downloadOnClick(event); | |
| return false; | |
| }, | |
| onCloseBtnClick: function(event) | |
| { | |
| if(event.button == 2) | |
| return true; | |
| event.preventDefault(); | |
| event.stopPropagation(); | |
| parent = SaveFrom_Utils.getParentByClass(this, downloadLinkClassName); | |
| if(parent) | |
| parent.style.display = 'none'; | |
| return false; | |
| }, | |
| deleteLink: function(trackId, node) | |
| { | |
| if(!node && trackId) | |
| node = document.getElementById(audio.downloadIdPrefix + trackId); | |
| if(!node) | |
| return; | |
| var parent = SaveFrom_Utils.getParentByClass(node, downloadLinkClassName); | |
| if(parent) | |
| { | |
| parent.parentNode.removeChild(parent); | |
| return; | |
| } | |
| }, | |
| getHash: function(src, magic) | |
| { | |
| if(!magic) | |
| magic = [4,3,5,6,1,2,8,7,2,9,3,5,7,1,4,8,8,3,4,3,1,7,3,5,9,8,1,4,3,7,2,8]; | |
| var a = []; | |
| for(var i = 0; i < src.length; i++) | |
| { | |
| a.push(parseInt('0x0' + src.charAt(i))); | |
| } | |
| src = a; | |
| var res = []; | |
| src = src.slice(0); | |
| src[32] = src[31]; | |
| var sum = 0; | |
| var i = 32; | |
| while(i-- > 0) | |
| sum += src[i]; | |
| for(x = 0; x < 32; x++) | |
| res[x] = Math.abs(sum - src[x + 1] * src[x] * magic[x]); | |
| return res.join(''); | |
| }, | |
| setLinkFromCache: function(trackId, node) | |
| { | |
| if(!audio.cache[trackId]) | |
| return false; | |
| if(!node) | |
| node = document.getElementById(audio.downloadIdPrefix + trackId); | |
| if(!node) | |
| return; | |
| node.href = audio.cache[trackId].url; | |
| node.innerHTML = ''; | |
| if(audio.cache[trackId].downloadAttr) | |
| node.setAttribute('download', audio.cache[trackId].downloadAttr); | |
| var icon = document.createElement('img'); | |
| icon.src = SaveFrom_Utils.svg.getSrc('download', '#ffffff'); | |
| icon.title = chrome.i18n.getMessage('download'); | |
| SaveFrom_Utils.setStyle(icon, { | |
| width: '16px', | |
| height: '16px', | |
| verticalAlign: 'middle', | |
| opacity: '0.9' | |
| }); | |
| node.appendChild(icon); | |
| var info = document.createTextNode(audio.cache[trackId].info); | |
| if(node.nextSibling) | |
| node.parentNode.insertBefore(info, node.nextSibling); | |
| else | |
| node.parentNode.appendChild(info); | |
| return true; | |
| }, | |
| setLink: function(trackId, data, clientHash) | |
| { | |
| if(!trackId) | |
| return; | |
| window.clearTimeout(audio.ajaxTimer[trackId]); | |
| var node = document.getElementById(audio.downloadIdPrefix + trackId); | |
| if(!node) | |
| return; | |
| if(audio.setLinkFromCache(trackId, node)) | |
| return; | |
| if(!data || !data.play) | |
| { | |
| audio.deleteLink(trackId, node); | |
| node.innerHTML = '?'; | |
| return; | |
| } | |
| if(clientHash === undefined) | |
| { | |
| var md5 = data.play.match(/(?:\?|&)md5=([\da-f]{32})/i); | |
| if(md5 && md5.length > 1) | |
| { | |
| md5 = md5[1]; | |
| try | |
| { | |
| md5 = SaveFrom_Utils.md5(md5 + 'secret'); | |
| audio.setLink(trackId, data, audio.getHash(md5)); | |
| return; | |
| } | |
| catch(err) | |
| { | |
| } | |
| } | |
| audio.deleteLink(trackId, node); | |
| return; | |
| } | |
| var size = SaveFrom_Utils.getMatchFirst(data.play, /(?:\?|&)size=(\d+)/i); | |
| if(!size) | |
| return; | |
| audio.cache[trackId] = {}; | |
| audio.cache[trackId].url = data.play + (clientHash ? '&clientHash=' + clientHash : ''); | |
| var info = ' (' + SaveFrom_Utils.sizeHuman(size, 2); | |
| var duration = node.getAttribute('data-savefrom-helper-duration'); | |
| if(data.track) | |
| { | |
| if(data.track.duration) | |
| duration = data.track.duration; | |
| if(data.track.ensemble && data.track.name) | |
| { | |
| var title = data.track.ensemble + ' - ' + data.track.name; | |
| audio.cache[trackId].title = title; | |
| audio.cache[trackId].downloadAttr = SaveFrom_Utils.fileName.modify(title + '.mp3'); | |
| } | |
| } | |
| if(size && duration) | |
| { | |
| duration = parseInt(duration); | |
| if(isNaN(duration)) | |
| { | |
| delete audio.cache[trackId]; | |
| return; | |
| } | |
| var bitrate = Math.floor((size / duration) / 125) + ' ' + chrome.i18n.getMessage('kbps'); | |
| info += ' ~ ' + bitrate; | |
| } | |
| info += ')'; | |
| audio.cache[trackId].info = info; | |
| audio.setLinkFromCache(trackId, node); | |
| }, | |
| getTitle: function(id, row) | |
| { | |
| if(!id || !row) | |
| return ''; | |
| var name = ''; | |
| var performer = row.querySelector('.m_c_artist, .mus-tr_artist, .m_portal_c_artist'); | |
| var title = row.querySelector('.m_track_source, .mus-tr_song, .m_portla_track_name'); | |
| if(performer) | |
| { | |
| performer = performer.textContent; | |
| if(performer) | |
| name += SaveFrom_Utils.trim(performer); | |
| } | |
| if(title) | |
| { | |
| title = title.textContent; | |
| if(title) | |
| { | |
| if(name) | |
| name += ' - '; | |
| name += SaveFrom_Utils.trim(title); | |
| } | |
| } | |
| if(name) | |
| return name.replace(/\<a\s+[^\>]+\>/ig, '').replace(/\<\/a\>/ig, ''); | |
| return ''; | |
| }, | |
| secondsFromDurationNode: function(node) | |
| { | |
| if(!node) | |
| return 0; | |
| var text = node.innerText; | |
| if(!text) | |
| return 0; | |
| var m = text.match(/^(?:\s*(\d+)\s*\:)?\s*(\d+)\s*\:\s*(\d+)/); | |
| if(m && m.length > 3) | |
| { | |
| if(!m[1]) | |
| m[1] = 0; | |
| return parseInt(m[1]) * 3600 + parseInt(m[2]) * 60 + parseInt(m[3]); | |
| } | |
| return 0; | |
| }, | |
| showListOfAudioFiles: function(playlist) | |
| { | |
| } | |
| }; | |
| // /AUDIO | |
| /////////////////////////////////////////////////////////////////// | |
| /////////////////////////////////////////////////////////////////// | |
| // VIDEO | |
| var video = { | |
| popupTimer: 0, | |
| panelId: 'savefrom__ok_video_links_', | |
| panelCount: 0, | |
| parentDataAttr: 'data-savefrom-video-container', | |
| titleTimer: 0, | |
| style: {fontSize: '10pt', margin: '15px 0', padding: '0'}, | |
| inline: { | |
| 'feed_panel_activity': {selector: 'img.vid-card_img'}, | |
| 'share_card': {selector: 'img.vid-card_img'}, | |
| 'dsub': {selector: 'img.cthumb_img'}, | |
| 'd_comment_w_center': {selector: '.videomail_Thumb img', parent: true}, | |
| 'd_comment_right_w': {selector: '.vid-card_img_w img', parent: true}, | |
| 'media-layer-new_hld': {'selector': 'img.vid-card_img'} | |
| }, | |
| reImg: { | |
| 'getYoutubeLinks': /(?:\/|\.)ytimg\.com\/vi\/([\w\-]+)/i, | |
| 'getVimeoLinks': /(?:\/|\.)vimeocdn\.com\/ts\/(.+)/i, | |
| 'getOdnoklassnikiLinks': /\.mail\.ru\/media\/(OK_\d+_\d+)/i, | |
| 'getOdklLinks': /\.mycdn\.me\/getImage\?(?:.+&)?id=(\d+)/i, | |
| 'getDailymotionLinks': /\.dmcdn\.net\/(\w+)\//i | |
| }, | |
| appendButton: function(links, title, style, request, parent, parentClass) | |
| { | |
| if(!parent) | |
| return; | |
| if(parent.getAttribute(video.parentDataAttr)) | |
| return; | |
| parent.setAttribute(video.parentDataAttr, '1'); | |
| if(!parentClass || !video.inline[parentClass] || !video.inline[parentClass].parent) | |
| { | |
| var newParent = parent.querySelector('ul.controls-list'); | |
| if(!newParent) | |
| return; | |
| parent = newParent; | |
| } | |
| if(parent.querySelector('.' + downloadLinkClassName)) | |
| return; | |
| var box = document.createElement('li'); | |
| box.className = downloadLinkClassName + ' controls-list_item'; | |
| var a = document.createElement('a'); | |
| a.href = '#'; | |
| a.className = 'al'; | |
| a.textContent = chrome.i18n.getMessage('download'); | |
| a.style.fontWeight = 'bold'; | |
| box.appendChild(a); | |
| parent.appendChild(box); | |
| var panel = document.createElement('div'); | |
| panel.className = downloadLinkClassName + ' al'; | |
| panel.id = video.panelId + video.panelCount; | |
| video.panelCount++; | |
| panel.style.textDecoration = 'none'; | |
| a.setAttribute('data-savefrom-video-box', panel.id); | |
| var panelParent = parent, popupPlayer = false; | |
| if(SaveFrom_Utils.hasClass(parent, 'vp_ac')) | |
| { | |
| panel.style.display = 'none'; | |
| style.backgroundColor = '#d0d0d0'; | |
| style.padding = '10px 0'; | |
| panelParent = parent.parentNode.parentNode; | |
| var player = SaveFrom_Utils.getElementByIds( | |
| ['VideoPopup_playerObject', 'VideoPopup_player']); | |
| if(player) | |
| { | |
| popupPlayer = true; | |
| panelParent = player.parentNode; | |
| style.margin = '0'; | |
| style.position = 'absolute'; | |
| style.bottom = '50px'; | |
| style.left = 0; | |
| style.right = 0; | |
| style.zIndex = 10; | |
| } | |
| } | |
| if(popupPlayer) | |
| { | |
| panelParent.appendChild(panel); | |
| } | |
| else if(panelParent.nextSibling) | |
| { | |
| panelParent.parentNode.insertBefore(panel, panelParent.nextSibling); | |
| } | |
| else | |
| { | |
| panelParent.parentNode.appendChild(panel); | |
| } | |
| a.addEventListener('click', function(event){ | |
| event.stopPropagation(); | |
| event.preventDefault(); | |
| var node = event.target; | |
| var id = node.getAttribute('data-savefrom-video-box'); | |
| if(!id) | |
| return; | |
| var panel = document.getElementById(id); | |
| if(!panel) | |
| return; | |
| if(panel.getAttribute('data-savefrom-video') == 'active') | |
| { | |
| panel.style.display = (panel.style.display == 'none') ? 'block' : 'none'; | |
| return false; | |
| } | |
| panel.setAttribute('data-savefrom-video', 'active'); | |
| panel.style.display = 'block'; | |
| if(links) | |
| { | |
| video.count++; | |
| video.show(links, title, panel, style); | |
| } | |
| else if(request) | |
| { | |
| video.show('<img src="data:image/gif;base64,R0lGODlhHgAKAKEAAPz+3Pz+/Pz+5P///yH/C05FVFNDQVBFMi4wAwEAAAAh+QQIAwAAACwAAAAAHgAKAAACQpwTpovrrYIQQCQ2643ZjgCE4gaKIWmeVCooq9karzibVyoe+D4avL6rVVy42EBowaFSS9tn5cGEopzp5nN9ZBmbAgAh+QQIAwAAACwAAAAAHgAKAIL8/rz8/uT8/tT8/vT8/sT8/tz8/vz///8DWXhqpv7syeiGIESMGUIJDdR9zUAAKEBsS+G+4TG8sJCmguPRn85/J1WKEPq5FjteEHUiKoyFltEmROUUyVfAxwuYbiuH4Rcb80qXDEu8A3FcbnFMcqDQ67EEACH5BAgDAAAALAAAAAAeAAoAg/z2pPz+3Pz+vPz+9Pz6pPz+5Pz+xPz+/Pz6rP///wAAAAAAAAAAAAAAAAAAAAAAAAReMMlzpL306myHQIgwbEURFBVWntVAEEBMjNIQ3Hia2Ph9CADYCyCwmHqnDvIkDMpSy9skGhgKX9DoNApsEo3LghJZcDlftN1Sx+u1BC+BWHVDaQbH8mWQ1iQ4fn86EQAh+QQIAwAAACwAAAAAHgAKAIP82oT8/tz86qz8/vz84oz8+uz83oz8/uT///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAEVRDJMaS99OpsiyCEUGzHERwVVp5VYQAwYIxTYN8pMty4EMcCi4l3EhJPr58sdbTVmkkls/k8+pRByZB3MBIPLiVNd8ztiC2BwSAi2VBuFian0dE3uQgAIfkECAMAAAAsAAAAAB4ACgCD/Lpk/Pbk/NaU/MJs/P78/P7c/MZ0/L5k/MJ0/P7k////AAAAAAAAAAAAAAAAAAAABGBQSUKkvfTqbIMwiBBsSVIkFVaeVWAAMICMU2HfqULcuAAfAKDAYuKdiMbTIMg8HFJFYy1ZWAKviBS1ME36gL+hJHpLII2JAOJ6mFl2xhyc1/qEaO8iimTbv3MaOoAbOREAIfkECAMAAAAsAAAAAB4ACgCD/J5E/PLk/MKE/KZU/P7c/KpU/P78/J5M/P7k/Kpc////AAAAAAAAAAAAAAAAAAAABF9QSWOkvfTqbIMoiRBsCEEgFYaUqBIUBxAX42TeRKoYuGkIAFnwILCUeghj7zQQxgCD1NJkmzZjh1hUMiVUl8CnrCg54pLlJeIlm9V2Sx2vV/GARCRTS6XX7fwbgBg6EQAh+QQIAwAAACwAAAAAHgAKAIPsgiz87tz8rmz0jjz8/tz8/vz0ijT8rnT0kjz8/uT///8AAAAAAAAAAAAAAAAAAAAEW1DJUqS99Opsw0HIEWwJQSQVlpSoEgxADAzjZN5EqhS4WQgymcBS6iWIvZMhGDOkkiYbdMl0SqAEaRLIHEqKuOM3mXgFaRZeT6fGVTwgQS1dbKlM9olOs9tvdBEAIfkECAMAAAAsAAAAAB4ACgCD/J5E/P68/PLk/MKE/KZU/P7U/P7k/KpU/P70/J5M/P7E/P7c/Kpc/P78////AAAABHPQydakvfTqbMU4zCBoSKEoBbIZxmJUwpEA8zFKiBLsgaJOi6CwMQDQjImBpcDjFSwtYdBAOM4AhIqjqesBpcLqLDHLSnTdXuALXhSvNKWEues+JVGpIUar3Rw5XD8ODW0wHyF/OCYogxNRLxiOG1oaE5URACH5BAgDAAAALAAAAAAeAAoAhPy6ZPz2pPz25PzWlPz+9PzCbPz+vPz+3Pz6pPzGdPz+7Py+ZPz+/PzCdPz+xPz+5Pz6rP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAV+YCQyjGie5KmmpjAkzSCohAFBBrE+z/GUggRgCGjMRAREIKBE6JCHqJQxGC4A14HJwOwiDKaeNPooYM+LRSnSXDZH47H5Sm+sm20EPB6tXq1aIlxuS2AiYmMPAg10C0YmSV4ICiYMfEAvMUcmCgYIXw87ZGsjpCoRDE+nqKQhACH5BAgDAAAALAAAAAAeAAoAg/zahPz+3PzqrPz+/PzijPz67PzejPz+5P///wAAAAAAAAAAAAAAAAAAAAAAAAAAAARfEMkxpL306myLIIRQaB4obscRHFVhADBgjNLxxrM1BHw/CLGYwAIMAoa1Xs9mlFUQTdhEqbwZn1bclMorBpEIr9Cioh5cRhqi0FTvqC2BwXC6eOZ1XZmFeWomfn8cCBEAIfkECAMAAAAsAAAAAB4ACgCE/Lpk/Pak/Pbk/NaU/MJs/P68/P70/Pqk/P7c/MZ0/L5k/MJ0/P7E/P78/Pqs/P7k////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABX0gJDaNaJ7kqaamUThOYajCkCyDsD4P8pSGwyFAPMxEgoUCsFzoRoiotFEIDIWBgmkA6DIBg5ZU+rhaiyUIgblcEqBjKfYqTBPa3zekEZdWzVlbXl5hIgZ9D0FnQkcQAncKkU5icUAFQgUPNAMLOE8mDT0+jRAGpCtpKiOpIQAh+QQIAwAAACwAAAAAHgAKAIP8nkT8/rz88uT8woT8plT8/tT8/uT8/vT8nkz8/sT8qlz8/tz8/vz///8AAAAAAAAEdbBJxqS99OpsT0lJcWjCoCiDsBnLYlRHEsxBMkqCAuyIokqHlnDBKNBoBcuAtwMMLKyhS1ajJSoNAgCx5RImUiF1JrtKtNz0t8EIt4zVWVKy3DafkujQEDvaLAIEaT0/bGEwHyE3gCYohUBRLxhYGkCLlRwNEQAh+QQIAwAAACwAAAAAHgAKAIPsgiz87tz8rmz0jjz8/tz8/vz0ijT8rnT0kjz8/uT///8AAAAAAAAAAAAAAAAAAAAEWVDJUqS99OpsS0pEUl3BgSBHsIFhVRBwPCrBANzAoE6xzPYJiwCHE1h+MWTPZSDeDK6edEpgOgFQxYuqDAmvRklXNJ3ViLpOWcsSaQKCk2DXac+0900eM4sAACH5BAgDAAAALAAAAAAeAAoAg/yeRPz+vPzy5PzChPymVPz+1Pz+5Pz+9PyeTPz+xPyqXPz+3Pz+/P///wAAAAAAAAR2sEnGpL306myZMYtRXcKgKIOgHUWSFEfDLHQ9NoICAAigqJJDIkAMJA6gGs1gGex6u4GlUCwWlMoRgcfrESZVoxFrk2yh3slwWEwklUyJk8uTSqhiYmGGvQkIPQgIPxZCRGsxHks3EiUnKRogLjAYjCsxGh03EQAh+QQIAwAAACwAAAAAHgAKAIT8umT89qT89uT81pT8wmz8/rz8/vT8+qT8/tz8xnT8vmT8wnT8/sT8/vz8+qz8/uT///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFfyAkNo1onuSppmbzPMhTnsKQLIOgGoXjFAZIA0EsziCChQKwXOhEhsMhQD0YYEXiwzQAeJmAgakQmEoDhWx2RmAul4SRo1wtq40iwhscF5rpUgZ3WyJdX15iImR/aIJqR0kKkgpOJlF1B1suWkciNQs4T5YFUgWEI50rqShBIiEAIfkECAMAAAAsAAAAAB4ACgCD/NqE/P7c/Oqs/P78/OKM/Prs/N6M/P7k////AAAAAAAAAAAAAAAAAAAAAAAAAAAABGEQyTGkvfTqbMc5wVFdhUAQQqGVZ4oMQSyPyGEAOGCokp3rBZAsdrAIfjiBEQkQDIejG3PCxD1nEunPMNH+hMOi5IhUjpkC2JNW8AJ4iAJT5SHSJCWDwUUS6PkTdxuCGDQRACH5BAgDAAAALAAAAAAeAAoAhPy6ZPz2pPz25PzWlPz+9PzCbPz+vPz+3Pz6pPzGdPz+7Py+ZPz+/PzCdPz+xPz+5Pz6rP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAV9YCQyjGie5KmmJvM8x1OeigNBBqEKQ9IMggjjQCzOIgpIIIBg6kSCBGABADQUsCLxYXI0vwGDaVCdVgda7QzMZI6oCzigkDaKvmDEqGCGFxR1XCIGS21hY2ZlAwR1RwoIeQomAg1yDUEuW0ciCgaQBoKTPT+SLZsrTyojRyEAIfkECAMAAAAsAAAAAB4ACgCD/J5E/P68/PLk/MKE/KZU/P7U/P7k/KpU/P70/J5M/P7E/P7c/Kpc/P78////AAAABHbQydakvfTqbJsxi1FdSKEoBaIJA3MMgtMsdD06iBLsgaJKgkMCMGQIQDWawVLg8QqWAYBIHSSTI11vq5gQqEMA4WqTaJ1d2XfIPiCTS0lzu4NKpOHhYHa95XY6PhZBREMHMR5KNxIlJykrAwcMMBiLG5YYPw4RACH5BAgDAAAALAAAAAAeAAoAg+yCLPzu3PyubPSOPPz+3PSKNPz+/PyudPSSPPz+5PSKPP///wAAAAAAAAAAAAAAAARdcEljpL306mxNSkRSYV84WsGBIEewGEQsn7Acn8EA7MAQgLaQBWhLWAQ8niA4kzBjE10SUHgSRtZJYUolyowSbwy8OHAFNRuNiZPufC+gaCM/SQKClcDVsW/8GCcRACH5BAgDAAAALAAAAAAeAAoAg/yeRPzy5PzChPymVPz+3PyqVPz+/PyeTPz+5PyqXP///wAAAAAAAAAAAAAAAAAAAARhUEljpL306mwNQgRSYV84WoGQFEKgGEQsn7Acn0EBHAeQBCBbyBK0ISyCHUApEM4kzthkoOwBBlHCKDut7gpF2VESjo0VyZ5VULPRnLiC2ufymE+ToEiTKiRaGHgbgoEWEQAh+QQIAwAAACwAAAAAHgAKAIP8umT89uT81pT8wmz8/vz8/tz8xnT8vmT8wnT8/uT///8AAAAAAAAAAAAAAAAAAAAEX1BJQqS99OpsSUpFUmFfOFqBYCBCoBBFLJ+wHJ+BARwAgAQgW8gStCUsgt5uJxDOJM7YZLDjVaOFEXa6PPAQRdlREo6NFUkrs2ajOXEI3tflMZ8mQZEmtWph7huAfxYRACH5BAgDAAAALAAAAAAeAAoAg/zahPz+3PzqrPz+/PzijPz67PzejPz+5P///wAAAAAAAAAAAAAAAAAAAAAAAAAAAARbEMkxpL306mzHOcFRYV84WoVAEEKBDEEsn7Acn4cB7IBRgLaQBWg7WAQ8niA4kzBjE11y9wyMqtHpjigzSrgxLwI5FdRsNOapIOW5POHTBCjSpAyGFka+4e8tEQAh+QQIAwAAACwAAAAAHgAKAIP89qT8/tz8/rz8/vT8+qT8/uT8/sT8/vz8+qz///8AAAAAAAAAAAAAAAAAAAAAAAAEXDDJc6S99OpsTylBUWFfOFqDgCDCkBxBLJ+DPKMEAezEANohFDAoEQB0OYBgGBsxAxMk7/h0MieIozZXAxaEXotRquzaaEOabvv1xEQa39t1SeUE385J89pv6AkRACH5BAgDAAAALAAAAAAeAAoAgvz+vPz+5Pz+1Pz+9Pz+xPz+3Pz+/P///wNZeGqm/uzJ6EwIJTR483aDQBDCcBhFqn6DuoIEIAPEgLmZc7uBI8wzAe512LkWMZqSMExtmgUkUEYwpnoKa07xS8YEKNwn7GJ5aSbL9bO4aSShUQnCntTpjgQAOw=="/>', | |
| '', panel, style); | |
| if(request.action == 'getOdklLinks') | |
| { | |
| video.getOdklLinks(panel.id, request); | |
| } | |
| else | |
| { | |
| chrome.extension.sendRequest(request, function(response){ | |
| showVideoLinks(panel.id, response); | |
| }); | |
| } | |
| } | |
| return false; | |
| }, false); | |
| }, | |
| show: function(links, title, parent, style, action) | |
| { | |
| if(!parent) | |
| return; | |
| SaveFrom_Utils.emptyNode(parent); | |
| if(!links || links.length == 0) | |
| { | |
| parent.appendChild(document.createTextNode(chrome.i18n.getMessage('noLinksFound'))); | |
| return; | |
| } | |
| if(action == 'getYoutubeLinks') | |
| { | |
| SaveFrom_Utils.video.yt.init(prefs); | |
| SaveFrom_Utils.video.yt.show(links, parent, prefs.moduleShowDownloadInfo, { | |
| link: {color: '#eb722e', 'line-height': 'normal'}, | |
| text: null, | |
| btn: {color: '#777', borderColor: '#555', fontSize: '95%'}, | |
| fsIcon: {opacity: '.5'}, | |
| fsText: {fontSize: '80%', 'line-height': 'normal'} | |
| }, title); | |
| return; | |
| } | |
| if(title) | |
| title = SaveFrom_Utils.trim(title.replace(/\x2B+/g, ' ')); | |
| var html = false; | |
| if(typeof(links) == 'string') | |
| html = true; | |
| else if(links.length == 0) | |
| return; | |
| SaveFrom_Utils.setStyle(parent, { | |
| color: '#555', | |
| display: 'block', | |
| float: 'none', | |
| fontSize: '11pt', | |
| fontWeight: 'bold', | |
| margin: '15px 0', | |
| padding: '0', | |
| textAlign: 'center' | |
| }); | |
| if(style && typeof(style) == 'object') | |
| SaveFrom_Utils.setStyle(parent, style); | |
| if(html) | |
| { | |
| parent.innerHTML = links; | |
| return; | |
| } | |
| parent.appendChild(document.createTextNode(chrome.i18n.getMessage('download') + ':')); | |
| var color = ''; | |
| for(var i = 0; i < links.length; i++) | |
| { | |
| var a = null; | |
| if(typeof(links[i]) == 'object' && links[i].url) | |
| { | |
| var ext = links[i].ext; | |
| if(!ext) | |
| { | |
| ext = 'FLV'; | |
| if(links[i].url.search(/\.mp4$/i) != -1) | |
| ext = 'MP4'; | |
| } | |
| var name = links[i].name ? links[i].name : ext; | |
| a = createTextLink(links[i].url, name); | |
| if(title && !links[i].noTitle) | |
| { | |
| a.setAttribute('download', SaveFrom_Utils.fileName.modify( | |
| title + '.' + ext.toLowerCase())); | |
| a.addEventListener('click', SaveFrom_Utils.downloadOnClick, false); | |
| } | |
| if(links[i].subname) | |
| { | |
| var st = document.createElement('span'); | |
| SaveFrom_Utils.setStyle(st, { | |
| fontSize: '80%', | |
| fontWeight: 'normal', | |
| marginLeft: '3px' | |
| }); | |
| st.innerText = links[i].subname; | |
| a.appendChild(st); | |
| } | |
| } | |
| else | |
| { | |
| var ext = 'FLV'; | |
| if(links[i].search(/\.mp4$/i) != -1) | |
| ext = 'MP4'; | |
| var name = ext; | |
| q = SaveFrom_Utils.getMatchFirst(links[i], /\.(\d+)\.mp4/i); | |
| if(q) | |
| name += ' (' + q + ')'; | |
| a = createTextLink(links[i], name); | |
| if(title) | |
| { | |
| a.setAttribute('download', SaveFrom_Utils.fileName.modify( | |
| title + '.' + ext.toLowerCase())); | |
| a.addEventListener('click', SaveFrom_Utils.downloadOnClick, false); | |
| } | |
| } | |
| if(a) | |
| { | |
| a.style.marginLeft = '10px'; | |
| a.style.lineHeight = 'normal'; | |
| a.title = chrome.i18n.getMessage('downloadTitle'); | |
| parent.appendChild(a); | |
| SaveFrom_Utils.appendFileSizeIcon(a, | |
| {opacity: '.5'}, | |
| {fontSize: '80%', opacity: '.9', 'line-height': 'normal'}); | |
| if(!color) | |
| color = SaveFrom_Utils.getStyle(a, 'color'); | |
| } | |
| } | |
| if(prefs.moduleShowDownloadInfo == '1') | |
| { | |
| if(!color) | |
| color = '#a0a0a0'; | |
| parent.appendChild(document.createElement('br')); | |
| SaveFrom_Utils.appendDownloadInfo(parent, color); | |
| } | |
| }, | |
| showExternalLinks: function(vid, action, title, parent, parentClass) | |
| { | |
| video.appendButton('', '', video.style, { | |
| action: action, | |
| extVideoId: vid, | |
| title: title | |
| }, parent, parentClass); | |
| }, | |
| getMetadata: function(url, cb) { | |
| if (!url) { | |
| return; | |
| } | |
| SaveFrom_Utils.sendRequest(url, function(r) { | |
| if (r.status !== 200) { | |
| return; | |
| } | |
| try { | |
| var data = JSON.parse(r.responseText); | |
| return cb(data); | |
| } catch (e) {} | |
| }); | |
| }, | |
| appendVideoLink: function(provider, vid, metadata, parent) { | |
| if(!provider || !vid) { | |
| return; | |
| } | |
| var action = undefined; | |
| switch(provider) | |
| { | |
| case 'user_youtube': | |
| if(!prefs.lite) | |
| { | |
| action = 'getYoutubeLinks'; | |
| } | |
| break; | |
| case 'open_graph': | |
| vid = SaveFrom_Utils.getMatchFirst(vid, /clip_id=(\w+)/i); | |
| action = 'getVimeoLinks'; | |
| break; | |
| case 'uploaded': | |
| action = 'getOdnoklassnikiLinks'; | |
| break; | |
| case 'uploaded_odkl': | |
| if(metadata.movie && metadata.movie.movieId) | |
| { | |
| vid = metadata.movie.movieId; | |
| action = 'getOdklLinks'; | |
| } | |
| break; | |
| } | |
| if(action !== undefined) | |
| { | |
| video.showExternalLinks(vid, action, '', parent); | |
| } | |
| }, | |
| showLinks: function() | |
| { | |
| window.clearInterval(video.titleTimer); | |
| var node = document.querySelectorAll('*[' + video.parentDataAttr + '="1"]'); | |
| if(node && node.length > 0) | |
| { | |
| for(var i = 0; i < node.length; i++) | |
| node[i].removeAttribute(video.parentDataAttr); | |
| } | |
| node = null; | |
| var parent = SaveFrom_Utils.getElementByIds(['vp_w', 'videoPlayerPanel']); | |
| if(parent && !parent.getAttribute(video.parentDataAttr)) | |
| { | |
| node = parent.querySelectorAll('param[name="flashvars"]'); | |
| for(var i = 0; i < node.length; i++) | |
| { | |
| var vid = undefined, metadata = undefined, | |
| provider = SaveFrom_Utils.getMatchFirst(node[i].value, /providerId=(\w+)/); | |
| if(provider) | |
| { | |
| provider = provider.toLowerCase(); | |
| var vid = SaveFrom_Utils.getMatchFirst(node[i].value, /movieId=([\w\-]+)/); | |
| } | |
| else | |
| { | |
| var md = SaveFrom_Utils.getMatchFirst(node[i].value, /metadata=([^&\s]+)/); | |
| if(md) | |
| { | |
| md = decodeURIComponent(md); | |
| md = JSON.parse(md); | |
| if(md) | |
| { | |
| metadata = md; | |
| if(md.provider && md.movie && md.movie.contentId) | |
| { | |
| provider = md.provider.toLowerCase(); | |
| vid = md.movie.contentId; | |
| } | |
| } | |
| } | |
| md = SaveFrom_Utils.getMatchFirst(node[i].value, /metadataUrl=([^&\s]+)/); | |
| if(md) { | |
| this.getMetadata(decodeURIComponent(md), function(data) { | |
| if (data === undefined || data.provider === undefined || data.movie === undefined) { | |
| return; | |
| } | |
| video.appendVideoLink(data.provider.toLowerCase(), data.movie.contentId, data, parent); | |
| }); | |
| } | |
| } | |
| this.appendVideoLink(provider, vid, metadata, parent); | |
| } | |
| } | |
| var result = false; | |
| for(var i in video.inline) | |
| { | |
| var node = document.querySelectorAll('.' + i + ' ' + | |
| video.inline[i].selector); | |
| for(var j = 0; j < node.length; j++) | |
| { | |
| video.handleInlineVideo(node[j], null, i); | |
| } | |
| } | |
| video.catchPopupLinks(); | |
| return result; | |
| }, | |
| handleInlineVideo: function(node, parent, parentClass) | |
| { | |
| var src = node.src; | |
| if(!src) | |
| return; | |
| var msg = ''; | |
| for(var k in video.reImg) | |
| { | |
| var vid = SaveFrom_Utils.getMatchFirst(src, video.reImg[k]); | |
| if(vid) | |
| { | |
| var title = node.alt; | |
| if(!parent) | |
| parent = SaveFrom_Utils.getParentByClass(node, parentClass); | |
| if (!parent) { | |
| continue; | |
| } | |
| if(k == 'getOdklLinks') | |
| { | |
| var mid = video.findMetaDataId(parent); | |
| if(mid) | |
| vid = mid; | |
| } | |
| else if(k == 'getVimeoLinks') | |
| { | |
| var vid = video.findMetaDataId(parent, /clip_id=(\w+)/i); | |
| } | |
| else if (k === 'getDailymotionLinks') | |
| { | |
| vid = video.findMetaDataId(parent, /dailymotion\.com\/swf\/video\/(\w+)\??/i); | |
| } | |
| if(vid) | |
| video.showExternalLinks(vid, k, title, parent, parentClass); | |
| break; | |
| } | |
| } | |
| }, | |
| findMetaDataId: function(parent, regexp) | |
| { | |
| var info = '', keyRe = /videoPlayerMetadata|metadata/i; | |
| var node = parent.querySelectorAll('div[data-query],span[data-query]'); | |
| if(node && node.length > 0) | |
| { | |
| for(var i = 0; i < node.length; i++) | |
| { | |
| var q = node[i].getAttribute('data-query'); | |
| if(q.search(keyRe) > -1) | |
| { | |
| info = q; | |
| break; | |
| } | |
| } | |
| } | |
| if(!info) | |
| { | |
| node = parent.querySelectorAll('div[onclick],span[onclick]'); | |
| for(var i = 0; i < node.length; i++) | |
| { | |
| var q = node[i].getAttribute('onclick'); | |
| if(q.search(keyRe) > -1) | |
| { | |
| info = q; | |
| break; | |
| } | |
| } | |
| } | |
| if(!info) | |
| return ''; | |
| info = SaveFrom_Utils.decodeHTML(info); | |
| info = decodeURIComponent(info); | |
| return SaveFrom_Utils.getMatchFirst(info, regexp || /(?:\?|&)mid=(\d+)/i); | |
| }, | |
| catchPopupLinks: function() | |
| { | |
| document.removeEventListener('mousedown', video.onVideoClick, false); | |
| document.addEventListener('mousedown', video.onVideoClick, false); | |
| document.removeEventListener('mouseover', video.onVideoHover, false); | |
| document.addEventListener('mouseover', video.onVideoHover, false); | |
| var loc = document.location.href; | |
| video.titleTimer = window.setInterval(function(){ | |
| if(document.location.href != loc) | |
| { | |
| loc = document.location.href; | |
| window.clearInterval(video.titleTimer); | |
| video.showLinks(); | |
| } | |
| }, 3000); | |
| }, | |
| onVideoClick: function(event) | |
| { | |
| var node = event.target; | |
| if(node.tagName != 'A') | |
| { | |
| for(var parent = node; parent; parent = parent.parentNode) | |
| { | |
| if(parent.tagName == 'A') | |
| { | |
| node = parent; | |
| break; | |
| } | |
| } | |
| } | |
| if(node.tagName != 'A') | |
| return; | |
| if(node.href && node.href.search(/((?:\?|&)cmd=PopLayerMovie|\/video\/\d+)/i) > -1) | |
| { | |
| setTimeout(function(){ | |
| var node = SaveFrom_Utils.getElementByIds(['VideoPopup_player', 'videoPlayerPanel']); | |
| if(node) | |
| video.catchPopup(); | |
| }, 1000); | |
| return; | |
| } | |
| if(node.getAttribute('hrefattrs')) | |
| { | |
| setTimeout(function(){ | |
| video.catchPopup(); | |
| }, 1000); | |
| return; | |
| } | |
| }, | |
| catchPopup: function(event) | |
| { | |
| clearTimeout(video.popupTimer); | |
| video.popupTimer = setTimeout(function(){ | |
| clearTimeout(video.popupTimer); | |
| video.showLinks(); | |
| }, 2000); | |
| }, | |
| onVideoHover: function(event) | |
| { | |
| var node = event.target; | |
| if(node.tagName = 'IMG' && node.src) | |
| { | |
| for(var i in video.inline) | |
| { | |
| if(SaveFrom_Utils.matchesSelector(node, video.inline[i].selector)) | |
| { | |
| video.handleInlineVideo(node, null, i); | |
| return; | |
| } | |
| } | |
| } | |
| }, | |
| getOdklLinks: function(parentId, request) | |
| { | |
| var url = '/dk?cmd=videoPlayerMetadata&mid=' + request.extVideoId + | |
| '&rnd=' + (new Date()).getTime() + Math.random(); | |
| var response = request; | |
| SaveFrom_Utils.sendRequest(url, function(r){ | |
| if(r.status == 200 && r.responseText) | |
| { | |
| try | |
| { | |
| var md = JSON.parse(r.responseText); | |
| if(md && md.videos && md.videos.length > 0) | |
| { | |
| if (md.provider === 'USER_YOUTUBE') { | |
| var v = md.videos[0].url; | |
| var vId = v.substr(v.lastIndexOf('/')+1); | |
| var request = { | |
| action: 'getYoutubeLinks', | |
| extVideoId: vId | |
| }; | |
| chrome.extension.sendRequest(request, function(response){ | |
| showVideoLinks(parentId, response); | |
| }); | |
| return; | |
| } | |
| var links = []; | |
| for(var i = 0; i < md.videos.length; i++) | |
| { | |
| var v = md.videos[i]; | |
| if(v.url && v.url.search(/^https?:\/\//i) > -1) | |
| { | |
| links.push({ | |
| url: v.url, | |
| subname: v.name ? v.name : '', | |
| ext: 'MP4' | |
| }); | |
| } | |
| } | |
| if (md.movie !== undefined && md.movie.title) { | |
| response.title = md.movie.title; | |
| } | |
| if(links) | |
| { | |
| response.links = links; | |
| } | |
| } | |
| } | |
| catch(err){} | |
| } | |
| showVideoLinks(parentId, response); | |
| }, '', url); | |
| } | |
| }; | |
| // /VIDEO | |
| /////////////////////////////////////////////////////////////////// | |
| var odnoklassniki = { | |
| run: function() | |
| { | |
| audio.showLinks(); | |
| video.showLinks(); | |
| video.catchPopup(); | |
| } | |
| }; | |
| SaveFrom_Utils.initModule(moduleName, function(response) { | |
| //console.log('odnoklassniki', response); | |
| if (response.moduleEnable) | |
| { | |
| prefs = response; | |
| SaveFrom_Utils.runModule(response, odnoklassniki); | |
| } | |
| }); | |
| }; | |
| _modules.savefrom = function(){ | |
| if(window.top != window.self) | |
| return; | |
| if(window.location.href.search(/savefrom\.net\/(index\.php|user\.php|\d+-[^\/]+\/|articles\/.+)?(\?|#|$)/i) == -1) | |
| return; | |
| window.savefrom__lm = {}; | |
| var moduleName = 'savefrom', | |
| prefs = {}; | |
| var savefrom = { | |
| name: moduleName, | |
| scriptId: 'savefrom__ext_script', | |
| dataAttr: 'data-extension-disabled', | |
| run: function() | |
| { | |
| savefrom.setExtParams(); | |
| if(!prefs.moduleEnable) | |
| return; | |
| var form = document.getElementById('sf_form'); | |
| if(!form) | |
| return; | |
| form.addEventListener('submit', function(event){ | |
| var url = form.sf_url.value; | |
| if(!url) | |
| return; | |
| if(form.getAttribute(savefrom.dataAttr) == '1') | |
| return; | |
| var re = { | |
| getVKLinks: [ | |
| /^https?:\/\/(?:[a-z]+\.)?(?:vk\.com|vkontakte\.ru)\/(video-?\d+_-?\d+)/i, | |
| /^https?:\/\/(?:[a-z]+\.)?(?:vk\.com|vkontakte\.ru)\/video_ext.php\?(.*oid=-?\d+.*)$/i, | |
| /^https?:\/\/(?:[a-z]+\.)?(?:vk\.com|vkontakte\.ru)\/[\w\-]+\?.*z=(video-?\d+_-?\d+)/i | |
| ], | |
| getYoutubeLinks: [ | |
| /^https?:\/\/(?:[a-z]+\.)?youtube\.com\/(?:#!?\/)?watch\?.*v=([\w\-]+)/i, | |
| /^https?:\/\/(?:[a-z0-9]+\.)?youtube\.com\/(?:embed|v)\/([\w\-]+)/i, | |
| /^https?:\/\/(?:[a-z]+\.)?youtu\.be\/([\w\-]+)/i | |
| ], | |
| getVimeoLinks: [ | |
| /^https?:\/\/(?:[\w\-]+\.)?vimeo\.com\/(?:\w+\#)?(\d+)/i, | |
| /^https?:\/\/player\.vimeo\.com\/video\/(\d+)/i | |
| ], | |
| getDailymotionLinks: [ | |
| /^http:\/\/dai\.ly\/([a-z0-9]+)_?/i, | |
| /^https?:\/\/(?:[\w]+\.)?dailymotion\.com(?:\/embed)?\/video\/([a-z0-9]+)_?/i | |
| ] | |
| }; | |
| for(var i in re) | |
| { | |
| for(var j = 0; j < re[i].length; j++) | |
| { | |
| var vid = url.match(re[i][j]); | |
| if(vid && vid.length > 1) | |
| { | |
| vid = vid[1]; | |
| var playlist = SaveFrom_Utils.getMatchFirst(url, /list=([\w\-]+)/i); | |
| event.preventDefault(); | |
| event.stopPropagation(); | |
| var request = { | |
| extVideoId: vid, | |
| action: i, | |
| checkSubtitles: true, | |
| checkLinks: true | |
| }; | |
| chrome.extension.sendRequest(request, function(r){ | |
| savefrom.setLinks(r.action, r.extVideoId, r.links, r.title, null, | |
| r.subtitles, playlist, r.duration, r.thumb, r.checkLinks); | |
| }); | |
| return false; | |
| } | |
| } | |
| } | |
| }, false); | |
| document.body.addEventListener('click', function(event){ | |
| var node = event.target; | |
| if(node.tagName != 'A') | |
| { | |
| if(node.parentNode.tagName == 'A') | |
| node = node.parentNode; | |
| else | |
| return; | |
| } | |
| var vid = node.getAttribute('data-video-id'); | |
| if(!vid) | |
| return; | |
| if(node.getAttribute(savefrom.dataAttr) == '1') | |
| return; | |
| var action = {vk: 'getVKLinks', yt: 'getYoutubeLinks'}; | |
| vid = vid.split(':', 2); | |
| if(vid.length != 2 || !action[vid[0]]) | |
| return; | |
| event.preventDefault(); | |
| event.stopPropagation(); | |
| node.style.display = 'none'; | |
| if(!node.id) | |
| { | |
| node.id = vid[0] + '_' + vid[1] + '_' + (Math.random() * 1000) + | |
| '_' + (new Date()).getTime(); | |
| } | |
| var request = { | |
| extVideoId: vid[1], | |
| action: action[vid[0]], | |
| checkSubtitles: true, | |
| checkLinks: true | |
| }; | |
| chrome.extension.sendRequest(request, function(r){ | |
| savefrom.setLinks(r.action, r.extVideoId, r.links, r.title, node, | |
| r.subtitles, null, r.duration, r.thumb, r.checkLinks); | |
| }); | |
| return false; | |
| }, true); | |
| }, | |
| setExtParams: function() | |
| { | |
| var s = document.createElement('script'); | |
| s.id = 'savefrom__ext_params'; | |
| s.type = 'text/javascript'; | |
| var params = { | |
| id: prefs.lite ? 'chromelite' : 'chrome', | |
| version: prefs.version, | |
| userjs: true, | |
| enable: prefs.moduleEnable | |
| }; | |
| s.text = 'try{' + | |
| 'if(window.setBrowserExtension && typeof setBrowserExtension == "function"){' + | |
| 'setBrowserExtension(' + JSON.stringify(params) + ');}' + | |
| '}catch(err){}'; | |
| document.body.appendChild(s); | |
| }, | |
| setLinks: function(action, vid, links, title, btn, subtitles, playlist, | |
| duration, thumb, valid) | |
| { | |
| if(valid === false) | |
| { | |
| savefrom.handleError(btn); | |
| return; | |
| } | |
| switch(action) | |
| { | |
| case 'getYoutubeLinks': | |
| savefrom.setYoutubeLinks(vid, links, title, btn, subtitles, | |
| playlist, duration, thumb); | |
| break; | |
| case 'getVKLinks': | |
| savefrom.setVKLinks(vid, links, title, btn, duration, thumb); | |
| break; | |
| case 'getVimeoLinks': | |
| savefrom.setVimeoLinks(vid, links, title, btn, duration, thumb); | |
| break; | |
| case 'getDailymotionLinks': | |
| savefrom.setDailymotionLinks(vid, links, title, btn, duration, thumb); | |
| break; | |
| } | |
| }, | |
| handleError: function(btn) | |
| { | |
| if(btn) | |
| { | |
| if(btn) | |
| { | |
| btn.style.display = ''; | |
| btn.setAttribute(savefrom.dataAttr, '1'); | |
| btn.click(); | |
| } | |
| return; | |
| } | |
| var form = document.getElementById('sf_form'); | |
| if(!form) | |
| return; | |
| form.setAttribute(savefrom.dataAttr, '1'); | |
| form.submit(); | |
| form.removeAttribute(savefrom.dataAttr); | |
| }, | |
| showVideoResult: function(result, btn) | |
| { | |
| if(!result || !result.url || !result.url.length) | |
| { | |
| savefrom.handleError(btn); | |
| return; | |
| } | |
| var s = document.getElementById(savefrom.scriptId); | |
| if(s) | |
| s.parentNode.removeChild(s); | |
| s = document.createElement('script'); | |
| s.id = savefrom.scriptId; | |
| s.type = 'text/javascript'; | |
| if(btn) | |
| { | |
| s.text = 'try{' + | |
| 'var btn = document.getElementById("' + btn.id + '");' + | |
| 'sf.result.replaceAjaxResult(' + JSON.stringify(result) + ', true, true, btn);' + | |
| '}catch(err){}'; | |
| } | |
| else | |
| { | |
| s.text = 'try{' + | |
| 'sf.finishRequest(true);' + | |
| 'sf.videoResult.show(' + JSON.stringify(result) + ');' + | |
| '}catch(err){}'; | |
| } | |
| document.body.appendChild(s); | |
| }, | |
| setVKLinks: function(vid, links, title, btn, duration, thumb) | |
| { | |
| if(!vid || !links) | |
| { | |
| savefrom.handleError(btn); | |
| return; | |
| } | |
| var result = { | |
| url: links, | |
| meta: { | |
| title: (title ? SaveFrom_Utils.fileName.modify(title) : ''), | |
| source: "http://vk.com/" + vid, | |
| duration: SaveFrom_Utils.secondsToDuration(duration) | |
| } | |
| }; | |
| if(thumb) | |
| result.thumb = thumb; | |
| for(var i = 0; i < result.url.length; i++) | |
| { | |
| result.url[i].info_url = ''; | |
| if(!result.url[i].ext && result.url[i].type) | |
| result.url[i].ext = result.url[i].type; | |
| if(!result.sd && !result.url[i].subname) | |
| result.sd = {url: result.url[i].url}; | |
| else if(!result.hd && result.url[i].subname && parseInt(result.url[i].subname) >= 720) | |
| result.hd = {url: result.url[i].url}; | |
| } | |
| savefrom.showVideoResult(result, btn); | |
| }, | |
| setYoutubeLinks: function(vid, links, title, btn, subtitles, playlist, | |
| duration, thumb) | |
| { | |
| if(!vid || !links) | |
| { | |
| savefrom.handleError(btn); | |
| return; | |
| } | |
| var result = { | |
| url: [], | |
| meta: { | |
| title: (title ? SaveFrom_Utils.fileName.modify(title) : ''), | |
| source: (vid ? 'http://youtube.com/watch?v=' + vid : ''), | |
| duration: SaveFrom_Utils.secondsToDuration(duration) | |
| }, | |
| thumb: (vid ? 'http://i.ytimg.com/vi/' + vid + '/hqdefault.jpg' : '') | |
| }; | |
| var sig = false; | |
| SaveFrom_Utils.video.yt.filterLinks(links); | |
| for(var i in SaveFrom_Utils.video.yt.format) | |
| { | |
| var f = SaveFrom_Utils.video.yt.format[i]; | |
| for(var j in f) | |
| { | |
| if(links[j]) | |
| { | |
| if(!sig && links[j].search(/(\?|&)sig(nature)?=/i) > -1) | |
| sig = true; | |
| var l = { | |
| url: links[j], | |
| name: i, | |
| subname: f[j].quality + ( (i === 'Audio MP4' || i === 'Audio OGG')? ' '+chrome.i18n.getMessage('kbps') : '' ), | |
| info_url: '', | |
| type: i, | |
| quality: f[j].quality, | |
| attr: {} | |
| }; | |
| if(f[j]['3d']) | |
| { | |
| l.name = '3D ' + l.name; | |
| l.group = '3d'; | |
| l['3d'] = true; | |
| } | |
| else if(f[j]['noAudio']) | |
| { | |
| l.group = 'MP4 '; | |
| l.attr['class'] = 'no-audio'; | |
| l.ext = 'mp4'; | |
| } | |
| else if(i == 'Audio MP4') | |
| { | |
| l.type = 'AAC'; | |
| l.ext = 'aac'; | |
| l.attr.style = 'white-space: nowrap;'; | |
| } | |
| else | |
| { | |
| if(i.toLowerCase() == 'flv' && !result.sd) | |
| { | |
| result.sd = {url: links[j]}; | |
| } | |
| if(parseInt(f[j].quality) >= 720 && result.sd && !result.hd) | |
| { | |
| result.hd = {url: links[j]}; | |
| } | |
| } | |
| result.url.push(l); | |
| delete links[j]; | |
| } | |
| } | |
| } | |
| if(!sig) | |
| { | |
| savefrom.handleError(btn); | |
| return; | |
| } | |
| if(subtitles) | |
| { | |
| var subsId = vid.replace(/[^\w]/, '_'); | |
| var btnId = 'yt_subs_btn_' + subsId; | |
| subsId = 'yt_subs_' + subsId; | |
| var subtToken = 'extension'; | |
| var subsTitle = result.meta.title ? | |
| SaveFrom_Utils.base64_encode(SaveFrom_Utils.utf8Encode(result.meta.title)) : ''; | |
| result.action = []; | |
| result.action.push({ | |
| name: chrome.i18n.getMessage('subtitles'), | |
| attr: { | |
| id: btnId, | |
| href: '#', | |
| }, | |
| bind: { | |
| click: { | |
| fn: "sf.youtubeSubtitles('" + vid + "','" + subsId + "'" + | |
| ",'#" + btnId + "','" + subtToken + "','" + subsTitle + "');" | |
| } | |
| } | |
| }); | |
| } | |
| if(playlist) | |
| { | |
| playlist = 'http://www.youtube.com/playlist?list=' + playlist; | |
| if(!result.action) | |
| result.action = []; | |
| result.action.push({ | |
| name: chrome.i18n.getMessage('playlist'), | |
| attr: { | |
| href: '#', | |
| class: 'tooltip', | |
| title: chrome.i18n.getMessage('downloadWholePlaylist'), | |
| }, | |
| bind: { | |
| click: { | |
| fn: "sf.processLink('" + playlist + "');" | |
| } | |
| } | |
| }); | |
| } | |
| savefrom.showVideoResult(result, btn); | |
| }, | |
| setVimeoLinks: function(vid, links, title, btn, duration, thumb) | |
| { | |
| if(!vid || !links) | |
| { | |
| savefrom.handleError(btn); | |
| return; | |
| } | |
| var result = { | |
| url: links, | |
| meta: { | |
| title: (title ? SaveFrom_Utils.fileName.modify(title) : ''), | |
| source: "http://vimeo.com/" + vid, | |
| duration: SaveFrom_Utils.secondsToDuration(duration) | |
| } | |
| }; | |
| if(thumb) | |
| result.thumb = thumb; | |
| for(var i = 0; i < result.url.length; i++) | |
| { | |
| result.url[i].info_url = ''; | |
| if(!result.url[i].ext && result.url[i].type) | |
| result.url[i].ext = result.url[i].type; | |
| if(!result.sd && result.url[i].name == 'SD') | |
| result.sd = {url: result.url[i].url}; | |
| else if(!result.hd && result.url[i].name == 'HD') | |
| result.hd = {url: result.url[i].url}; | |
| } | |
| savefrom.showVideoResult(result, btn); | |
| }, | |
| setDailymotionLinks: function(vid, links, title, btn, duration, thumb) { | |
| if(!vid || !links) | |
| { | |
| savefrom.handleError(btn); | |
| return; | |
| } | |
| var result = { | |
| url: links, | |
| meta: { | |
| title: (title ? SaveFrom_Utils.fileName.modify(title) : ''), | |
| source: "http://dai.ly/" + vid, | |
| duration: SaveFrom_Utils.secondsToDuration(duration) | |
| } | |
| }; | |
| if(thumb) | |
| result.thumb = thumb; | |
| var hd_size = 0, sd_size = 0; | |
| for (var i = 0, item; item = links[i]; i++) { | |
| if (item.height >= 720) { | |
| if (hd_size < item.height) { | |
| result.hd = {url: item.url}; | |
| hd_size = item.height; | |
| } | |
| } else | |
| if (sd_size < item.height) { | |
| result.sd = {url: item.url}; | |
| sd_size = item.height; | |
| } | |
| delete item.height; | |
| } | |
| savefrom.showVideoResult(result, btn); | |
| } | |
| } | |
| SaveFrom_Utils.initModule(moduleName, function(response) { | |
| //console.log('savefrom', response); | |
| prefs = response; | |
| SaveFrom_Utils.runModule(response, savefrom); | |
| }); | |
| }; | |
| _modules.soundcloud = function(){ | |
| if(window.top != window.self) | |
| return; | |
| window.savefrom__lm = {}; | |
| var moduleName = 'soundcloud', | |
| prefs = {}; | |
| var sc = { | |
| client_id: 'b45b1aa10f1ac2941910a7f0d10f8e28', | |
| lastRow: null, | |
| lastRowCandidate: null, | |
| timer: 0, | |
| timeout: 10000, | |
| rowAttr: 'data-savefrom-helper', | |
| btnClass: 'savefrom-helper--btn', | |
| tracks: {}, | |
| run: function(){ | |
| document.removeEventListener('mouseover', sc.onMouseOver, true); | |
| document.removeEventListener('mouseout', sc.onMouseOut, true); | |
| document.addEventListener('mouseover', sc.onMouseOver, true); | |
| document.addEventListener('mouseout', sc.onMouseOut, true); | |
| sc.handleSingleTrack(); | |
| }, | |
| getTime: function() | |
| { | |
| return (new Date()).getTime(); | |
| }, | |
| checkRow: function(row) | |
| { | |
| var attr = row.getAttribute(sc.rowAttr); | |
| if(attr) | |
| { | |
| attr = parseInt(attr); | |
| if(!isNaN(attr) && (sc.getTime() - attr) <= sc.timeout) | |
| return false; | |
| } | |
| if(row.querySelector('.' + sc.btnClass)) | |
| return false; | |
| return true; | |
| }, | |
| onMouseOver: function(event) | |
| { | |
| var row = SaveFrom_Utils.getParentByClass(event.target, | |
| ['soundList__item', 'searchList__item', 'trackList__item', 'soundBadgeList__item', 'sound']); | |
| if(!row || !sc.checkRow(row)) | |
| return; | |
| sc.lastRowCandidate = row; | |
| clearTimeout(sc.timer); | |
| if(sc.lastRow == row) | |
| return; | |
| sc.timer = setTimeout(function(){ | |
| sc.lastRow = row; | |
| sc.lastRowCandidate = null; | |
| sc.handleRow(sc.lastRow); | |
| }, 1000); | |
| }, | |
| onMouseOut: function(event) | |
| { | |
| if(!sc.lastRow && !sc.lastRowCandidate) | |
| return; | |
| var node = event.target; | |
| if(!SaveFrom_Utils.isParent(node, sc.lastRow) && | |
| !SaveFrom_Utils.isParent(node, sc.lastRowCandidate)) | |
| { | |
| clearTimeout(sc.timer); | |
| } | |
| }, | |
| handleSingleTrack: function() | |
| { | |
| var count = 0; | |
| var timer = setInterval(function(){ | |
| count++; | |
| var row = document.querySelector('.sound.single'); | |
| if(row || count > 10) | |
| { | |
| clearInterval(timer); | |
| sc.handleRow(row); | |
| } | |
| }, 1000); | |
| }, | |
| handleRow: function(row) | |
| { | |
| if(!row) | |
| return; | |
| row.setAttribute(sc.rowAttr, sc.getTime()); | |
| setTimeout(function(){ | |
| row.removeAttribute(sc.rowAttr); | |
| }, sc.timeout); | |
| var a = row.querySelector('a.sound__coverArt[href], a.soundTitle__title[href]'); | |
| if(a) | |
| { | |
| sc.getTrackInfo(a.href, row); | |
| return; | |
| } | |
| if(SaveFrom_Utils.hasClass(row, 'single')) | |
| sc.getTrackInfo(window.location.href, row); | |
| }, | |
| getTrackInfo: function(url, row) | |
| { | |
| url = url.replace(/#.*$/i, ''); | |
| if(url.search(/^\/\/(?:[\w-]+\.)?soundcloud\.com(?:\d+)?\//i) > -1) | |
| { | |
| url = window.location.protocol + url; | |
| } | |
| else if(url.search(/https?:\/\//i) == -1) | |
| { | |
| if(url.charAt(0) != '/') | |
| url = '/' + url; | |
| url = window.location.protocol + '//' + window.location.host + url; | |
| } | |
| if(sc.tracks[url]) | |
| { | |
| sc.tracks[url].row = row; | |
| if(sc.tracks[url].url || sc.tracks[url].playlist) | |
| { | |
| sc.appendButton(url); | |
| } | |
| return; | |
| } | |
| sc.tracks[url] = {row: row}; | |
| var request = { | |
| action: 'getSoundcloudTrackInfo', | |
| trackUrl: url, | |
| client_id: sc.client_id | |
| }; | |
| chrome.extension.sendRequest(request, function(response){ | |
| sc.setTrackInfo(response); | |
| }); | |
| }, | |
| removeTrackInfo: function(url) | |
| { | |
| if(url && sc.tracks[url]) | |
| { | |
| sc.tracks[url].row.removeAttribute(sc.rowAttr); | |
| delete sc.tracks[url]; | |
| } | |
| }, | |
| setTrackInfo: function(data) | |
| { | |
| var url = data.trackUrl; | |
| if(!url || !sc.tracks[url]) | |
| return; | |
| var info = data.data; | |
| if(!info) | |
| { | |
| sc.removeTrackInfo(url); | |
| return; | |
| } | |
| if(info.kind != 'track' && info.tracks && info.tracks.length == 1) | |
| info = info.tracks[0]; | |
| if(info.kind == 'track' && info.stream_url) | |
| { | |
| sc.setSingleTrackParams(sc.tracks[url], info); | |
| sc.tracks[url].checkLinks = data.checkLinks; | |
| sc.appendButton(url); | |
| return; | |
| } | |
| if(info.tracks) | |
| { | |
| var playlist = []; | |
| for(var i = 0; i < info.tracks.length; i++) | |
| { | |
| var t = {}; | |
| sc.setSingleTrackParams(t, info.tracks[i]); | |
| playlist.push(t); | |
| } | |
| if(playlist.length > 0) | |
| { | |
| if(info.title) | |
| sc.tracks[url].title = info.title; | |
| sc.tracks[url].playlist = playlist; | |
| sc.tracks[url].checkLinks = data.checkLinks; | |
| sc.appendButton(url); | |
| return true; | |
| } | |
| } | |
| sc.removeTrackInfo(url); | |
| }, | |
| setSingleTrackParams: function(track, info) | |
| { | |
| var downloadUrl = info.stream_url; | |
| downloadUrl += (downloadUrl.indexOf('?') == -1) ? '?' : '&'; | |
| downloadUrl += 'client_id=' + sc.client_id; | |
| track.url = downloadUrl; | |
| var param = ['id', 'title', 'duration']; | |
| for(var i = 0; i < param.length; i++) | |
| { | |
| if(info[param[i]]) | |
| track[param[i]] = info[param[i]]; | |
| } | |
| }, | |
| appendButton: function(url) | |
| { | |
| if(!url || !sc.tracks[url]) | |
| return; | |
| var track = sc.tracks[url]; | |
| var parent = track.row.querySelector('.soundActions .sc-button-group'); | |
| if(!parent) | |
| { | |
| return; | |
| } | |
| var btnClass = ['sc-button-small', 'sc-button-medium', 'sc-button-large']; | |
| for(var i = 0; i < btnClass.length; i++) | |
| { | |
| if(parent.querySelector('.' + btnClass[i])) | |
| btnClass = [btnClass[i]]; | |
| } | |
| var a = document.createElement('a'); | |
| a.className = sc.btnClass + ' sc-button sc-button-responsive ' + btnClass[0]; | |
| a.style.position = 'relative'; | |
| var icon = document.createElement('img'); | |
| if(track.playlist) | |
| { | |
| a.href = '#'; | |
| a.title = chrome.i18n.getMessage('playlist'); | |
| var title = track.title ? SaveFrom_Utils.fileName.modify(track.title) : 'soundcloud'; | |
| a.addEventListener('click', function(event){ | |
| event.preventDefault(); | |
| setTimeout(function(){ | |
| SaveFrom_Utils.playlist.popupPlaylist(track.playlist, title, true); | |
| }, 100); | |
| return false; | |
| }, false); | |
| if (track.checkLinks === false) { | |
| icon.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAAJElEQVQoz2P4//8/A7mYgWqa6+vr/xPCtNE86udRP9PWz6RiANU4hUYGNDpOAAAAAElFTkSuQmCC'; | |
| } else { | |
| icon.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAAMUlEQVR42mL8//8/A7mAiYECwILC82Uk7IzN/xmpYjPjqJ9H/UxTP1OkGQAAAP//AwDcahUV6UvyJwAAAABJRU5ErkJggg=='; | |
| } | |
| icon.alt = chrome.i18n.getMessage('playlist'); | |
| } | |
| else { | |
| if (track.checkLinks === false) { | |
| a.href = '#'; | |
| a.title = chrome.i18n.getMessage('noLinksFound'); | |
| a.addEventListener('click', function(e) { | |
| e.preventDefault(); | |
| var style = { | |
| backgroundColor: '#fff', | |
| border: '1px solid #777', | |
| padding: '2px 5px 3px' | |
| }; | |
| SaveFrom_Utils.showTooltip(a,chrome.i18n.getMessage('noLinksFound'), undefined, style); | |
| return false; | |
| }); | |
| icon.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAAVklEQVQoz2P4//8/A7mYgSqa0UF9ff1/GEaXG0SagYrmI2vAg+djtZkIA+bjdTYeA+YT5WcsBswnNcDmY9NIlGaoAQnYxHEFGMHQxqe5gRDGqpnuGQMALmDKhkjc9oYAAAAASUVORK5CYII='; | |
| icon.alt = 'noLinksFound' | |
| } else { | |
| a.href = track.url; | |
| a.title = chrome.i18n.getMessage('download'); | |
| if (track.title) { | |
| a.setAttribute('download', | |
| SaveFrom_Utils.fileName.modify(SaveFrom_Utils.trim(track.title) + '.mp3')); | |
| a.addEventListener('click', SaveFrom_Utils.downloadOnClick, false); | |
| } | |
| icon.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAAPklEQVR42mNgGHTgvw/DfxgexJqBiuYja8CD55NrwHxyXTCfWP/OJ0sjFgPmkxvXCWRFDy6MT3MDITw40j8Ak46HYQ4gDfUAAAAASUVORK5CYII='; | |
| icon.alt = 'download'; | |
| } | |
| } | |
| SaveFrom_Utils.setStyle(icon, { | |
| width: '15px', | |
| height: '15px', | |
| position: 'absolute', | |
| top: '50%', | |
| left: '50%', | |
| margin: '-7px 0 0 -7px' | |
| }); | |
| a.appendChild(icon); | |
| parent.appendChild(a); | |
| track.row.removeAttribute(sc.rowAttr); | |
| } | |
| }; | |
| SaveFrom_Utils.initModule(moduleName, function(response) { | |
| //console.log('soundcloud', response); | |
| prefs = response; | |
| SaveFrom_Utils.runModule(response, sc); | |
| }); | |
| }; | |
| _modules.vimeo = function(){ | |
| var iframe = false; | |
| if(window.top != window.self) | |
| { | |
| var iframeClipId = location.href.match(/player\.vimeo\.com\/video\/([\w\-]+)/i); | |
| if(iframeClipId && iframeClipId.length > 1) | |
| iframe = true; | |
| else | |
| return; | |
| } | |
| window.savefrom__lm = {}; | |
| var moduleName = 'vimeo', | |
| prefs = {}; | |
| var vimeo = { | |
| panelId: 'savefrom__vimeo_links', | |
| btnBox: null, | |
| clipId: null, | |
| timer: null, | |
| btnPrefix: 'sd_ld_bnt_', | |
| popupIsShow: false, | |
| run: function() | |
| { | |
| if(!vimeo.clipId) { | |
| vimeo.clipId = vimeo.getClipId(); | |
| } | |
| var isList = Array.isArray(vimeo.clipId); | |
| if(vimeo.clipId) { | |
| if (iframe && !isList) { | |
| vimeo.appendIframeButtons(); | |
| return; | |
| } | |
| vimeo.showButtonList(vimeo.clipId); | |
| } else | |
| if (document.location.href.indexOf('vimeo.com/home') === -1) { | |
| return; | |
| } else { | |
| var count = 5; | |
| var ajaxWaitTimer = setInterval(function() { | |
| count--; | |
| if (count < 0) { | |
| clearInterval(ajaxWaitTimer); | |
| } | |
| vimeo.clipId = vimeo.getClipId(); | |
| if (vimeo.clipId) { | |
| clearInterval(ajaxWaitTimer); | |
| vimeo.showButtonList(vimeo.clipId); | |
| } | |
| }, 1000); | |
| } | |
| if(!iframe) { | |
| window.clearInterval(vimeo.timer); | |
| var loc = document.location.href; | |
| vimeo.timer = window.setInterval(function(){ | |
| if(document.location.href === loc) { | |
| return; | |
| } | |
| loc = document.location.href; | |
| var clipId = vimeo.getClipId(); | |
| if (!clipId || vimeo.clipId === clipId) { | |
| clipId = vimeo.getClipIdFromLocation(loc); | |
| } | |
| var isList = Array.isArray(clipId); | |
| if(!clipId || vimeo.clipId === clipId) { | |
| return; | |
| } | |
| vimeo.clipId = clipId; | |
| if (!isList) { | |
| vimeo.showButton(vimeo.clipId); | |
| vimeo.btnExistsChecker(vimeo.clipId); | |
| } else { | |
| vimeo.showButtonList(vimeo.clipId); | |
| } | |
| }, 1000); | |
| } | |
| }, | |
| btnExistsChecker: function(clipId) { | |
| var n = 10; | |
| var btnExInterval; | |
| btnExInterval = setInterval(function(){ | |
| n--; | |
| if (n < 0 || vimeo.clipId !== clipId) { | |
| return clearInterval(btnExInterval); | |
| } | |
| var btn = document.getElementById(vimeo.btnPrefix+clipId); | |
| if (btn === null) { | |
| vimeo.showButton(clipId); | |
| } else { | |
| return clearInterval(btnExInterval); | |
| } | |
| }, 1000); | |
| }, | |
| getClipIdFromLocation: function(loc) | |
| { | |
| if(!loc) | |
| loc = document.location.href; | |
| var id = loc.match(/\/(\d+)$/); | |
| if(id !== null && id.length > 1) { | |
| return id[1]; | |
| } | |
| return null; | |
| }, | |
| getClipId: function() | |
| { | |
| if(iframe && iframeClipId) | |
| return iframeClipId[1]; | |
| var tags = { | |
| meta: {attr: 'content', re: /(?:\?|&)clip_id=(\d+)/i}, | |
| embed: {attr: 'flashvars', re: /(?:^|&)clip_id=(\d+)/i}, | |
| object: {attr: 'data', re: /(?:\?|&)clip_id=(\d+)/i}, | |
| param: {attr: 'value', re: /(?:\?|&)clip_id=(\d+)/i} | |
| }; | |
| var selector = [ | |
| {attr: 'content', sel: 'meta[itemprop="embedUrl"]'}, | |
| {attr: 'href', sel: 'link[rel="canonical"]'} | |
| ]; | |
| for (var i = 0, item; item = selector[i]; i++) { | |
| var el = document.querySelector(item.sel); | |
| if (el === null) { | |
| continue; | |
| } | |
| var url = el.getAttribute(item.attr); | |
| if (url === null) { | |
| continue; | |
| } | |
| var id = url.match(/\/(?:video\/)(\d+)(?:$|\/)/); | |
| if (id !== null && id.length > 1) { | |
| return id[1]; | |
| } | |
| } | |
| selector = [ | |
| {attr: 'data-fallback-url', sel: 'div.player_container > div.player[data-fallback-url]'}, | |
| {attr: 'data-clip_id', sel: 'div.player_wrapper > div.faux_player[data-clip_id]'} | |
| ]; | |
| var linkList = []; | |
| for (var n = 0, item; item = selector[n]; n++) { | |
| var elList = document.querySelectorAll(item.sel); | |
| for (var i = 0, el; el = elList[i]; i++) { | |
| var type = n; | |
| var url = el.getAttribute(item.attr); | |
| if (url === null) { | |
| continue; | |
| } | |
| var container; | |
| if (type === 1) { | |
| container = el.parentNode; | |
| if (container) { | |
| container = container.parentNode; | |
| } | |
| linkList.push({id: url, container: container, type: type}); | |
| } else | |
| if (type === 0) { | |
| var id = url.match(/\/(?:video\/)(\d+)(?:$|\/)/); | |
| if (id !== null && id.length > 1) { | |
| container = el.parentNode; | |
| if (container) { | |
| container = container.parentNode; | |
| } | |
| linkList.push({id: id[1], container: container, type: type}); | |
| } | |
| } | |
| } | |
| } | |
| var linkLen = linkList.length; | |
| if (linkLen > 0) { | |
| if (linkLen === 1) { | |
| return linkList[0].id; | |
| } | |
| return linkList; | |
| } | |
| return null; | |
| }, | |
| hidePopup: function(e) { | |
| if (vimeo.popupIsShow === false) { | |
| return; | |
| } | |
| if (e !== undefined) { | |
| SaveFrom_Utils.embedDownloader.onBodyClick(e); | |
| } else { | |
| SaveFrom_Utils.embedDownloader.hidePanel(); | |
| SaveFrom_Utils.embedDownloader.lastLink = null; | |
| } | |
| vimeo.popupIsShow = SaveFrom_Utils.embedDownloader.lastLink !== null; | |
| if ( vimeo.popupIsShow === false ) { | |
| document.removeEventListener('click', vimeo.hidePopup, true); | |
| } | |
| }, | |
| showButtonList: function(idList) { | |
| if (!Array.isArray(idList)) { | |
| return vimeo.showButton(idList); | |
| } | |
| for (var i = 0, item; item = idList[i]; i++) { | |
| var btn_id = vimeo.btnPrefix+item.id; | |
| if (document.getElementById(btn_id)) { | |
| continue; | |
| } | |
| var btn = document.createElement('a'); | |
| btn.id = btn_id; | |
| btn.setAttribute('data-savefrom-get-links', document.location.protocol+'//player.vimeo.com/video/' + item.id); | |
| btn.textContent = chrome.i18n.getMessage('download'); | |
| btn.href = '#'; | |
| if (item.type === 0) { | |
| var box = item.container.querySelector('#info>p.meta>span.stats'); | |
| if (!box) { | |
| continue; | |
| } | |
| var firstChild = box.firstChild; | |
| if (firstChild) { | |
| box.insertBefore(btn, firstChild); | |
| box.insertBefore(document.createTextNode(' / '), firstChild); | |
| } else { | |
| box.appendChild(btn); | |
| } | |
| } | |
| if (item.type === 1) { | |
| var box = item.container.querySelector('div.info>div.byline>dl dd.by'); | |
| if (!box) { | |
| continue; | |
| } | |
| box.appendChild(btn); | |
| } | |
| btn.addEventListener('click', function(e) { | |
| e.preventDefault(); | |
| var id = this.getAttribute('data-id'); | |
| vimeo.popupIsShow = true; | |
| SaveFrom_Utils.embedDownloader.onClick(e); | |
| document.removeEventListener('click', vimeo.hidePopup, true); | |
| document.addEventListener('click', vimeo.hidePopup, true); | |
| }); | |
| } | |
| }, | |
| showButton: function(clipId) | |
| { | |
| var otherStyle = 0; | |
| var box = document.querySelector('.video_container_hd'); | |
| if(!box) { | |
| box = document.getElementById('tools'); | |
| if (box) { | |
| otherStyle = 1; | |
| } | |
| } | |
| if (!box) { | |
| // channels | |
| box = document.querySelector('#info>p.meta>span.stats'); | |
| if (box) { | |
| otherStyle = 2; | |
| } | |
| } | |
| if (!box) { | |
| // channel too | |
| // https://vimeo.com/channels/mbmagazine/92235056 | |
| box = document.querySelector('div.col_small section.block > div.tools') || | |
| document.querySelector('div.col_small section.block > div.intro'); | |
| if (box) { | |
| otherStyle = 3; | |
| } | |
| } | |
| if(!box) { | |
| return; | |
| } | |
| var loadingIcon = 'data:image/gif;base64,R0lGODlhEAAQAPQAAP///6Ghg/v7+7W1ntHRwqOjha6ule/v6t7e1KmpjczMvMbGtPT08djYzOnp4ru7pcDArAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH+GkNyZWF0ZWQgd2l0aCBhamF4bG9hZC5pbmZvACH5BAAKAAAAIf8LTkVUU0NBUEUyLjADAQAAACwAAAAAEAAQAAAFUCAgjmRpnqUwFGwhKoRgqq2YFMaRGjWA8AbZiIBbjQQ8AmmFUJEQhQGJhaKOrCksgEla+KIkYvC6SJKQOISoNSYdeIk1ayA8ExTyeR3F749CACH5BAAKAAEALAAAAAAQABAAAAVoICCKR9KMaCoaxeCoqEAkRX3AwMHWxQIIjJSAZWgUEgzBwCBAEQpMwIDwY1FHgwJCtOW2UDWYIDyqNVVkUbYr6CK+o2eUMKgWrqKhj0FrEM8jQQALPFA3MAc8CQSAMA5ZBjgqDQmHIyEAIfkEAAoAAgAsAAAAABAAEAAABWAgII4j85Ao2hRIKgrEUBQJLaSHMe8zgQo6Q8sxS7RIhILhBkgumCTZsXkACBC+0cwF2GoLLoFXREDcDlkAojBICRaFLDCOQtQKjmsQSubtDFU/NXcDBHwkaw1cKQ8MiyEAIfkEAAoAAwAsAAAAABAAEAAABVIgII5kaZ6AIJQCMRTFQKiDQx4GrBfGa4uCnAEhQuRgPwCBtwK+kCNFgjh6QlFYgGO7baJ2CxIioSDpwqNggWCGDVVGphly3BkOpXDrKfNm/4AhACH5BAAKAAQALAAAAAAQABAAAAVgICCOZGmeqEAMRTEQwskYbV0Yx7kYSIzQhtgoBxCKBDQCIOcoLBimRiFhSABYU5gIgW01pLUBYkRItAYAqrlhYiwKjiWAcDMWY8QjsCf4DewiBzQ2N1AmKlgvgCiMjSQhACH5BAAKAAUALAAAAAAQABAAAAVfICCOZGmeqEgUxUAIpkA0AMKyxkEiSZEIsJqhYAg+boUFSTAkiBiNHks3sg1ILAfBiS10gyqCg0UaFBCkwy3RYKiIYMAC+RAxiQgYsJdAjw5DN2gILzEEZgVcKYuMJiEAOwAAAAAAAAAAAA=='; | |
| if (otherStyle === 2 || otherStyle === 3) { | |
| // channel | |
| var btn = document.createElement('a'); | |
| btn.id = vimeo.btnPrefix+clipId; | |
| btn.textContent = chrome.i18n.getMessage('download'); | |
| btn.href = '#'; | |
| if (otherStyle === 3) { | |
| btn.classList.add('btn'); | |
| } | |
| btn.addEventListener('click', function(e){ | |
| e.preventDefault(); | |
| var panel = document.getElementById(vimeo.panelId); | |
| if (panel) { | |
| var parentNode = panel.parentNode; | |
| if(parentNode.style.display == 'none') | |
| { | |
| SaveFrom_Utils.addClass(btn, 'active'); | |
| parentNode.style.display = 'block'; | |
| } | |
| else | |
| { | |
| SaveFrom_Utils.removeClass(btn, 'active'); | |
| parentNode.style.display = 'none'; | |
| } | |
| return; | |
| } | |
| var panelBox = document.createElement('div'); | |
| var panelBoxStyle = { | |
| display: 'block', | |
| 'float': 'none', | |
| margin: '0', | |
| clear: 'both' | |
| }; | |
| if (otherStyle === 2) { | |
| panelBoxStyle.padding = '20px 0 0 0'; | |
| } else | |
| if (otherStyle === 3) { | |
| panelBoxStyle.padding = '0 0 5px 0'; | |
| } | |
| SaveFrom_Utils.setStyle(panelBox, panelBoxStyle); | |
| panel = document.createElement('div'); | |
| panel.id = vimeo.panelId; | |
| var panelStyle = { | |
| display: 'block', | |
| 'float': 'none', | |
| padding: '5px 10px', | |
| margin: '0' | |
| }; | |
| if (otherStyle === 2) { | |
| panelStyle.border = '1px solid rgba(0, 0, 0, 0.42)'; | |
| panelStyle.backgroundColor = 'rgba(0, 0, 0, 0.32)'; | |
| } | |
| SaveFrom_Utils.setStyle(panel, panelStyle); | |
| panelBox.appendChild(panel); | |
| var img = document.createElement('img'); | |
| img.src = loadingIcon; | |
| img.alt = '---'; | |
| if (otherStyle === 2) { | |
| img.setAttribute('style', '' + | |
| 'filter: invert(0.85);' + | |
| '-webkit-filter: invert(0.85);' + | |
| '-moz-filter: invert(0.85);' + | |
| '-o-filter: invert(0.85);' + | |
| '-ms-filter: invert(0.85);'); | |
| } | |
| panel.appendChild(img); | |
| var request = {extVideoId: clipId, action: 'getVimeoLinks'}; | |
| chrome.extension.sendRequest(request, function(response){ | |
| var fsIconStyle; | |
| if (otherStyle === 2) { | |
| fsIconStyle = { | |
| color: '#ffffff', | |
| opacity: '.7' | |
| }; | |
| } | |
| vimeo.showLinks(response.links, response.title, fsIconStyle); | |
| }); | |
| if (otherStyle === 2) { | |
| box.parentNode.parentNode.appendChild(panelBox); | |
| } else | |
| if (otherStyle === 3) { | |
| var nextSibling = box.nextSibling; | |
| if (nextSibling) { | |
| box.parentNode.insertBefore(panelBox, nextSibling); | |
| } else { | |
| box.appendChild(panelBox); | |
| } | |
| } | |
| }); | |
| if (otherStyle === 2) { | |
| var firstChild = box.firstChild; | |
| if (firstChild) { | |
| box.insertBefore(btn, firstChild); | |
| box.insertBefore(document.createTextNode(' / '), firstChild); | |
| } else { | |
| box.appendChild(btn); | |
| } | |
| } else | |
| if (otherStyle === 3) { | |
| box.appendChild(btn); | |
| } | |
| return; | |
| } | |
| if(otherStyle === 1) | |
| { | |
| var btn = document.createElement('a'); | |
| btn.id = vimeo.btnPrefix+clipId; | |
| btn.href = 'javascript:void(0)'; | |
| btn.innerHTML = chrome.i18n.getMessage('download'); | |
| btn.className = 'btn iconify_down_b'; | |
| btn.addEventListener('click', function(event){ | |
| var panel = document.getElementById(vimeo.panelId); | |
| if(!panel) | |
| { | |
| SaveFrom_Utils.addClass(btn, 'active'); | |
| var panelBox = document.createElement('div'); | |
| SaveFrom_Utils.setStyle(panelBox, { | |
| display: 'block', | |
| 'float': 'none', | |
| padding: '20px 0 0 0', | |
| margin: '0', | |
| clear: 'both' | |
| }); | |
| box.appendChild(panelBox); | |
| panel = document.createElement('div'); | |
| panel.id = vimeo.panelId; | |
| SaveFrom_Utils.setStyle(panel, { | |
| background: '#fff', | |
| fontSize: '16px', | |
| display: 'block', | |
| 'float': 'none', | |
| padding: '10px', | |
| margin: '0' | |
| }); | |
| panelBox.appendChild(panel); | |
| var img = document.createElement('img'); | |
| img.src = loadingIcon; | |
| img.alt = '---'; | |
| panel.appendChild(img); | |
| var request = {extVideoId: clipId, action: 'getVimeoLinks'}; | |
| chrome.extension.sendRequest(request, function(response){ | |
| vimeo.showLinks(response.links, response.title); | |
| }); | |
| return false; | |
| } | |
| panel = panel.parentNode; | |
| if(panel.style.display == 'none') | |
| { | |
| SaveFrom_Utils.addClass(btn, 'active'); | |
| panel.style.display = 'block'; | |
| } | |
| else | |
| { | |
| SaveFrom_Utils.removeClass(btn, 'active'); | |
| panel.style.display = 'none'; | |
| } | |
| return false; | |
| }, false); | |
| var node = document.querySelectorAll('#tools a.btn'); | |
| if(node && node.length > 0) | |
| { | |
| node = node[node.length - 1]; | |
| var next = SaveFrom_Utils.nextSibling(node); | |
| if(next) | |
| box.insertBefore(btn, next); | |
| else | |
| box.appendChild(btn); | |
| } | |
| else | |
| box.insertBefore(btn, box.firstChild); | |
| return; | |
| } | |
| var next = SaveFrom_Utils.nextSibling(box); | |
| box = box.parentNode; | |
| var panel = document.createElement('div'); | |
| panel.id = vimeo.panelId; | |
| SaveFrom_Utils.setStyle(panel, { | |
| display: 'block', | |
| padding: '10px 0', | |
| fontSize: '16px' | |
| }); | |
| if(next) | |
| box.insertBefore(panel, next); | |
| else | |
| box.appendChild(panel); | |
| var btn = document.createElement('button'); | |
| btn.id = vimeo.btnPrefix+clipId; | |
| btn.innerHTML = chrome.i18n.getMessage('download'); | |
| btn.className = 'blue_button'; | |
| SaveFrom_Utils.setStyle(btn, { | |
| borderRadius: '5px', | |
| fontSize: '16px' | |
| }); | |
| btn.addEventListener('click', function(event){ | |
| var request = {extVideoId: clipId, action: 'getVimeoLinks'}; | |
| chrome.extension.sendRequest(request, function(response){ | |
| vimeo.showLinks(response.links, response.title); | |
| }); | |
| var img = document.createElement('img'); | |
| img.src = loadingIcon; | |
| img.alt = '---'; | |
| this.parentNode.appendChild(img); | |
| this.parentNode.removeChild(this); | |
| }, false); | |
| panel.appendChild(btn); | |
| }, | |
| showLinks: function(links, title, customFsIconStyle) | |
| { | |
| var box = document.getElementById(vimeo.panelId); | |
| if(!box) | |
| return; | |
| while(box.firstChild) | |
| box.removeChild(box.firstChild); | |
| if(links && links.length > 0) | |
| { | |
| box.appendChild(document.createTextNode(chrome.i18n.getMessage('download') + ': ')); | |
| var aStyle = {margin: '0 0 0 15px'}, | |
| fsIconStyle = {}, | |
| fsTextStyle = { | |
| position: 'relative', | |
| top: '-1px' | |
| }; | |
| if(iframe) | |
| { | |
| aStyle = { | |
| color: '#fff', | |
| borderBottom: '1px solid #808080', | |
| whiteSpace: 'nowrap', | |
| textDecoration: 'none', | |
| margin: '0 0 0 10px' | |
| }; | |
| fsIconStyle = {color: '#ffffff', opacity: '.5'}; | |
| fsTextStyle = {color: '#d0d0d0'}; | |
| } | |
| if (customFsIconStyle !== undefined) { | |
| fsIconStyle = customFsIconStyle; | |
| } | |
| var success = false, color = ''; | |
| for(var i = 0; i < links.length; i++) | |
| { | |
| var a = document.createElement('a'); | |
| if(links[i].url && links[i].name) | |
| { | |
| success = true; | |
| var ext = links[i].ext; | |
| if(!ext) | |
| { | |
| ext = 'MP4'; | |
| if(links[i].url.search(/\.flv($|\?)/i) != -1) | |
| ext = 'FLV'; | |
| } | |
| var name = links[i].name ? links[i].name : ext; | |
| a.href = links[i].url; | |
| a.title = chrome.i18n.getMessage('downloadTitle'); | |
| a.appendChild(document.createTextNode(name)); | |
| SaveFrom_Utils.setStyle(a, aStyle); | |
| box.appendChild(a); | |
| SaveFrom_Utils.appendFileSizeIcon(a, fsIconStyle, fsTextStyle); | |
| if(title && !links[i].noTitle) | |
| { | |
| a.setAttribute('download', SaveFrom_Utils.fileName.modify( | |
| title + '.' + ext.toLowerCase())); | |
| a.addEventListener('click', function(event){ | |
| SaveFrom_Utils.downloadOnClick(event, null, true); | |
| }, false); | |
| } | |
| if(!color) | |
| color = SaveFrom_Utils.getStyle(a, 'color'); | |
| } | |
| } | |
| if(success) | |
| { | |
| if(!color) | |
| color = '#2786c2'; | |
| if(prefs.moduleShowDownloadInfo == '1') | |
| { | |
| box.appendChild(document.createElement('br')); | |
| SaveFrom_Utils.appendDownloadInfo(box, color); | |
| } | |
| return; | |
| } | |
| } | |
| box.appendChild(document.createTextNode(chrome.i18n.getMessage('noLinksFound'))); | |
| return; | |
| }, | |
| appendIframeButtons: function() | |
| { | |
| var p = document.getElementsByTagName('div')[0], | |
| b = document.createElement('div'), | |
| a = document.createElement('a'), | |
| panel = document.createElement('div'); | |
| a.href = '#'; | |
| a.textContent = chrome.i18n.getMessage('download').toLowerCase(); | |
| SaveFrom_Utils.setStyle(a, { | |
| display: 'inline-block', | |
| color: 'rgba(255,255,255,.9)', | |
| textDecoration: 'none', | |
| padding: '5px 10px' | |
| }); | |
| b.appendChild(a); | |
| SaveFrom_Utils.setStyle(b, { | |
| background: 'rgba(0, 0, 0, .4)', | |
| border: '1px solid rgba(255,255,255,.5)', | |
| borderRadius: '4px', | |
| fontFamily: 'Arial,Helvetica,sans-serif', | |
| fontSize: '13px', | |
| lineHeight: 'normal', | |
| position: 'absolute', | |
| top: '5px', | |
| left: '5px', | |
| padding: 0, | |
| margin: 0, | |
| zIndex: 99999 | |
| }); | |
| panel.id = vimeo.panelId; | |
| SaveFrom_Utils.setStyle(panel, { | |
| color: '#fff', | |
| background: 'rgba(0,0,0,0.7)', | |
| textAlign: 'center', | |
| border: 0, | |
| display: 'none', | |
| fontFamily: 'Arial,Helvetica,sans-serif', | |
| fontSize: '13px', | |
| fontWeight: 'normal', | |
| position: 'absolute', | |
| top: 0, | |
| left: 0, | |
| right: 0, | |
| margin: 0, | |
| padding: '3px', | |
| zIndex: 99990, | |
| lineHeight: '31px' | |
| }); | |
| if(document.body.scrollWidth <= 400) | |
| { | |
| panel.style.paddingTop = '28px'; | |
| } | |
| vimeo.btnBox = document.createElement('div'); | |
| vimeo.btnBox.style.display = 'none'; | |
| vimeo.btnBox.appendChild(b); | |
| vimeo.btnBox.appendChild(panel); | |
| document.removeEventListener('mouseover', vimeo.onExtPlayerOver, false); | |
| document.removeEventListener('mouseout', vimeo.onExtPlayerOver, false); | |
| document.addEventListener('mouseover', vimeo.onExtPlayerOver, false); | |
| document.addEventListener('mouseout', vimeo.onExtPlayerOver, false); | |
| a.addEventListener('click', vimeo.fetchIframeLinks, false); | |
| a.addEventListener('click', vimeo.toggleIframePanel, false); | |
| document.body.appendChild(vimeo.btnBox); | |
| }, | |
| fetchIframeLinks: function(e) | |
| { | |
| e.preventDefault(); | |
| e.stopPropagation(); | |
| var button = e.target; | |
| // try to get links from document | |
| var scripts = document.querySelectorAll('script'), | |
| l = scripts.length, i, content, matches, config, | |
| links = null, hd = false, title = '', | |
| re = new RegExp('=(\{\"cdn_url\"\:.*?\});', 'i'), | |
| re2 = new RegExp('clip' + vimeo.clipId + '_\\d+\\s*=\\s*(\\{[\\s\\S]+?\\})\\s*;', 'i'); | |
| for(i=0; i<l; i++) | |
| { | |
| content = scripts[i].innerHTML; | |
| //if(content && (matches = content.match(/=(\{\"cdn_url\"\:.*?\});/i))) | |
| if(content && ( (matches = content.match(re)) || (matches = content.match(re2)) )) | |
| break; | |
| } | |
| if(matches) { | |
| try { | |
| matches = matches[1].replace(/(\{|,)\s*(\w+)\s*:/ig, '$1"$2":'). | |
| replace(/(:\s+)\'/g, '$1"').replace(/\'([,\]\}])/g, '"$1'); | |
| config = JSON.parse(matches); | |
| links = []; | |
| if(config.config) { | |
| config = config.config; | |
| if(config && config.request && config.video && | |
| config.request.signature && config.request.timestamp) | |
| { | |
| var data = { | |
| 'clip_id': vimeo.clipId, | |
| 'sig': config.request.signature, | |
| 'time': config.request.timestamp, | |
| 'type': 'moogaloop_local', | |
| 'quality': 'sd', | |
| 'codecs': 'H264,VP8,VP6' | |
| }; | |
| links.push({ | |
| url: 'http://player.vimeo.com/play_redirect?' + | |
| SaveFrom_Utils.getQueryString(data), | |
| name: 'SD', | |
| type: 'mp4', | |
| ext: 'MP4' | |
| }); | |
| if(config.video.hd == 1) | |
| { | |
| data.quality = 'hd'; | |
| hd = true; | |
| links.push({ | |
| url: 'http://player.vimeo.com/play_redirect?' + | |
| SaveFrom_Utils.getQueryString(data), | |
| name: 'HD', | |
| type: 'mp4', | |
| ext: 'MP4' | |
| }); | |
| } | |
| if(config.video.files && config.video.files.h264) | |
| { | |
| var files = config.video.files.h264; | |
| if(files.length > 0) | |
| { | |
| for(var i = 0; i < files.length; i++) | |
| { | |
| if(files[i] != 'sd' && files[i] != 'hd') | |
| { | |
| data.quality = files[i]; | |
| links.push({ | |
| url: 'http://player.vimeo.com/play_redirect?' + | |
| SaveFrom_Utils.getQueryString(data), | |
| name: (files[i].length <= 3) ? files[i].toUpperCase() : | |
| ucfirst(files[i].toLowerCase()), | |
| type: 'mp4', | |
| ext: 'MP4' | |
| }); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } else { | |
| for(i in config.request.files.h264) { | |
| var url = config.request.files.h264[i].url, | |
| t = url.match(/\.([a-z0-9]+)\?/i); | |
| if(i == 'hd') | |
| hd = true; | |
| links.push({ | |
| 'ext': t[1], | |
| 'name': i.toUpperCase(), | |
| 'type': t[1], | |
| 'url': url | |
| }); | |
| } | |
| } | |
| if(config.video.title) | |
| title = config.video.title; | |
| } catch(e) { | |
| // no data | |
| } | |
| } | |
| if(links && hd) | |
| { | |
| vimeo.appendIframeLinks(links, title, button); | |
| } | |
| else | |
| { | |
| var request = { | |
| action: 'getVimeoLinks', | |
| extVideoId: vimeo.clipId | |
| }; | |
| chrome.extension.sendRequest(request, function(response){ | |
| if(response.links) | |
| { | |
| vimeo.appendIframeLinks(response.links, response.title, button); | |
| } | |
| }); | |
| vimeo.appendIframeLinks(chrome.i18n.getMessage('download') + ' ...', button); | |
| } | |
| }, | |
| appendIframeLinks: function(links, title, button) | |
| { | |
| var panel = document.getElementById(vimeo.panelId); | |
| if(typeof(links) == 'object') | |
| { | |
| vimeo.showLinks(links, title); | |
| button.removeEventListener('click', vimeo.fetchIframeLinks, false); | |
| } | |
| else if(typeof(links) == 'string') | |
| { | |
| panel.innerHTML = links; | |
| } | |
| }, | |
| toggleIframePanel: function(e) | |
| { | |
| e.preventDefault(); | |
| e.stopPropagation(); | |
| var panel = document.getElementById(vimeo.panelId); | |
| if(panel) | |
| { | |
| panel.style.display = (panel.style.display == 'none') ? '' : 'none'; | |
| } | |
| }, | |
| onExtPlayerOver: function(event) | |
| { | |
| if(vimeo.btnBox) | |
| { | |
| if(event.type == 'mouseover') | |
| { | |
| if(vimeo.btnBox.style.display == 'none') | |
| vimeo.btnBox.style.display = 'block'; | |
| } | |
| else if(event.type == 'mouseout') | |
| { | |
| vimeo.btnBox.style.display = 'none'; | |
| } | |
| } | |
| } | |
| }; | |
| function ucfirst(str) | |
| { | |
| if(str.length) | |
| str = str.charAt(0).toUpperCase() + str.slice(1); | |
| return str; | |
| } | |
| SaveFrom_Utils.initModule(moduleName, function(response) { | |
| //console.log('vimeo', response); | |
| prefs = response; | |
| SaveFrom_Utils.runModule(response, vimeo); | |
| }); | |
| }; | |
| _modules.vk = function(){ | |
| var iframe = false, videoExt = false; | |
| if(window.location.href.search(/\/video_ext\.php\?.+/) > -1) | |
| videoExt = true; | |
| if(window.top != window.self) | |
| { | |
| if(!videoExt && window.location.href.search(/\/widget_comments\.php\?.+/) == -1) | |
| return; | |
| iframe = true; | |
| } | |
| window.savefrom__lm = {}; | |
| var moduleName = 'vk', | |
| prefs = {}; | |
| function showVideoLinks(response) | |
| { | |
| //console.log('vk showVideoLinks', response); | |
| var links = response.links; | |
| if (response.extVideoId == video.extVideoId && links && video.iframeParent) | |
| { | |
| video.show(response.links, response.title, | |
| null, video.style, response.action); | |
| } | |
| } | |
| // actions | |
| chrome.extension.onRequest.addListener(function(request, sender, callback){ | |
| switch(request.action) | |
| { | |
| case 'updateLinks': | |
| updateLinks(); | |
| break; | |
| case 'downloadMP3Files': | |
| audio.showListOfAudioFiles(false); | |
| break; | |
| case 'downloadPlaylist': | |
| audio.showListOfAudioFiles(true); | |
| break; | |
| case 'downloadPhotos': | |
| embedPhoto.download(); | |
| break; | |
| } | |
| }); | |
| var domain = window.location.hostname.replace(/^(?:[\w\-]+\.)*(\w+\.[a-z]{2,6})$/i, '$1'); | |
| var downloadLinkClassName = 'savefrom_vk_download'; | |
| var mp3InfoCache = {}; | |
| var titleTimer = 0; | |
| var curModule = ''; | |
| function updateLinks() | |
| { | |
| removeDownloadLinks(); | |
| audio.showLinks(); | |
| video.showLinks(); | |
| photo.showLinks(); | |
| } | |
| function autoFocusLoginForm() | |
| { | |
| if(window.location.href.search(/https?:\/\/(vkontakte\.ru|vk\.com)\/(login\.php)?$/i) != -1) | |
| { | |
| var email = document.getElementById('email'); | |
| if(email && email.tagName == 'INPUT' && email.focus) | |
| setTimeout(function(){email.focus();}, 1000); | |
| } | |
| } | |
| function createTextLink(href, text, blank) { | |
| if(blank == undefined) | |
| blank = true; | |
| var a = document.createElement('a'); | |
| a.href = href; | |
| a.className = downloadLinkClassName; | |
| a.innerHTML = text; | |
| if(blank) | |
| a.setAttribute('target', '_blank', false); | |
| return a; | |
| } | |
| function removeDownloadLinks() | |
| { | |
| var selector = 'a.' + downloadLinkClassName + | |
| ',div.' + downloadLinkClassName + | |
| ',span.' + downloadLinkClassName; | |
| var e = document.querySelectorAll(selector); | |
| for(var i = e.length-1; i >= 0; i--) | |
| e[i].parentNode.removeChild(e[i]); | |
| } | |
| function getModuleName() | |
| { | |
| var attr = 'data-sf--module'; | |
| var s = document.createElement('script'); | |
| s.text = '(function(){\ | |
| if(window..cur.module && typeof(window.cur.module) == \'string\')\ | |
| {\ | |
| document.body.setAttribute(\'' + attr + '\', window.cur.module);\ | |
| }\ | |
| })();'; | |
| var value = document.body.getAttribute(attr); | |
| if(value) | |
| { | |
| curModule = value; | |
| document.body.removeAttribute(attr); | |
| s.parentNode.removeChild(s); | |
| } | |
| return value; | |
| } | |
| /////////////////////////////////////////////////////////////////// | |
| // AUDIO | |
| var audio = { | |
| downloadIdPrefix: 'savefrom_vk_audio_download_', | |
| infoIdPrefix: 'savefrom_vk_audio_info_', | |
| visibleAttr: 'savefrom_vk_audio_visible', | |
| rowIdAttr: 'savefrom_vk_audio_row', | |
| lastRow: null, | |
| timer: 0, | |
| timerdl: 0, | |
| showRowElements: function(row) | |
| { | |
| if(!row) | |
| return; | |
| var node = row.querySelectorAll('a.' + downloadLinkClassName); | |
| if(!node || node.length == 0) | |
| { | |
| audio.showRowLinks(row); | |
| } | |
| }, | |
| getMp3Link: function(elID, cb) { | |
| var audioId = elID.split('_'); | |
| var ownerId = audioId[0]; | |
| audioId = audioId[1]; | |
| var query = 'act=reload_audio&al=1&audio_id='+audioId+'&owner_id='+ownerId; | |
| SaveFrom_Utils.sendRequest(document.location.protocol + '//' + domain + '/audio', function(r) { | |
| if (r.status !== 200) { | |
| return cb(); | |
| } | |
| var text = r.responseText; | |
| text = text.substr(text.indexOf('[')); | |
| try { | |
| var arr = JSON.parse(text); | |
| var src = arr[0].substr(0, arr[0].indexOf('?')); | |
| cb(elID, src); | |
| } catch(e) { | |
| return cb(); | |
| } | |
| }, 'POST', '', query); | |
| }, | |
| getAudioLinks: function(parent, cb) | |
| { | |
| if(!parent) | |
| parent = document; | |
| var links = {}; | |
| var img = parent.querySelectorAll('img.playimg'); | |
| for(var i = 0; i < img.length; i++) | |
| { | |
| var a = ''; | |
| try | |
| { | |
| a = img[i].getAttribute('onclick', false); | |
| } | |
| catch(err) | |
| { | |
| a = img[i].onclick; | |
| } | |
| a = a.toString(); | |
| if(a && a.search(/(operate|operatewall)/i) >= 0) | |
| { | |
| var audioId = '', src = ''; | |
| var r = a.match(/(?:operate|operatewall)\s*\x28\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*[\x22\x27](\w+)[\x22\x27]/i); | |
| if(r && r.length > 4) | |
| { | |
| audioId = r[1]; | |
| src = 'http://cs' + r[2] + '.' + domain + '/u' + r[3] + '/audio/' + r[4] + '.mp3'; | |
| } | |
| else | |
| { | |
| var r = a.match(/(?:operate|operatewall)\s*\x28\s*[\x22\x27]?([\w\-]+)[\x22\x27]?\s*,\s*[\x22\x27](https?:\/\/[\w\_]+\.(?:vkontakte\.ru|vk\.com)\/u\d+\/audio\/\w+\.mp3)[\x22\x27]/i); | |
| if(r && r.length > 2) | |
| { | |
| audioId = r[1]; | |
| src = r[2]; | |
| } | |
| } | |
| if(!audioId && img[i].id && img[i].id.search(/^imgbutton/i) != -1) | |
| audioId = img[i].id.replace(/^imgbutton/i, ''); | |
| links[audioId] = src; | |
| } | |
| } | |
| if (cb !== undefined) { | |
| var wait_link = 0; | |
| var ready_link = 0; | |
| var gotLink = function (audioId, src) { | |
| ready_link++; | |
| if (src) { | |
| links[audioId] = src; | |
| } | |
| if (wait_link !== ready_link) { | |
| return; | |
| } | |
| cb(links); | |
| }; | |
| } | |
| var play = parent.querySelectorAll('div.play, div.play_new'); | |
| if(play && play.length > 0) | |
| { | |
| for(var i = 0; i < play.length; i++) | |
| { | |
| if(play[i].id) | |
| { | |
| var audioId = play[i].id.replace(/^[^\d]+?(\-?\d+.+)$/i, '$1'); | |
| var info = document.getElementById('audio_info' + audioId); | |
| if(info && info.value) | |
| { | |
| var src = SaveFrom_Utils.getMatchFirst(info.value, | |
| /(https?:\/\/.+\.mp3)/i); | |
| if(src) | |
| { | |
| links[audioId] = src; | |
| } else | |
| if (cb !== undefined) { | |
| wait_link++; | |
| audio.getMp3Link(audioId, gotLink); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| if (cb !== undefined) { | |
| if (wait_link === 0) { | |
| cb(links); | |
| } | |
| return; | |
| } | |
| return links; | |
| }, | |
| showRowLinks: function(row) | |
| { | |
| if ( ['ac_performer','pd_performer'].indexOf(row.id) !== -1 ) { | |
| if (audio.tmp_creating) { | |
| return; | |
| } | |
| audio.tmp_creating = true; | |
| pageLS.get('pad_lastsong', function(data) { | |
| audio.handleAudioRow(data, 1, row); | |
| audio.tmp_creating = false; | |
| }); | |
| return; | |
| } | |
| audio.getAudioLinks(row, function(links) { | |
| for(var i in links) | |
| { | |
| audio.handleAudioRow(i, links[i]); | |
| } | |
| }); | |
| }, | |
| showLinks: function() | |
| { | |
| for(var i in mp3InfoCache) | |
| delete mp3InfoCache[i]; | |
| // remove visibleAttr | |
| var node = document.querySelectorAll('*[' + audio.visibleAttr + '="1"]'); | |
| if(node && node.length > 0) | |
| { | |
| for(var i = 0; i < node.length; i++) | |
| node[i].removeAttribute(audio.visibleAttr, false); | |
| } | |
| SaveFrom_Utils.addStyleRules('.' + downloadLinkClassName + ' .icon-over', { | |
| 'display': 'none' | |
| }); | |
| SaveFrom_Utils.addStyleRules('.' + downloadLinkClassName + ' .icon', { | |
| 'display': 'block' | |
| }); | |
| SaveFrom_Utils.addStyleRules('.audio .actions .' + downloadLinkClassName, { | |
| 'display': 'none' | |
| }); | |
| SaveFrom_Utils.addStyleRules('.' + downloadLinkClassName + ':hover .icon-over', { | |
| 'display': 'block' | |
| }); | |
| SaveFrom_Utils.addStyleRules('.' + downloadLinkClassName + ':hover .icon', { | |
| 'display': 'none' | |
| }); | |
| SaveFrom_Utils.addStyleRules('.audio.over .actions .' + downloadLinkClassName, { | |
| 'display': 'block' | |
| }); | |
| SaveFrom_Utils.addStyleRules('.audio.over .duration', { | |
| 'opacity': '0' | |
| }); | |
| SaveFrom_Utils.addStyleRules('.savefrom-tooltip', { | |
| background: '#FFF', | |
| border: '1px solid #96AABE', | |
| padding: '2px 5px 3px', | |
| color: '#2C587D', | |
| 'max-width': '200px' | |
| }); | |
| document.removeEventListener('mouseover', audio.onMouseOver, false); | |
| document.addEventListener('mouseover', audio.onMouseOver, false); | |
| }, | |
| onMouseOver: function(event) | |
| { | |
| var node = event.target; | |
| var row = SaveFrom_Utils.getParentByClass(node, ['audioRow', 'audioRowWall', 'audio']); | |
| if (!row) { | |
| if (['ac_performer','pd_performer'].indexOf(node.id) !== -1) { | |
| row = node; | |
| } | |
| } | |
| if(row) | |
| { | |
| window.clearTimeout(audio.timer); | |
| if(audio.lastRow == row) | |
| return; | |
| audio.timer = window.setTimeout(function(){ | |
| audio.lastRow = row; | |
| audio.showRowElements(audio.lastRow); | |
| }, 0); | |
| } | |
| }, | |
| handleAudioRow: function(id, mp3Src, current) | |
| { | |
| if(!id || !mp3Src) | |
| return false; | |
| var duration, title, actions, row; | |
| if (current) { | |
| var currentTrack = JSON.parse(id); | |
| id = currentTrack[0] + '_' + currentTrack[1]; | |
| row = {id: id}; | |
| mp3Src = currentTrack[2]; | |
| duration = {innerText: currentTrack[4]}; | |
| title = currentTrack[5] + ' - ' + currentTrack[6]; | |
| actions = current; | |
| mp3Src = mp3Src.substr(0, mp3Src.indexOf('?')); | |
| } else { | |
| row = document.getElementById('audio' + id); | |
| if (!row) | |
| return false; | |
| var parent = row.querySelector('.info'); | |
| if (!parent) | |
| return; | |
| parent.style.position = 'relative'; | |
| duration = row.querySelector('div.duration'); | |
| if (!duration) | |
| return false; | |
| actions = row.querySelector('div.actions'); | |
| if (!actions) | |
| return false; | |
| title = audio.getTitle(id, row); | |
| } | |
| var link1 = createTextLink(mp3Src, ''); | |
| link1.id = audio.downloadIdPrefix + id; | |
| //link1.title = chrome.i18n.getMessage('downloadTitle'); | |
| link1.setAttribute(audio.rowIdAttr, row.id); | |
| link1.setAttribute('data-savefrom-helper-duration', | |
| audio.secondsFromDurationNode(duration)); | |
| link1.className = downloadLinkClassName + ' audio_edit_wrap fl_r'; | |
| if(title) | |
| { | |
| title += '.mp3'; | |
| link1.setAttribute('download', SaveFrom_Utils.fileName.modify(title)); | |
| } | |
| SaveFrom_Utils.setStyle(link1, { | |
| color: '#fff', | |
| fontWeight: 'normal', | |
| width: 'auto', | |
| background: 'none', | |
| opacity: 1 | |
| }); | |
| if(!current && !actions.querySelector('div.audio_edit_wrap') && !actions.querySelector('div.audio_remove_wrap') && !actions.querySelector('div.audio_add_wrap')) | |
| { | |
| if(!SaveFrom_Utils.getParentByClass(parent, 'post_media')) | |
| { | |
| if(SaveFrom_Utils.getParentByClass(parent, 'pad_audio_table')) | |
| SaveFrom_Utils.setStyle(link1, { | |
| margin: '9px 9px 9px 0' | |
| }); | |
| else | |
| SaveFrom_Utils.setStyle(link1, { | |
| margin: '6px 6px 6px 0' | |
| }); | |
| } | |
| else if(SaveFrom_Utils.getParentByClass(parent, 'audio_list')) | |
| { | |
| SaveFrom_Utils.setStyle(link1, { | |
| padding: '0' | |
| }); | |
| } | |
| } | |
| else | |
| if (!current) { | |
| var titleWrap = parent.querySelector('.title_wrap'); | |
| if(titleWrap) | |
| titleWrap.style.width = (parseInt(SaveFrom_Utils.getStyle(titleWrap, 'width')) - 30) + 'px'; | |
| if(SaveFrom_Utils.getParentByClass(parent, 'pad_audio_table')) | |
| SaveFrom_Utils.setStyle(link1, { | |
| margin: '9px 7px 0 0' | |
| }); | |
| } | |
| link1.addEventListener('click', audio.onDownloadLinkClick, false); | |
| var icon = document.createElement('img'); | |
| icon.className = 'icon'; | |
| if (current) { | |
| icon.src = SaveFrom_Utils.svg.getSrc('download', '#6C8CAC'); | |
| } else { | |
| icon.src = SaveFrom_Utils.svg.getSrc('download', '#b4c3d3'); | |
| } | |
| SaveFrom_Utils.setStyle(icon, { | |
| width: '16px', | |
| height: '16px', | |
| verticalAlign: 'middle', | |
| //opacity: '0.9', | |
| cursor: 'pointer' | |
| }); | |
| icon.addEventListener('mouseover', audio.onDownloadLinkHover, false); | |
| icon.addEventListener('mouseout', audio.onDownloadLinkHover, false); | |
| var iconOver = icon.cloneNode(true); | |
| iconOver.className = 'icon-over'; | |
| if (current) { | |
| iconOver.src = SaveFrom_Utils.svg.getSrc('download', '#5D80A4'); | |
| } else { | |
| iconOver.src = SaveFrom_Utils.svg.getSrc('download', '#78A2CC'); | |
| } | |
| iconOver.addEventListener('mouseover', audio.onDownloadLinkHover, false); | |
| iconOver.addEventListener('mouseout', audio.onDownloadLinkHover, false); | |
| link1.appendChild(icon); | |
| link1.appendChild(iconOver); | |
| if (current) { | |
| SaveFrom_Utils.setStyle(link1, { | |
| padding: 0, | |
| margin: 0, | |
| cssFloat: 'left', | |
| marginRight: '3px', | |
| marginTop: '1px', | |
| marginBottom: '-2px' | |
| }); | |
| SaveFrom_Utils.setStyle(icon, { | |
| width: '12px', | |
| height: '12px' | |
| }); | |
| SaveFrom_Utils.setStyle(iconOver, { | |
| width: '12px', | |
| height: '12px' | |
| }); | |
| actions.insertBefore(link1, actions.firstChild); | |
| } else { | |
| SaveFrom_Utils.setStyle(actions, { | |
| 'zIndex': 2 | |
| }); | |
| actions.appendChild(link1); | |
| } | |
| if(prefs.vkShowBitrate == '1') | |
| audio.onDownloadLinkHover(false, link1); | |
| return true; | |
| }, | |
| onDownloadLinkHover: function(event, link) | |
| { | |
| if(event) | |
| link = event.target.parentNode; | |
| window.clearTimeout(audio.timerdl); | |
| if(event && event.type == 'mouseover') | |
| { | |
| SaveFrom_Utils.showTooltip(link.querySelector('img.icon-over'), link.getAttribute('savefrom-title') || '<img src="/images/upload.gif" />', SaveFrom_Utils.getParentByClass(link, 'audio')); | |
| } | |
| if(!event || event.type == 'mouseover' && !link.getAttribute('savefrom-title')) | |
| { | |
| audio.timerdl = window.setTimeout(function() { | |
| var title, request = { | |
| action: 'getFileSize', | |
| url: link.href | |
| }; | |
| chrome.extension.sendRequest(request, function(response){ | |
| if(response.fileSize == 0) | |
| { | |
| if(event) | |
| SaveFrom_Utils.showTooltip(link.querySelector('img.icon-over'), chrome.i18n.getMessage('getFileSizeFailTitle'), SaveFrom_Utils.getParentByClass(link, 'audio')); | |
| } | |
| else | |
| { | |
| var seconds = link.getAttribute('data-savefrom-helper-duration', false); | |
| seconds = parseInt(seconds); | |
| if(!isNaN(seconds)) | |
| { | |
| var size = SaveFrom_Utils.sizeHuman(response.fileSize, 2); | |
| var bitrate = Math.floor((response.fileSize / seconds) / 125) + ' ' + | |
| chrome.i18n.getMessage('kbps'); | |
| title = ' (' + size + ' ~ ' + bitrate + ')'; | |
| } | |
| else | |
| { | |
| title = ' (' + SaveFrom_Utils.sizeHuman(response.fileSize, 2) + ')'; | |
| //node.title = response.fileType ? response.fileType : ''; | |
| } | |
| if(event) | |
| SaveFrom_Utils.showTooltip(link.querySelector('img.icon-over'), title, SaveFrom_Utils.getParentByClass(link, 'audio')); | |
| link.setAttribute('savefrom-title', title); | |
| } | |
| }); | |
| }, event ? 1000 : 100); | |
| // don't reset timer when vkShowBitrate is true | |
| if(!event) | |
| audio.timerdl = null; | |
| } | |
| }, | |
| onDownloadLinkClick: function(event) | |
| { | |
| if(event.button == 2) | |
| return false; | |
| event.stopPropagation(); | |
| SaveFrom_Utils.downloadOnClick(event, null, true); | |
| var rowId = this.getAttribute(audio.rowIdAttr); | |
| if(rowId) | |
| { | |
| var row = document.getElementById(rowId); | |
| if(row) | |
| { | |
| row.style.backgroundColor = '#f4f7fc'; | |
| row.setAttribute(audio.visibleAttr, '1', false); | |
| } | |
| } | |
| return false; | |
| }, | |
| onCloseBtnClick: function(event) | |
| { | |
| if(event.button == 2) | |
| return true; | |
| event.preventDefault(); | |
| event.stopPropagation(); | |
| parent = SaveFrom_Utils.getParentByClass(this, downloadLinkClassName); | |
| if(parent) | |
| parent.style.display = 'none'; | |
| return false; | |
| }, | |
| getTitle: function(id, row) | |
| { | |
| if(!id || !row) | |
| return ''; | |
| var name = ''; | |
| var performer = row.querySelector('#performer' + id); | |
| if(!performer) | |
| { | |
| performer = row.querySelector('#performerWall' + id); | |
| if(!performer) | |
| performer = row.querySelector('.info b'); | |
| } | |
| var title = row.querySelector('#title' + id); | |
| if(!title) | |
| { | |
| title = row.querySelector('#titleWall' + id); | |
| if(!title) | |
| title = row.querySelector('span.title'); | |
| } | |
| if(performer && performer.textContent) | |
| name += SaveFrom_Utils.trim(performer.textContent); | |
| if(title && title.textContent) | |
| { | |
| if(name) | |
| name += ' - '; | |
| name += SaveFrom_Utils.trim(title.textContent); | |
| } | |
| if(name) | |
| return name.replace(/\<a\s+[^\>]+\>/ig, '').replace(/\<\/a\>/ig, ''); | |
| return ''; | |
| }, | |
| secondsFromDurationNode: function(node) | |
| { | |
| if(!node) | |
| return 0; | |
| var text = node.innerText; | |
| if(!text) | |
| return 0; | |
| var m = text.match(/^(?:\s*(\d+)\s*\:)?\s*(\d+)\s*\:\s*(\d+)/); | |
| if(m && m.length > 3) | |
| { | |
| if(!m[1]) | |
| m[1] = 0; | |
| return parseInt(m[1]) * 3600 + parseInt(m[2]) * 60 + parseInt(m[3]); | |
| } | |
| return 0; | |
| }, | |
| showListOfAudioFiles: function(playlist) | |
| { | |
| var links = audio.getAudioLinks(document); | |
| var html = ''; | |
| if(playlist) | |
| { | |
| var list = []; | |
| for(var i in links) | |
| { | |
| var id = i; | |
| var row = document.getElementById('audio' + id); | |
| if(row) | |
| { | |
| var title = audio.getTitle(id, row); | |
| var duration = 0; | |
| var d = row.querySelector('div.duration'); | |
| if(d) | |
| duration = audio.secondsFromDurationNode(d); | |
| list.push({url: links[i], title: title, duration: duration}); | |
| } | |
| } | |
| if(list.length > 0) | |
| { | |
| SaveFrom_Utils.playlist.popupPlaylist(list, 'vk_playlist', true); | |
| return true; | |
| } | |
| } | |
| else | |
| { | |
| var list = []; | |
| for(var i in links) | |
| { | |
| list.push({url: links[i]}); | |
| } | |
| if(list.length > 0) | |
| { | |
| SaveFrom_Utils.playlist.popupFilelist(list); | |
| return true; | |
| } | |
| } | |
| alert(chrome.i18n.getMessage('vkMp3LinksNotFound')); | |
| return false; | |
| } | |
| }; | |
| // /AUDIO | |
| /////////////////////////////////////////////////////////////////// | |
| /////////////////////////////////////////////////////////////////// | |
| // VIDEO | |
| var videoLinks = { | |
| getFlvLink: function(v) | |
| { | |
| if(v.host.search(/^https?:\/\//i) != -1) | |
| { | |
| if(v.host.charAt(v.host.length - 1) != '/') | |
| v.host += '/'; | |
| if(v.host.search(/^https?:\/\/cs\d+\./i) != -1) | |
| return v.host + 'u' + v.uid + '/videos/' + v.vtag + '.flv'; | |
| return v.host + 'assets/video/' + v.vtag + v.vkid + '.vk.flv'; | |
| } | |
| if(v.host.search(/\D/) == -1) | |
| return 'http://cs' + v.host + '.' + 'vk.com/u' + v.uid + '/videos/' + v.vtag + '.flv'; | |
| return 'http://' + v.host + '/assets/video/' + v.vtag + v.vkid + '.vk.flv'; | |
| }, | |
| getMp4Link: function(v, q) | |
| { | |
| if(q == 240 && v.no_flv == 0) | |
| return videoLinks.getFlvLink(v); | |
| if(v.host.search(/^https?:\/\//i) != -1) | |
| { | |
| if(v.host.charAt(v.host.length - 1) != '/') | |
| v.host += '/'; | |
| return v.host + 'u' + v.uid + '/videos/' + v.vtag + '.' + q + '.mp4'; | |
| } | |
| return 'http://cs' + v.host + '.' + 'vk.com/u' + v.uid + '/videos/' + v.vtag + '.' + q + '.mp4'; | |
| }, | |
| getLinks: function(v) | |
| { | |
| if(!v || !v.host || !v.vtag || (!v.vkid && !v.uid)) | |
| return null; | |
| if(typeof(v.host) != 'string' && v.host.toString) | |
| v.host = v.host.toString(); | |
| v.host = v.host.replace(/\\\//g, '/'); | |
| if(v.hd > 0 && (!v.hd_def || v.hd > v.hd_def)) | |
| v.hd_def = v.hd; | |
| var links = []; | |
| if(v.hd_def <= 0 && v.no_flv == 0) | |
| { | |
| links.push({ | |
| url: videoLinks.getFlvLink(v), | |
| name: 'FLV', | |
| subname: '', | |
| type: 'flv' | |
| }); | |
| } | |
| else | |
| { | |
| links.push({ | |
| url: videoLinks.getMp4Link(v, 240), | |
| name: (v.no_flv == 0) ? 'FLV' : 'MP4', | |
| subname: '', | |
| type: (v.no_flv == 0) ? 'flv': 'mp4' | |
| }); | |
| if(v.hd_def > 0) | |
| { | |
| links.push({ | |
| url: videoLinks.getMp4Link(v, 360), | |
| name: 'MP4', | |
| subname: '360', | |
| type: 'mp4' | |
| }); | |
| if(v.hd_def > 1) | |
| { | |
| links.push({ | |
| url: videoLinks.getMp4Link(v, 480), | |
| name: 'MP4', | |
| subname: '480', | |
| type: 'mp4' | |
| }); | |
| if(v.hd_def > 2) | |
| { | |
| links.push({ | |
| url: videoLinks.getMp4Link(v, 720), | |
| name: 'MP4', | |
| subname: '720', | |
| type: 'mp4' | |
| }); | |
| } | |
| } | |
| } | |
| } | |
| return links; | |
| } | |
| }; | |
| var video = { | |
| popupTimer: 0, | |
| iframeParent: null, | |
| extVideoId: null, | |
| panelId: 'savefrom__vk_video_links', | |
| videoAttr: 'data-savefrom-video', | |
| hiddenAttr: 'data-savefrom-hidden', | |
| btnBox: null, | |
| style: {fontSize: '10pt', margin: '15px 0', padding: '0'}, | |
| getSingleVideoInfo: function() | |
| { | |
| var json = SaveFrom_Utils.getMatchFirst(document.body.innerHTML, | |
| /loadflashplayer\s*\(\s*(\{[^\}]+\})/i); | |
| if(json) | |
| { | |
| var o = null; | |
| try | |
| { | |
| o = JSON.parse(json); | |
| } | |
| catch(err){} | |
| if(o) | |
| return o; | |
| } | |
| var e = SaveFrom_Utils.getElementByIds(['player', 'playerObj']); | |
| if(e && e.tagName == 'OBJECT') | |
| { | |
| var fv = '', cn = e.childNodes; | |
| for(var i = cn.length - 1; i >= 0; i--) | |
| { | |
| if(cn[i].nodeType == '1' && cn[i].name == 'flashvars') | |
| { | |
| try{fv = cn[i].value;}catch(err){fv = cn[i].getAttribute('value', false);} | |
| break; | |
| } | |
| } | |
| var host = SaveFrom_Utils.getMatchFirst(fv, /(?:^|[\?\&])host=([^\s\"\&]+)/i); | |
| var vtag = SaveFrom_Utils.getMatchFirst(fv, /(?:^|[\?\&])vtag=([\w\-]+)/i); | |
| var vkid = SaveFrom_Utils.getMatchFirst(fv, /(?:^|[\?\&])vkid=(\d+)/i); | |
| var uid = SaveFrom_Utils.getMatchFirst(fv, /(?:^|[\?\&])uid=(\d+)/i); | |
| var no_flv = SaveFrom_Utils.getMatchFirst(fv, /(?:^|[\?\&])no_flv=(\d+)/i); | |
| var hd_def = SaveFrom_Utils.getMatchFirst(fv, /(?:^|[\?\&])hd_def=(\d+)/i); | |
| var hd = SaveFrom_Utils.getMatchFirst(fv, /(?:^|[\?\&])hd=(\d+)/i); | |
| var md_title = SaveFrom_Utils.getMatchFirst(fv, /(?:^|[\?\&])md_title=([^\s\"\&]+)/i); | |
| if(md_title) | |
| md_title = decodeURIComponent(md_title); | |
| if(hd > 0 && (!hd_def || hd > hd_def)) | |
| hd_def = hd; | |
| if(host && vtag && (vkid || uid)) | |
| { | |
| return { | |
| host: host, | |
| uid: uid, | |
| vtag: vtag, | |
| vkid: vkid, | |
| hd_def: hd_def, | |
| no_flv: no_flv, | |
| md_title: md_title | |
| }; | |
| } | |
| } | |
| return null; | |
| }, | |
| onExtPlayerOver: function(event) | |
| { | |
| if(video.btnBox) | |
| { | |
| var panel = document.getElementById(video.panelId); | |
| if(panel && (panel.getAttribute(video.videoAttr) != 'active' || | |
| panel.getAttribute(video.hiddenAttr))) | |
| { | |
| panel = null; | |
| } | |
| if(event.type == 'mouseover') | |
| { | |
| if(video.btnBox.style.display == 'none') | |
| video.btnBox.style.display = 'block'; | |
| if(panel) | |
| panel.style.display = 'block'; | |
| } | |
| else if(event.type == 'mouseout') | |
| { | |
| video.btnBox.style.display = 'none'; | |
| if(panel) | |
| panel.style.display = 'none'; | |
| } | |
| } | |
| }, | |
| appendButton: function(links, title, style, request) | |
| { | |
| var parent = document.getElementById('mv_controls_line'); | |
| if(videoExt) | |
| parent = document.getElementById('playerWrap'); | |
| if(!parent) | |
| return; | |
| if(parent.querySelector('.' + downloadLinkClassName)) | |
| return; | |
| var panel = document.getElementById(video.panelId); | |
| if(panel) | |
| panel.parentNode.removeChild(panel); | |
| var box, a; | |
| if(videoExt) | |
| { | |
| if(video.btnBox) | |
| video.btnBox.parentNode.removeChild(video.btnBox); | |
| box = document.createElement('div'); | |
| box.id = video.btnBoxId; | |
| box.className = downloadLinkClassName; | |
| SaveFrom_Utils.setStyle(box, { | |
| background: '#000', | |
| border: '1px solid #fff', | |
| display: 'none', | |
| fontFamily: 'Arial,Helvetica,sans-serif', | |
| fontSize: '13px', | |
| lineHeight: 'normal', | |
| position: 'absolute', | |
| top: '2px', | |
| right: '2px', | |
| padding: '3px 5px', | |
| margin: 0, | |
| zIndex: 99999 | |
| }); | |
| video.btnBox = box; | |
| document.removeEventListener('mouseover', video.onExtPlayerOver, false); | |
| document.removeEventListener('mouseout', video.onExtPlayerOver, false); | |
| document.addEventListener('mouseover', video.onExtPlayerOver, false); | |
| document.addEventListener('mouseout', video.onExtPlayerOver, false); | |
| a = document.createElement('a'); | |
| a.href = '#'; | |
| a.textContent = chrome.i18n.getMessage('download'); | |
| a.style.color = '#fff'; | |
| a.style.textDecoration = 'none'; | |
| box.appendChild(a); | |
| panel = document.createElement('div'); | |
| panel.id = video.panelId; | |
| panel.className = downloadLinkClassName; | |
| SaveFrom_Utils.setStyle(panel, { | |
| background: '#000', | |
| border: 0, | |
| display: 'block', | |
| fontFamily: 'Arial,Helvetica,sans-serif', | |
| fontSize: '13px', | |
| lineHeight: 'normal', | |
| position: 'absolute', | |
| top: '25px', | |
| left: 0, | |
| right: 0, | |
| margin: 0, | |
| padding: 0, | |
| zIndex: 99990 | |
| }); | |
| parent.parentNode.insertBefore(panel, parent); | |
| } | |
| else | |
| { | |
| box = document.createElement('span'); | |
| box.className = downloadLinkClassName; | |
| var d = document.createElement('span'); | |
| d.className = 'divider'; | |
| d.textContent = '|'; | |
| box.appendChild(d); | |
| a = document.createElement('a'); | |
| a.href = '#'; | |
| a.textContent = chrome.i18n.getMessage('download'); | |
| a.style.color = '#a0a0a0'; | |
| a.style.fontWeight = 'bold'; | |
| box.appendChild(a); | |
| panel = document.createElement('div'); | |
| panel.id = video.panelId; | |
| panel.className = downloadLinkClassName; | |
| parent.parentNode.insertBefore(panel, parent); | |
| } | |
| a.addEventListener('click', function(event){ | |
| event.stopPropagation(); | |
| event.preventDefault(); | |
| if(panel.getAttribute(video.videoAttr) == 'active') | |
| { | |
| if(panel.style.display == 'none') | |
| { | |
| panel.style.display = 'block'; | |
| panel.removeAttribute(video.hiddenAttr); | |
| } | |
| else | |
| { | |
| panel.style.display = 'none'; | |
| panel.setAttribute(video.hiddenAttr, '1'); | |
| } | |
| return false; | |
| } | |
| panel.setAttribute(video.videoAttr, 'active'); | |
| if(links) | |
| video.show(links, title, panel, style); | |
| else if(request) | |
| { | |
| video.show('<img src="/images/upload.gif"/>', '', panel, style); | |
| chrome.extension.sendRequest(request, function(response){ | |
| showVideoLinks(response); | |
| }); | |
| } | |
| return false; | |
| }, false); | |
| parent.appendChild(box); | |
| }, | |
| show: function(links, title, parent, style, action) | |
| { | |
| if(!links) | |
| return; | |
| if(!parent) | |
| parent = document.getElementById(video.panelId); | |
| if(!parent) | |
| return; | |
| SaveFrom_Utils.emptyNode(parent); | |
| if(action == 'getYoutubeLinks') | |
| { | |
| SaveFrom_Utils.video.yt.init(prefs); | |
| SaveFrom_Utils.video.yt.show(links, parent, prefs.moduleShowDownloadInfo, { | |
| link: null, | |
| text: null, | |
| btn: {color: '#777', borderColor: '#555', fontSize: '95%'}, | |
| fsIcon: null, | |
| fsText: {fontSize: '80%'} | |
| }, title); | |
| return; | |
| } | |
| if(title) | |
| title = SaveFrom_Utils.trim(title.replace(/\x2B+/g, ' ')); | |
| var html = false; | |
| if(typeof(links) == 'string') | |
| html = true; | |
| else if(links.length == 0) | |
| return; | |
| if(videoExt) | |
| { | |
| SaveFrom_Utils.setStyle(parent, { | |
| color: '#fff', | |
| display: 'block', | |
| float: 'none', | |
| fontSize: '11pt', | |
| fontWeight: 'normal', | |
| margin: 0, | |
| padding: '5px', | |
| textAlign: 'center' | |
| }); | |
| } | |
| else | |
| { | |
| SaveFrom_Utils.setStyle(parent, { | |
| color: '#555', | |
| display: 'block', | |
| float: 'none', | |
| fontSize: '11pt', | |
| fontWeight: 'bold', | |
| margin: '15px 0', | |
| padding: '0', | |
| textAlign: 'center' | |
| }); | |
| } | |
| if(style && typeof(style) == 'object') | |
| SaveFrom_Utils.setStyle(parent, style); | |
| if(html) | |
| { | |
| parent.innerHTML = links; | |
| return; | |
| } | |
| var color = ''; | |
| for(var i = 0; i < links.length; i++) | |
| { | |
| var a = null; | |
| if(typeof(links[i]) == 'object' && links[i].url) | |
| { | |
| var ext = links[i].ext; | |
| if(!ext) | |
| { | |
| ext = 'FLV'; | |
| if(links[i].url.search(/\.mp4$/i) != -1) | |
| ext = 'MP4'; | |
| } | |
| var name = links[i].name ? links[i].name : ext; | |
| a = createTextLink(links[i].url, name); | |
| if(!links[i].noTitle) | |
| { | |
| if(title) | |
| { | |
| a.setAttribute('download', SaveFrom_Utils.fileName.modify( | |
| title + '.' + ext.toLowerCase())); | |
| } | |
| a.addEventListener('click', function(event){ | |
| SaveFrom_Utils.downloadOnClick(event, null, true); | |
| }, false); | |
| } | |
| if(links[i].subname) | |
| { | |
| var st = document.createElement('span'); | |
| SaveFrom_Utils.setStyle(st, { | |
| fontSize: '80%', | |
| fontWeight: 'normal', | |
| marginLeft: '3px' | |
| }); | |
| st.innerText = links[i].subname; | |
| a.appendChild(st); | |
| } | |
| } | |
| if(a) | |
| { | |
| a.style.marginLeft = '10px'; | |
| if(videoExt) | |
| a.style.color = '#fff'; | |
| a.title = chrome.i18n.getMessage('downloadTitle'); | |
| parent.appendChild(a); | |
| SaveFrom_Utils.appendFileSizeIcon(a, | |
| {color: '#a0a0a0', opacity: '.75'}, | |
| {fontSize: '95%', opacity: '.9'}); | |
| if(!color) | |
| color = SaveFrom_Utils.getStyle(a, 'color'); | |
| } | |
| } | |
| if(prefs.moduleShowDownloadInfo == '1' && !videoExt) | |
| { | |
| if(!color) | |
| color = '#a0a0a0'; | |
| parent.appendChild(document.createElement('br')); | |
| SaveFrom_Utils.appendDownloadInfo(parent, color); | |
| } | |
| }, | |
| showLinks: function() | |
| { | |
| var v = video.getSingleVideoInfo(); | |
| if(v && v.host) | |
| { | |
| var links = videoLinks.getLinks(v); | |
| if(links) | |
| { | |
| video.appendButton(links, v.md_title); | |
| return true; | |
| } | |
| } | |
| video.catchPopup(); | |
| var result = false; | |
| var count = 0; | |
| var a = document.getElementsByTagName('a'); | |
| for(var i = 0; i < a.length; i++) | |
| { | |
| if(a[i].href && a[i].href.search(/\/?video[\d\_\-]+/i) != -1) | |
| { | |
| var onclick = ''; | |
| try | |
| { | |
| onclick = a[i].getAttribute('onclick', false); | |
| } | |
| catch(err) | |
| { | |
| onclick = a[i].onclick; | |
| } | |
| if(onclick) | |
| { | |
| var json = SaveFrom_Utils.getMatchFirst(onclick, | |
| /showvideoboxcommon\s*\(\s*(\{[^\}]+\})/i); | |
| if(json) | |
| { | |
| var o = null; | |
| try | |
| { | |
| var o = JSON.parse(json); | |
| } | |
| catch(err){} | |
| if(o) | |
| { | |
| if(o.hd > 0 && (!o.hd_def || o.hd > o.hd_def)) | |
| o.hd_def = o.hd; | |
| var links = videoLinks.getLinks(o); | |
| if(links) | |
| video.appendButton(links, o.md_title, video.style); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| video.catchPopupLinks(); | |
| return result; | |
| }, | |
| catchPopupLinks: function() | |
| { | |
| document.removeEventListener('click', video.onVideoClick, false); | |
| document.addEventListener('click', video.onVideoClick, false); | |
| }, | |
| catchPopup: function(event) | |
| { | |
| clearInterval(video.popupTimer); | |
| if(video.getPopupLinks()) | |
| return; | |
| var count = 0; | |
| video.popupTimer = setInterval(function(){ | |
| if(count >= 10 || video.getPopupLinks()) | |
| { | |
| clearInterval(video.popupTimer); | |
| return; | |
| } | |
| count++; | |
| }, 1000); | |
| }, | |
| getPopupLinks: function() | |
| { | |
| var ids = ['mv_layer_wrap', 'box_layer_wrap']; | |
| var box = SaveFrom_Utils.getElementByIds(ids); | |
| if(!box) | |
| return false; | |
| var embed = box.querySelector('embed'), iframe = null; | |
| if(!embed) | |
| iframe = box.querySelector('iframe'); | |
| var extVideoId, parent; | |
| if(iframe && iframe.src) | |
| { | |
| parent = video.getPopupParent(iframe, true); | |
| extVideoId = SaveFrom_Utils.getMatchFirst(iframe.src, | |
| /youtube.com\/embed\/([\w\-]+)/i); | |
| if(extVideoId && !prefs.lite) | |
| { | |
| // youtube | |
| video.extVideoId = extVideoId; | |
| video.iframeParent = parent; | |
| video.appendButton('', '', video.style, { | |
| action: 'getYoutubeLinks', | |
| extVideoId: extVideoId | |
| }); | |
| return true; | |
| } | |
| extVideoId = SaveFrom_Utils.getMatchFirst(iframe.src, | |
| /vimeo.com\/video\/(\d+)/i); | |
| if(extVideoId) | |
| { | |
| video.extVideoId = extVideoId; | |
| video.iframeParent = parent; | |
| video.appendButton('', '', video.style, { | |
| action: 'getVimeoLinks', | |
| extVideoId: extVideoId, | |
| }); | |
| return true; | |
| } | |
| } | |
| video.extVideoId = null; | |
| video.iframeParent = null; | |
| if(!embed) | |
| { | |
| return video.getLinksFromHtml5Video(box); | |
| } | |
| var src = embed.getAttribute('src', false); | |
| if (src !== null) { | |
| extVideoId = SaveFrom_Utils.getMatchFirst(src, /dailymotion.com(?:\/swf)?\/video\/([\w\d]+)\??/); | |
| if(extVideoId && !prefs.lite) { | |
| // dailymotion | |
| parent = video.getPopupParent(embed, true); | |
| video.iframeParent = parent; | |
| video.extVideoId = extVideoId; | |
| video.appendButton('', '', video.style, { | |
| action: 'getDailymotionLinks', | |
| extVideoId: extVideoId | |
| }); | |
| return true; | |
| } | |
| } | |
| var fv = embed.getAttribute('flashvars', false); | |
| if(!fv) | |
| return false; | |
| //fv = decodeURIComponent(fv); | |
| fv = SaveFrom_Utils.parseQuery(fv); | |
| var vid = { | |
| host: '', | |
| uid: 0, | |
| vtag: 0, | |
| vkid: '', | |
| hd: 0, | |
| hd_def: 0, | |
| no_flv: 0, | |
| md_title: '' | |
| }; | |
| for(var i in vid) | |
| { | |
| if(fv[i]) | |
| vid[i] = decodeURIComponent(fv[i]); | |
| } | |
| if(vid.hd > 0 && (!vid.hd_def || vid.hd > vid.hd_def)) | |
| vid.hd_def = vid.hd; | |
| var links = videoLinks.getLinks(vid); | |
| if(links) | |
| { | |
| video.appendButton(links, vid.md_title, video.style); | |
| } | |
| return true; | |
| }, | |
| getPopupParent: function(node, removeOldLinks) | |
| { | |
| var parent = SaveFrom_Utils.getParentByClass(node, 'wrap'); | |
| if(!parent) | |
| parent = node.parentNode.parentNode; | |
| if(removeOldLinks) | |
| { | |
| node = parent.querySelector('.' + downloadLinkClassName); | |
| if(node) | |
| node.parentNode.removeChild(node); | |
| } | |
| return parent; | |
| }, | |
| onVideoClick: function(event) | |
| { | |
| var node = event.target; | |
| if(node.tagName != 'A') | |
| { | |
| for(var parent = node; parent; parent = parent.parentNode) | |
| { | |
| if(parent.tagName == 'A') | |
| { | |
| node = parent; | |
| break; | |
| } | |
| } | |
| } | |
| if(node.tagName == 'A' && node.href && node.href.search(/\/video-?\d+_\d+/i) > -1) | |
| { | |
| clearInterval(video.popupTimer); | |
| setTimeout(function(){ | |
| var node = document.getElementById('mv_layer_wrap'); | |
| if(node) | |
| { | |
| video.catchPopup(); | |
| } | |
| }, 1000); | |
| } | |
| }, | |
| getLinksFromHtml5Video: function(parent) | |
| { | |
| if(!parent) | |
| return false; | |
| var v = parent.querySelector('video'); | |
| if(!v) | |
| return false; | |
| var src = v.src; | |
| if(!src) | |
| { | |
| var source = video.querySelector('source[src]'); | |
| if(source) | |
| src = source.getAttribute('src'); | |
| } | |
| var m = src.match(/(https?:\/\/(?:[^\/]+\/)+)u(\d+)\/videos\/([\da-f]+)\.(\d{3,4})\.mp4/i); | |
| if(!m || m.length < 5) | |
| return false; | |
| var quality = ['240', '360', '480', '720', '1080']; | |
| var vid = { | |
| host: m[1], | |
| uid: m[2], | |
| vtag: m[3], | |
| vkid: '', | |
| hd: 0, | |
| hd_def: 0, | |
| no_flv: 1, | |
| md_title: '' | |
| }; | |
| for(var i = quality.length - 1; i >= 0; i--) | |
| { | |
| if(m[4] == quality[i] || | |
| document.getElementById('button' + quality[i]) || | |
| parent.querySelector('button[val="' + quality[i] + 'p"]')) | |
| { | |
| vid.hd_def = i; | |
| break; | |
| } | |
| } | |
| var links = videoLinks.getLinks(vid); | |
| if(links) | |
| { | |
| video.appendButton(links, vid.md_title, video.style); | |
| } | |
| } | |
| }; | |
| var videoFeed = { | |
| linkAttr: 'data-savefrom-hasBtn', | |
| lastLink: undefined, | |
| isShow: false, | |
| addDownloadBtn: function(link) { | |
| var btn_container = document.createElement('span'); | |
| btn_container.addEventListener('click', function(e) { | |
| e.stopPropagation(); | |
| }, false); | |
| var dl_link = document.createElement('a'); | |
| var url = link.href; | |
| dl_link.href = 'http://savefrom.net/?url=' + encodeURIComponent(url); | |
| dl_link.setAttribute(SaveFrom_Utils.embedDownloader.dataAttr, url); | |
| dl_link.addEventListener('click', videoFeed.showPopup, false); | |
| SaveFrom_Utils.setStyle(dl_link, { | |
| display: 'inline-block', | |
| width: '16px', | |
| height: '16px', | |
| marginLeft: '5px', | |
| backgroundImage: 'url('+SaveFrom_Utils.svg.getSrc('download', '#78A2CC')+')', | |
| backgroundRepeat: 'no-repeat', | |
| marginBottom: '-4px' | |
| }); | |
| btn_container.appendChild(dl_link); | |
| link.appendChild(btn_container); | |
| }, | |
| showPopup: function(e) { | |
| videoFeed.isShow = true; | |
| SaveFrom_Utils.embedDownloader.onClick(e); | |
| document.removeEventListener('click', videoFeed.hidePopup, true); | |
| document.addEventListener('click', videoFeed.hidePopup, true); | |
| }, | |
| hidePopup: function(e) { | |
| if (videoFeed.isShow === false) { | |
| return; | |
| } | |
| if (e !== undefined) { | |
| SaveFrom_Utils.embedDownloader.onBodyClick(e); | |
| } else { | |
| SaveFrom_Utils.embedDownloader.hidePanel(); | |
| SaveFrom_Utils.embedDownloader.lastLink = null; | |
| } | |
| videoFeed.isShow = SaveFrom_Utils.embedDownloader.lastLink !== null; | |
| if ( videoFeed.isShow === false ) { | |
| document.removeEventListener('click', videoFeed.hidePopup, true); | |
| } | |
| }, | |
| onLinkHover: function(event) | |
| { | |
| var link = event.target; | |
| if(link.tagName !== 'A') { | |
| link = link.parentNode; | |
| if(link !== null && link.tagName !== 'A') { | |
| return; | |
| } | |
| } | |
| var href = link.href; | |
| var id = link.id; | |
| if (id.substr(0, 14) !== 'post_media_lnk' || href.indexOf('/video') === -1 ) { | |
| return; | |
| } | |
| if (videoFeed.lastLink === link) { | |
| link = link.parentNode; | |
| if(link !== null && link.tagName !== 'A') { | |
| return; | |
| } | |
| } | |
| videoFeed.lastLink = link; | |
| videoFeed.hidePopup(); | |
| var hasBtn = link.getAttribute(videoFeed.linkAttr); | |
| if (hasBtn !== null) { | |
| return; | |
| } | |
| link.setAttribute(videoFeed.linkAttr, '1'); | |
| videoFeed.addDownloadBtn(link); | |
| }, | |
| run: function() { | |
| document.removeEventListener('mouseover', this.onLinkHover, true); | |
| document.addEventListener('mouseover', this.onLinkHover, true); | |
| } | |
| }; | |
| // /VIDEO | |
| /////////////////////////////////////////////////////////////////// | |
| /////////////////////////////////////////////////////////////////// | |
| // PHOTO | |
| var photo = { | |
| box: null, | |
| album: '', | |
| links: {}, | |
| count: 0, | |
| found: 0, | |
| indicator: null, | |
| warning: null, | |
| warningTimer: null, | |
| offset: 0, | |
| offsetStep: 10, | |
| cache: {}, | |
| init: function() | |
| { | |
| photo.box = null; | |
| photo.album = ''; | |
| photo.links = {}; | |
| photo.count = 0; | |
| photo.found = 0; | |
| photo.indicator = null; | |
| photo.warning = null; | |
| clearTimeout(photo.warningTimer); | |
| photo.offset = 0; | |
| }, | |
| showLinks: function() | |
| { | |
| photo.init(); | |
| if(window.location.href.search(/(\?|&|#)act=edit/i) > -1) | |
| return false; | |
| if(window.location.href.search(/\/(?:albums?|tag|photos)-?\d+(?:_\d+)?/i) == -1) | |
| return false; | |
| var id = window.location.href.match(/#\/(albums?|tag|photos)(-?\d+)(?:_(\d+))?/i); | |
| if(!id || id.length == 0) | |
| id = window.location.href.match(/\/(albums?|tag|photos)(-?\d+)(?:_(\d+))?/i); | |
| if(!id || id.length < 3) | |
| return false; | |
| if(id.length > 3 && id[3]) | |
| photo.album = 'album' + id[2] + '_' + id[3]; | |
| else | |
| { | |
| if(id[1] == 'albums') | |
| id[1] = 'photos'; | |
| photo.album = id[1] + id[2]; | |
| } | |
| var parent = document.getElementById('photos_albums_container'); | |
| if(!parent) | |
| parent = document.getElementById('photos_container'); | |
| if(!photo.album || !parent) | |
| return false; | |
| photo.box = document.createElement('div'); | |
| photo.box.id = 'savefrom_vk_photo_box'; | |
| photo.box.className = downloadLinkClassName; | |
| photo.box.style.margin = '10px 20px'; | |
| parent.parentNode.insertBefore(photo.box, parent); | |
| photo.addDownloadAlbumBtn(chrome.i18n.getMessage('vkDownloadPhotoAlbum')); | |
| return true; | |
| }, | |
| addDownloadAlbumBtn: function(value) { | |
| var parent = document.querySelector('.photos_album_page, .photos_albums_page, ' + | |
| '.photos_tag_page, #photos_albums'); | |
| if(parent) | |
| parent = parent.querySelector('.summary_wrap .summary'); | |
| if(parent) | |
| { | |
| var divide = document.createElement('span'); | |
| divide.className = 'divide ' + downloadLinkClassName; | |
| divide.innerHTML = '|'; | |
| parent.appendChild(divide); | |
| var btn = document.createElement('a'); | |
| btn.href = '#'; | |
| btn.className = downloadLinkClassName; | |
| btn.innerHTML = value; | |
| btn.style.fontWeight = 'bold'; | |
| btn.addEventListener('click', function(event){ | |
| event.stopPropagation(); | |
| event.preventDefault(); | |
| if(photo.box) | |
| { | |
| if(!photo.box.firstChild) | |
| photo.ajaxStart(); | |
| else | |
| { | |
| if (photo.box.parentNode !== null | |
| && photo.box.parentNode.parentNode !== null | |
| && photo.box.parentNode.parentNode.id === 'photo_box_popup') { | |
| return; | |
| } | |
| if(photo.box.style.display == 'none') | |
| photo.box.style.display = ''; | |
| else | |
| photo.box.style.display = 'none'; | |
| } | |
| } | |
| }, false); | |
| return parent.appendChild(btn); | |
| } | |
| var clear_fix = document.createElement('div'); | |
| clear_fix.className = 'clear_fix'; | |
| var blue_box = document.createElement('div'); | |
| blue_box.className = 'button_blue fl_l'; | |
| var btn = document.createElement('button'); | |
| btn.innerHTML = value; | |
| btn.onclick = function(){ | |
| var node = this.parentNode.parentNode; | |
| node.parentNode.removeChild(node); | |
| photo.ajaxStart(); | |
| }; | |
| blue_box.appendChild(btn); | |
| clear_fix.appendChild(blue_box); | |
| return photo.box.appendChild(clear_fix); | |
| }, | |
| getAlbumTitle: function() | |
| { | |
| var title = ''; | |
| if(document.title) | |
| { | |
| title = document.title.replace(/\|[^\|]+$/, ''); | |
| if(title) | |
| title = ' "' + title + '"'; | |
| } | |
| return '<b>' + chrome.i18n.getMessage('vkDownloadPhotoAlbum') + title + '</b><br><br>'; | |
| }, | |
| ajaxStart: function() | |
| { | |
| var d = document.createElement('div'); | |
| d.style.marginTop = '15px'; | |
| photo.box = photo.box.appendChild(d); | |
| var warn = document.createElement('span'); | |
| photo.warning = photo.box.appendChild(warn); | |
| var ind = document.createElement('img'); | |
| ind.src = '//' + domain + '/images/upload.gif'; | |
| ind.alt = '---'; | |
| photo.indicator = photo.box.appendChild(ind); | |
| photo.getLinks(true); | |
| }, | |
| warningUpdate: function() { | |
| if (!photo.warning) { | |
| return; | |
| } | |
| var count = photo.count - photo.found; | |
| clearTimeout(photo.warningTimer); | |
| if (count < 1) { | |
| photo.warning.parentNode.removeChild(photo.warning); | |
| photo.warning = null; | |
| return; | |
| } | |
| photo.warningTimer = setTimeout(function () { | |
| photo.warning.textContent = chrome.i18n.getMessage('vkNotAvailablePhotos').replace('%d', count); | |
| }, 500); | |
| }, | |
| ajaxStop: function() | |
| { | |
| photo.offset = -1; | |
| photo.indicator.parentNode.removeChild(photo.indicator); | |
| photo.warningUpdate(); | |
| if(!photo.found) | |
| { | |
| photo.box.appendChild(document.createTextNode(chrome.i18n.getMessage('vkFoundPhotos') + ': 0')); | |
| return; | |
| } | |
| photo.createLinkPanel(); | |
| }, | |
| getLinks: function(init) | |
| { | |
| if(photo.offset < 0) { | |
| photo.warningUpdate(); | |
| return; | |
| } | |
| if(photo.count && photo.offset >= photo.count) | |
| { | |
| photo.offset = -1; | |
| return photo.ajaxStop(); | |
| } | |
| var post = 'act=show&al=1&list=' + photo.album + '&offset=' + photo.offset; | |
| photo.offset += photo.offsetStep; | |
| var counterId = 'savefrom_vk_photo_found'; | |
| photo.getLinksViaAPI(post, function(links, found, t){ | |
| if(!links || typeof(links) != 'object') | |
| { | |
| return photo.ajaxStop(); | |
| } | |
| for(var i in links) | |
| { | |
| if(!photo.links[links[i]]) | |
| { | |
| photo.found++; | |
| photo.links[links[i]] = 1; | |
| } | |
| } | |
| if(init) | |
| { | |
| photo.count = SaveFrom_Utils.getMatchFirst(t, | |
| /\<!int>(\d+)/i); | |
| if(!photo.count) | |
| return photo.ajaxStop(); | |
| var info = document.createElement('span'); | |
| info.innerHTML = chrome.i18n.getMessage('vkFoundLinks') + | |
| ': <span id="' + counterId + '">0</span> ' + | |
| chrome.i18n.getMessage('vkFoundOf') + ' ' + photo.count; | |
| info.style.marginRight = '20px'; | |
| photo.box.insertBefore(info, photo.box.firstChild); | |
| } | |
| var node = document.getElementById(counterId); | |
| if(node) | |
| node.innerText = photo.found; | |
| if(init) | |
| { | |
| if(photo.offset >= photo.count) | |
| return photo.ajaxStop(); | |
| window.setTimeout(function(){ | |
| photo.getLinks(false); | |
| photo.getLinks(false); | |
| photo.getLinks(false); | |
| }, 100); | |
| } | |
| else | |
| { | |
| window.setTimeout(function(){ | |
| photo.getLinks(false); | |
| }, 100); | |
| } | |
| }, photo.ajaxStop); | |
| }, | |
| getLinksViaAPI: function(query, onSuccess, onError) | |
| { | |
| var url = document.location.protocol + '//' + domain + '/al_photos.php'; | |
| SaveFrom_Utils.sendRequest(url, function(r){ | |
| if(!r.responseText) | |
| return onError(); | |
| var t = r.responseText.replace(/\<!\>/g, '\n'); | |
| var json = SaveFrom_Utils.getMatchFirst(t, /\<!json\>(.+?\}\s*\])/i); | |
| if(!json) | |
| return onError(); | |
| json = JSON.parse(json); | |
| if(!json || !json.length) | |
| return onError(); | |
| var found = 0, links = {}; | |
| var src = ['w_src', 'z_src', 'y_src', 'x_src']; | |
| for(var i = 0; i < json.length; i++) | |
| { | |
| for(var j = 0; j < src.length; j++) | |
| { | |
| if(json[i][src[j]] && json[i]['id']) | |
| { | |
| if(!photo.cache[json[i][src[j]]]) | |
| { | |
| found++; | |
| links[json[i]['id']] = json[i][src[j]]; | |
| photo.cache[json[i]['id']] = json[i][src[j]]; | |
| } | |
| break; | |
| } | |
| } | |
| } | |
| if(found < 1) | |
| return onError(); | |
| onSuccess(links, found, t); | |
| }, '', '', query); | |
| }, | |
| createLinkPanel: function() | |
| { | |
| var title = photo.getAlbumTitle(); | |
| photo.box.appendChild(document.createElement('br')); | |
| photo.box.appendChild(document.createElement('br')); | |
| photo.box.appendChild(document.createTextNode(chrome.i18n.getMessage('vkShowAs') + ':')); | |
| var btn1 = createTextLink('javascript:void(0)', chrome.i18n.getMessage('vkListOfLinks'), false); | |
| SaveFrom_Utils.setStyle(btn1, {margin: '0 20px', fontWeight: 'bold'}); | |
| btn1.onclick = function(){photo.showListOfLinks(title);}; | |
| photo.box.appendChild(btn1); | |
| var btn2 = createTextLink('javascript:void(0)', chrome.i18n.getMessage('vkListOfPhotos'), false); | |
| SaveFrom_Utils.setStyle(btn2, {marginRight: '20px', fontWeight: 'bold'}); | |
| btn2.onclick = function(){photo.showListOfPhotos(title);}; | |
| photo.box.appendChild(btn2); | |
| }, | |
| showListOfLinks: function(title, links, showListOfPhotosLink, callback) | |
| { | |
| var html = title + '<p>' + chrome.i18n.getMessage('vkListOfLinksInstruction') + '</p><br>'; | |
| if(showListOfPhotosLink) | |
| { | |
| html += '<div><div style="float:left;">' + | |
| '<a href="#" class="sf__hidden" style="display:none;">' + | |
| chrome.i18n.getMessage('vkListOfPhotos') + | |
| '</a></div>' + | |
| '<div class="sf__info" style="float:right;"></div></div><br><br>'; | |
| } | |
| else | |
| { | |
| html += '<br>'; | |
| } | |
| html += '<textarea cols="60" rows="10" style="width:100%">'; | |
| var oldLinks = photo.links; | |
| if(!links) | |
| links = photo.links; | |
| for(var i in links) | |
| { | |
| html += i + '\r\n'; | |
| } | |
| html += '</textarea>'; | |
| photo.links = oldLinks; | |
| setTimeout(function(){ | |
| var popup = SaveFrom_Utils.popupDiv(html); | |
| if(popup && showListOfPhotosLink) | |
| { | |
| var a = popup.querySelector('a.sf__hidden'); | |
| if(a) | |
| { | |
| a.addEventListener('click', function(event){ | |
| photo.showListOfPhotos(title, links); | |
| event.preventDefault(); | |
| return false; | |
| }, false); | |
| SaveFrom_Utils.setStyle(a, { | |
| display: 'block', | |
| fontWeight: 'bold', | |
| border: 'none', | |
| textDecoration: 'underline' | |
| }); | |
| } | |
| } | |
| if(callback) | |
| { | |
| callback(popup, links); | |
| } | |
| }, 100); | |
| return false; | |
| }, | |
| showListOfPhotos: function(title, links) | |
| { | |
| var html = '<html><head><style type="text/css">' + | |
| 'a,img{display:block;margin-bottom:5px;}' + | |
| '</style></head><body>' + title + | |
| '<p style="width:640px">' + | |
| chrome.i18n.getMessage('vkListOfPhotosInstruction') + | |
| '</p><br><br>'; | |
| var oldLinks = photo.links; | |
| if(!links) | |
| links = photo.links; | |
| for(var i in links) | |
| { | |
| var fileName = SaveFrom_Utils.getMatchFirst(i, /\/([\w\-]+\.[a-z0-9]{3,4})(?:\?|$)/i); | |
| if(fileName) | |
| { | |
| html += '<a href="' + i + '" download="' + fileName + '">' + | |
| '<img src="' + i + '" alt="photo"></a>'; | |
| } | |
| else | |
| html += '<img src="' + i + '" alt="photo">'; | |
| } | |
| html += '</body></html>'; | |
| photo.links = oldLinks; | |
| window.open('data:text/html;charset=utf-8;base64,' + | |
| escape(SaveFrom_Utils.base64_encode(SaveFrom_Utils.utf8Encode(html))), '_blank'); | |
| return false; | |
| } | |
| }; | |
| var embedPhoto = { | |
| indicator: null, | |
| counterId: 'sf__embed_photo_counter', | |
| counter: 0, | |
| processId: 0, | |
| find: function(links) | |
| { | |
| var a = document.querySelectorAll('a[onclick]'); | |
| var count = 0; | |
| for(var i = 0; i < a.length; i++) | |
| { | |
| var attr = a[i].getAttribute('onclick', false); | |
| if(attr && attr.search(/showPhoto\s*\(/i) >= 0) | |
| { | |
| var photoId = '', listId = ''; | |
| var params = attr.match(/showPhoto\s*\(\s*[\"']([\d\-_]+)[\"']\s*,\s*[\"']([\w\-]+)[\"']/i); | |
| if(params && params.length > 2) | |
| { | |
| photoId = params[1]; | |
| listId = params[2]; | |
| } | |
| if(photoId) | |
| { | |
| var json = attr.match(/\{[\"']?temp[\"']?\s*:\s*(\{.+?\})/i); | |
| if(json) | |
| { | |
| json = json[1].replace(/(\{|,)\s*(\w+)\s*:/ig, '$1"$2":'); | |
| var src = ''; | |
| try | |
| { | |
| json = JSON.parse(json); | |
| if(!json.base) | |
| json.base = ''; | |
| var v = ['w_', 'z_', 'y_', 'x_']; | |
| for(var j = 0; j < v.length; j++) | |
| { | |
| if(json[v[j]]) | |
| { | |
| if(typeof json[v[j]] == 'object') | |
| src = json.base + json[v[j]][0] + '.jpg'; | |
| else | |
| src = json.base + json[v[j]] + '.jpg'; | |
| break; | |
| } | |
| } | |
| } | |
| catch(err){} | |
| if(src && !links[photoId]) | |
| { | |
| links[photoId] = {src: src, list: listId}; | |
| count++; | |
| } | |
| } | |
| } | |
| } | |
| } | |
| return count; | |
| }, | |
| createStatusPopup: function() { | |
| var id = 'photo_box_popup'; | |
| var box_el = photo.box; | |
| if (box_el.id !== 'SaveFrom_vk_album') { | |
| box_el = SaveFrom_Utils.getParentByClass(box_el, downloadLinkClassName); | |
| } | |
| var parent_el = box_el.parentNode; | |
| if (parent_el.id === id) { | |
| return; | |
| } | |
| var next_node = box_el.nextElementSibling; | |
| SaveFrom_Utils.popupDiv('<div style="width: 400px;" id="'+id+'">', undefined, undefined, undefined, function() { | |
| parent_el.insertBefore(box_el, next_node); | |
| box_el.childNodes[0].style.display = 'none'; | |
| }); | |
| var popup_container = document.getElementById(id); | |
| if (!popup_container) { | |
| return; | |
| } | |
| popup_container.style.margin = '10px'; | |
| popup_container.appendChild(box_el); | |
| if (!box_el.firstChild) { | |
| photo.ajaxStart(); | |
| } | |
| if (box_el.childNodes[0] !== undefined) { | |
| box_el.childNodes[0].style.display = ''; | |
| } | |
| }, | |
| download: function() | |
| { | |
| var links = {}, count = embedPhoto.find(links); | |
| if(!count) | |
| { | |
| if (photo.box) { | |
| embedPhoto.createStatusPopup(); | |
| return; | |
| } | |
| alert(chrome.i18n.getMessage('vkPhotoLinksNotFound')); | |
| return; | |
| } | |
| photo.showListOfLinks('', {}, true, function(popup, src){ | |
| embedPhoto.getFullSizeSrc(popup, src, links, count, true); | |
| }); | |
| }, | |
| removeIndicator: function() | |
| { | |
| var node = embedPhoto.indicator; | |
| if(node && node.parentNode) | |
| node.parentNode.removeChild(node); | |
| embedPhoto.indicator = null; | |
| }, | |
| initProgressInfo: function(popup, count) | |
| { | |
| embedPhoto.counter = 0; | |
| if(embedPhoto.indicator) | |
| embedPhoto.removeIndicator(); | |
| var box = popup.querySelector('.sf__info'); | |
| if(!box) | |
| return; | |
| var cnt = document.createElement('span'); | |
| cnt.innerHTML = chrome.i18n.getMessage('vkFoundLinks') + | |
| ': <span id="' + embedPhoto.counterId + '">0</span> ' + | |
| chrome.i18n.getMessage('vkFoundOf') + ' ' + count; | |
| box.appendChild(cnt); | |
| var ind = document.createElement('img'); | |
| ind.src = '//' + domain + '/images/upload.gif'; | |
| ind.alt = '---'; | |
| ind.style.marginLeft = '1em'; | |
| embedPhoto.indicator = box.appendChild(ind); | |
| }, | |
| updateProgress: function() | |
| { | |
| var node = document.getElementById(embedPhoto.counterId); | |
| if(node) | |
| node.textContent = embedPhoto.counter; | |
| }, | |
| getFullSizeSrc: function(popup, src, links, count, init) | |
| { | |
| var ta = popup.querySelector('textarea'); | |
| if(!ta) | |
| return embedPhoto.removeIndicator(); | |
| if(init) | |
| { | |
| embedPhoto.processId++; | |
| embedPhoto.initProgressInfo(popup, count); | |
| } | |
| var found = false, value = ''; | |
| for(var i in links) | |
| { | |
| if(photo.cache[i]) | |
| { | |
| found = true; | |
| embedPhoto.counter++; | |
| delete links[i]; | |
| src[photo.cache[i]] = 1; | |
| value += photo.cache[i] + '\r\n'; | |
| } | |
| } | |
| embedPhoto.updateProgress(); | |
| if(value) | |
| ta.value += value; | |
| if(!init && !found) | |
| { | |
| value = ''; | |
| for(var i in links) | |
| { | |
| if(links[i].src) | |
| { | |
| embedPhoto.counter++; | |
| src[links[i].src] = 1; | |
| value += links[i].src + '\r\n'; | |
| delete links[i]; | |
| } | |
| } | |
| if(value) | |
| ta.value += value; | |
| embedPhoto.updateProgress(); | |
| return embedPhoto.removeIndicator(); | |
| } | |
| var query = null; | |
| if(!curModule) | |
| getModuleName(); | |
| for(var i in links) | |
| { | |
| if(links[i].list) | |
| { | |
| query = 'act=show&al=1&list=' + links[i].list + | |
| '&module=' + curModule + '&photo=' + i; | |
| break; | |
| } | |
| } | |
| if(!query) | |
| return embedPhoto.removeIndicator(); | |
| var processId = embedPhoto.processId; | |
| photo.getLinksViaAPI(query, function(l, found, t){ | |
| setTimeout(function(){ | |
| if(processId == embedPhoto.processId) | |
| { | |
| embedPhoto.getFullSizeSrc(popup, src, links, count, false); | |
| } | |
| }, 20); | |
| }, embedPhoto.removeIndicator); | |
| } | |
| }; | |
| // /PHOTO | |
| /////////////////////////////////////////////////////////////////// | |
| var pageLS = function() { | |
| var cb = undefined; | |
| return { | |
| init: function() { | |
| var script = document.createElement('script'); | |
| var injectScript = function() { | |
| window.addEventListener('sf-storage-get', function(e) { | |
| var data = e.detail || e.data; | |
| var event = new CustomEvent('sf-storage-send', {detail: data+':'+(localStorage[data] || '')}); | |
| window.dispatchEvent(event); | |
| }); | |
| }; | |
| script.textContent = '('+injectScript.toString()+')()'; | |
| document.body.appendChild(script); | |
| window.addEventListener('sf-storage-send', function(e) { | |
| var data = e.detail || e.data; | |
| if (data) { | |
| data = data.substr(data.indexOf(':')+1); | |
| if (data === 'undefined' || data === 'null') { | |
| data = undefined; | |
| } | |
| } | |
| cb && cb(data); | |
| cb = undefined; | |
| }); | |
| }, | |
| get: function(key, _cb) { | |
| var event = new CustomEvent('sf-storage-get', {detail: key}); | |
| cb = _cb; | |
| window.dispatchEvent(event); | |
| } | |
| } | |
| }; | |
| function catchTitleChanging(event) | |
| { | |
| clearTimeout(titleTimer); | |
| titleTimer = setTimeout(function(){ | |
| removeDownloadLinks(); | |
| audio.showLinks(); | |
| video.showLinks(); | |
| photo.showLinks(); | |
| }, 200); | |
| } | |
| var vk = { | |
| run: function() | |
| { | |
| autoFocusLoginForm(); | |
| audio.showLinks(); | |
| video.showLinks(); | |
| photo.showLinks(); | |
| videoFeed.run(); | |
| pageLS = pageLS(); | |
| pageLS.init(); | |
| var current_url = document.URL; | |
| setInterval(function(){ | |
| if (current_url != document.URL) | |
| { | |
| current_url = document.URL; | |
| catchTitleChanging(); | |
| } | |
| }, 1000); | |
| } | |
| }; | |
| SaveFrom_Utils.initModule(moduleName, function(response) { | |
| //console.log('vk', response); | |
| if (response.moduleEnable) | |
| { | |
| prefs = response; | |
| SaveFrom_Utils.runModule(response, vk); | |
| } | |
| }); | |
| }; | |
| _modules.youtube = function(){ | |
| var iframe = false; | |
| if(window.top != window.self) | |
| { | |
| var m = location.href.match(/\/embed\/([\w\-]+)/i); | |
| if(m && m.length > 1) | |
| { | |
| iframe = true; | |
| } | |
| else | |
| { | |
| return; | |
| } | |
| } | |
| window.savefrom__lm = {}; | |
| var moduleName = 'youtube', | |
| prefs = {}; | |
| var youtube = { | |
| swfargs: null, | |
| token: '', | |
| video_id: '', | |
| sts: '', | |
| needDecipher: false, | |
| newInterface: false, | |
| panelId: 'savefrom__yt_links', | |
| buttonId: 'savefrom__yt_btn', | |
| panelParent: null, | |
| panelInsertBefore: null, | |
| timer: null, | |
| btnBox: null, | |
| links: null, | |
| run: function(vid, links) | |
| { | |
| youtube.links = links || null; | |
| if(iframe) { | |
| youtube.isVideoPage(); | |
| youtube.video_id = youtube.swfargs.video_id; | |
| youtube.appendIframeButtons(); | |
| return; | |
| } | |
| if(youtube.isVideoPage() || links) | |
| { | |
| if(vid) | |
| youtube.video_id = vid; | |
| var p = youtube.findPanel(); | |
| if(p) | |
| youtube.appendDownloadButton(p); | |
| } | |
| if(!iframe) | |
| { | |
| window.clearInterval(youtube.timer); | |
| var loc = document.location.href; | |
| youtube.timer = window.setInterval(function(){ | |
| if(document.location.href != loc) | |
| { | |
| loc = document.location.href; | |
| var vid = youtube.getIdFromLocation(); | |
| if(!vid) | |
| return; | |
| youtube.links = null; | |
| chrome.extension.sendRequest({action: 'getYoutubeLinks', extVideoId: vid}, function(response){ | |
| if(response.links) | |
| youtube.catchVideoChange(loc, vid, response.links); | |
| }); | |
| } | |
| }, 1000); | |
| } | |
| }, | |
| catchVideoChange: function(loc, vid, links) | |
| { | |
| var count = 0; | |
| var timer = setInterval(function() { | |
| if(loc != document.location.href) | |
| { | |
| window.clearInterval(timer); | |
| return; | |
| } | |
| if(!document.getElementById(youtube.buttonId) && !!youtube.findPanel()) | |
| { | |
| window.clearInterval(timer); | |
| youtube.run(vid, links); | |
| } | |
| if(count > 20) | |
| window.clearInterval(timer); | |
| count++; | |
| }, 1000); | |
| }, | |
| findPanel: function() | |
| { | |
| var p = document.getElementById('watch-headline-user-info'); | |
| if(!p) | |
| { | |
| p = document.getElementById('watch7-subscription-container'); | |
| if(p) | |
| youtube.newInterface = true; | |
| } | |
| if(!p) | |
| { | |
| var e = document.getElementById('watch-video-count'); | |
| if(!e) | |
| e = document.getElementById('editSubscriptionDiv'); | |
| if(e) | |
| p = e.parentNode; | |
| } | |
| if(p) | |
| { | |
| youtube.panelParent = p.parentNode; | |
| youtube.panelInsertBefore = SaveFrom_Utils.nextSibling(p); | |
| //youtube.appendDownloadButton(p); | |
| } | |
| return p; | |
| }, | |
| getIdFromLocation: function(loc) | |
| { | |
| if(!loc) | |
| loc = document.location.href; | |
| var m = loc.match(/\/watch\?(?:.+&)?v=([\w\-]+)/i); | |
| if(m && m.length > 1) | |
| return m[1]; | |
| return null; | |
| }, | |
| isVideoPage: function() | |
| { | |
| var swfargs = youtube.getSwfArgs(); | |
| if(!swfargs) | |
| return false; | |
| youtube.swfargs = swfargs; | |
| var token = swfargs.t ? swfargs.t : swfargs.token; | |
| if(!token) | |
| return false; | |
| youtube.token = token; | |
| var video_id = swfargs.video_id; | |
| if(!video_id) | |
| video_id = youtube.getIdFromLocation(); | |
| if(!video_id) | |
| return false; | |
| youtube.video_id = video_id; | |
| youtube.sts = SaveFrom_Utils.getMatchFirst(document.body.innerHTML, | |
| /[\"']sts[\"']\s*:\s*[\"']?(\d+)/i); | |
| return true; | |
| }, | |
| appendDownloadButton: function(parent) | |
| { | |
| if(document.getElementById(youtube.buttonId)) | |
| return; | |
| var b = document.createElement('button'); | |
| b.id = youtube.buttonId; | |
| b.className = 'yt-uix-button yt-uix-button-default'; | |
| b.addEventListener('mousedown', youtube.getLinks, false); | |
| SaveFrom_Utils.setStyle(b, { | |
| marginLeft: '10px', | |
| fontSize: 'inherit', | |
| height: '24px' | |
| }); | |
| var s = document.createElement('span'); | |
| s.className = 'yt-uix-button-content'; | |
| s.innerHTML = chrome.i18n.getMessage('download'); | |
| s.style.fontWeight = 'bold'; | |
| b.appendChild(s); | |
| var icon = document.createElement('img'); | |
| icon.className = 'icon'; | |
| icon.src = SaveFrom_Utils.svg.getSrc('download', '#000000'); | |
| SaveFrom_Utils.setStyle(icon, { | |
| width: '12px', | |
| height: '12px', | |
| verticalAlign: 'middle', | |
| marginLeft: '4px', | |
| position: 'relative', | |
| top: '-1px', | |
| cursor: 'pointer', | |
| opacity: 0.6 | |
| }); | |
| s.appendChild(icon); | |
| parent.appendChild(b); | |
| }, | |
| updateWmode: function(p) | |
| { | |
| var e = p.querySelector('embed'); | |
| if(!e) // html5 | |
| return; | |
| // check wmode | |
| var m = e.getAttribute('wmode'); | |
| if(m != 'opaque' && m != 'transparent') | |
| { | |
| // update wmode | |
| e.setAttribute('wmode', 'opaque'); | |
| p.removeChild(e); | |
| p.appendChild(e); | |
| } | |
| }, | |
| appendIframeButtons: function() | |
| { | |
| var p = document.getElementById('player'), | |
| b = document.createElement('div'), | |
| a = document.createElement('a'), | |
| panel = document.createElement('div'); | |
| setTimeout(function() { | |
| youtube.updateWmode(p); | |
| }, 50); | |
| a.href = '#'; | |
| a.textContent = chrome.i18n.getMessage('download').toLowerCase(); | |
| SaveFrom_Utils.setStyle(a, { | |
| display: 'inline-block', | |
| color: 'rgba(255,255,255,.9)', | |
| textDecoration: 'none', | |
| padding: '5px 10px' | |
| }); | |
| b.appendChild(a); | |
| SaveFrom_Utils.setStyle(b, { | |
| background: 'rgba(0, 0, 0, .4)', | |
| border: '1px solid rgba(255,255,255,.5)', | |
| borderRadius: '4px', | |
| fontFamily: 'Arial,Helvetica,sans-serif', | |
| fontSize: '13px', | |
| lineHeight: 'normal', | |
| position: 'absolute', | |
| top: '30px', | |
| right: '5px', | |
| padding: 0, | |
| margin: 0, | |
| zIndex: 99999 | |
| }); | |
| panel.id = youtube.panelId; | |
| SaveFrom_Utils.setStyle(panel, { | |
| color: '#fff', | |
| background: 'rgba(0,0,0,0.7)', | |
| textAlign: 'center', | |
| border: 0, | |
| display: 'none', | |
| fontFamily: 'Arial,Helvetica,sans-serif', | |
| fontSize: '13px', | |
| fontWeight: 'normal', | |
| lineHeight: 'normal', | |
| position: 'absolute', | |
| top: '25px', | |
| left: 0, | |
| right: 0, | |
| margin: 0, | |
| padding: '3px', | |
| zIndex: 99990 | |
| }); | |
| if(document.body.scrollWidth <= 400) | |
| { | |
| panel.style.paddingTop = '28px'; | |
| } | |
| youtube.btnBox = document.createElement('div'); | |
| youtube.btnBox.style.display = 'none'; | |
| youtube.btnBox.appendChild(b); | |
| youtube.btnBox.appendChild(panel); | |
| document.removeEventListener('mouseover', youtube.onExtPlayerOver, false); | |
| document.removeEventListener('mouseout', youtube.onExtPlayerOver, false); | |
| document.addEventListener('mouseover', youtube.onExtPlayerOver, false); | |
| document.addEventListener('mouseout', youtube.onExtPlayerOver, false); | |
| a.addEventListener('click', youtube.fetchIframeLinks, false); | |
| a.addEventListener('click', youtube.toggleIframePanel, false); | |
| document.body.appendChild(youtube.btnBox); | |
| }, | |
| fetchIframeLinks: function(e) | |
| { | |
| e.preventDefault(); | |
| e.stopPropagation(); | |
| var button = e.target; | |
| var request = { | |
| action: 'getYoutubeLinks', | |
| extVideoId: youtube.video_id | |
| }; | |
| chrome.extension.sendRequest(request, function(response){ | |
| if(response.links) | |
| { | |
| youtube.appendIframeLinks(response.links, button); | |
| } | |
| }); | |
| youtube.appendIframeLinks(chrome.i18n.getMessage('download') + ' ...', button); | |
| }, | |
| appendIframeLinks: function(links, button) | |
| { | |
| var panel = document.getElementById(youtube.panelId); | |
| if(typeof(links) == 'object') | |
| { | |
| var title = youtube.getTitle(), titleAttr = ''; | |
| if(title) | |
| { | |
| title = modifyTitle(title); | |
| titleAttr = '&title=' + encodeURIComponent(title); | |
| for(var i in links) | |
| links[i] += titleAttr; | |
| } | |
| panel.innerHTML = ''; | |
| SaveFrom_Utils.video.yt.init(prefs); | |
| SaveFrom_Utils.video.yt.show(links, panel, prefs.moduleShowDownloadInfo, { | |
| link: {color: '#fff', borderBottom: '1px solid #808080', | |
| whiteSpace: 'nowrap', textDecoration: 'none'}, | |
| text: {color: '#d0d0d0'}, | |
| btn: {color: '#d0d0d0'}, | |
| fsIcon: {color: '#ffffff', opacity: '.5'}, | |
| fsText: {color: '#d0d0d0'} | |
| }, title); | |
| button.removeEventListener('click', youtube.fetchIframeLinks, false); | |
| } | |
| else if(typeof(links) == 'string') | |
| { | |
| panel.innerHTML = links; | |
| } | |
| }, | |
| toggleIframePanel: function(e) | |
| { | |
| e.preventDefault(); | |
| e.stopPropagation(); | |
| var panel = document.getElementById(youtube.panelId); | |
| if(panel) | |
| { | |
| panel.style.display = (panel.style.display == 'none') ? '' : 'none'; | |
| } | |
| }, | |
| onExtPlayerOver: function(event) | |
| { | |
| if(youtube.btnBox) | |
| { | |
| if(event.type == 'mouseover') | |
| { | |
| if(youtube.btnBox.style.display == 'none') | |
| youtube.btnBox.style.display = 'block'; | |
| } | |
| else if(event.type == 'mouseout') | |
| { | |
| youtube.btnBox.style.display = 'none'; | |
| } | |
| } | |
| }, | |
| getTitle: function() | |
| { | |
| var t = document.getElementById('watch-headline-title'); | |
| if(t) | |
| return t.innerText; | |
| var meta = document.getElementsByTagName('meta'); | |
| for(var i = 0; i < meta.length; i++) | |
| { | |
| var name = meta[i].getAttribute('name', false); | |
| if(name && name.toLowerCase() == 'title') | |
| return meta[i].getAttribute('content', false); | |
| } | |
| if(iframe) | |
| return document.title.replace(/ - YouTube$/, ''); | |
| return ''; | |
| }, | |
| getSwfArgs: function() | |
| { | |
| var html = document.body.innerHTML; | |
| var t = html.match(/[\"\'](?:swf_)?args[\"\']\s*:\s*(\{[^\}]+\})/i); | |
| if(t && t.length > 1) | |
| { | |
| if(t[1].search(/:\s*\"[^\"]+\s*\}$/) > -1) | |
| t[1] = t[1].replace(/\s*\}$/i, '"}'); | |
| try | |
| { | |
| return JSON.parse(t[1]); | |
| } | |
| catch(err){ | |
| t = html.match(/ytplayer.config\s*=\s*(\{.*?\});?<\/script>/i); | |
| if(t && t.length > 1) { | |
| try | |
| { | |
| return JSON.parse(t[1]); | |
| } | |
| catch(err){} | |
| } | |
| } | |
| } | |
| else | |
| { | |
| t = html.match(/flashvars\s*=\s*\\?[\"']?([^\"']+)/i); | |
| if(t && t.length > 1) | |
| { | |
| t = t[1]; | |
| if(t.indexOf(/&/) == -1) | |
| t = t.replace(/(?:\\u0026|%26|%2526|&)amp;/ig, '&'); | |
| t = SaveFrom_Utils.parseQuery(t); | |
| for(var i in t) | |
| t[i] = decodeURIComponent(t[i]); | |
| return t; | |
| } | |
| } | |
| var e = document.getElementsByTagName('embed'); | |
| for(var i = 0; i < e.length; i++) | |
| { | |
| var f = e[i].getAttribute('flashvars', false); | |
| if(f && f.search(/fmt_map=/i) != -1) | |
| { | |
| return SaveFrom_Utils.parseQuery(f); | |
| } | |
| } | |
| return null; | |
| }, | |
| getDownloadLink: function (video_id, token, fmt) | |
| { | |
| return 'http://' + location.host + '/get_video?video_id=' + video_id + '&t=' + token + '&fmt=' + fmt + '&asv='; | |
| }, | |
| showLinks: function(links, button) { | |
| var button = document.getElementById(youtube.buttonId); | |
| if (typeof links === 'string') { | |
| SaveFrom_Utils.popupMenu.create({ | |
| links: links, | |
| button: button, | |
| popupId: youtube.panelId, | |
| document: document, | |
| sfUtils: SaveFrom_Utils | |
| }); | |
| } else { | |
| var title = youtube.getTitle(); | |
| if(title) { | |
| title = modifyTitle(title); | |
| } | |
| var menuLinks = SaveFrom_Utils.popupMenu.prepareLinks.youtube(links, title, SaveFrom_Utils); | |
| SaveFrom_Utils.popupMenu.create({ | |
| links: menuLinks, | |
| button: button, | |
| popupId: youtube.panelId, | |
| document: document, | |
| sfUtils: SaveFrom_Utils, | |
| showFileSize: true | |
| }); | |
| } | |
| SaveFrom_Utils.addClass(button, 'yt-uix-button-toggled'); | |
| button.removeEventListener('mousedown', youtube.getLinks, false); | |
| button.removeEventListener('mousedown', youtube.togglePanel, false); | |
| button.addEventListener('mousedown', youtube.togglePanel, false); | |
| document.removeEventListener('mousedown', youtube.closePopup, false); | |
| document.addEventListener('mousedown', youtube.closePopup, false); | |
| }, | |
| closePopup: function () { | |
| var event = new CustomEvent('mousedown'); | |
| youtube.togglePanel(event); | |
| document.removeEventListener('mousedown', youtube.closePopup); | |
| }, | |
| togglePanel: function(event) | |
| { | |
| var button = document.getElementById(youtube.buttonId); | |
| event.preventDefault(); | |
| event.stopPropagation(); | |
| var e = document.getElementById(youtube.panelId); | |
| if(e) | |
| { | |
| if(e.style.display == 'none') | |
| { | |
| e.style.display = ''; | |
| SaveFrom_Utils.addClass(button, 'yt-uix-button-toggled'); | |
| document.addEventListener('mousedown', youtube.closePopup, false); | |
| } | |
| else | |
| { | |
| e.style.display = 'none'; | |
| SaveFrom_Utils.removeClass(button, 'yt-uix-button-toggled'); | |
| document.removeEventListener('mousedown', youtube.closePopup, false); | |
| } | |
| } | |
| }, | |
| signatureDecipher: function(sig, sts) | |
| { | |
| if(!sts) | |
| return sig; | |
| function swap(a, b) | |
| { | |
| var t = a[0]; | |
| a[0] = a[b % a.length]; | |
| a[b] = t; | |
| } | |
| if(sts == '15917') | |
| { | |
| var s = sig.split(''); | |
| s = s.reverse(); | |
| s = s.slice(2); | |
| swap(s, 65); | |
| s = s.reverse(); | |
| return s.join(''); | |
| } | |
| if(sts == '15956') | |
| { | |
| var s = sig.split(''); | |
| swap(s, 43); | |
| swap(s, 2); | |
| swap(s, 54); | |
| s = s.reverse(); | |
| swap(s, 8); | |
| s = s.slice(1); | |
| return s.join(''); | |
| } | |
| youtube.needDecipher = true; | |
| return sig; | |
| }, | |
| getDashQuery: function() | |
| { | |
| if(!youtube.swfargs || !youtube.swfargs.dashmpd) | |
| return ''; | |
| var u = youtube.swfargs.dashmpd.replace(/^.+\/api\/manifest\/dash\//i, ''); | |
| if(u == youtube.swfargs.dashmpd) | |
| return ''; | |
| u = u.split('/'); | |
| if(!u || u.length < 2) | |
| return ''; | |
| var query = {}; | |
| for(var i = 0; i < u.length - 1; i += 2) | |
| { | |
| if(u[i] != 'itag') | |
| { | |
| u[i] = decodeURIComponent(u[i]); | |
| u[i + 1] = decodeURIComponent(u[i + 1]); | |
| if(u[i] == 's') | |
| { | |
| u[i] = 'signature'; | |
| u[i + 1] = youtube.signatureDecipher(u[i + 1], youtube.sts); | |
| } | |
| else if(u[i] == 'sig') | |
| { | |
| u[i] = 'signature'; | |
| } | |
| else if(u[i] == 'sparams' && u[i + 1].search(/(^|,|%2C)itag(^|,|%2C)/i)) | |
| { | |
| return ''; | |
| } | |
| query[u[i]] = u[i + 1]; | |
| } | |
| } | |
| if(!query.signature) | |
| return ''; | |
| query.ratebypass = 'yes'; | |
| return SaveFrom_Utils.getQueryString(query); | |
| }, | |
| getLinks: function(event) | |
| { | |
| event.preventDefault(); | |
| event.stopPropagation(); | |
| var button = event.target; | |
| var d = button; | |
| while(d && d != document.body) | |
| { | |
| if(d.style.display == 'none') | |
| d.style.display = ''; | |
| if(d.style.visibility == 'hidden') | |
| d.style.visibility = 'visible'; | |
| d.style.zOrder = '9999'; | |
| d = d.parentNode; | |
| } | |
| if(youtube.links) | |
| { | |
| youtube.showLinks(youtube.links, button); | |
| return; | |
| } | |
| if(!youtube.swfargs || !youtube.token || !youtube.video_id) | |
| return; | |
| var links = youtube.parseFmtMap(youtube.swfargs.fmt_url_map || youtube.swfargs.url_encoded_fmt_stream_map); | |
| if(youtube.swfargs.adaptive_fmts) | |
| { | |
| var adaptive_links = youtube.parseFmtMap(youtube.swfargs.adaptive_fmts); | |
| for (var i in adaptive_links) { | |
| if(!links[i]) | |
| links[i] = adaptive_links[i]; | |
| } | |
| } | |
| if(youtube.needDecipher) | |
| { | |
| var request = { | |
| action: 'getYoutubeLinks', | |
| extVideoId: youtube.video_id | |
| }; | |
| chrome.extension.sendRequest(request, function(response){ | |
| if(response.links) | |
| { | |
| youtube.showLinks(response.links, button); | |
| } | |
| else | |
| { | |
| youtube.showLinks(links, button); | |
| } | |
| }); | |
| youtube.showLinks(chrome.i18n.getMessage('download') + | |
| ' ...', button); | |
| return; | |
| } | |
| youtube.getDashLinks(links, youtube.swfargs.dashmpd, function(_links) { | |
| if (_links) { | |
| links = _links; | |
| } | |
| youtube.showLinks(links, button); | |
| }); | |
| }, | |
| parseFmtMap: function(u) | |
| { | |
| if(!u) | |
| return; | |
| var l = {}, baseUrl = ''; | |
| if(u.search(/url=http/i) > -1) | |
| { | |
| u = u.split(','); | |
| for(var i = 0; i < u.length; ++i) | |
| { | |
| u[i] = u[i].replace(/\\u0026/ig, '&').replace(/\\\//g, '/'); | |
| var q = SaveFrom_Utils.parseQuery(u[i]); | |
| if(q.url) | |
| { | |
| q.url = decodeURIComponent(q.url); | |
| if(q.url.search(/(\?|&)sig(nature)?=/i) == -1) | |
| { | |
| if(q.sig) | |
| q.url += '&signature=' + q.sig; | |
| else if(q.signature) | |
| q.url += '&signature=' + q.signature; | |
| else if(q.s) | |
| q.url += '&signature=' + youtube.signatureDecipher(q.s, youtube.sts); | |
| } | |
| if(q.url.search(/(\?|&)itag=/i) == -1) | |
| { | |
| if(q.itag) | |
| q.url += '&itag=' + q.itag; | |
| } | |
| var fmt = q.url.match(/(?:\?|&)itag=(\d+)/i); | |
| if(fmt && fmt.length > 1) | |
| { | |
| q.url = q.url.replace(/(\?|&)sig=/i, '$1signature='). | |
| replace(/\\u0026/ig, '&').replace(/\\\//g, '/'); | |
| l[fmt[1]] = q.url; | |
| if(!baseUrl) | |
| baseUrl = SaveFrom_Utils.getMatchFirst(q.url, /^(https?:\/\/[^\?]+\?)/); | |
| } | |
| } | |
| } | |
| } | |
| else | |
| { | |
| u = decodeURIComponent(u); | |
| u = u.replace(/\\u0026/ig, '&').replace(/\\\//g, '/'); | |
| u = u.replace(/,(\d+)\|/g, "\n$1|"); | |
| u = u.split('\n'); | |
| if(u && u.length > 0) | |
| { | |
| for(var i = 0; i < u.length; i++) | |
| { | |
| var t = u[i].split('|'); | |
| if(t && t.length == 2) | |
| { | |
| l[t[0]] = t[1]; | |
| } | |
| } | |
| } | |
| } | |
| // Deprecated | |
| // youtube.findAvailableLinks(baseUrl, l); | |
| return l; | |
| }, | |
| findAvailableLinks: function(baseUrl, links) | |
| { | |
| if(!baseUrl) | |
| return; | |
| var dashQuery = youtube.getDashQuery(); | |
| if(!dashQuery) | |
| return; | |
| var itags = youtube.getAdaptiveFtmItags(); | |
| if(!itags) | |
| return; | |
| var map = { | |
| '133': ['5'], // 240 | |
| '134': ['34', '18', '43'], // 360 | |
| '135': ['35', '44'], // 480 | |
| '136': ['22', '45'], // 720 | |
| '137': ['37', '46'], // 1080 | |
| '138': ['38'] // 4k | |
| }; | |
| for(var i = 0; i < itags.length; i++) | |
| { | |
| if(map[itags[i]]) | |
| { | |
| for(var j = 0; j < map[itags[i]].length; j++) | |
| { | |
| var itag = map[itags[i]][j]; | |
| if(!links[itag]) | |
| { | |
| links[itag] = baseUrl + dashQuery + '&itag=' + itag; | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| getAdaptiveFtmItags: function() | |
| { | |
| var u = youtube.swfargs.adaptive_fmts; | |
| if(!u) | |
| return; | |
| var itags = []; | |
| u = u.split(','); | |
| for(var i = 0; i < u.length; ++i) | |
| { | |
| var q = SaveFrom_Utils.parseQuery(u[i]); | |
| var itag = 0; | |
| if(q.url) | |
| { | |
| q.url = decodeURIComponent(q.url); | |
| itag = SaveFrom_Utils.getMatchFirst(q.url, /(?:\?|&)itag=(\d+)/i); | |
| } | |
| if(!itag && q.itag) | |
| itag = q.itag; | |
| if(itag) | |
| itags.push(itag); | |
| } | |
| return itags; | |
| }, | |
| getDashLinks: (function() { | |
| var parseDash = function(xml, links, cb) { | |
| var parser = new DOMParser(); | |
| var xmlDoc = parser.parseFromString(xml,"text/xml"); | |
| var elList = xmlDoc.querySelectorAll('Representation'); | |
| if (!links) { | |
| links = {}; | |
| } | |
| for (var i = 0, el; el = elList[i]; i++) { | |
| var itag = el.id; | |
| if (links[itag] !== undefined) { | |
| continue; | |
| } | |
| var baseurl = el.querySelector('BaseURL'); | |
| if (baseurl === null) { | |
| continue; | |
| } | |
| var url = baseurl.textContent; | |
| links[itag] = url; | |
| } | |
| cb(links); | |
| }; | |
| var _getDashLinks = function(links, dashmpd, cb) { | |
| if (!dashmpd) { | |
| return cb(); | |
| } | |
| var signature_pos = dashmpd.indexOf('signature'); | |
| if (signature_pos === -1) { | |
| var s_pos = dashmpd.indexOf('/s/'); | |
| if (s_pos === -1) { | |
| return cb(); | |
| } | |
| s_pos += 3; | |
| var s_end = dashmpd.indexOf('/', s_pos); | |
| if (s_end === -1) { | |
| s_end = dashmpd.length; | |
| } | |
| var s = dashmpd.substr( s_pos, s_end - s_pos ); | |
| var signature = youtube.signatureDecipher(s, youtube.sts); | |
| if (signature === s) { | |
| return cb(); | |
| } | |
| dashmpd = dashmpd.substr(0, s_pos - 2) + 'signature/' + signature + dashmpd.substr(s_end); | |
| } | |
| SaveFrom_Utils.sendRequest(dashmpd, function(r) { | |
| if(r.status !== 200) { | |
| return cb(); | |
| } | |
| parseDash(r.responseText, links, cb); | |
| }); | |
| }; | |
| return _getDashLinks; | |
| })() | |
| }; | |
| function modifyTitle(t) | |
| { | |
| t = t.replace(/[\x2F\x5C\x3A\x7C]/g, '-'); | |
| t = t.replace(/[\x2A\x3F]/g, ''); | |
| t = t.replace(/\x22/g, '\''); | |
| t = t.replace(/\x3C/g, '('); | |
| t = t.replace(/\x3E/g, ')'); | |
| t = t.replace(/(?:^\s+)|(?:\s+$)/g, ''); | |
| return t; | |
| } | |
| SaveFrom_Utils.initModule(moduleName, function(response){ | |
| //console.log('youtube', response); | |
| if(response.lite) | |
| return; | |
| prefs = response; | |
| SaveFrom_Utils.runModule(response, youtube); | |
| }); | |
| }; | |
| _modules.lm = function(){ | |
| if(window.top != window.self) | |
| return; | |
| var moduleName = 'lm', | |
| prefs = {}; | |
| chrome.extension.onRequest.addListener(function(request, sender, callback){ | |
| switch(request.action){ | |
| case 'updateLinks': | |
| lm.run(); | |
| break; | |
| } | |
| }); | |
| var lm = { | |
| htmlAfter: '', | |
| linkText: '', | |
| linkStyle: { | |
| 'border': 'none', | |
| 'textDecoration': 'none', | |
| 'padding': '0', | |
| 'position': 'relative' | |
| }, | |
| imgStyle: { | |
| 'border': 'none', | |
| 'width': 'auto', | |
| 'height': 'auto' | |
| }, | |
| buttonSrc: 'data:image/gif;base64,R0lGODlhEAAQAOZ3APf39+Xl5fT09OPj4/Hx8evr6/3+/u7u7uDh4OPi497e3t7e3/z8/P79/X3GbuXl5ubl5eHg4WzFUfb39+Pj4lzGOV7LOPz7+/n6+vn5+ZTLj9/e387Ozt7f3/7+/vv7/ISbePn5+m/JV1nRKXmVbkCnKVrSLDqsCuDh4d/e3uDn3/z7/H6TdVeaV1uSW+bn5v39/eXm5eXm5kyHP/f39pzGmVy7J3yRd9/f3mLEKkXCHJbka2TVM5vaZn6Wdfn6+YG/c/r5+ZO/jeLi41aHTIeageLn4f39/vr6+kzNG2PVM5i+lomdf2CXYKHVmtzo2YXNeDqsBebl5uHh4HDKWN3g3kKqEH6WeZHTXIPKdnSPbv79/pfmbE7PHpe1l4O8dTO5DODg4VDLIlKUUtzo2J7SmEWsLlG4NJbFjkrJHP7+/VK5Nfz8+zmnC3KKa+Hg4OHh4Y63j/3+/eDg4Ojo6P///8DAwP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAHcALAAAAAAQABAAAAfWgHd2g4SFhYJzdYqLjIpzgx5bBgYwHg1Hk2oNDXKDFwwfDF5NLmMtcStsn4MhGT8YS04aGmU1QRhIGYMTADQAQlAODlloAMYTgwICRmRfVBISIkBPKsqDBAREZmcVFhYVayUz2IMHB1dWOmImI2lgUVrmgwUFLzdtXTxKSSduMfSD6Aik48MGlx05SAykM0gKhAAPAhTB0oNFABkPHg5KMIBCxzlMQFQZMGBIggSDpsCJgGDOmzkIUCAIM2dOhEEcNijQuQDHgg4KOqRYwMGOIENIB90JBAA7', | |
| sfref: '&utm_source={helper}&utm_medium=extensions&utm_campaign=link_modifier', | |
| pageUrl: 'http://savefrom.net/', | |
| anchorAttribute: 'savefrom_lm', | |
| anchorIndexAttribute: 'savefrom_lm_index', | |
| linkRegExp: null, | |
| savefromLinkCount: 0, | |
| re: { | |
| filehosting: { | |
| 'rapidshare.com': [/^https?:\/\/([\w\-]+\.)?rapidshare\.com\/\#\!download\|\d+\|\d+\|[^\s\"\|]+\|\d+/i, /^https?:\/\/(rs\d+\.|www\.)?rapidshare\.com\/files\/\d+\/.+/i], | |
| 'filefactory.com': [/^http:\/\/(www\.)?filefactory\.com\/file\/[a-z0-9]+\/?/i], | |
| 'sendspace.com': [/^http:\/\/(www\.)?sendspace\.com\/file\/\w+/i] | |
| }, | |
| mediahosting: { | |
| 'youtube.com': [ | |
| /^https?:\/\/([a-z]+\.)?youtube\.com\/(#!?\/)?watch\?.*v=/i, | |
| /^https?:\/\/([a-z0-9]+\.)?youtube\.com\/(embed|v)\/[\w\-]+/i | |
| ], | |
| 'youtu.be': [/^https?:\/\/([a-z]+\.)?youtu\.be\/[\w\-]+/i], | |
| 'google.com': [/^http:\/\/video\.google\.com\/videoplay\?.*docid=/i], | |
| 'metacafe.com': [/^http:\/\/(www\.)?metacafe\.com\/watch\/\d+\/[^\/]+\/?/i], | |
| 'break.com': [/^http:\/\/(www\.)?break\.com\/(index|movies\w*|(\w+\-)+\w+)\/.+\.html$/i, /^http:\/\/view\.break\.com\/\d+/i], | |
| 'vimeo.com': [/^http:\/\/([\w\-]+\.)?vimeo\.com\/\d+$/i], | |
| 'sevenload.com': [/^http:\/\/([\w\-]+\.)?sevenload\.com\/videos\/[\w\-\+\/=]+/i, /^http:\/\/([\w\-]+\.)?sevenload\.com\/shows\/.+/i], | |
| 'facebook.com': [/^https?:\/\/(?:www\.)facebook\.com\/([^\/]+\/)*video\.php\?([^&]+&)*v=\d+/i], | |
| //'rutube.ru': [/^http:\/\/rutube\.ru\/tracks\/\d+\.html\?.*v=[a-f0-9]+/i], | |
| 'mail.ru': [/^http:\/\/([a-z0-9_-]+\.)?video\.mail\.ru\/(.+\/)+\d+\.html/i, /^http:\/\/r\.mail\.ru\/\w+\/video\.mail\.ru\/(.+\/)+\d+\.html/i], | |
| 'yandex.ru': [/^http:\/\/video\.yandex\.ru\/users\/[\w\-,!\+]+\/view\/[\w\-,!\+]+\/?/i], | |
| 'rambler.ru': [/^http:\/\/vision\.rambler\.ru\/users\/[^\/\s]+\/\d+\/[\w\-_\+!]+\/?/i], | |
| 'smotri.com': [/^http:\/\/([a-z0-9_-]+\.)?smotri\.com\/video\/view\/\?.*id=v[0-9a-f]/i], | |
| 'tvigle.ru': [/^http:\/\/(www\.)?tvigle\.ru\/channel\/\d+\?.*vid_id=\d+/i, /^http:\/\/(www\.)tvigle\.ru\/prg\/\d+\/\d+/i], | |
| 'intv.ru': [/^http:\/\/(www\.)?intv\.ru\/(view|quickdl)\/\?.*film_id=\w+/i, /^http:\/\/(www\.)?intv\.ru\/v\/\w+/i], | |
| 'yasee.ru': [/^http:\/\/([a-z0-9_-]+\.)?yasee\.ru\/video\/view\/\?.*id=v[0-9a-f]/i], | |
| 'narod.tv': [/^http:\/\/(?:www\.)?narod\.tv\/\?.*vid=/i], | |
| 'vkadre.ru': [/^http:\/\/(www\.)?vkadre\.ru\/videos\/\d+/i], | |
| 'myvi.ru': [ | |
| /^http:\/\/(www\.)?myvi\.ru\/([a-z][a-z]\/)?videodetail\.aspx\?.*video=/i, | |
| /^http:\/\/(www|kino|anime)\.myvi\.ru\/watch\/[\w\-]+/i | |
| ], | |
| '1tv.ru': [/^http:\/\/(www\.)?1tv\.ru(\:\d+)?\/newsvideo\/\d+/i, /^http:\/\/(www\.)?1tv\.ru(\:\d+)?\/news\/\w+\d+/i], | |
| 'ntv.ru': [/^http:\/\/news\.ntv\.ru\/(\w+\/)?\d+\/video\/?/i], | |
| 'vesti.ru': [/^http:\/\/(www\.)?vesti\.ru\/videos\?.*vid=\d+/i], | |
| 'bibigon.ru': [/^http:\/\/(www\.)?bibigon\.ru\/videow\.html\?id=\d+/i, /^http:\/\/(www\.)?bibigon\.ru\/video\.html\?vid=\d+/i], | |
| 'mreporter.ru': [/^http:\/\/(www\.)?mreporter\.ru\/reportermessages\!viewreport\.do[^\?]*\?.*reportid=\d+/i], | |
| 'autoplustv.ru': [/^http:\/\/(www\.)?autoplustv\.ru\/494\/\?id=\d+/i], | |
| 'russia.ru': [/^http:\/\/([\w\-]+\.)?russia\.ru\/video\/?/i], | |
| 'amik.ru': [/^http:\/\/(www\.)?amik\.ru\/video\/vid\d+\.html/i, /^http:\/\/(www\.)?amik\.ru\/video\/vcid\d+\.html/i], | |
| 'life.ru': [/^http:\/\/([\w+\-]+\.)?life\.ru\/video\/\d+/i] | |
| } | |
| }, | |
| parseHref: function(href, search) | |
| { | |
| var res = new Array(); | |
| res.push(href); | |
| var i = href.toLowerCase().indexOf('http://', 7); | |
| if(i > 7) | |
| { | |
| res.push(href.substring(i)); | |
| } | |
| else if(search) | |
| { | |
| var h = search.match(/http%3a(%2f%2f|\/\/)[^\s\&\"\<\>]+/i); | |
| if(h && h.length > 0) | |
| { | |
| res.push(decodeURIComponent(h[0])); | |
| } | |
| else | |
| { | |
| var s = ''; | |
| try | |
| { | |
| s = decodeURIComponent(search); | |
| } | |
| catch(err) | |
| { | |
| } | |
| if(s) | |
| { | |
| h = s.match(/((?:aHR0cDovL|aHR0cHM6Ly)[a-z0-9+\/=]+)/i); | |
| if(h && h.length > 1) | |
| { | |
| h = base64.decode(h[1]); | |
| if(h.search(/^https?:\/\//i) != -1) | |
| res.push(decodeURIComponent(h)); | |
| } | |
| } | |
| } | |
| } | |
| return res; | |
| }, | |
| href: function(a) | |
| { | |
| return a.getAttribute('href', false); | |
| }, | |
| getElementIndex: function(e) | |
| { | |
| var html = e.innerHTML; | |
| if(!html || html == ' ') | |
| return 1; | |
| var bg = e.style.backgroundImage; | |
| if(bg && bg != 'none') | |
| return 1; | |
| var c = e.getElementsByTagName('*'); | |
| for(var i = 0; i < c.length; i++) | |
| { | |
| if(c[i].tagName == 'IMG') | |
| return 2; | |
| else | |
| { | |
| bg = c[i].style.backgroundImage; | |
| if(bg && bg != 'none') | |
| return 1; | |
| } | |
| } | |
| return 0; | |
| }, | |
| run: function() | |
| { | |
| SaveFrom_Utils.embedDownloader.init(); | |
| lm.sfref = lm.sfref.replace('{helper}', prefs.helper); | |
| var prefFileHosting = (prefs.lmFileHosting == '0') ? false : true; | |
| var prefMediaHosting = (prefs.lmMediaHosting == '0') ? false : true; | |
| if(!prefFileHosting && !prefMediaHosting) | |
| return; | |
| lm.linkRegExp = {}; | |
| if(prefFileHosting) | |
| { | |
| for(var i in lm.re.filehosting) | |
| lm.linkRegExp[i] = lm.re.filehosting[i]; | |
| } | |
| if(prefMediaHosting) | |
| { | |
| for(var i in lm.re.mediahosting) | |
| lm.linkRegExp[i] = lm.re.mediahosting[i]; | |
| } | |
| var a = document.getElementsByTagName('a'); | |
| if(lm.savefromLinkCount != a.length) | |
| { | |
| lm.savefromLinkCount = a.length; | |
| var found = {}, lastHref = ''; | |
| for(var i = 0; i < a.length; i++) | |
| { | |
| var href = handleAnchor(a[i]); | |
| if(href) | |
| { | |
| var index = 0; | |
| var attr = a[i].getAttribute(lm.anchorIndexAttribute, false); | |
| if(attr === 0 || attr) | |
| index = parseInt(attr); | |
| else | |
| { | |
| index = lm.getElementIndex(a[i]); | |
| a[i].setAttribute(lm.anchorIndexAttribute, index, false); | |
| } | |
| if(found[href]) | |
| { | |
| if(index < found[href].index) | |
| { | |
| found[href].elements = [a[i]]; | |
| found[href].index = index; | |
| lastHref = href; | |
| } | |
| else if(index == found[href].index && href != lastHref) | |
| { | |
| found[href].elements.push(a[i]); | |
| lastHref = href; | |
| } | |
| } | |
| else | |
| { | |
| found[href] = { | |
| index: index, | |
| elements: [a[i]] | |
| }; | |
| lastHref = href; | |
| } | |
| } | |
| } | |
| var count = 0; | |
| for(var i in found) | |
| { | |
| for(var j = 0; j < found[i].elements.length; j++) | |
| { | |
| var e = found[i].elements[j]; | |
| count++; | |
| if(!e.getAttribute(lm.anchorAttribute, false)) | |
| modifyLink(e, i); | |
| } | |
| } | |
| } | |
| function checkLink(link, domain) | |
| { | |
| if(!link) | |
| return false; | |
| if(link == window.location.href) | |
| return false; | |
| domain = SaveFrom_Utils.getTopLevelDomain(domain); | |
| if(!domain || !lm.linkRegExp[domain]) | |
| return false; | |
| for(var i = 0; i < lm.linkRegExp[domain].length; i++) | |
| { | |
| if(link.search(lm.linkRegExp[domain][i]) != -1) | |
| return true; | |
| } | |
| return false; | |
| } | |
| function handleAnchor(obj) | |
| { | |
| var href = obj.href; | |
| if(href && (href.search(/^https?:\/\/([\w\-]+\.)?savefrom\.net\//i) == -1)) | |
| { | |
| var hrefArray = lm.parseHref(href, obj.search); | |
| if(hrefArray.length > 0) | |
| { | |
| if(lm.href(obj).indexOf('#') != 0 && checkLink(hrefArray[0], obj.hostname)) | |
| { | |
| return hrefArray[0]; | |
| } | |
| else if(hrefArray.length > 1) | |
| { | |
| for(var j = 1; j < hrefArray.length; j++) | |
| { | |
| var aTemp = document.createElement('a'); | |
| aTemp.href = hrefArray[j]; | |
| if(lm.href(aTemp).indexOf('#') != 0 && checkLink(hrefArray[j], aTemp.hostname)) | |
| { | |
| return hrefArray[j]; | |
| } | |
| } | |
| } | |
| } | |
| } | |
| return ''; | |
| } | |
| function modifyLink(obj, link) | |
| { | |
| if(!obj) | |
| return; | |
| obj.setAttribute(lm.anchorAttribute, '1', false); | |
| var box = document.createElement('span'); | |
| box.setAttribute('style', 'padding: 0; margin: 0; margin-left: 5px;', false); | |
| box.addEventListener('click', function(e) { | |
| e.stopPropagation(); | |
| }); | |
| var parent = obj.parentNode; | |
| if(!parent) | |
| return; | |
| try | |
| { | |
| link = encodeURIComponent(link); | |
| } | |
| catch(err) | |
| { | |
| return; | |
| } | |
| var href = lm.pageUrl + '?url=' + link; | |
| if(lm.sfref) | |
| href += lm.sfref; | |
| // add button | |
| var a = document.createElement('a'); | |
| a.href = href; | |
| a.target = '_blank'; | |
| a.title = chrome.i18n.getMessage('lmButtonTitle'); | |
| a.style.backgroundImage = 'url('+lm.buttonSrc+')'; | |
| a.style.backgroundRepeat = 'no-repeat'; | |
| a.style.width = '16px'; | |
| a.style.height = '16px'; | |
| a.style.display = 'inline-block'; | |
| for(var i in lm.linkStyle) | |
| a.style[i] = lm.linkStyle[i]; | |
| if (obj.style.zIndex) { | |
| a.style.zIndex = obj.style.zIndex; | |
| } | |
| a.setAttribute(lm.anchorAttribute, '1', false); | |
| if(lm.linkText) | |
| { | |
| a.innerHTML = lm.linkText; | |
| } | |
| box.appendChild(a); | |
| if(lm.htmlAfter) | |
| box.innerHTML += lm.htmlAfter; | |
| if(obj.nextSibling) | |
| parent.insertBefore(box, obj.nextSibling); | |
| else | |
| parent.appendChild(box); | |
| } | |
| } | |
| }; | |
| // Base64 | |
| var base64 = { | |
| key: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", | |
| decode: function(text) | |
| { | |
| var res = ''; | |
| var c1, c2, c3, e1, e2, e3, e4; | |
| var i = 0; | |
| text = text.replace(/[^A-Za-z0-9\+\/\=]/g, ''); | |
| while(i < text.length) | |
| { | |
| e1 = base64.key.indexOf(text.charAt(i++)); | |
| e2 = base64.key.indexOf(text.charAt(i++)); | |
| e3 = base64.key.indexOf(text.charAt(i++)); | |
| e4 = base64.key.indexOf(text.charAt(i++)); | |
| c1 = (e1 << 2) | (e2 >> 4); | |
| c2 = ((e2 & 15) << 4) | (e3 >> 2); | |
| c3 = ((e3 & 3) << 6) | e4; | |
| res += String.fromCharCode(c1); | |
| if(e3 != 64) | |
| res += String.fromCharCode(c2); | |
| if(e4 != 64) | |
| res += String.fromCharCode(c3); | |
| } | |
| return res; | |
| } | |
| }; | |
| SaveFrom_Utils.initModule(moduleName, function(response){ | |
| if (response && response.moduleEnable) | |
| { | |
| prefs = response; | |
| prefs.lmFileHosting = prefs.lmFileHosting || '1'; | |
| prefs.lmMediaHosting = prefs.lmMediaHosting || '1'; | |
| SaveFrom_Utils.runModule(response, lm); | |
| window.addEventListener('load', function(event){ | |
| lm.run(); | |
| window.removeEventListener('load', arguments.callee, false); | |
| }, false); | |
| } | |
| }); | |
| }; | |
| ///////////////////////////////////////////////// | |
| // LOCALES | |
| chrome.i18n.messages.de = { | |
| "extName": {"message": "SaveFrom.net Helfer"}, | |
| "extDescription": {"message": "Laden Sie von YouTube, RapidShare, VK.com und mehr als 40 anderen Seiten mit einem Klick herunter."}, | |
| "extNameLite": {"message": "SaveFrom.net Helfer Lite"}, | |
| "extDescriptionLite": {"message": "Herunterladen von RapidShare, VK.com und mehr als 40 weiteren Seiten mit einem Klick herunter."}, | |
| "lang": {"message": "de"}, | |
| "titleDefault": {"message": "SaveFrom.net Helfer"}, | |
| "titleDesabled": {"message": "SaveFrom.net Helfer deaktiviert"}, | |
| "menuEnable": {"message": "Aktivieren"}, | |
| "menuDisable": {"message": "Deaktivieren"}, | |
| "download": {"message": "Herunterladen"}, | |
| "downloadTitle": {"message": "Klicken Sie den Link während Sie die Alt/Einstellung oder Ctrl/Strg Taste drücken zum Herunterladen der Dateien."}, | |
| "noLinksFound": {"message": "Keine Links wurden gefunden"}, | |
| "more": {"message": "Mehr"}, | |
| "close": {"message": "Schließen"}, | |
| "kbps": {"message": "kbps"}, | |
| "withoutAudio": {"message": "without audio"}, | |
| "subtitles": {"message": "Untertitel"}, | |
| "playlist": {"message": "Wiedergabliste"}, | |
| "filelist": {"message": "List of files"}, | |
| "downloadWholePlaylist": {"message": "Die komplette Wiedergabliste herunterladen"}, | |
| "getFileSizeTitle": {"message": "Dateigröße bestimmen" }, | |
| "getFileSizeFailTitle": {"message": "Fehler bei bestimmung der Dateigröße. Bitte versuchen Sie es erneut."}, | |
| "lmButtonTitle": {"message": "Holen Sie sich einen direkten Link."}, | |
| "downloadFromCurrentPage": {"message": "Download von der aktuellen Seite"}, | |
| "updateLinks": {"message": "Download-Links Aktualisieren"}, | |
| "updateLinksNotification": {"message": "Links updated"}, | |
| "downloadMP3Files": {"message": "Alle MP3 Dateien herunterladen"}, | |
| "downloadPlaylist": {"message": "MP3 Playlist herunterladen"}, | |
| "downloadPhotos": {"message": "Download all photos"}, | |
| "installFullVersion": {"message": "Install full version"}, | |
| "disable": {"message": "Deaktivieren"}, | |
| "showOptions": {"message": "Options"}, | |
| "reportBug": {"message": "Report a bug"}, | |
| "aboutPage": {"message": "Über"}, | |
| "aboutTitle": {"message": "SaveFrom.net Helfer"}, | |
| "aboutVersion": {"message": "Version"}, | |
| "aboutDescription": {"message": "Hilft den Nutzern direkte Links zu Herunterladen von mehr als 40 Webseiten, inklusive Dailymotion.com, RapidShare.com, YouTube.com, VK.com und weiteren zu bekommen."}, | |
| "aboutDescriptionLite": {"message": "Hilft den Nutzern direkte Links zu Herunterladen von mehr als 40 Webseiten, inklusive Dailymotion.com, RapidShare.com, VK.com und weiteren zu bekommen."}, | |
| "aboutSupported": {"message": "Unterstützte Ressourcen"}, | |
| "homePage": {"message": "Homepage"}, | |
| "menuTooltip": {"message": "This is a menu of SaveFrom.net Helper.<br><br>Using it, you can download videos and audio from a current page or set up the extension.<br><br>Menu items will vary from site to site.<br><br>You can hide a button with the right click on an icon."}, | |
| "optionsTitle": {"message": "SaveFrom.net Helfer - Einstellungen"}, | |
| "optionsHandleLinks": {"message": "Links handhaben"}, | |
| "optionsFileHostings": {"message": "Zu Dateihoster"}, | |
| "optionsMediaHostings": {"message": "Zu Medienhoster"}, | |
| "optionsModules": {"message": "Module"}, | |
| "optionsYoutube": {"message": "YouTube"}, | |
| "optionsYTHideLinks": {"message": "Links ausblenden"}, | |
| "optionsDailymotion": {"message": "Dailymotion"}, | |
| "optionsVimeo": {"message": "Vimeo"}, | |
| "optionsFacebook": {"message": "Facebook"}, | |
| "optionsSoundcloud": {"message": "SoundCloud"}, | |
| "optionsVkontakte": {"message": "VK"}, | |
| "optionsOdnoklassniki": {"message": "Odnoklassniki"}, | |
| "optionsBitrate": {"message": "Bitrate sofort zeigen"}, | |
| "filelistTitle": {"message": "Die Liste der gefundenen MP3-Dateien"}, | |
| "filelistInstruction": {"message": "Zum Herunterladen aller MP3-Datien kopieren Sie die liste der Links in Ihren <a href=\"http://en.wikipedia.org/wiki/Download_manager\">Download Manager</a>. Wenn Sie noch keinen Download Manager haben we empfehlen wir Ihnen die Installation des <a href=\"http://www.freedownloadmanager.org/\">Free Download Manager</a>."}, | |
| "playlistTitle": {"message": "Wiedergabliste"}, | |
| "playlistInstruction": {"message": "Um eine Wiedergabliste zu speichern, Rechtsklicken Sie auf den jeweiligen Link und wählen Sie "Ziel speichern unter ..." aus. Oder kopieren Sie den Inhalt des Textfelds und speichern Sie die Datei unter Angabe der entsprechenden Erweiterung.<br><br>Zur Wiedergabe Ihrer gespeicherten Wiedergabliste kann es nun mit einem Musik-Player geöffnet werden."}, | |
| "vkInfo": {"message": "Info"}, | |
| "vkInfoTitle": {"message": "Dateigröße und Bitrate"}, | |
| "vkMp3LinksNotFound": {"message": "Links zu MP3 Dateien wurden nicht gefunden"}, | |
| "vkPhotoLinksNotFound": {"message": "Photos are not found"}, | |
| "vkDownloadPhotoAlbum": {"message": "Album herunterladen"}, | |
| "vkDownloadAllPhotoAlbums": {"message": "Alle Alben herunterladen"}, | |
| "vkFoundPhotos": {"message": "Gefundene Fotos"}, | |
| "vkNotAvailablePhotos": {"message": "%d Foto(s) vorübergehend nicht verfügbar"}, | |
| "vkFoundLinks": {"message": "Gefundene Links"}, | |
| "vkFoundOf": {"message": "von"}, | |
| "vkShowAs": {"message": "Zeigen als"}, | |
| "vkListOfLinks": {"message": "Liste der Links"}, | |
| "vkListOfLinksInstruction": {"message": "Um alle Fotos herunterzuladen, kopieren Sie die Links aus der Liste und fügen Sie diese in Ihren <a href=\"http://en.wikipedia.org/wiki/Download_manager\">Download Manager</a> ein. Wenn Sie noch keinen Download Manager haben we empfehlen wir Ihnen die Installation des <a href=\"http://www.freedownloadmanager.org/\">Free Download Manager</a>."}, | |
| "vkTableOfThumbnails": {"message": "Tabelle der Thumbnails"}, | |
| "vkListOfPhotos": {"message": "Liste der Fotos"}, | |
| "vkListOfPhotosInstruction": {"message": "Klicken Sie auf ein Foto um es herunterzuladen."}, | |
| "vkKbps": {"message": "kbps"}, | |
| "vkFileSizeByte": {"message": "B"}, | |
| "vkFileSizeKByte": {"message": "kB"}, | |
| "vkFileSizeMByte": {"message": "MB"}, | |
| "vkFileSizeGByte": {"message": "GB"}, | |
| "vkFileSizeTByte": {"message": "TB"}, | |
| "vkDownloadFromYoutube": {"message": "Herunterladen: Öffnen Sie <a href=\"{url}\">die Video Seite</a> und drücken Sie den "Herunterladen" Knopf über dem Video-Spieler"} | |
| }; | |
| chrome.i18n.messages.en = { | |
| "extName": {"message": "SaveFrom.net helper"}, | |
| "extDescription": {"message": "Download YouTube, RapidShare, VK.com and 40+ sites in one click."}, | |
| "extNameLite": {"message": "SaveFrom.net helper lite"}, | |
| "extDescriptionLite": {"message": "Download RapidShare, VK.com and 40+ sites in one click."}, | |
| "lang": {"message": "en"}, | |
| "titleDefault": {"message": "SaveFrom.net helper"}, | |
| "titleDesabled": {"message": "SaveFrom.net helper disabled"}, | |
| "menuEnable": {"message": "Enable"}, | |
| "menuDisable": {"message": "Disable"}, | |
| "download": {"message": "Download"}, | |
| "downloadTitle": {"message": "Click the link while holding Alt/Option or Ctrl key to download the file."}, | |
| "noLinksFound": {"message": "No links were found"}, | |
| "more": {"message": "More"}, | |
| "close": {"message": "Close"}, | |
| "kbps": {"message": "kbps"}, | |
| "withoutAudio": {"message": "without audio"}, | |
| "subtitles": {"message": "Subtitles"}, | |
| "playlist": {"message": "Playlist"}, | |
| "filelist": {"message": "List of files"}, | |
| "downloadWholePlaylist": {"message": "Download the whole playlist"}, | |
| "getFileSizeTitle": {"message": "Get file size" }, | |
| "getFileSizeFailTitle": {"message": "Unable to get the file size. Please try again."}, | |
| "lmButtonTitle": {"message": "Get a direct link"}, | |
| "downloadFromCurrentPage": {"message": "Download from current page"}, | |
| "updateLinks": {"message": "Refresh download links"}, | |
| "updateLinksNotification": {"message": "Links updated"}, | |
| "downloadMP3Files": {"message": "Download all MP3 files"}, | |
| "downloadPlaylist": {"message": "Download MP3 playlist"}, | |
| "downloadPhotos": {"message": "Download all photos"}, | |
| "installFullVersion": {"message": "Install full version"}, | |
| "disable": {"message": "Disable"}, | |
| "showOptions": {"message": "Options"}, | |
| "reportBug": {"message": "Report a bug"}, | |
| "aboutPage": {"message": "About"}, | |
| "aboutTitle": {"message": "SaveFrom.net Helper"}, | |
| "aboutVersion": {"message": "Version"}, | |
| "aboutDescription": {"message": "Helps users to get direct links to download from more than 40 websites, including Dailymotion.com, RapidShare.com, YouTube.com, VK.com and others."}, | |
| "aboutDescriptionLite": {"message": "Helps users to get direct links to download from more than 40 websites, including Dailymotion.com, RapidShare.com, VK.com and others."}, | |
| "aboutSupported": {"message": "Supported resources"}, | |
| "homePage": {"message": "Home page"}, | |
| "menuTooltip": {"message": "This is a menu of SaveFrom.net Helper.<br><br>Using it, you can download videos and audio from a current page or set up the extension.<br><br>Menu items will vary from site to site.<br><br>You can hide a button with the right click on an icon."}, | |
| "optionsTitle": {"message": "SaveFrom.net Helper - Preferences"}, | |
| "optionsHandleLinks": {"message": "Handle links"}, | |
| "optionsFileHostings": {"message": "To filehostings"}, | |
| "optionsMediaHostings": {"message": "To mediahostings"}, | |
| "optionsModules": {"message": "Modules"}, | |
| "optionsYoutube": {"message": "YouTube"}, | |
| "optionsYTHideLinks": {"message": "Hide links"}, | |
| "optionsDailymotion": {"message": "Dailymotion"}, | |
| "optionsVimeo": {"message": "Vimeo"}, | |
| "optionsFacebook": {"message": "Facebook"}, | |
| "optionsSoundcloud": {"message": "SoundCloud"}, | |
| "optionsVkontakte": {"message": "VK"}, | |
| "optionsOdnoklassniki": {"message": "Odnoklassniki"}, | |
| "optionsBitrate": {"message": "Show bitrate instantly"}, | |
| "filelistTitle": {"message": "The list of the found MP3 files"}, | |
| "filelistInstruction": {"message": "To download all MP3 files copy the list of links and paste it into the <a href=\"http://en.wikipedia.org/wiki/Download_manager\">download manager</a>. If you do not have a download manager installed we recommend installing <a href=\"http://www.freedownloadmanager.org/\">Free Download Manager</a>."}, | |
| "playlistTitle": {"message": "Playlist"}, | |
| "playlistInstruction": {"message": "To save a playlist right-click on the respective link and select "Save Target As ...". Or copy the text field contents and save the file specifying the appropriate extension.<br><br>To playback the saved playlist it may be now opened in the music player."}, | |
| "vkInfo": {"message": "Info"}, | |
| "vkInfoTitle": {"message": "File size and bitrate"}, | |
| "vkMp3LinksNotFound": {"message": "Links to MP3 files are not found"}, | |
| "vkPhotoLinksNotFound": {"message": "Photos are not found"}, | |
| "vkDownloadPhotoAlbum": {"message": "Download album"}, | |
| "vkDownloadAllPhotoAlbums": {"message": "Download all albums"}, | |
| "vkFoundPhotos": {"message": "Found photos"}, | |
| "vkNotAvailablePhotos": {"message": "%d photos are temporarily unavailable"}, | |
| "vkFoundLinks": {"message": "Found links"}, | |
| "vkFoundOf": {"message": "of"}, | |
| "vkShowAs": {"message": "Show as"}, | |
| "vkListOfLinks": {"message": "List of links"}, | |
| "vkListOfLinksInstruction": {"message": "To download all photos copy the list of links and paste it into the <a href=\"http://en.wikipedia.org/wiki/Download_manager\">download manager</a>. If you do not have a download manager installed we recommend installing <a href=\"http://www.freedownloadmanager.org/\">Free Download Manager</a>."}, | |
| "vkTableOfThumbnails": {"message": "Table of thumbnails"}, | |
| "vkListOfPhotos": {"message": "List of photos"}, | |
| "vkListOfPhotosInstruction": {"message": "Click on the photo to download it."}, | |
| "vkKbps": {"message": "kbps"}, | |
| "vkFileSizeByte": {"message": "B"}, | |
| "vkFileSizeKByte": {"message": "kB"}, | |
| "vkFileSizeMByte": {"message": "MB"}, | |
| "vkFileSizeGByte": {"message": "GB"}, | |
| "vkFileSizeTByte": {"message": "TB"}, | |
| "vkDownloadFromYoutube": {"message": "Download: open <a href=\"{url}\">the video page</a> and press the "Download" button above the player"} | |
| }; | |
| chrome.i18n.messages.ru = { | |
| "extName": {"message": "SaveFrom.net помощник"}, | |
| "extDescription": {"message": "Скачивайте с Вконтакте, YouTube, RapidShare и еще 40 сайтов за 1 клик."}, | |
| "extNameLite": {"message": "SaveFrom.net помощник lite"}, | |
| "extDescriptionLite": {"message": "Скачивайте с Вконтакте, RapidShare и еще 40 сайтов за 1 клик."}, | |
| "lang": {"message": "ru"}, | |
| "titleDefault": {"message": "SaveFrom.net помощник"}, | |
| "titleDesabled": {"message": "SaveFrom.net помощник выключен"}, | |
| "menuEnable": {"message": "Включить"}, | |
| "menuDisable": {"message": "Выключить"}, | |
| "download": {"message": "Скачать"}, | |
| "downloadTitle": {"message": "Нажмите на ссылку, удерживая клавишу Alt или Ctrl, чтобы сохранить файл."}, | |
| "noLinksFound": {"message": "Не удалось найти ссылки"}, | |
| "more": {"message": "Ещё"}, | |
| "close": {"message": "Закрыть"}, | |
| "kbps": {"message": "кб/с"}, | |
| "withoutAudio": {"message": "без аудио"}, | |
| "subtitles": {"message": "Субтитры"}, | |
| "playlist": {"message": "Плейлист"}, | |
| "filelist": {"message": "Список файлов"}, | |
| "downloadWholePlaylist": {"message": "Скачать весь плейлист"}, | |
| "getFileSizeTitle": {"message": "Определить размер файла" }, | |
| "getFileSizeFailTitle": {"message": "Не удалось определить размер файла. Попробуйте повторить попытку."}, | |
| "lmButtonTitle": {"message": "Получи прямую ссылку"}, | |
| "downloadFromCurrentPage": {"message": "Скачать с текущей страницы"}, | |
| "updateLinks": {"message": "Обновить ссылки для скачивания"}, | |
| "updateLinksNotification": {"message": "Ссылки обновлены"}, | |
| "downloadMP3Files": {"message": "Скачать все MP3 файлы"}, | |
| "downloadPlaylist": {"message": "Скачать MP3 плейлист"}, | |
| "downloadPhotos": {"message": "Скачать все фотографии"}, | |
| "installFullVersion": {"message": "Установить полную версию"}, | |
| "disable": {"message": "Выключить"}, | |
| "showOptions": {"message": "Настройки"}, | |
| "reportBug": {"message": "Сообщить об ошибке"}, | |
| "aboutPage": {"message": "О расширении"}, | |
| "aboutTitle": {"message": "SaveFrom.net помощник"}, | |
| "aboutVersion": {"message": "Версия"}, | |
| "aboutDescription": {"message": "Позволяет получать прямые ссылки для скачивания с более чем 40 сайтов, среди которых Vkontakte.ru, RapidShare.com, YouTube.com и другие."}, | |
| "aboutDescriptionLite": {"message": "Позволяет получать прямые ссылки для скачивания с более чем 40 сайтов, среди которых Vkontakte.ru, RapidShare.com и другие."}, | |
| "aboutSupported": {"message": "Поддерживаемые ресурсы"}, | |
| "homePage": {"message": "Домашняя страница"}, | |
| "menuTooltip": {"message": "Это меню SaveFrom.net помощника.<br><br>С его помощью можно скачивать видео, аудио, плейлисты с текущей страницы и настраивать расширение.<br><br>Возможности меню зависят от сайта, на котором вы находитесь.<br><br>Скрыть кнопку можно щелчком правой кнопкой мышки на значке."}, | |
| "optionsTitle": {"message": "SaveFrom.net помощник - Настройки"}, | |
| "optionsHandleLinks": {"message": "Обрабатывать ссылки"}, | |
| "optionsFileHostings": {"message": "На файлообменники"}, | |
| "optionsMediaHostings": {"message": "На медиахостинги"}, | |
| "optionsModules": {"message": "Модули"}, | |
| "optionsYoutube": {"message": "YouTube"}, | |
| "optionsYTHideLinks": {"message": "Скрывать ссылки"}, | |
| "optionsDailymotion": {"message": "Dailymotion"}, | |
| "optionsVimeo": {"message": "Vimeo"}, | |
| "optionsFacebook": {"message": "Facebook"}, | |
| "optionsSoundcloud": {"message": "SoundCloud"}, | |
| "optionsVkontakte": {"message": "Вконтакте"}, | |
| "optionsOdnoklassniki": {"message": "Одноклассники"}, | |
| "optionsBitrate": {"message": "Показывать битрейт сразу"}, | |
| "filelistTitle": {"message": "Список найденных MP3 файлов"}, | |
| "filelistInstruction": {"message": "Чтобы скачать все MP3 файлы, скопируйте список ссылок и вставьте его в <a href=\"http://ru.wikipedia.org/wiki/Менеджер_загрузок\">менеджер закачек</a>. Если у вас не установлен менеджер закачек, рекомендуем установить <a href=\"http://www.westbyte.com/dm/\">Download Master</a>."}, | |
| "playlistTitle": {"message": "Плейлист"}, | |
| "playlistInstruction": {"message": "Чтобы сохранить плейлист, щелкните правой кнопкой мыши по соответствующей ссылке и выберите в меню пункт "Сохранить объект как...". Либо скопируйте содержимое текстового поля, и сохраните в файл с соответствующим расширением.<br><br>Сохраненный плейлист можно открыть в плеере для воспроизведения."}, | |
| "vkInfo": {"message": "Параметры"}, | |
| "vkInfoTitle": {"message": "Размер файла и битрейт"}, | |
| "vkMp3LinksNotFound": {"message": "Не найдены ссылки на MP3 файлы"}, | |
| "vkPhotoLinksNotFound": {"message": "Не найдены ссылки на фотографии"}, | |
| "vkDownloadPhotoAlbum": {"message": "Скачать альбом"}, | |
| "vkDownloadAllPhotoAlbums": {"message": "Скачать все альбомы"}, | |
| "vkFoundPhotos": {"message": "Найдено фотографий"}, | |
| "vkNotAvailablePhotos": {"message": "%d фото временно не доступно"}, | |
| "vkFoundLinks": {"message": "Найдено ссылок"}, | |
| "vkFoundOf": {"message": "из"}, | |
| "vkShowAs": {"message": "Показать как"}, | |
| "vkListOfLinks": {"message": "Список ссылок"}, | |
| "vkListOfLinksInstruction": {"message": "Чтобы скачать все фотографии, скопируйте список ссылок и вставьте его в <a href=\"http://ru.wikipedia.org/wiki/Менеджер_загрузок\">менеджер закачек</a>. Если у вас не установлен менеджер закачек, рекомендуем установить <a href=\"http://www.westbyte.com/dm/\">Download Master</a>."}, | |
| "vkTableOfThumbnails": {"message": "Таблицу эскизов"}, | |
| "vkListOfPhotos": {"message": "Список фотографий"}, | |
| "vkListOfPhotosInstruction": {"message": "Чтобы скачать фотографию, щелкните на ней левой кнопкой мыши."}, | |
| "vkKbps": {"message": "кб/с"}, | |
| "vkFileSizeByte": {"message": "Б"}, | |
| "vkFileSizeKByte": {"message": "кБ"}, | |
| "vkFileSizeMByte": {"message": "МБ"}, | |
| "vkFileSizeGByte": {"message": "ГБ"}, | |
| "vkFileSizeTByte": {"message": "ТБ"}, | |
| "vkDownloadFromYoutube": {"message": "Скачать: откройте <a href=\"{url}\">страницу видео ролика</a> и нажмите кнопку "Скачать" над плеером"} | |
| }; | |
| chrome.i18n.messages.tr = { | |
| "extName": {"message": "SaveFrom.net asistan"}, | |
| "extDescription": {"message": "Sadece bir tıklama ile YouTube, RapidShare, VK.com ve 40'dan fazla siteden dosya indirin."}, | |
| "extNameLite": {"message": "SaveFrom.net asistan lite"}, | |
| "extDescriptionLite": {"message": "Sadece bir tıklama ile RapidShare, VK.com ve 40'dan fazla siteden dosya indirin"}, | |
| "lang": {"message": "tr"}, | |
| "titleDefault": {"message": "SaveFrom.net asistan"}, | |
| "titleDesabled": {"message": "SaveFrom.net asistan devre dışı"}, | |
| "menuEnable": {"message": "Etkin"}, | |
| "menuDisable": {"message": "Devre dışı"}, | |
| "download": {"message": "İndir"}, | |
| "downloadTitle": {"message": "Dosyayı indirmek için Alt/Option veya Ctrl tuşuna basılı tutarak bağlantıyı tıklayın."}, | |
| "noLinksFound": {"message": "Hiçbir bağlantı bulunamadı"}, | |
| "more": {"message": "Daha fazla"}, | |
| "close": {"message": "Kapat"}, | |
| "kbps": {"message": "kbps"}, | |
| "withoutAudio": {"message": "without audio"}, | |
| "subtitles": {"message": "Alt yazı"}, | |
| "playlist": {"message": "Çalma listesi"}, | |
| "filelist": {"message": "Dosya listesi"}, | |
| "downloadWholePlaylist": {"message": "Tüm çalma listesini indir"}, | |
| "getFileSizeTitle": {"message": "Dosya boyutunu al" }, | |
| "getFileSizeFailTitle": {"message": "Dosya boyutu alınamadı. Lütfen tekrar deneyiniz."}, | |
| "lmButtonTitle": {"message": "Doğrudan bağlantı al"}, | |
| "downloadFromCurrentPage": {"message": "Geçerli sayfadan indir"}, | |
| "updateLinks": {"message": "İndirme bağlantılarını yenile"}, | |
| "updateLinksNotification": {"message": "Links updated"}, | |
| "downloadMP3Files": {"message": "Tüm MP3 dosyalarını indir"}, | |
| "downloadPlaylist": {"message": "MP3 çalma listesini indir"}, | |
| "downloadPhotos": {"message": "Tüm fotoğrafları indir"}, | |
| "installFullVersion": {"message": "Tam versiyonu kur"}, | |
| "disable": {"message": "Devre dışı"}, | |
| "showOptions": {"message": "Options"}, | |
| "reportBug": {"message": "Report a bug"}, | |
| "aboutPage": {"message": "Hakkında"}, | |
| "aboutTitle": {"message": "SaveFrom.net Asistan"}, | |
| "aboutVersion": {"message": "Versiyon"}, | |
| "aboutDescription": {"message": "Kullanıcıların, Dailymotion.com, RapidShare.com, YouTube.com, VK.com ve diğerleri de dahil olmak üzere 40'dan fazla web sitesinden dosya indirmek için doğrudan bağlantılar almalarını sağlar."}, | |
| "aboutDescriptionLite": {"message": "Kullanıcıların, Dailymotion.com, RapidShare.com, VK.com ve diğerleri de dahil olmak üzere 40'dan fazla web sitesinden dosya indirmek için doğrudan bağlantılar almalarını sağlar."}, | |
| "aboutSupported": {"message": "Desteklenen kaynaklar"}, | |
| "homePage": {"message": "Ana Sayfa"}, | |
| "menuTooltip": {"message": "This is a menu of SaveFrom.net Helper.<br><br>Using it, you can download videos and audio from a current page or set up the extension.<br><br>Menu items will vary from site to site.<br><br>You can hide a button with the right click on an icon."}, | |
| "optionsTitle": {"message": "SaveFrom.net Asistan - Tercihler"}, | |
| "optionsHandleLinks": {"message": "Linkleri taşı"}, | |
| "optionsFileHostings": {"message": "Dosya paylaşıma"}, | |
| "optionsMediaHostings": {"message": "Medya paylaşıma"}, | |
| "optionsModules": {"message": "Modüller"}, | |
| "optionsYoutube": {"message": "YouTube"}, | |
| "optionsYTHideLinks": {"message": "Bağlantıları gizle"}, | |
| "optionsDailymotion": {"message": "Dailymotion"}, | |
| "optionsVimeo": {"message": "Vimeo"}, | |
| "optionsFacebook": {"message": "Facebook"}, | |
| "optionsSoundcloud": {"message": "SoundCloud"}, | |
| "optionsVkontakte": {"message": "VK"}, | |
| "optionsOdnoklassniki": {"message": "Odnoklassniki"}, | |
| "optionsBitrate": {"message": "Bit hızını anlık olarak göster"}, | |
| "filelistTitle": {"message": "Bulunan MP3 dosyalarını listesi"}, | |
| "filelistInstruction": {"message": "Tüm MP3 dosyalarını indirmek için bağlantı listesini kopyalayın ve <a href=\"http://en.wikipedia.org/wiki/Download_manager\">indirme yöneticisine</a> yapıştırın. Kurulu bir indirme yöneticiniz yoksa <a href=\"http://www.freedownloadmanager.org/\">Free Download Manager</a> yüklemenizi tavsiye ederiz."}, | |
| "playlistTitle": {"message": "Çalma Listesi"}, | |
| "playlistInstruction": {"message": "Çalma listesini kaydetmek için, linke sağ tıklayın ve "Hedefi Farklı Kaydet..." seçeneğini seçin. Ya da metin kutusunun içeriğini kopyalayın ve uygun uzantıyı belirterek dosyayı kaydedin. <br><br>Artık kaydedilen çalma listenizi yürütmek için müzik çalarınızda açabilirsiniz."}, | |
| "vkInfo": {"message": "Bilgi"}, | |
| "vkInfoTitle": {"message": "Dosya boyutu ve bit hızı"}, | |
| "vkMp3LinksNotFound": {"message": "MP3 dosyaları için bağlantılar bulunamıyor"}, | |
| "vkPhotoLinksNotFound": {"message": "Fotoğraflar bulunamadı"}, | |
| "vkDownloadPhotoAlbum": {"message": "Albümü indir"}, | |
| "vkDownloadAllPhotoAlbums": {"message": "Tüm albümleri indir"}, | |
| "vkFoundPhotos": {"message": "Bulunan fotoğraflar"}, | |
| "vkNotAvailablePhotos": {"message": "%d resim geçici olarak kullanılamıyor"}, | |
| "vkFoundLinks": {"message": "Bulunan bağlantılar"}, | |
| "vkFoundOf": {"message": "den"}, | |
| "vkShowAs": {"message": "Olarak göster"}, | |
| "vkListOfLinks": {"message": "Bağlantı listesi"}, | |
| "vkListOfLinksInstruction": {"message": "Tüm fotoğrafları indirmek için bağlantı listesini kopyalayın ve <a href=\"http://en.wikipedia.org/wiki/Download_manager\">indirme yöneticisine</a> yapıştırın. Kurulu bir indirme yöneticiniz yoksa <a href=\"http://www.freedownloadmanager.org/\">Free Download Manager</a> yüklemenizi tavsiye ederiz."}, | |
| "vkTableOfThumbnails": {"message": "Küçükk resimler tablosu"}, | |
| "vkListOfPhotos": {"message": "Fotoğraf listesi"}, | |
| "vkListOfPhotosInstruction": {"message": "İndirmek için fotoğrafın üzerine tıklayın."}, | |
| "vkKbps": {"message": "kbps"}, | |
| "vkFileSizeByte": {"message": "B"}, | |
| "vkFileSizeKByte": {"message": "kB"}, | |
| "vkFileSizeMByte": {"message": "MB"}, | |
| "vkFileSizeGByte": {"message": "GB"}, | |
| "vkFileSizeTByte": {"message": "TB"}, | |
| "vkDownloadFromYoutube": {"message": "İndirme: <a href=\"{url}\">video sayfasını</a> açın ve oynatıcı üzerindeki "İndir" dümesine basın"} | |
| }; | |
| chrome.i18n.messages.uk = { | |
| "extName": {"message": "SaveFrom.net помічник"}, | |
| "extDescription": {"message": "Завантажуйте з «ВКонтакте», YouTube, RapidShare і ще 40 сайтів за 1 клік."}, | |
| "extNameLite": {"message": "SaveFrom.net помічник lite"}, | |
| "extDescriptionLite": {"message": "Завантажуйте з «ВКонтакте», YouTube, RapidShare і ще 40 сайтів за 1 клік."}, | |
| "lang": {"message": "ru"}, | |
| "titleDefault": {"message": "SaveFrom.net помічник"}, | |
| "titleDesabled": {"message": "SaveFrom.net помічник вимкнений"}, | |
| "menuEnable": {"message": "Увімкнути"}, | |
| "menuDisable": {"message": "Вимкнути"}, | |
| "download": {"message": "Завантажити"}, | |
| "downloadTitle": {"message": "Натисніть на посилання, утримуючи клавішу Alt чи Ctrl, щоб зберегти файл."}, | |
| "noLinksFound": {"message": "Не вдалося знайти посилання"}, | |
| "more": {"message": "Ще"}, | |
| "close": {"message": "Закрити"}, | |
| "kbps": {"message": "кб/с"}, | |
| "withoutAudio": {"message": "без аудіо"}, | |
| "subtitles": {"message": "Субтитри"}, | |
| "playlist": {"message": "Плейліст"}, | |
| "filelist": {"message": "Список файлів"}, | |
| "downloadWholePlaylist": {"message": "Завантажити весь плейліст"}, | |
| "getFileSizeTitle": {"message": "Визначити розмір файлу" }, | |
| "getFileSizeFailTitle": {"message": "Не вдалося визначити розмір файлу. Спробуйте ще раз."}, | |
| "lmButtonTitle": {"message": "Отримай пряме посилання"}, | |
| "downloadFromCurrentPage": {"message": "Завантажити з поточної сторінки"}, | |
| "updateLinks": {"message": "Оновити посилання для завантаження"}, | |
| "updateLinksNotification": {"message": "Links updated"}, | |
| "downloadMP3Files": {"message": "Завантажити усі MP3-файли"}, | |
| "downloadPlaylist": {"message": "Завантажити MP3-плейліст"}, | |
| "downloadPhotos": {"message": "Завантажити усі фотографії"}, | |
| "installFullVersion": {"message": "Встановити повну версію"}, | |
| "disable": {"message": "Вимкнути"}, | |
| "showOptions": {"message": "Options"}, | |
| "reportBug": {"message": "Повідомити про помилку"}, | |
| "aboutPage": {"message": "Про розширення"}, | |
| "aboutTitle": {"message": "SaveFrom.net помічник"}, | |
| "aboutVersion": {"message": "Версія"}, | |
| "aboutDescription": {"message": "Дозволяє отримувати прямі посилання для завантаження з понад 40 сайтів, серед яких Vkontakte.ru, RapidShare.com, YouTube.com та інші."}, | |
| "aboutDescriptionLite": {"message": "Дозволяє отримувати прямі посилання для завантаження з понад 40 сайтів, серед яких Vkontakte.ru, RapidShare.com та інші."}, | |
| "aboutSupported": {"message": "Ресурси, які підтримуються"}, | |
| "homePage": {"message": "Домашня сторінка"}, | |
| "menuTooltip": {"message": "This is a menu of SaveFrom.net Helper.<br><br>Using it, you can download videos and audio from a current page or set up the extension.<br><br>Menu items will vary from site to site.<br><br>You can hide a button with the right click on an icon."}, | |
| "optionsTitle": {"message": "SaveFrom.net помічник - Налаштування"}, | |
| "optionsHandleLinks": {"message": "Обробляти посилання"}, | |
| "optionsFileHostings": {"message": "На файлообмінники"}, | |
| "optionsMediaHostings": {"message": "На медіахостинги"}, | |
| "optionsModules": {"message": "Модулі"}, | |
| "optionsYoutube": {"message": "YouTube"}, | |
| "optionsYTHideLinks": {"message": "Сховати посилання"}, | |
| "optionsDailymotion": {"message": "Dailymotion"}, | |
| "optionsVimeo": {"message": "Vimeo"}, | |
| "optionsFacebook": {"message": "Facebook"}, | |
| "optionsSoundcloud": {"message": "SoundCloud"}, | |
| "optionsVkontakte": {"message": "ВКонтакте"}, | |
| "optionsOdnoklassniki": {"message": "Одноклассники"}, | |
| "optionsBitrate": {"message": "Показувати бітрейт одразу"}, | |
| "filelistTitle": {"message": "Список знайдених MP3-файлів"}, | |
| "filelistInstruction": {"message": "Щоб завантажити усі MP3-файли, скопіюйте список посилань і вставте його у <a href=\"http://ru.wikipedia.org/wiki/Менеджер_загрузок\">менеджер завантажень</a>. Якщо у вас не встановлений менеджер завантажень, рекомендуємо встановити <a href=\"http://www.westbyte.com/dm/\">Download Master</a>."}, | |
| "playlistTitle": {"message": "Плейліст"}, | |
| "playlistInstruction": {"message": "Щоб зберегти плейліст, натисніть правою кнопкою миші на відповідне посилання і оберіть у меню пункт "Зберегти об'єкт як...". Або скопіюйте вміст текстового поля і збережіть у файл з відповідним розширенням.<br><br>Збережений плейліст можна відкрити у плеєрі для відтворення."}, | |
| "vkInfo": {"message": "Параметри"}, | |
| "vkInfoTitle": {"message": "Розмір файлу і бітрейт"}, | |
| "vkMp3LinksNotFound": {"message": "Не знайдено посилань на MP3-файли"}, | |
| "vkPhotoLinksNotFound": {"message": "Не знайдено посилань на фотографії"}, | |
| "vkDownloadPhotoAlbum": {"message": "Завантажити альбом"}, | |
| "vkDownloadAllPhotoAlbums": {"message": "Завантажити усі альбоми"}, | |
| "vkFoundPhotos": {"message": "Знайдено фотографій"}, | |
| "vkNotAvailablePhotos": {"message": "%d фото тимчасово недоступно"}, | |
| "vkFoundLinks": {"message": "Знайдено посилань"}, | |
| "vkFoundOf": {"message": "з"}, | |
| "vkShowAs": {"message": "Показати як"}, | |
| "vkListOfLinks": {"message": "Список посилань"}, | |
| "vkListOfLinksInstruction": {"message": "Щоб завантажити усі фотографії, скопіюйте список посилань і вставте його у <a href=\"http://ru.wikipedia.org/wiki/Менеджер_загрузок\">менеджер завантажень</a>. Якщо у вас не встановлений менеджер завантажень, рекомендуємо встановити <a href=\"http://www.westbyte.com/dm/\">Download Master</a>."}, | |
| "vkTableOfThumbnails": {"message": "Таблицю ескізів"}, | |
| "vkListOfPhotos": {"message": "Список фотографій"}, | |
| "vkListOfPhotosInstruction": {"message": "Щоб завантажити фотографію, натисніть на неї лівою кнопкою миші."}, | |
| "vkKbps": {"message": "кб/с"}, | |
| "vkFileSizeByte": {"message": "Б"}, | |
| "vkFileSizeKByte": {"message": "кБ"}, | |
| "vkFileSizeMByte": {"message": "МБ"}, | |
| "vkFileSizeGByte": {"message": "ГБ"}, | |
| "vkFileSizeTByte": {"message": "ТБ"}, | |
| "vkDownloadFromYoutube": {"message": "Завантажити: відкрийте <a href=\"{url}\">сторінку відео-ролика</a> і натисніть кнопку "Завантажити" над плеєром"} | |
| }; | |
| // RUN | |
| chrome.i18n.detectUserLanguage(); | |
| _background(); | |
| var host = SaveFrom_Utils.getTopLevelDomain(location.hostname); | |
| if(!host) | |
| return; | |
| var moduleName = 'lm'; | |
| if(_moduleHosts[host] && _modules[_moduleHosts[host]]) | |
| moduleName = _moduleHosts[host]; | |
| var _this = this; | |
| setTimeout(function(){ | |
| if(!window.sessionStorage || sessionStorage['savefrom-helper-extension'] != '1') | |
| { | |
| _modules[moduleName].call(_this); | |
| } | |
| }, 1000); | |
| })(); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment