[ Links open in: same window | new window ]

Radical Software

LCST 2234, Fall 2024 (CRN 9430)
Rory Solomon

Project 1, Tutorial 4: Some additional techniques

Some additional code snippets and techniques:

  1. Highlighting text
  2. Options page formatting
  3. Modifying HTML, can be used to create "popup" effects

01. Highlighting text

I got some questions about how to highlight a word or phrase in a webpage. This is almost possible given what we've already talked about in class, but it's actually a little bit more complicated. I created the below code snippet to illustrate how to do this.

var html = document.querySelector('html');
var walker = document.createTreeWalker(html, NodeFilter.SHOW_TEXT);
var node;

while (node = walker.nextNode()) {

  if ( node.nodeValue.includes("paragraph") ) {
    newNodeValue = node.nodeValue.replace(/paragraph/gi,"<span style='border: solid 1px red;'>paragraph</span>");
    newElement = document.createElement("template");
    newElement.innerHTML = newNodeValue;
    node.before(newElement.content);
    oldNode = node;
    node = walker.nextNode();
    oldNode.remove();
  }
}

This would go inside your content_scripts file. (For example tutorial1-content.js or whatever you have indicated in manifest.json.)

Change the orange words above to be whatever word or phrase you want to highlight. And change the blue text above to be any other CSS styling that you'd like to use to highlight that word or phrase. For example, you could try this to style it as a traditional yellow highlight:

background-color: yellow;
(jump back up to table of contents)

02. Options page formatting

Several people were planning to add more to their options page by adding additional input fields. We didn't talk abou thow to format those nicely so I wanted to give an example of how to do that.

At the very least, if you want your various <input> elements to appear each on their own line, you could enclose each inside a <p> tag. So building on where we left off with options.html, you might add those tags with the file looking like this:

<body>
  <div>
    <p>
      From text: <input id="fromField" type="text" />
    </p>
    <p>
      To text: <input id="toField" type="text" />
    </p>
    <button type="button" id="button">Set text</button>
    <button type="button" id="clear">Clear text</button>
  </div>
</body>

Next, if you want to have more elements on the page and you want to control their placement and spacing, you could include groupings of HTML elements in <div> elements. Like this:

<body>
  <div>
    <div>
      <p>
        From text 1: <input id="fromField1" type="text" />
      </p>
      <p>
        To text 1: <input id="toField1" type="text" />
      </p>
    </div>

    <div>
      <p>
        From text 2: <input id="fromField2" type="text" />
      </p>
      <p>
        To text 2: <input id="toField2" type="text" />
      </p>
    </div>

    <button type="button" id="button">Set text</button>
    <button type="button" id="clear">Clear text</button>
  </div>
</body>

Note that I have changed the id attributes for my HTML <input> elements here. If you do this, you'll need to go through your extenions (your options.js file, and your content scripts) and change any references to these fields. So fromField should become fromField1, etc. You should then push this through so that all those fields end with ...1, and if you want to access the other fields, they'll all end with ...2 etc.

Now, if you want to style those <div>s in some way, you can add some CSS to control their appearance. See my comments in Tutorial 2, part 02.a for three different ways of attaching CSS rules to an HTML page. If there is a lot of styling that you want to do to your opttions page, you should probably put that in a separate CSS file. In your options.html file, add this:

<html>
<head>
  <script src="options.js" defer></script>
  <link rel="stylesheet" href="options-styles.css">
</head>
<body>

Then, create a new file called options-styles.css and start to add CSS rules to it. Here is some sample CSS that starts to work on controlling the appearance of this options.html code:

div {
  width: 250px;
  border: solid 1px #000;
  padding: 5px;
  margin: 5px;
}

If you do all that, and click in to your extenion's options page, you should see something that looks like this:

If you want to format the different <div>s differently, you can add CSS classes, like this:

  <body>
    <div class="outter">
      <div>

and modify your CSS file like this:

div {
  width: 250px;
  border: solid 1px #000;
  padding: 5px;
  margin: 5px;
}

div.outter {
  width: 275px;
  margin: 25px;
  padding: 10px;
}

Which should space things out a little better. And then if you'd like, maybe add some additional HTML and text to offer some context, explanation, or instructions to your user:

    <div class="outter">
      <h1>Rory's Browser Extension Options</h1>
      <p>
        Specify some options here ...
      </p>
      <div>

If you do all that, you should end up with something that looks like this:

Hopefully that's enough to get you started exploring further.

(jump back up to table of contents)

03. Modifying HTML & "popup" effects

Another technique people have asked about is how to create "pop-up" like effects. You do this by using Javascript code to add or modify HTML within the current page.

You can create a "pop-up" effect specifically by adding a <div> to the page, specify its position, dimensions, and appearance, and then when the user clicks somewhere, delete it.

Let's start with the example I explained in Part 01 above modified slightly:

var html = document.querySelector('html');
var walker = document.createTreeWalker(html, NodeFilter.SHOW_TEXT);
var node;

while (node = walker.nextNode()) {

  if ( node.nodeValue.includes("paragraph") ) {
    newNodeValue = node.nodeValue.replace(/paragraph/gi,"<span class='click-me'>paragraph</span>");
    newElement = document.createElement("template");
    newElement.innerHTML = newNodeValue;
    node.before(newElement.content);
    oldNode = node;
    node = walker.nextNode();
    oldNode.remove();
  }
}

This is the same as the code snippet from Part 01 except that I've made a change to the <span>. Instead of specifying a style attribute with CSS rules, it assigns a CSS class to that span.

The point of using a CSS class is that it makes it easier to use Javascript code to target all HTML elements that are marked with that class. In other words, using CSS classes, we can write Javascript code that is triggered by some user interaction event on any element with that CSS class.

So this finds all instances of the word "paragraph" on the page and puts that word in a <span> element with the CSS class click-me. (The word click-me here is not a special keyword in any sense. I could have used any word I'd like.)

To use this, I'm going to use document.getElementsByClassName() to select a list of all HTML elements with the click-me class, and then use addEventListener() to add code that responds to a click on each of those words. The code to do that is the following:

var clickableWords = document.getElementsByClassName('click-me');
for (var word of clickableWords) {
  word.addEventListener('click', function() {
    var popup = document.createElement("div");
    popup.style.width = "500px";
    popup.style.height = "250px";
    popup.style.border = "solid 1px #000";
    popup.style.margin = "10px";
    popup.style.padding = "10px";
    popup.style.position = "absolute";
    popup.style.top = "50px";
    popup.style.left = "50px";
    popup.style.backgroundColor = "#fff";
    popup.style.zIndex = "9999";
    popup.textContent = "Hello this is some sample text.";
    document.body.insertAdjacentElement("afterbegin",popup);

    popup.addEventListener('click', function() {
      popup.remove();
    });
  });
}

All of the lines that begin with popup.style are setting CSS properties on our "pop-up". You can modify these to control the size, position, and color of the <div> as well as any other CSS properties.

The line that begins popup.textContent sets the text that will be the content of the pop-up.

And the last few lines that begin with popup.addEventListener adds an event listener so that if the user clicks anywhere in the pop-up, it will be closed (i.e., removed).