📜 ⬆️ ⬇️

We write the extension for Chrome "download audio recordings from Vkontakte"

The chrome extension store probably already has song loaders with VKontakte, but we will try to write our own.
Our extension will add a link to each of the songs in the My Audio Recordings section, which will download the song.

It should look like this:
Initially:Let's try this:

Let's start.
Generally, writing extensions is not so difficult. An extension is only a file description + html / js / css content. Ours will consist of three files - a description file (manifest.json), an injected js script (vk_inject.js), and an inline style file vk_styles.css).

The main file in the extension is, of course, manifest.json. It contains a handle to the extension, and links to the embedded files.

mainfest.json
{ "manifest_version": 2, "name": "   vk.com", "description": "       .", "version": "1.0", "content_scripts": [ { "matches": ["*://vk.com/audios*"], "js": ["vk_inject.js"], "css": ["vk_styles.css"] } ] } 

So far, nothing complicated. In addition to the description, this contains the “content_scripts” tag, which determines which js and css files will be embedded in the page.
In this case, our extension will embed the vk_inject.js and vk_styles.css files into each page that matches the address to the masks http://vk.com/audios* or https://vk.com/audios*. These are exactly the addresses where our (or other users) audio recordings are kept on Vkontakte website.
')
The style file (vk_styles.css) will be very simple. We just define the css class for the link being injected.
Be sure to ensure that the class does not overlap with the styles of the original page.
Of course, we can do without the injected css file, and just set all the styles in the code when creating the link element, but I
I want to show you the possibility of introducing styles. You can also override styles for your links.

vk_styles.css
 .downloadLink { float: right; } 

Almost all actions will occur in the embedded code vk_inject.js.
So, what shall we do:
The vk.com/audios* page contains two lists of songs - 1) the initial audio recordings on your page are the element <div id = "initial_list"> and 2) the search list is <div id = "search_list">. The search list will display the found songs if you enter the search mode. Both of these elements are initially present on the audio recording page, so that we can change each of them.
The problem is, in each of these lists, entries can be added or deleted. We need to keep an eye on this.
The injected script is executed in a separate virtual machine, and cannot interact with the script on the village. Therefore, we cannot override the source functions or otherwise intercept the js code on the source page.
But, fortunately, both of these scripts share a DOM tree, so we’ll follow the updates to DOM list items using MutationObserver.

vk_insert.js
 (function (){ //     ,      -    var observer = new MutationObserver(listModified); //   observer ->  listModified    DOM var initialList = document.getElementById('initial_list'); //       if (initialList) { //        -   ""      var rows = initialList.children; for (var i = 0; i < rows.length; i++) { addDownloadLink(rows[i]); //   } observer.observe(initialList, {childList: true}); //        } //     var searchList = document.getElementById('search_list'); if (searchList) { // search_list   ,         observer.observe(searchList, {childList: true}); //    } // ,      ( )  function listModified(mutations) { for (var i = 0; i < mutations.length; i++) { var mut = mutations[i]; if (mut.type != 'childList') { return; } //     for (var j = 0; j < mut.addedNodes.length; j++) { addDownloadLink(mut.addedNodes[j]); } //   - mut.removedNodes  } } //    ""    function addDownloadLink(row) { var titleNode = row.querySelector('div.title_wrap'); //   +  if (!titleNode) //     (,   ?)-  { return; } var input = row.querySelector('div.play_btn > input'); //  input,    url if (!input) { return; } var ref = input.getAttribute('value'); //  URL  ref = ref.substr(0, ref.indexOf('?')); //    '?',      mp3 var link = document.createElement('a'); link.className = 'downloadLink'; //  css  'downloadLink'    link.textContent = ""; link.setAttribute('download', titleNode.textContent + '.mp3'); //     link.setAttribute('href', ref); link.addEventListener('click', function(event){ //     ,    event.stopPropagation(); }); titleNode.appendChild(link); } })(); 

Install the extension.


So all three files are ready. You can copy them from the post or download the archive .
In your browser, go to the settings page, select the Extensions tab (or just type “chrome: // extensions” in the address bar). Be sure to enable Developer Mode . Then click Download unpacked extension ....


Select the folder where you saved these three files. In my case, this is D: \ Droopy \ work \ habr \ plugin.
The extension should appear in the list. Turn it on.



Let's check how it works. To do this, go to vk.com, and select the section My audio .

So, nothing works ...

Why? Because when switching from page to page, Vkontakte automatically updates html and programmatically changes the url in the address bar. This is not a classic browser transition from page to page.
Therefore, the browser has not launched our extension, although the page address has become “https://vk.com/audios*”.
To run our script, we need to explicitly refresh the audio recordings page.
We update.



Hurray, links "Download" appeared!
Moreover, if we start searching for audio recordings on the same page, then for each song found there will automatically be a download link. The extension works.

But there is one difficulty with the name of the song being downloaded. When you click on the “Download” link, in the file saving dialog you will be offered the name of a file from a set of numbers. We need the normal name of the song.
The fact is that VKontakte stores audio recordings on a separate domain, and chrome for this case will use the file name on the server instead of the one suggested in the link.
In the chrome bug tracker, it says that in this case you need to select the Save link as item in the context menu. Then we will be offered a normal file name.



Our extension, of course, does not always work on all pages of VKontakte, but it is quite suitable for downloading favorite songs from your audio recordings.

Source: https://habr.com/ru/post/254005/


All Articles