Surligneur MarkIt
Il s'agit d'un lien d'extension Chrome qui vous permet de mettre en évidence du texte important sur n'importe quelle page Web. Revisitez la page dans 1 minute, 1 semaine ou 1 an – vos données seront toujours là.
Technologies
- (Vanille) JavaScript
- API Google
Caractéristiques
- Mettez en surbrillance n’importe quel texte et appuyez sur Commande+K pour l’enregistrer automatiquement
- L'utilisateur peut effacer les surlignages stockés pour n'importe quelle URL avec une simple commande, Commande+Maj+A.
- Synchronisation sur tous les appareils : si vous surlignez du texte à partir d'un ordinateur portable, puis consultez la même page Web depuis votre téléphone, vos surlignages seront là (si vous êtes connecté à Chrome sur les deux).
Ma structure de données stockée (objet)
highlights = {
google.com: {
text1: ["query selector", index, note, color]
text2: ["query selector", index, note, color]
},
yahoo.com: {
text3: ["query selector", index, note, color],
text4: ["query selector", index, note, color]
},
https://developer.mozilla.org/en-US/docs/Web/API/document/execCommand: {
"When an HTML document has been switched to designMode, its document object exposes an execCommand": ["p.summary", 20],
"A DOMString specifying the name of the command to execute. See Commands for a list of possible commands.": ["p", 0, "example note", #CFFFDF]
}
}
Comment ça marche
J'ai deux scripts qui se chargent sur chaque page. Le premier est background.js qui écoute un événement spécifique. L'événement Command+K déclenche une fonction qui injecte un script dans le navigateur (injection_script.js), qui met en évidence le texte sélectionné.
Pour mettre en surbrillance, faites glisser votre souris sur du texte et appuyez sur Commande+K. Cela déclenche une fonction qui en appelle plusieurs autres. Séquence des événements :
- Récupère le texte sélectionné
- Active le mode Conception "activé", nous permettant d'apporter des modifications temporaires au DOM
- Si l'arrière-plan est déjà mis en surbrillance, nous devons alors supprimer la surbrillance :
- Sélectionne la balise < span > entourant le texte et définit style.backgroundColor = transparent (supprime la surbrillance)
- Obtient l'objet 'highlights' du stockage -
chrome.storage.get()
- Parcourt toutes les clés (qui sont les faits saillants enregistrés) pour rechercher une correspondance et la supprime du stockage
- Sinon, enveloppez le texte dans un < span > et appliquez la couleur d'arrière-plan
- Lors de l'actualisation de la page : récupérer les « faits saillants » du stockage
- S'il n'y a aucune donnée pour l'URL active, définissez la clé sur l'URL actuelle et la valeur sur un objet vide (aol.com : {}).
- Si tel est le cas, récupérez la structure de données des faits saillants du stockage (chrome.storage.get()).
- Récupérez et attribuez une valeur de sélecteur de requête valide pour le texte sélectionné (elle sera utilisée pour interroger le DOM et appliquer les surbrillance plus tard. Reportez-vous à la structure de l'objet ci-dessus pour plus de précisions)
- Si l'élément parent du texte en surbrillance a un nom de classe, stockez une chaîne "element.className" ("p.firstParagraph", "h2.sectionHeader", etc.)
- S'il n'y a pas de nom de classe, stockez la chaîne "element" ("p", "h2", "li", etc.)
- Donnez à la clé (texte en surbrillance) une valeur (un tableau contenant 2 valeurs - d'abord, le sélecteur de requête et ensuite, l'index de l'endroit où le texte sélectionné est apparu dans l'élément parent)
- Je stocke l'index de la chaîne car si je stockais uniquement le texte et le sélecteur de requête, disons que vous avez mis en surbrillance "le" sous une balise "p", lors de l'application des surbrillances si vous actualisez la page, chaque occurrence de "le" dans un La balise "p" sera mise en surbrillance. L'ajout de la valeur indexOf me permet de vérifier que les index correspondent au DOM et ensuite seulement d'appliquer la surbrillance, j'applique donc la surbrillance au mot correct.
- Stockez la variable de surbrillance mise à jour contenant le nouveau texte en surbrillance à l'aide de chrome.storage.set()
- Désactiver le mode conception
Le deuxième fichier JavaScript qui s'exécute sur chaque page est content_script.js. Il vérifie s'il existe un objet stocké appelé « faits saillants ». Si ce n’est pas le cas, cela signifie que l’utilisateur n’a jamais rien mis en surbrillance. Il crée ensuite un objet vide et le stocke dans Chrome.
S'il trouve un objet « faits saillants », il vérifie s'il existe des données stockées pour l'URL active. Si ce n'est pas le cas, le script revient.
Si des surlignages sont stockés pour l'URL :
- La fonction applyHighlights() s'exécute
- Il prend deux paramètres, l'objet 'highlights' et l'URL active
- Parcourt les clés de l'objet stocké (les clés sont les surlignages stockés, tandis que les valeurs de ces clés sont un tableau contenant les valeurs querySelector et indexOf)
- Exécute document.body.querySelectorAll() pour obtenir un tableau de tous les nœuds correspondants
- Parcourt chaque nœud renvoyé et si le innerHTML contient une "chaîne" correspondant à la clé de l'objet (texte en surbrillance) ET à la même valeur indexOf : 1. Exécute une fonction .replace() en enveloppant le texte correspondant dans une balise < span > avec un attribut de style en ligne pour la couleur d'arrière-plan
- remarque complémentaire : à l'origine, j'ai parcouru chaque nœud DOM de manière récursive pour vérifier les correspondances, mais le stockage de la valeur querySelector et la comparaison des valeurs HTML des nœuds correspondants uniquement à mes valeurs stockées sont beaucoup plus rapides.
Mises à niveau pour la prochaine version
- Stockez la chaîne spécifique que vous avez mise en surbrillance
- "Téléchargez la bibliothèque jQuery depuis jQuery.com".
- Si vous mettez en surbrillance le deuxième "jQuery", la valeur stockée sera celle de la première instance.
- En effet, la valeur indexOf que je stocke revient après la première correspondance.
- PLAN - commence à compter l'index après la balise span
- ne peut pas surligner les éléments du bloc (si vous faites glisser la surbrillance d'un h2 vers la balise ap, seul le h2 sera enregistré)
- EN COURS : Autoriser les utilisateurs à choisir la couleur de surbrillance
- Afficher le nombre de faits saillants et les faits saillants réels d'une page dans l'extension popup.html
- Limitations/cas limites : e-mail, PDF
- Je demande des autorisations pour chaque site. auxquels certains sites bloquent l'accès '*' (cnn.com)
- Si vous mettez en surbrillance "jQuery" dans un élément, puis le mettez à nouveau en surbrillance dans un autre, le second remplace le premier (car la clé est la même)
- Si l'élément parent est une balise en ligne, l'indexOf innertext/html ne s'enregistre pas (-1) ou il termine la surbrillance à la fin de la balise en ligne. Recherchez l'index de la balise span et démarrez-y l'indexOf.
- Mode Réduire - réduire le document aux seuls éléments parents des surbrillances stockées
Problèmes résolus
- Stockage des faits saillants couvrant les balises d'éléments en ligne (a, em, st, etc.)
- Avant, seul le texte précédant la balise en ligne était enregistré, car je stockais le innerText
- Je l'ai résolu en stockant le innerHTML à la place
- Le problème qui découlait de ce changement était que je stockais l'indexOf du innerText, qui réappliquerait les surlignages au texte standard à l'intérieur d'un élément de texte, comme une balise "p". Mais l'indexOf est différent pour les éléments situés autour des éléments en ligne car l'indexOf compte chaque caractère dans les balises.
- Pour résoudre ce problème, je compare les valeurs innerText.indexOf ET innerHTML.indexOf et je compare chacune d'elles aux nœuds correspondants lors de l'application de surbrillance aux pages qu'un utilisateur visite à nouveau.
- Si vous double-cliquiez pour mettre en surbrillance une section, les valeurs indexOf ne seraient pas enregistrées et mon application n'aurait donc pas pu réappliquer les surlignages.
- Pour le résoudre, j'ai ajouté les méthodes .toString() et .trim() au indexOf(...)
- La mise en surbrillance d'une balise < a > supprimerait le lien lors du chargement de la page.
Futures mises à niveau
## Exemple d'image
Cas de pointe
- Si les noms de classe changent
- Solution : si le nom de la classe n'existe pas dans le DOM, supprimez le nom de la classe du sélecteur de requête et recherchez simplement les nœuds de balise d'élément.
- Si le contenu est masqué par un bouton, mes surlignages ne seront pas enregistrés car ils recherchent on_load et le contenu n'est révélé qu'après un événement du navigateur (c'est pourquoi cela ne fonctionne pas sur le courrier électronique)
Autoriser quelqu'un à accéder à tous les surlignages du popup.html Autoriser les utilisateurs à changer la couleur du surligneur Correction d'un bug de surbrillance des éléments en ligne