Tutorials: Difference between revisions

From GreaseSpot Wiki
Jump to navigationJump to search
No edit summary
mNo edit summary
 
(4 intermediate revisions by 3 users not shown)
Line 1: Line 1:
== Basic Description ==
Most of the information on this site is helpful. See the [[Greasemonkey Manual]] for starters.


Each script has a [[Metadata Block]] that describes a few characteristics of a GreaseMonkey script. It usually contains the name of the script (@name), the description (@description) and for what URLs it should be activated (@include). An example of this would be:
== Greasemonkey tutorials ==


<pre>// ==UserScript==
Warning: these are both several years old.
// @name          Absterge
// @namespace      http://userscripts.org/users/astojanov
// @include        http://*.facebook.com/*
// @include        https://*.facebook.com/*
// @require        http://code.jquery.com/jquery-1.7.1.min.js
// ==/UserScript==</pre>


* [http://commons.oreilly.com/wiki/index.php/Greasemonkey_Hacks Greasemonkey hacks] (as a wiki)<br />
* [http://codebazaar.blogspot.com/2010/11/monkey-see-greasemonkey-do.html Monkey see, GreaseMonkey do!] - Video tutorial for GreaseMonkey userscript development


== JavaScript tutorials ==


After the [[Metadata Block]] the Javascript code follows which will be executed within the pages specified by the @include keys.
* [https://developer.mozilla.org/en/JavaScript/Guide Mozilla's JavaScript Guide]
* [http://www.tizag.com/javascriptT/ tizag's JavaScript Tutorial]
* [http://www.quirksmode.org/js/contents.html JavaScript on QuirksMode]
* The JavaScript Programming Language ([http://video.yahoo.com/watch/111593/1710507 part 1], [http://video.yahoo.com/watch/111594/1710553 2], [http://video.yahoo.com/watch/111595/1710607 3], [http://video.yahoo.com/watch/111596/1710658 4]) by Douglas Crockford<br />A set of videos of a wonderful lecture by this JavaScript guru.<br />You can check Crockford's JavaScript dedicated website at http://javascript.crockford.com/
* [http://blog.morrisjohns.com/javascript_closures_for_dummies.html JavaScript Closures for Dummies]
* [http://www.jibbering.com/faq/faq_notes/closures.html JavaScript Closures]


== JavaScript references ==
Once familiar with the language, one may notice there are many available features in JavaScript which are initially hard to remember.
* [https://developer.mozilla.org/ MDC, an extensive wiki from Mozilla which details JavaScript and Firefox-unique features alike]
* [https://developer.mozilla.org/en/Gecko_DOM_Reference Gecko DOM Reference]
* [http://www.w3schools.com/jsref/ w3schools JS reference]


== Example Script ==
== JavaScript Books ==
 
* [http://www.oreilly.com/catalog/jscript5/ JavaScript: The Definitive Guide] is well regarded
There's an example script that does something on Facebook.
* For a modern introduction to JavaScript, check out John Resig's [http://www.amazon.com/Pro-JavaScript-Techniques-John-Resig/dp/1590597273 Pro JavaScript Techniques]
 
 
<pre>// ==UserScript==
// @name          Absterge
// @namespace      http://userscripts.org/users/astojanov
// @include        http://*.facebook.com/*
// @include        https://*.facebook.com/*
// @require        http://code.jquery.com/jquery-1.7.1.min.js
// ==/UserScript==
 
function parseUri (str) {
    var o  = parseUri.options,
    m  = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
    uri = {},
    i  = 14;
 
    while (i--) uri[o.key[i]] = m[i] || "";
 
    uri[o.q.name] = {};
    uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
        if ($1) uri[o.q.name][$1] = $2;
    });
 
    return uri;
};
 
parseUri.options = {
    strictMode: false,
    key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],
    q:  {
        name:  "queryKey",
        parser: /(?:^|&)([^&=]*)=?([^&]*)/g
    },
    parser: {
        strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
        loose:  /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
    }
};
window.addEventListener('load', function()  {
 
    var fb_dtsg = null;
   
    // Get the value of fb_dtsg
    var getConstantParameters = function () {
        if ( fb_dtsg !== null ) {
            return true;
        } else {
           
            if ( fb_dtsg === null ) {
                $('input[name="fb_dtsg"]').each(function(){
                    fb_dtsg = $(this).attr("value");
                });
            }
            return (fb_dtsg !== null);
        }
    }
 
    var generatePhstamp = function(qs, dtsg) {
        var input_len = qs.length;
        numeric_csrf_value='';
 
        for(var ii=0;ii<dtsg.length;ii++) {
            numeric_csrf_value+=dtsg.charCodeAt(ii);
        }
        return '1' + numeric_csrf_value + input_len;
    };
 
 
    var deleteMinistories = function (actions) {
 
        getConstantParameters();
   
        $('li[class="pvs uiStreamMinistoryGroup timelineMinistoryGroup uiListItem uiListMedium uiListVerticalItemBorder"]').each( function() {
                       
            // Make sure whether this ministory is supposed to be skipped or not
            if ( $(this).attr('absterge') !== undefined && $(this).attr('absterge') === 'dismiss' ) {
                return;
            } else {
                if ( $(this).attr('absterge') === undefined || $(this).attr('absterge') === null ) {
                    $(this).attr('absterge', 'dismiss');
                }
            }
            var ministory = $(this);
 
           
            // In the first pass, just try to unroll the action
            if ( ministory.attr('absterge') !== 'considered' ) {
                ministory.find('a[ajaxify]').each(function () {               
                    var ajaxify = parseUri("http://facebook.com" + $(this).attr("ajaxify"));
                    if ( ajaxify.file === "show_story_options.php") {
                        var evt = document.createEvent("MouseEvents");
                        evt.initMouseEvent("mouseover", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
                        $(this).context.dispatchEvent(evt);
                        ministory.attr('absterge', 'considered');
                    }
                });
            }
           
            // Now try to remove the actual action
            if ( ministory.attr('absterge') === 'considered' ) {
                ministory.find('a[ajaxify]').each(function () {
                   
                    var ajaxify = parseUri("http://facebook.com" + $(this).attr("ajaxify"));
                    if ( ajaxify.file === "take_action_on_story.php" ) {
                               
                        if ( actions.indexOf (ajaxify.queryKey["action"]) === -1 ) {
                            ministory.attr('absterge', 'dismiss');
                        } else {
                       
                            var remove = true;
                            var keys = ['profile_id', 'story_fbid', 'story_row_time', 'story_dom_id'];
                            for ( var i = 0; i < keys.length; ++i ) {
                                if ( ajaxify.queryKey[keys[i]] === undefined ) {
                                    remove = false;
                                }
                            }
                           
                            if ( remove ) {
                               
                                var pagelet_all_activity = ministory.parent().attr('id').replace("timeline_all_activity_stream", "pagelet_all_activity");
                             
                                var data = {
                                    'nctr[_mod]'   : pagelet_all_activity,
                                    // 'post_form_id'   : post_form_id,
                                    'fb_dtsg'   : fb_dtsg,
                                    // 'lsd'   : "",
                                    // 'post_form_id_source'        : "AsyncRequest",
                                    'confirmed'   : "true",
                                    'ban_user'   : "0"
                                };
                                for ( var key in ajaxify.queryKey ) {
                                    data[key] = ajaxify.queryKey[key];
                                }
                                data['phstamp'] = generatePhstamp($.param(data), fb_dtsg);
                               
                                $.ajax({
                                    type    : "POST",
                                    url    : "https://www.facebook.com/ajax/timeline/take_action_on_story.php?__a=1",
                                    data    : data,
                                    complete: function(jqXHR, textStatus) {
                                        if ( jqXHR.status === 200 ) {
                                            if ( $('#cmdAbsterge').attr('deletecount') === undefined || $('#cmdAbsterge').attr('deletecount') === null ) {
                                                $('#cmdAbsterge').attr('deletecount', '0');
                                            }
                                            var deleteCount = parseInt($('#cmdAbsterge').attr('deletecount')) + 1;
                                            $('#cmdAbsterge').html("Absterge (" + deleteCount + ")");
                                            $('#cmdAbsterge').attr('deletecount', '' + deleteCount);
                                            ministory.remove();
                                        }
                                       
                                        console.log("Deleting:", jqXHR);
                                    }
                                });
                             
                               
                            } else {
                                ministory.attr('absterge', 'dismiss');
                            }
                        }
                           
                    }
                     
                });
                 
                 
            }
        });
       
        $("html, body").animate({ scrollTop: $(document).height() }, "slow");
        setTimeout(function(){
            deleteMinistories(actions);
        }, 1000);
 
        // setTimeout(deleteMinistories, 500, [actions]);
    };
    var deleteLikes = function () {
        $('#menuAbsterge').css('display', 'none');
        var likes = new Array();
        likes.push("unlike");
        deleteMinistories (likes);
    };
   
    var deleteComments = function () {
        $('#menuAbsterge').css('display', 'none');
        var comments = new Array();
        comments.push("remove_comment");
        deleteMinistories (comments);
    };
    var deleteContent = function () {
        $('#menuAbsterge').css('display', 'none');
        var content = new Array();
        content.push("remove_content");
        deleteMinistories (content);
    };
   
    var deleteAll = function () {
        $('#menuAbsterge').css('display', 'none');
        var all = new Array();
        all.push("unlike");
        all.push("remove_comment");
        all.push("remove_content");
        deleteMinistories (all);
    };
 
    // Include the
    $('<li id="navAbsterge" class="topNavLink middleLink"><a id="cmdAbsterge" href="#">Absterge</a></li>').insertAfter('#navHome');
       
    var pathname = window.location.pathname;   
    if ( pathname.indexOf('/allactivity') === -1 ) {
        $('#cmdAbsterge').click(function () {
            alert('You must navigate to "Activity Log" using the "Timeline" feature in order to use Absterge');         
        });
    } else {
        $('#cmdAbsterge').css("color", "red");
        $('<ul id="menuAbsterge" aria-label="Absterge" role="navigation" id="abstergeNavigation" class="navigation">' +
            '<li><a id="abstergeDeleteLikes" href="#" class="navSubmenu">Delete Likes</a></li>' +
            '<li><a id="abstergeDeleteComments" href="#" class="navSubmenu">Delete Comments</a></li>' +
            '<li><a id="abstergeDeleteContent" href="#" class="navSubmenu">Delete Content</a></li>' +
            '<li><a id="abstergeDeleteAll" href="#" class="navSubmenu">Delete All</a></li>' +
            '</ul>').appendTo('#navAccount');
        $('#menuAbsterge').css('z-index', '-1');
       
        $('#abstergeDeleteLikes').click(function (){ deleteLikes(); });
        $('#abstergeDeleteComments').click(function (){ deleteComments();});
        $('#abstergeDeleteContent').click(function (){ deleteContent(); });
        $('#abstergeDeleteAll').click(function (){ deleteAll(); });
               
        $('#cmdAbsterge').click(function () {
            if ( $('#menuAbsterge').css('display') === 'block' ) {
                $('#menuAbsterge').css('display', 'none');
            } else {
                $('#menuAbsterge').css('display', 'block');
            }                   
        });
    }
});
</pre>

Latest revision as of 16:12, 3 November 2017

Most of the information on this site is helpful. See the Greasemonkey Manual for starters.

Greasemonkey tutorials

Warning: these are both several years old.

JavaScript tutorials

JavaScript references

Once familiar with the language, one may notice there are many available features in JavaScript which are initially hard to remember.

JavaScript Books