📜 ⬆️ ⬇️

Bookmarklet: analysis of essential points, part two, loadable

Recall that a bookmarklet is a small javascript code stored in browser bookmarks and designed to perform any tasks on the current web page.

As noted in the previous post, the bookmarklet can be divided into 3 interacting parts:
  1. The first part, a small, up to 2000 characters javascript code, which is stored in browser bookmarks and, in the simplest case, can do all the work, but usually serves to initiate the work of the bookmarklet.
  2. The second, loadable part of the bookmarklet: javascript code that is loaded into the current document during the bookmarklet initiation process and provides the main functionality.
  3. The third, backup part of the bookmarklet that works if you load javascript into the current document failed.

The first part of the bookmarklet was thoroughly disassembled in the previous post on the live example of the bookmarklet of the web service TheOnlyPage (a service for storing bookmarks, notes and html fragments)

This time we will focus on the loaded part of the bookmarklet.
')
The variety of possible actions of the loading part of the bookmarklet is immense, therefore we will consider only the most significant moments.

This time we will not examine the source code line by line, but analyze some problem points and the best ways to solve them. Thus, you will get the following set of individual nodes for creating a downloadable part of the bookmarklet:

  1. Wrap - Isolation of the bookmarklet code from the external environment
  2. Turn on and off the load on / off indicator
  3. Reset CSS styles
  4. Loading libraries

For clarity, we will illustrate the material in question, referring to the work of the bookmarklet of the web service TheOnlyPage . Detailed information on how to install this bookmarklet can be obtained in the web service help system.

Wrap - isolation of the bookmarklet from the external environment


In a previous publication, we already said that the javascript code of the bookmarklet must be placed inside an anonymous function. The same is true for the code of the second, loadable part of the bookmarklet. This code should be wrapped in an anonymous function approximately as follows:

(function (window, undefined) { //     })(window); 

The anonymous function contains 2 parameters window and undefined , which is done so that instead of the reusable global variables window and undefined , the local variables window and undefined are used in the body of the function, which are easily compressed using javascript minifiers.
Calling an anonymous function passes only one parameter: the window . The second parameter automatically takes the required value undefined , without being passed to the function.

Turn on and off the load on / off indicator


After the second, downloadable part of the bookmarklet is successfully downloaded, it's time to turn off the download indicator , which in the bookmarklet of the web service TheOnlyPage looks like this: image .
The simple action to disable the load indicator is as follows:

 // id  : theonlypageAjaxLoaderGif var image = window.document.getElementById('theonlypageAjaxLoaderGif'); //   image.parentNode.removeChild(image); 

When adding additional visual elements to the current document, it makes sense to wrap them in a common container. In the bookmarklet of the web service TheOnlyPage it is implemented like this:

 //   div var veil = window.document.createElement('div'); //    id veil.id = 'theonlypageContainer'; // , ,   … // …    // …    //       window.document.body.appendChild(veil); 

As already mentioned in the previous publication, an important point is the use of unique id on a foreign web page. For this id you can use the name of the web service. In our case, it is theonlypageContainer .

If markup elements added by a bookmarklet are placed in a container marked with a specific id , then when reloading, you can implement a bookmarklet shutdown mechanism:

 var veil = window.document.getElementById('theonlypageContainer'); if(veil){ //        //      veil.parentNode.removeChild(veil); //     return; } 

All visual elements from the current page are deleted and the bookmarklet is turned off. In this way, the mechanism of on / off bookmarklet is realized by successively clicking on the bookmarklet link in the browser bookmarks bar.

Reset CSS styles


When you embed your markup elements in someone else’s document, you need to keep in mind that these elements can inherit the CSS properties of the current document. And, as a result, our div will, for example, have completely unnecessary indents, and our iframe inside it, for example, completely inappropriate shadows.

To get rid of possible rounding, colors, indents, animation effects and other unnecessary properties, we need to reset the styles of each created element as follows:

 //     CSS    var ResetCSS = "animation:none;animation-delay:0;animation-direction:normal;animation-duration:0;animation-fill-mode:none;animation-iteration-count:1;animation-name:none;animation-play-state:running;animation-timing-function:ease;backface-visibility:visible;background:0;background-attachment:scroll;background-clip:border-box;background-color:transparent;background-image:none;background-origin:padding-box;background-position:0 0;background-position-x:0;background-position-y:0;background-repeat:repeat;background-size:auto auto;border:0;border-style:none;border-width:medium;border-color:inherit;border-bottom:0;border-bottom-color:inherit;border-bottom-left-radius:0;border-bottom-right-radius:0;border-bottom-style:none;border-bottom-width:medium;border-collapse:separate;border-image:none;border-left:0;border-left-color:inherit;border-left-style:none;border-left-width:medium;border-radius:0;border-right:0;border-right-color:inherit;border-right-style:none;border-right-width:medium;border-spacing:0;border-top:0;border-top-color:inherit;border-top-left-radius:0;border-top-right-radius:0;border-top-style:none;border-top-width:medium;bottom:auto;box-shadow:none;box-sizing:content-box;caption-side:top;clear:none;clip:auto;color:inherit;columns:auto;column-count:auto;column-fill:balance;column-gap:normal;column-rule:medium none currentColor;column-rule-color:currentColor;column-rule-style:none;column-rule-width:none;column-span:1;column-width:auto;content:normal;counter-increment:none;counter-reset:none;cursor:auto;direction:ltr;display:inline;empty-cells:show;float:none;font:normal;font-family:inherit;font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;height:auto;hyphens:none;left:auto;letter-spacing:normal;line-height:normal;list-style:none;list-style-image:none;list-style-position:outside;list-style-type:disc;margin:0;margin-bottom:0;margin-left:0;margin-right:0;margin-top:0;max-height:none;max-width:none;min-height:0;min-width:0;opacity:1;orphans:0;outline:0;outline-color:invert;outline-style:none;outline-width:medium;overflow:visible;overflow-x:visible;overflow-y:visible;padding:0;padding-bottom:0;padding-left:0;padding-right:0;padding-top:0;page-break-after:auto;page-break-before:auto;page-break-inside:auto;perspective:none;perspective-origin:50% 50%;position:static;right:auto;tab-size:8;table-layout:auto;text-align:inherit;text-align-last:auto;text-decoration:none;text-decoration-color:inherit;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-shadow:none;text-transform:none;top:auto;transform:none;transform-style:flat;transition:none;transition-delay:0s;transition-duration:0s;transition-property:none;transition-timing-function:ease;unicode-bidi:normal;vertical-align:baseline;visibility:visible;white-space:normal;widows:0;width:auto;word-spacing:normal;z-index:auto;"; //  ,      … // …   CSS    … // …    CSS      veil.style.cssText = ResetCSS + 'position:absolute ;background-color:rgba(0,0,0,.2); cursor:pointer; '; 


Loading libraries


TheOnlyPage downloadable part of the bookmarklet does not use additional libraries, however, if necessary, it is easy to use additional libraries.

Consider the most widely requested option - loading the jQuery library

 //    jQuery var v = "1.11.1"; if (window.jQuery===undefined||window.jQuery.fn.jquery<v){ //   jQuery     jQuery   //   //       var script=document.createElement('script'); //       script.src="https://ajax.googleapis.com/ajax/libs/jquery/"+v+"/jquery.min.js"; script.async=true; //     var entry=document.getElementsByTagName('script')[0]; entry.parentNode.insertBefore(script,entry); script.onload=script.onreadystatechange=function(){ var readyState=script.readyState; if (!readyState||/complete|loaded/.test(script.readyState)){ //    //        main(); //     ... // ...      script.onload = null; script.onreadystatechange = null; } }; }else{ main(); } var main=function(){ //       } 


An important point , which has already been noted in the previous publication, if the downloadable javascript code has the address protocol: http:// then errors will occur when working on the current page, the address protocol of which is: https:// . The reason for this is: restrictions imposed on mixed active content ( mixed active content ), which prohibit downloading code from unprotected addresses into a document protected by TLS (SSL). There are 2 ways to ensure that the javascript code always loads normally:
  1. or place it at the address with the https:// protocol
  2. or use a special // notation, for example:
    script.src='//ajax.googleapis.com/ajax/libs/jquery/v.1.11.1/jquery.min.js'
    which means using the same protocol as the parent document. Then, depending on the protocol of the current web page http:// or https:// , the corresponding address will be used:
    ajax.googleapis.com/ajax/libs/jquery/v.1.11.1/jquery.min.js
    or
    ajax.googleapis.com/ajax/libs/jquery/v.1.11.1/jquery.min.js

By the way, if you intend to use the jQuery library, then you should pay attention to the following important point : to avoid possible conflicts, it is unacceptable to use the $ abbreviation of the jQuery global variable, since the global variable $ likely to be already used in the scripts of the current document, not as an alias for jQuery , but like another global variable, for example from the library Prototype.JS . Therefore, we use only jQuery , without abbreviations.

We covered all the basic elements of the downloadable part of the bookmarklet , but there are two more topics for discussion:
  1. cross-domain messaging with the server;
  2. Authentication of web service users when working with a bookmarklet.

However, these topics require a separate place and time, and separate publications will be devoted to them.

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


All Articles