J'ai écrit une extension multi-navigateur pour les onglets, mais vous ne le faites pas

Une introduction longue et fastidieuse avec une prétention à la mégalomanie


Une fois que j'ai découvert que, comme toujours, quelque chose ne me convenait pas beaucoup dans ce monde. À savoir, en entrant une sorte de longue requête dans un moteur de recherche sur un ordinateur de bureau, puis en passant à une tablette, je ne pouvais pas rappeler le texte de la requête textuellement afin d'obtenir exactement les mêmes résultats. Tout a si bien commencé. J'ai vu dans le moteur de recherche un lien vers la réponse à ma question et j'ai réalisé qu'il promet une longue lecture. Ensuite, j'ai éteint l'ordinateur et je me suis laissé tomber sur le canapé avec la tablette en pensant que maintenant je vais tout retaper dans le moteur de recherche, j'ouvrirai ce lien maintenant sur la tablette et je m'allonge, calmement, dans une position plus confortable, je vais le lire ... Mais pas ici était. Quelques divergences mineures dans le texte - et mon lien n'est plus dans le moteur de recherche. Jouer le lien lui-même n'est pas non plus une option: c'est trop long. Intrigué par les options pour le texte de la requête, j'étais presque furieux de casser la tablette. Bon sang, j'ai dû me lever, rallumer l'ordinateur, lancer le navigateur et plonger dans l'historique pour trouver le texte exact de ma demande.


Extension installée dans Chrome et Firefox

Idée


J'ai pensé, mais ce serait bien d'écrire une telle extension pour le navigateur qui vous permettrait de transférer n'importe lequel de vos onglets ouverts via le serveur vers n'importe quel autre ordinateur et de continuer à travailler avec eux. Oui, certains navigateurs ont déjà une fonctionnalité cloud - il vous suffit de vous connecter aux deux appareils et ... Mais c'est le problème. Mais que faire si j'ai Chrome sur mon ordinateur et Firefox sur ma tablette? Et puis ... Connectez-vous, oui. Si je me souviens encore de mon mot de passe depuis mon compte Google. Et je n'ai tout simplement pas de compte dans Firefox. Je ne sais même pas s'il y a des comptes là-bas? Il existe bien sûr des services cloud tiers où vous pouvez vous inscrire et probablement vous jeter le lien souhaité. Mais il faut quand même s’y inscrire et mémoriser fermement un autre mot de passe ... Non, c’est complètement irréaliste. Vous pouvez, à la fin, vous jeter un lien par la poste. Mais tout cela prend du temps et copiez-collez depuis, puis dans la barre d'adresse, ce qui, par exemple, sur une tablette est extrêmement gênant à faire. Non, tout cela est une sorte de non-sens ...

Allongé sur le canapé, je me suis lentement rendu compte que toutes ces actions nécessitaient trop de mouvement ... Non, les gars, ça ne va pas. Et quand je comprends que quelque chose ne me convient pas dans ce monde, alors je m'assois pour écrire du code pour tout faire à ma façon. Je pensais que j'étais autorisé sur les réseaux sociaux à la fois sur la tablette et l'ordinateur de bureau. Et dans différents navigateurs, par exemple, sur le même ordinateur - aussi. En général, la solution pour moi était évidente - authentifier l'utilisateur via les réseaux sociaux.

Digression lyrique


Au fait, quand j'écris quelque chose de moi-même, je le fais aussi à ma façon. J'écris en pur javaScript dans un cahier avancé, je n'utilise pas github, je n'utilise pas de bibliothèques tierces, je n'utilise même pas jquery. Par conséquent, il n'y aura pas de tutoriel sur la façon d'écrire une extension de navigateur. Je ne vous apprendrai pas cela. Ne fais pas comme moi. Je vous préviens - c'est un mauvais exemple. Je veux aussi dire à tous les critiques potentiels, anticiper leur réaction - oui, je suis entièrement d'accord avec toute votre colère juste. Oui, vous ne pouvez pas mettre le script entier dans un ou deux fichiers, mais vous devez tout couper, comme une salade, en plusieurs petits morceaux afin qu'il puisse ensuite être assemblé pendant 3 heures sur une longue commande intelligente à partir de la ligne de commande. Oui, vous ne pouvez pas combiner le code javascript et le code html dans un seul fichier - il est préférable de bousiller un autre niveau d'abstraction qui les combinera. Oui, vous ne pouvez pas utiliser la disposition des tableaux, mais bon sang, c'est du fer! Et, encore plus - maintenant ils vont me brûler - vous ne pouvez pas utiliser innerHtml et créer une structure html complexe d'un seul coup, mais vous devez attacher et détacher tous les enfants dans une boucle et attacher puis supprimer soigneusement chaque gestionnaire ... Oui, je fais tout mal. Pécheur, je me repens. Mais je le fais consciemment, car c'est plus facile. Et qui m'interdira? En fin de compte, ce n'est pas illégal, n'est-ce pas? Je ne sais pas comment programmer comme un mod moderne l'exige, et je ne veux même pas essayer, car je pense que le diagramme du processus de développement est inutilement compliqué. Je suis pour écrire du code avec mes mains, et non pour le construire à partir des morceaux de quelqu'un d'autre sans écrire une seule ligne. Cependant, mon code est léger, il n'a pas besoin d'être assemblé par une équipe spéciale et il fonctionne rapidement. J'écris du code en utilisant la technologie F5. C'est à ce moment que, pour voir comment fonctionne la version actuelle à tout moment du processus de développement, il suffit de cliquer sur le navigateur F5.



Cependant, j'ai quand même dû raccrocher les gestionnaires dans une boucle, car sinon l'extension ne passe pas le test. Également dans les extensions, juste au cas où, dans le fichier d'index html - soudainement - les scripts connectés dynamiquement sont interdits. Je les ai donc connectés via la balise script.

Stockage des onglets


J'ai donc décidé que les onglets ouverts dans le navigateur devraient être enregistrés dans certaines listes, qui seront appelées ordinateurs - ordinateur domestique, ordinateur professionnel, ordinateur local. Local - c'est lorsque la liste n'est pas stockée sur le serveur, mais dans la base de données du navigateur, et, par conséquent, vous ne pouvez l'utiliser que dans le navigateur à partir duquel elle est enregistrée. C'est pour les onglets qui n'ont pas besoin d'être lancés entre différents ordinateurs. Eh bien, le reste des listes peut être consulté sur tous les ordinateurs et navigateurs parmi ceux pris en charge par l'extension.

Pour chaque onglet, l'utilisateur peut laisser un commentaire de texte arbitraire. Par exemple, il est pratique pour moi de me souvenir de la série que j'ai arrêtée en regardant la série, et de marquer moi-même ce qui est sur la page, si ce n'est pas clair par son titre et le type de lien.

Selon la documentation pour la création d'extensions pour Chrome et Firefox, le code d'extension doit se trouver dans deux fichiers - le principal et l'arrière-plan. Le script principal traite de l'affichage de l'interface utilisateur et le script d'arrière-plan peut contrôler les onglets du navigateur et échanger des données avec le serveur. La gestion des onglets dans Chrome et Firefox est très similaire. Par exemple, le gestionnaire d'événements pour ouvrir ou fermer des onglets dans Chrome ressemble à ceci:

chrome.tabs.onUpdated.addListener( function(tabId, changeInfo) { }); 

Et dans Firefox comme ceci:

 browser.tabs.onUpdated.addListener( function(tabId, changeInfo, tabInfo) { }); 

Et la fonction qui affiche une liste de tous les onglets ouverts est écrite exactement de la même manière pour les deux navigateurs:

 chrome.tabs.query({},function(data){ }); 

Oui, oui, Chrome écrit également du chrome dans Firefox ... etc. C'est un peu étrange, cependant, le fait que les navigateurs s'orientent vers la standardisation de leur API est très encourageant.

En fait, toutes les fonctionnalités de l'extension sont obtenues en utilisant plusieurs fonctions - ouvrez la fenêtre d'extension en cliquant sur son icône, lisez les onglets ouverts, fermez un onglet, créez un nouvel onglet, écoutez les événements d'onglet et échangez des données avec la fenêtre d'extension. C’est tout. Ces méthodes sont disponibles uniquement à partir du script d'arrière-plan.

Après lecture, les onglets ouverts dans le navigateur sont envoyés à mon serveur et y sont enregistrés dans une base de données SQL régulière. Le script du serveur est écrit en PHP. Il existe une table utilisateur qui stocke les liens vers les lignes d'une autre table - la table de données. Ces données sont les adresses des pages, leurs noms et les commentaires de texte de l'utilisateur, stockés au format de chaînes de texte dans un champ de type texte d'environ un kilo-octet. Les données sont stockées sous forme non cryptée. Environ 1 000 onglets peuvent être enregistrés par mégaoctet. Un maximum de 25 de ces stockages («ordinateurs») est fourni pour chaque utilisateur.

Cependant, la version gratuite de l'extension limite l'utilisateur à deux stockages - ordinateur personnel et ordinateur professionnel, et chacun d'eux ne peut pas stocker plus de 10 onglets. Je travaille toujours sur la version payante et les méthodes de paiement. Il y aura jusqu'à 25 «ordinateurs» et jusqu'à environ 1000 onglets dans chacun, ainsi qu'un choix d'images d'arrière-plan, d'icônes et de noms pour chaque ordinateur, des listes hiérarchiques et bien plus encore.

Il existe un autre référentiel - ordinateur local. Il n'y a aucune restriction ici, car les données de l'onglet sont stockées dans la base de données du navigateur local sur l'ordinateur de l'utilisateur. Ici, vous pouvez stocker autant d'onglets que vous le souhaitez, mais pas plus que ne le permet le disque dur. De plus, comme les données ne sont pas stockées dans Local Storage, mais dans indexedDB, il n'y a pas de limite de 5 ou quelques mégaoctets. Il est seulement important de ne pas effacer accidentellement ce référentiel avec l'historique du navigateur. Je prévois également d'exporter et d'importer des onglets dans un fichier texte.

Pour travailler avec indexedDB, j'ai écrit une petite sous-bibliothèque qui ne fait que 106 lignes. Contrairement à la base de données sur le serveur, ici, toutes les données n'ont pas besoin d'être distillées dans une chaîne de texte, mais peuvent être enregistrées immédiatement dans le tableau associatif telles quelles. Le principe du stockage y est celui-ci: la clé est la valeur. Et la valeur peut être un énorme tableau associatif.

Authentification des utilisateurs



Firefox

L'autorisation, comme je l'ai déjà noté, se fait via les réseaux sociaux et, sur le serveur, en utilisant le protocole OAuth. Il est toujours pris en charge par Facebook et VKontakte, mais je prévois d'augmenter le nombre de méthodes d'authentification des utilisateurs. Le schéma d'autorisation du serveur OAuth est décrit en détail dans la documentation des deux réseaux sociaux, il est donc inutile de s'y attarder en détail. Je note seulement que je n'ai pas aimé le fait que lors de l'autorisation un nouvel onglet de navigateur s'ouvre même si l'utilisateur est déjà connecté au réseau social et a déjà accordé les droits d'extension. Cet onglet doit être capturé par le script d'extension d'arrière-plan, puis forcé de se fermer, et en général, il n'a pas l'air esthétique, se coince dans les autres onglets et clignote lorsqu'il apparaît et est détruit.

Pour le fermer, pour VKontakte, vous devez vérifier la présence de l'adresse dans le gestionnaire d'événements de l'onglet:

 oauth.vk.com/blank.html 

Et pour Facebook:

 https://www.facebook.com/connect/blank.html 

Et juste au cas où:

 facebook.com/connect/login_success.html 

Par conséquent, j'ai d'abord envoyé un assemblage d'extension au Google Web Store, dans lequel l'autorisation a été effectuée sur le client avec un pull-up préliminaire du réseau social client javascript api correspondant. De plus, comme l'extension est installée sur l'utilisateur et que je dois autoriser sur mon serveur, j'ai également extrait du code HTML de mon serveur dans le script d'extension dans l'i-frame, mais j'ai déjà extrait l'api du réseau social dedans ...

Et le schéma d'échange de données avec le serveur était comme ça. Une page d'index d'extension envoie une commande (informations de clic, par exemple) à un script d'extension d'arrière-plan. Le script d'arrière-plan utilisant postMessage envoie des données au format html i-frame. I-frame envoie des données au script php sur le serveur. Le serveur répond dans l'i-frame, l'i-frame répond dans le script d'arrière-plan, le script d'arrière-plan répond dans l'index, l'utilisateur voit la réponse. Ouf ... Et surtout - tout a fonctionné!

En général, cela n'a pas fonctionné. Google a enveloppé mon extension d'un certain nombre de formulations, parmi lesquelles il y avait quelque chose de vague qui, disent-ils, votre extension ne respecte pas notre politique de sécurité. Grâce à la correspondance avec le support, j'ai pu obtenir des détails. À savoir, ils n'aimaient pas le fait que l'extension récupère du HTML et du js à partir de serveurs tiers ... En général, je devais me retrouver avec l'autorisation du client et revenir au serveur. Oui, l'envoi d'une demande de publication http à partir d'un script d'extension d'arrière-plan directement à votre serveur, cependant, il s'est avéré être autorisé. Et bien. C’est encore mieux. Il s'est avéré plus court et pas besoin de retirer l'api javascript des réseaux sociaux - c'est un temps d'attente supplémentaire pour l'utilisateur.

Afficher les onglets


Retour aux options d'extension. La liste des onglets elle-même est une série de lignes dans lesquelles vient d'abord le favicon de l'image, puis le titre de la page et enfin le lien. Ce qui ne correspond pas à la taille de ligne indiquée à l'écran est rogné. Mais la base de données est complètement enregistrée. De plus, n'importe quelle ligne peut être déplacée vers le haut de l'écran sous la forme d'une tuile colorée. C'est pour les sites les plus importants qui devraient être sous vos yeux en premier lieu.


Liste des onglets Chrome

Les couleurs des tuiles sont sélectionnées automatiquement en fonction du nom de domaine du site. La fonction accepte l'url. Le nom de domaine est divisé en trois groupes de caractères approximativement égaux. Les premiers caractères de chaque groupe sont convertis en valeurs des composants de couleur: R, G, B. Cette conversion est effectuée comme suit. Les codes de ces trois caractères sont réduits à la plage d1, de 0 à 25, en prenant le reste de la division par 26. Même les caractères de l'alphabet russe seront réduits à cette plage. Peu importe que la 27e lettre y devienne la première: nous n'avons pas besoin que les composantes de couleur de toutes les lettres de l'alphabet soient nécessairement différentes, qu'elles soient répétées. Ensuite, les trois nombres obtenus à partir de la plage d1 (0 ... 25) sont proportionnellement réduits à la plage d2 (150 ... 255). En général, ces plages sont définies au début de la fonction et peuvent être modifiées pour n'importe quelle autre. J'ai pris 150 ... 255 pour que les composants de couleur soient brillants. Si vous définissez, par exemple, 0 ... 100, les carreaux deviendront sombres. Ainsi, trois caractères du nom de domaine sont convertis en 3 nombres compris entre 150 et 255. Et puis, comme vous l'avez probablement deviné, ils sont interprétés comme les composants de couleur des carreaux R, G et B. Tout est très simple.

 getSiteColor=function(url) { var d1=[0,25], d2=[150,255]; var code=0, codep=0, color=0, str='', domen='', ar=[], inc=0; ar=url.split('//'); if (ar.length>1) {str=ar[1];} else {str=ar[0];}; str=str.split('www.').join(''); domen=str.split('/')[0]; str=domen.split('.').join(''); ar=[]; inc=Math.floor(str.length/3); if (str.length % 3 >0) {inc++;}; for (var i=0; i<str.length; i+=inc) { code=str.slice(i, i+1).charCodeAt(0); codep=code % (d1[1]-d1[0]+1); color=Math.round( codep * (d2[1]-d2[0]) / (d1[1]-d1[0]) ) + d2[0]; ar.push(color); }; return {r:ar[0], g:ar[1], b:ar[2], domen:domen}; } 

Structure du document HTML


Un document html se compose de plusieurs éléments de canevas avec positionnement absolu, combinés par superposition, et d'un bloc div dans lequel la liste est affichée. Une fonction est accrochée au redimensionnement de la fenêtre du navigateur qui redimensionne tous ces éléments, en les ajustant à la nouvelle hauteur et largeur. Il existe également une taille minimale qui permet de surmonter l'apparition de barres de défilement. L'image d'arrière-plan s'affiche sur la toile inférieure. J'ai décidé que pour différentes listes (c'est-à-dire les ordinateurs), différents arrière-plans devraient être définis pour faciliter la navigation de l'utilisateur. L'image de fond remplit la fenêtre avec la préservation de ses proportions et est légèrement éclaircie pour ne pas attirer l'attention sur elle - un rectangle blanc translucide est dessiné au-dessus d'elle. Au-dessus du canevas d'arrière-plan se trouve le canevas du menu principal, il ne remplit que le haut de l'écran. Bien et encore plus haut se trouve le bloc div, dans lequel la liste des onglets elle-même est formée. La navigation dans le menu Canvas se fait via ma mini bibliothèque.


Navigateur Opera et Yandex

Localisation


Sur l'écran principal, il y a un drapeau, en cliquant sur lequel l'interface bascule entre le russe et l'anglais. Ici, la page est redirigée vers la même adresse, mais avec un paramètre sur la ligne de commande. Ce paramètre est lu avant de charger tous les autres éléments. Et en fonction de sa valeur, tel ou tel fichier js contenant des phrases en russe ou en anglais est chargé dans le tableau associatif pour les phrases: lng_en.js ou lng_ru.js. Et dans l'application elle-même, pour afficher des phrases d'interface, des liens vers des chaînes de texte de ce tableau associatif sont déjà utilisés. En outre, en fonction de la valeur dans la barre d'adresse, un fichier est chargé contenant les éléments de l'interface graphique - boutons: buttons_en.png, ou buttons_ru.png. J'ai décidé qu'il était préférable de créer des boutons avec les icônes et les inscriptions dans chaque langue dans l'éditeur graphique plutôt que de créer un bouton vide et des icônes et des inscriptions superposées dessus, d'autant plus qu'il n'y en a pas beaucoup et que toute cette liste de sprites ne pèse que 50 Ko Je prévois de continuer à travailler sur la conception et à rendre tous les boutons de forme différente.



Le fichier général avec sprites main.png, qui contient des éléments graphiques qui ne sont pas liés à une localisation spécifique, est quand même chargé.

Version Web


Je pensais que ce serait bien si les liens soigneusement stockés à partir de la maison ou de l'ordinateur de travail pouvaient être consultés en chemin depuis le téléphone. Mais tous les navigateurs OS mobiles ne prennent pas en charge les extensions. J'ai donc créé un assemblage Web. En visitant le site à une adresse spécifique, vous pouvez toujours vous connecter en utilisant l'un des réseaux sociaux et afficher vos onglets.

Oui, il n'y a aucun moyen d'ajouter des onglets à la liste ou de les modifier. Mais vous pouvez au moins ouvrir des onglets dans la liste et afficher les pages. Je pense qu'il vaut la peine de travailler sur la version mobile de ce site et d'y afficher de plus grandes listes d'onglets.


Version Web dans IE 11

La publicité


Jusqu'à présent, je n'ai pas vraiment travaillé sur la promotion de mon expansion. Il vient de créer des groupes sur les réseaux sociaux et y a invité tous ses amis. Oui, il a lancé une campagne publicitaire dans Yandex Direct pour 1 500 roubles. Elle n'a donné aucun résultat spécial, mais peut-être que je n'ai pas fait l'annonce correctement. Ou peut-être que le problème est que j'ai indiqué un lien vers la version anglaise de la page d'accueil de l'extension. Et peut-être valait-il la peine de donner un lien non pas vers la page d'accueil, mais immédiatement vers l'un des magasins d'extension. Comme vous le savez, je ne suis pas un génie du marketing. En général, je vais réessayer avec d'autres paramètres. La campagne a généré 39 clics. Il est difficile de dire si j'ai acquis de nouveaux utilisateurs à la suite de cela.


Il y avait une bizarrerie avec la version sous Firefox.


Les statistiques du 17 octobre indiquent jusqu'à 227 téléchargements. Je ne sais pas si la campagne dans Yandex.Direct y a contribué ou non, mais pour une raison quelconque, 1 à 2 téléchargements par jour continuent à nouveau pour une raison quelconque. Dans le même temps, pour l'extension de Firefox, il y a le concept d'utilisateurs quotidiens:


Pourquoi il y avait 227 téléchargements, mais il n'y avait que 1-2 utilisateurs quotidiens, ce n'est pas clair. C'était peut-être une sorte d'échec. En général, je ne comprenais toujours pas ce que c'était, et où étaient tous ces gens ...

Les statistiques sur le magasin d'extensions Chrome Web Store ont satisfait un calendrier éternel de non-chargement - c'est ce que je n'ai pas vu - et 5-10 utilisateurs quotidiens.


J'ai également envoyé l'assemblage au magasin d'extension Opera. Cependant, après avoir présenté deux versions et sans attendre la modération de l'une d'entre elles, j'ai à un moment donné craché d'en répandre de nouvelles. Et, en effet, pourquoi est-ce nécessaire si l'Opera installe parfaitement les extensions du Chrome Store.


Résumé


J'ai créé trois versions d'extensions - pour Chrome, Firefox et la version Web. En fait, les trois assemblys sont un seul et même assemblage, ce qui indique simplement dans la configuration quel moteur de navigateur est actuellement utilisé. Et les fonctions correspondantes pour travailler avec des onglets sont initialisées. Je modifie cette valeur avant d'emballer en zip et d'envoyer le colis au magasin d'extension approprié.

Les versions de Chrome et Firefox ont été testées et placées dans leurs magasins d'extensions officiels respectifs. De plus, l'inscription en tant que développeur d'extensions auprès de Google coûte 5 $. Mozilla l'a gratuitement. La version Web de l'extension se trouve sur le serveur. L'assemblage du Chrome Store fonctionne bien dans les navigateurs compatibles: il peut également être installé dans Yandex Browser et Opera. Je prévois de publier de nouvelles versions avec des fonctionnalités encore plus avancées.

En général, les extensions de navigateur sont puissantes. Maintenant, je n'ai pas besoin de me lever du canapé, et il n'y a pas non plus besoin de rage pour casser le comprimé. C'est complètement zen. Bon à tous.

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


All Articles