So, after upgrading
Firefox to version
19 , the beloved Yandex-Bar extension completely fell off. I will not forget to remind you that Yandex.Bar was replaced by
Yandex.Ilements that liked a little more than anybody, and therefore received their well-deserved
2 points out of 5 .
Why did not like? Replaced the address bar, it became inconvenient to view the mail, replaced the bookmarks and removed the address bar corrector (under the pretext of installing Punto Switcher, which can be good for the average employee, but not for the programmer. Therefore, it was removed almost immediately as installed. Yes and if it could be customized, then all the same the desire was gone).
A little later, it was decided to create its own similar extension, which will include such buns as viewing mail and address line corrector. Well, if not you, so who else?
')
First of all, it was decided not to create your own bike and resurrect Yandeks.Bar, which did not want to work in the 19 version of the browser. On the Internet, it was suggested that the extension is a regular zip archive. Opened, looked, were horrified and closed. It was not possible to resurrect, even with all the desire.
Then go to the developer center:
builder.addons.mozilla.org . I chose to work in a web editor, although sometimes it sometimes did not work very smoothly. Having looked at other extensions, having borrowed the code and having a little understood the whole meaning of sowing the device, it all started first with the smashing machine and ended with a file.
The builder includes 3 sections: this is the section with scripts (Lib), the section with downloadable content (images, styles and scripts) and the section with ready-made libraries (Libraries)
By the way, here is the documentation:
addons.mozilla.org/en-US/developers/docs/sdk/latest , well written.
The start of the extension starts with loading the
main.js file.
Called function:
exports.main .
An example of the main.js file:
const tabs = require("tabs"); exports.main = function (options) { tabs.on("ready", function(tab){ tab.attach({ contentScript: "document.addEventListener('click', function(e) { \ var target = e.target; \ if(target.tagName == 'A') { \ var mail_to = target.href.match(/^mailto:(.*)/i); \ if(mail_to != null) { \ e.preventDefault(); \ var form = document.createElement('form'); \ form.setAttribute('action','http://mail.yandex.ru/neo2/#compose/mailto=' + mail_to[1]); \ form.setAttribute('target','_blank'); \ document.getElementsByTagName('body')[0].appendChild(form); \ form.submit(); \ form.parentNode.removeChild(form); \ } \ } \ }, false);" }); }); }
What kind of magic happens in this code?
First of all, the
tabs module is connected.
In this case, it serves to add your JavaScript code to the browser page.
Those. what we have: during the onready document event, any JavaScript code is added to the document body. In this example, a handler is added for links whose address begins with
mailto .
Okay, let's do something more complicated. Add your button to the top bar!
Again, we will not build bicycles, but with a clear conscience, take the ready-made library
Toolbar Button Complete .
It also has an example of adding a button to the browser bar. I think you should not dump it here, because there is a bit of code.
So, there is a button, the icon has been installed, everything seems to be fine, but not very. How did we have in Yandex.Bar? Oh yeah, opposite the icon also the counter of unread messages was.
Here I found out several ways to add a counter:
- versatile but lighter (with styles)
- not very versatile, but not as simple as the first (using canvas)
The second method, however, was found by typing on the Internet. But I took the first one.
We know that the top bar is the same set of elements with its classes, identifiers, properties and ways of working with them.
Type tyke method:
for(var val in document.getElementById('yandex-menu')) { console.log(val); }
it was found that the methods are exactly the same as those we usually use when working with elements of the site. But I note that according to the standard, the browser does not know what neither
document nor
window is in extensions (and there are still differences).
Solution example:
var wuntils = require('sdk/window/utils'); var window = wuntils.getMostRecentBrowserWindow(); var document = window.document;
I note that the development of the builder does not stand still, and if earlier the way to get the active window
was :
var winUtils = require("window-utils"); for (window in winUtils.windowIterator()) { if ("chrome://browser/content/browser.xul" != window.location) return; console.log("An open window! " + window.location); }
now everything is much easier (I cited the example above).
Well, having a little talked about the features, I will return to adding the counter for the button.
Smart people suggested that, according to the standard, the style of the
label field of a button is
display: none; , so somehow it was necessary to inject your
css code into the bar. The solution, as it turned out, is not difficult (I advise you to wrap it in a file that will be included as needed):
const { Cc, Ci } = require('chrome'); const { when: unload } = require('sdk/system/unload'); var ios = Cc['@mozilla.org/network/io-service;1'].getService(Ci.nsIIOService); exports.addXULStylesheet = function addXULStylesheet(url) { var uri = newURI(url); var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService); sss.loadAndRegisterSheet(uri, sss.USER_SHEET); unload(function () { if (sss.sheetRegistered(uri, sss.USER_SHEET)) { sss.unregisterSheet(uri, sss.USER_SHEET); } }); return sss; }; function newURI(uriStr, base) { try { var baseURI = base ? ios.newURI(base, null, null) : null; return ios.newURI(uriStr, null, baseURI); } catch (e) { if (e.result === chrome.Cr.NS_ERROR_MALFORMED_URI) { throw new Error("malformed URI: " + uriStr); } else if (e.result === chrome.Cr.NS_ERROR_FAILURE || e.result === chrome.Cr.NS_ERROR_ILLEGAL_VALUE) { throw new Error("invalid URI: " + uriStr); } } return null; }
And
we add something like to the
exprorts.main function (although you can add it anywhere):
stylesheet.addXULStylesheet(data.url("stylesheet.css"));
Do not forget to create in the content file
stylesheet.css .
My file contains something like the following:
#yandex-mail { min-width: 16px; } #yandex-mail .toolbarbutton-text { float: right !important; display: inline-block !important; font-size: 13px; padding-left:20px; background: url(data:image/png;base64,iVB.............OCYII=) no-repeat left center; } #yandex-mail .toolbarbutton-icon { display: none; }
Why do we hide the icon and add a background? This is because if this is not done, the blocks are always displayed as
display: block , no matter what values ​​I put up (by the way, can anyone know about this topic?) Therefore, you have to be so cunning.
Also faced with the issue of downloading content from other sites and parsing xml.
With the first quickly figured out, do not go far:
Request
But with the second had to tinker.
As we know, you can get a
dom xml document using several functions:
- XMLHttpRequest - dropped, because gave a cross-domain query error (maybe I did something wrong?)
- DOMParser - but here, too, had to tinker
What actually fuss: as with getting a
window , so here:
var {Cc, Ci} = require("chrome"); var parser = Cc["@mozilla.org/xmlextras/domparser;1"].createInstance(Ci.nsIDOMParser); var dom = parser.parseFromString(xmlPrepare (text), "application/xml");
This is how creating extensions for Firefox is no different from creating plugins for jQuery :)
By the way, the final creation to this day:
CustomYandexBar , while it is being tested.
Sources , they have a lot of useful things.
If someone doesn’t like it, I’m using “their” pictures, brand or the like. - write.