About

Let me think is a browser plug-in that customizes my online shopping experience at Amazon by canceling the 'Add to Cart' functionality.

Once it is installed, when I visit the Amazon.com website, the 'Add to Cart' button is removed from the page. In its place, my own button is used. This personalized, truly customized button does not behave as the original one: instead of putting the products in the shopping cart immediately, a pop up screen is displayed, with a question such as 'Do you really need to buy a [name of product]? Take your time and think about it.' I can then cancel the plug-in and go back to Amazon's regular website or keep thinking about the purchase. The pop up screen will be withdrawn in any case, but if I chose to keep thinking, by clicking on the modified button again, a new question will be displayed and the purchase is postponed one more time.

By adding time to the shopping cycle, I'm trying to break this automatic, almost unconscious behavior that web shops wants us to engage with: just clicking on things and buying without reflecting on what we're doing.

This project is part of my Self-Directed Master Research at Piet Zwart Institute, in Rotterdam, where I studied Media Design and Communication between 2013 and 2015.

How To

You can do the same - in Amazon website or any other webshop. For that, follow the tutorial below. It contains detailed explanation on how this plugin works and what you have to do if you want to modify my custom version.

Nov 18, 2017 - UPDATE:
Both the tutorial below and the images require an upgrade to match current GreaseMonkey & Firefox versions. This is being taken care of and will be published soon.

Step 1 - install Greasemonkey

Greasemonkey is a Firefox add-on which allows us to load our own scripts in the browser. You can download it at https://addons.mozilla.org/en-US/firefox/addon/greasemonkey/ Let me think Let me think

Restart Firefox. Let me think

Once Greasemonkey is installed and Firefox has restarted, you will see a monkey icon on the top right side of your browser window. That means Greasemonkey is installed and ready to receive your code! If you click on this icon, you will see the options Greasemonkey gives you. Let me think

Step 2 - add your custom code

First, take a look at the code below. We'll be reviewing the code in chunks here.


// ==UserScript==
// @name        Let me think
// @description Adds delay to your online shopping experience
// @grant       none
// @include     https://www.amazon.tld/*
// @require 	http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js
// @version 	0.1
// ==/UserScript==

function htmlToDomNode(html) {
    var container = document.createElement('div');
    container.innerHTML = html;
    return container.firstChild;
}

$('.a-button-stack').each(function(index){
  if(index == 0){
    $(this).before(
      htmlToDomNode('<div class="new" id="more-time" style="cursor: pointer;"><img src="http://headroom.pzwart.wdka.hro.nl/~ldossin/let-me-think/img/new_cart.png" title="Let Me Think is enabled" /></div>')
    );
  }
});

$('.a-button-stack').css('display','none');

$('#navFooter').after(
     htmlToDomNode('<div id="interference" style="display: none; width: 100%; height: 100%; border: 3px solid orange; background-color: rgba(255, 255, 255, .9); z-index: 1000; padding: 50px;"><div style="background-color: #fff; padding: 10px;"><h2 style="margin-bottom: 40px;">Wait!</h2><p style="font-size: 1.1em;">Lorem ipsum.</p><div style="width: 80%; margin: 0 auto; margin-top: 40px; text-align: center;"><button id="quit" style="border-radius: 3px; border-color: #CBA957 #BF942A #AA8326; border-width: 1px; border-style: solid; background: -moz-linear-gradient(center top , #F7DFA5, #F0C14B) repeat scroll 0 0 rgba(0, 0, 0, 0); font-size: 11px; height: 24px; line-height: 21px;" >I desperately need it</button><button id="think" style="border-radius: 3px; border-color: #CBA957 #BF942A #AA8326; border-width: 1px; border-style: solid; background: -moz-linear-gradient(center top , #F7DFA5, #F0C14B) repeat scroll 0 0 rgba(0, 0, 0, 0); font-size: 11px; height: 24px; line-height: 21px; margin-left: 12px;" >Let me think</button></div></div><div id="stop" style="position: absolute; top: 2px; right: 10px; text-weight: bold; color: orange; cursor: pointer; border: 2px solid black; border-radius: 12px; padding: 4px;">x</div></div>')
);

product_name = $('span#productTitle').text();
product_price = $('span#priceblock_ourprice').text();
product_image = $('li.image img').attr('src');

if(!product_price){
    product_price = 'your money';
  }

args = [
        'Take the time you need to carefully think about this purchase - you really don\'t have to rush.',
        'Maybe you don\'t really need a <span style="font-weight: bold;">'+ product_name + '</span>. Do you?',
        'Can\'t you think of something more useful to do with <span class="a-color-price">' +product_price + '</span> than buying this?',
        'Have you already considered the amount of garbage involved in the making, selling and discarding of a product such as  <span style="font-weight: bold;">'+product_name+'</span>?',
        'Check what Richard Stallman has to say about Amazon:\n <a href="http://stallman.org/amazon.html" target="_blank">http://stallman.org/amazon.html</a>'
       ];
i = 0;

$('#more-time').on('click', function(){
    $('li.image img').attr({'src' : 'http://headroom.pzwart.wdka.hro.nl/~ldossin/let-me-think/img/8338838878_4744f4d92f_k.jpg','alt' : 'Photo by  Shishir Basant, from Flickr'});
    $('#interference').css({'display': 'block', 'width': '50%', 'height': '50%', 'position': 'fixed', 'top': '25%', 'left': '25%'});
    if(i<=args.length-1){
       $('#interference p').html(args[i]);
       i++;
    }else{
       i = 0;
       $('#interference p').html(args[i]);
       i = 1;
    }

});

function erase_it(){
  $('div.a-button-stack').css('display','block');
  $('div.new, div#interference').css('display','none');
  $('li.image img').attr('src' ,product_image);
}

$("#stop, #quit").on('click', function(){
  erase_it()
});

$('#think').on('click', function(){
  $('div#interference').css('display','none');
});

Select all code above and copy it.

Click on the monkey icon on the top right side of your browser window and then click on New User Script. Let me think

Then, click on 'Use Script From Clipboard'.
Let me think Paste the copied code and save.
Let me think

As promised above, here you will find relevant explanation on what this code does.

The code header

// ==UserScript==
// @name        Let me think
// @description Adds delay to your online shopping experience
// @grant       none
// @include     https://www.amazon.tld/*
// @require 	http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js
// @version 	0.1
// ==/UserScript==

These are the basic parameters, pretty straightforward.

@name is how you want to call your script - use a relevant name, it will help you identify this script, in case you have any other scripts running in Greasemonkey.
@description is the description - what this script does actually
@grant indicates eventual special privileges granted to the script. In this case, none.
@include indicates URLs in which the script will run (By using 'www.amazon.tld', we're including all domain extensions that come after 'www.amazon': .com, .co.uk, .de etc)
@require indicates external libraries and other requirements for the code to run properly. In this case, we need jQuery.
@version is self-explanatory :)

The code below is a function that will make the addition of a new element to the page. Don't change anything here, leave as it is.

function htmlToDomNode(html) {
    var container = document.createElement('div');
    container.innerHTML = html;
    return container.firstChild;
}

First, we identify the element that has the class .a-button-stack. There are several elements that match this condition, so we're going to find the first one and place our own button right before it. Our own button will contain an image (see img src below). You can use another image if you want. It can be a bit complicated to use a image file from your computer, so to avoid that and keep things easy, use an image that is online. You just need the URL to it, just how I did in the example below.

$('.a-button-stack').each(function(index){
  if(index == 0){
    $(this).before(
      htmlToDomNode('<div class="new" id="more-time" style="cursor: pointer;"><img src="http://headroom.pzwart.wdka.hro.nl/~ldossin/let-me-think/img/new_cart.png" title="Let Me Think is enabled" /></div>')
    );
  }
});

Then, we remove the original 'Add to Cart' button. '.a-button-stack' is how the button is identified (its CSS class). Actually there are many elements using this class and we're removing all of them from screen with this line of code.

$('.a-button-stack').css('display','none');

Now, we place our popup sign. It will be placed in the end of the page and it will initially be hidden. It will become visible later, when we click on the 'Add to Cart' button. To change the sentences used in the buttons, just edit according to your preferences. Do not change any names or ids or the code will not work.

$('#navFooter').after(
     htmlToDomNode('<div id="interference" style="display: none; width: 100%; height: 100%; border: 3px solid orange; background-color: rgba(255, 255, 255, .9); z-index: 1000; padding: 50px;"><div style="background-color: #fff; padding: 10px;"><h2 style="margin-bottom: 40px;">Wait!</h2><p style="font-size: 1.1em;">Lorem ipsum.</p><div style="width: 80%; margin: 0 auto; margin-top: 40px; text-align: center;"><button id="quit" style="border-radius: 3px; border-color: #CBA957 #BF942A #AA8326; border-width: 1px; border-style: solid; background: -moz-linear-gradient(center top , #F7DFA5, #F0C14B) repeat scroll 0 0 rgba(0, 0, 0, 0); font-size: 11px; height: 24px; line-height: 21px;" >I desperately need it</button><button id="think" style="border-radius: 3px; border-color: #CBA957 #BF942A #AA8326; border-width: 1px; border-style: solid; background: -moz-linear-gradient(center top , #F7DFA5, #F0C14B) repeat scroll 0 0 rgba(0, 0, 0, 0); font-size: 11px; height: 24px; line-height: 21px; margin-left: 12px;" >Let me think</button></div></div><div id="stop" style="position: absolute; top: 2px; right: 10px; text-weight: bold; color: orange; cursor: pointer; border: 2px solid black; border-radius: 12px; padding: 4px;">x</div></div>')
);

The first three lines are variables that we are creating to store the product's name, price and image. We'll use those in our sentences.
In some cases, there are several prices possible (used books, for example). In this case, we have to check if product_price exists. If not, we'll define the string 'your money' to it, instead of a price.

product_name = $('span#productTitle').text();
product_price = $('span#priceblock_ourprice').text();
product_image = $('li.image img').attr('src');

if(!product_price){
    product_price = 'your money';
  }
The args array stores the sentences that we use each time we click on the custom button. You can edit them and use your own arguments to prevent you from buying unnecessary stuff. If you want to add a new sentence, just add a comma after the last one and place the sentence between single quotes. If you use single quote inside your sentence (for example, as in don't), you have to escape it. It will look like this: don\'t. This will tell the code that this is not the end of the sentence (you put the sentence between single quotes, remember?)
args = [
        'Take the time you need to carefully think about this purchase - you really don\'t have to rush.',
        'Maybe you don\'t really need a <span style="font-weight: bold;">'+ product_name + '</span>. Do you?',
        'Can\'t you think of something more useful to do with <span class="a-color-price">' +product_price + '</span> than buying this?',
        'Have you already considered the amount of garbage involved in the making, selling and discarding of a product such as  <span style="font-weight: bold;">'+product_name+'</span>?',
        'Check what Richard Stallman has to say about Amazon:\n <a href="http://stallman.org/amazon.html" target="_blank">http://stallman.org/amazon.html</a>'
       ];
Take a look on the fourth argument in our list above. You see I'm using the product's name? I did that by grabbing the product's name and storing its value in a variable, called product_name (first line in the code above). Then, I'm using it inside my arguments. To do that, I have to close the single quotes, then add the variable, then open the single quotes again. The piece of code that says <span class="a-color-price"> is responsible for setting this text in red. That is defined in the CSS used by Amazon, that's how they style their prices in a page.

Below you'll find the code that runs when we click on our custom button.

It will first change the product image by one image of our choice (in this case, I used the picture located in the URL below). This picture was taken by Shishir Basant and I got it from Flickr. Then, the code will place our popup sign (#interference) in the center of the page. Next, it will display one of the sentences in our args array. When it gets to the last sentence, it will display the first one again.

i = 0;

$('#more-time').on('click', function(){
    $('li.image img').attr({'src' : 'http://headroom.pzwart.wdka.hro.nl/~ldossin/let-me-think/img/8338838878_4744f4d92f_k.jpg','alt' : 'Photo by  Shishir Basant, from Flickr'});
    $('#interference').css({'display': 'block', 'width': '50%', 'height': '50%', 'position': 'fixed', 'top': '25%', 'left': '25%'});
    if(i<=args.length-1){
       $('#interference p').html(args[i]);
       i++;
    }else{
       i = 0;
       $('#interference p').html(args[i]);
       i = 1;
    }

});

Now, we're first creating the function that will stop our code (erase_it()). Then, we assign that function to run when the 'close' button or the 'I desperately need it' button are clicked.

function erase_it(){
  $('div.a-button-stack').css('display','block');
  $('div.new, div#interference').css('display','none');
  $('li.image img').attr('src' ,product_image);
}

$("#stop, #quit").on('click', function(){
  erase_it()
});

This last piece of code closes our popup sign (but does not stop our code). It will allow the popup sign to be displayed again when we click on our custom button.

$('#think').on('click', function(){
  $('div#interference').css('display','none');
});

Back to the full code snippet.

Step 3 - edit your existing code

Go to the monkey icon again and click on Manage User Scripts.
Let me think

Click on Enable if it is disabled. Click on Preferences to edit your code. Let me think
Then, click on Edit this User Script. Make your changes to the code and don't forget to save it. Click OK when you're in this screen again. Let me think

FAQ

  1. First, you install Greasemonkey and the code that you can find (here) on this page. Once Greasemonkey is installed and the code is activated, you can browse Amazon.com and see what difference it makes when there is time to think about your purchases.
  2. Go to Greasemonkey download page, click on the green button that says '+ Add to Firefox' and add your script. You can follow the steps in the tutorial on this page to have the code according to your preferences.
  3. Yes, totally.
  4. There can be many reasons. First, check if the Greasemonkey Plugin is activated and if your code is enabled. If that doesn't solve your issue, check if the element you're calling in your code still exists in the webshop page. If it doesn't, you can fix that by changing your code. Don't forget to save it when you're done!
  5. No.
  6. I see your point, and it would, indeed be 'more efficient'. But that would go against one of the core principles of this project, which is to resist against features that are implemented without the full awareness of consumers/users and that are supposed to take advantage of our passiveness. This is more an exercise, an experiment and a statement than a proper tool.
  7. Well, you have the choice of not installing it, of course. But you could also install, try, see how it feels like. You can disable the code anytime you want.
  8. To disable just the code but keep Greasemonkey running, just go to the Greasemonkey tab on your browser and click on 'Manage user Scripts'. That will show you all your Scripts. Simply click on Remove.
  9. Yes, that's as simple as going to the Greasemonkey tab on your browser and clicking on 'Manage user Scripts'. That will show you all your Scripts. Simply click on Disable.
  10. Yes. You then need to change the code so that you are able to remove the right button. You may also want to change the code related to the product name and price. Check the tutorial on how to do/where to find that, if in doubt.

Back to top