Personalize web pages with GreaseMonkey

December 2016

GreaseMonkey is an extension of the Mozilla Firefox web-browser that allows users to modify web pages they have visited whilst surfing the internet. This unique software enables users to personalize web pages according to their preferences, by enhancing or deleting certain parts of the page. Some knowledge of scripting languages and programming languages is required to write GreaseMonkey scripts as they contain elements from Javascript, DOM, HTML, CSS and XPATH. For those interested in personalizing web pages using GreaseMonkey, the entire self help manual can be downloaded for free from the internet along with other useful resources.


What is GreaseMonkey?


GreaseMonkey is an extension for Firefox that allows you to tweak on the fly web pages you visit.
That is, it will change the page directly in the browser.

This allows you to change at will all the pages of any site as you wish: remove items that you don't like, edit the HTML, add the HTML code, change / add / remove javascript, change colors, add features, increase or decrease the size of tables, forms etc...

Example 1


This script will modify pages of Kioskea to enlarge the message field in forums.

// This script is in public domain.
//
// ==UserScript==
// @name KIOSKEA-Forums
// @namespace WEBSITE
// @description Modify web pages of ccm
// @include http://ccm.net/*
// @include http://www.commentcamarche.com/*
// @include http://www.commentcamarche.net/*
// ==/UserScript==

(function () {
// Removes all occurences of elements whose XPath is provided from the document.
//
// Example: Remove all tables which use the CSS class 'toto':
// removeElement("//table[@class='toto']");
function removeElement(ElementXpath)
{
var alltags = document.evaluate(ElementXpath,document,null,XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,null);
for (i=0; i<alltags.snapshotLength; i++)
{
element = alltags.snapshotItem(i);
element.parentNode.removeChild(element); // Remove this element from its parent.
}
}

// Removes an attribute from all occurences of elements whose XPath is provided.
// (All occurences of this elements are processed.)
//
// Example: Remove the bgcolor of all <table>:
// removeAttributeOfElement('bgcolor',"//table[@bgcolor]")
// Remove the fixed with of all tables or cells::
// removeAttributeOfElement('width',"//table[@width]|//td[@width]")
function removeAttributeOfElement(attributeName,ElementXpath)
{
var alltags = document.evaluate(ElementXpath,document,null,XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,null);
for (i=0; i<alltags.snapshotLength; i++)
alltags.snapshotItem(i).removeAttribute(attributeName);
}

// Set an attribute from all occurences of elements to a specified value.
// The previous value of this attribute is discarded.
// (All occurences of this elements are processed.)
//
// Example: Set with to 80 columns on all texteareas:
// setAttributeOfElement('cols',80,"//textarea")
function setAttributeOfElement(attributeName,attributeValue,ElementXpath)
{
var alltags = document.evaluate(ElementXpath,document,null,XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,null);
for (i=0; i<alltags.snapshotLength; i++)
alltags.snapshotItem(i).setAttribute(attributeName, attributeValue)
}

// Inject your own CSS in the page.
// Example: Do not underline link:
// injectCSS("a{text-decoration: none;}")
function injectCSS(cssdata)
{
head = document.getElementsByTagName("head")[0];
style = document.createElement("style");
style.setAttribute("type", 'text/css');
style.innerHTML = cssdata;
head.appendChild(style);
}

try
{
// Enlarging the field of the message setAttributeOfElement('rows','40',"//textarea[@name='message']");
setAttributeOfElement('cols','120',"//textarea[@name='message']");

// In the list of discussion, we put in bold the discussion that have not received any reply. setAttributeOfElement('style','font-weight:bold;',"//td[text()='0']/../td[1]/a");
}

catch (e)
{
alert("UserScript exception:\n" + e);
}

})();


The most important part of the script is:

setAttributeOfElement('rows','40',"//textarea[@name='message']"); setAttributeOfElement('cols','120',"//textarea[@name='message']");   


These two lines change the size (rows, cols) of the text box (text area) used to type messages (identified by name = "message").

It uses XPath (/ / textarea ...) to select the element on which to act.

XPath is a way to designate specific elements of an HTML page, but its use is not mandatory.
You can go through the traditional DOM methods (.GetElementsByTagName () and then do a for loop, etc.).

Example 2


This script also contains this line:

setAttributeOfElement('style','font-weight:bold;',"//td[text()='0']/../td[1]/a");    }


In the discussion area of the forum, this will add bold titles to discussions which have not been replied to.

The XPath :
- Select the table cells containing the text "0" (td [text () ='0 '])
- Go back on level <TR> (/..)
- We go on in the first <TD> cell (which contains the title) (/ td [1])
- We put in bold all the links (/ a) contained in this <TD>.

XPath


Some examples:

- Select all images: / / img
- Select all the images without borders: / / img [@ border ='0 ']
- Select all links pointing to Google: / / a [@ href = 'http://google.com']
- Select All links to Google and containing the text "Link to Google: / / a [@ href = 'http://google.com' and contains (., 'Link to Google')]
- Select all the links: / / a
- Select only those images that link: / / a / img
- Select only the links directly placed in a table cell: / / td / a
- Select only the first link placed directly in a table cell: / / td / a [1]
- Select only the last link placed directly in a table cell: / / td / a [last ()]
- Select all the table cells containing the exact text "Hello": / / td [text () = 'Hello']
- Select all the table cells containing (somewhere in the text) the word "Hello": / / td [contains (., 'Hello')]
- Select all table cells starting with the text "Hello": / / td [starts-with (., 'Hello')]
- Select all tables containing a cell containing the word "foo": / / td [contains (., 'Hello')]/../.. (The first / .. back in the <tr> and / .. following dates at the <table>)
- Select all cells in the second column of the tables: / / tr / td [2]
- Select all cells in the last column of the tables: / / tr / td [last ()]
- Select the cells in columns 1,2 and 3 tables: / / tr / td [position ()
<= 3]
- Select all tables with at least one attribute: / / table [@ *]
- Select all the tables with the attribute width: / / table [@ width]
- Select all the tables with a width of 400px: / / table [@ width ='400px ']
- Select all the tags that are direct daughters of a cell: / / td / *
- Select all links that are directly son of a cell: / / td / a
- Select the second link is the direct son of a cell: / / td / a [1]
- Select the first tag in a cell, what it is: / / td / * [1]
- Select the first tag with a onload attribute: / / td / * [@ onload]
- Select the tag being a tag after p in the html code: / / p / following:: a
- Select the tags that are immediately <a> girls tag p: / / p / a
- Select any tag that is contained in a p tag (regardless of depth) / / p / descendant:: a
- Select all the tags that are <a> after p tag, but at the same level: / / p / following-sibling:: a
In Firefox, you can use the DOM Inspector to help you find the elements to select (CTRL + SHIFT + I).

You can also use the extension to test your XPath expressions XPath.

Utilities


The script ccm.user.js contains 4 classes of utilities to make your life easier:
removeElement (path): remove an item from the page.
removeAttributeOfElement (nomattribut Road): remove the attribute of an element.
setAttributeOfElement (nomattribut, value, path): add or modify the attribute of an element
injectCSS (): inject your own CSS in a page.

Path is the path of the XPath element.

Examples:

removeElement()


...<td><span class="comment">blablabla</span></td>...


To delete the rubbish, it would be: removeElement ( '/ / td / span [@ class =' comment']');
To delete cell (td) containing that blabla: removeElement ( '/ / td / span [@ class =' comment']/..');
To delete all comments, even if they are not in a table cell, it would: removeElement ( '/ / span [@ class =' comment']');

removeAttributeOfElement()


...<table width="400px" bgcolor="#ffe">...


To remove the size indicated in this table: removeAttributeOfElement ( 'width','// table [@ bgcolor =' # ffe']');

setAttributeOfElement()


...<table width="400px" bgcolor="#ffe">...

To force the width of the table: setAttributeOfElement ( 'width','100 %','// table [@ bgcolor = '# ffe']');

injectCSS()


To change the default font on a web page:
injectCSS ( 'body (font-family: Verdana, sans-serif;)');

Links


GreaseMonkey Extension: https://addons.mozilla.org/fr/firefox/addon/748
GreaseMonkey Manual: http://diveintogreasemonkey.org/

Note: Writing scripts GreaseMonkey is not always easy (it must contain Javascript, DOM, HTML, CSS and XPath optionally).

Platypus is a Firefox extension that allows to automatically generate scripts GreaseMonkey:
https://addons.mozilla.org/fr/firefox/addon/737
But Platypus has a tendency to generate Javascript code which is rather slow and cumbersome.

Related :

This document entitled « Personalize web pages with GreaseMonkey » from CCM (ccm.net) is made available under the Creative Commons license. You can copy, modify copies of this page, under the conditions stipulated by the license, as this note appears clearly.