Search code examples
javascriptcssgreasemonkeytampermonkey

Add text value of a node as css-class to a parent element, using Tampermonkey


The target page HTML looks like:

<div class="conversation"> 
    <div class="subject"> 
        <div class="labels"> 
            <div title="Tag1" class="labelsElement-label"> 
                <span class="labelsElement-name">Tag1</span> 
            </div>
            <div title="Tag2" class="labelsElement-label"> 
                <span class="labelsElement-name">Tag2</span> 
            </div>
        </div> 
    </div> 
</div>

When ever a span.labelsElement-name is somewhere I'd like to add its contents to the parent div.conversion as a class. Like:

change:

<div class="conversation">

in the first row to:

<div class="conversation Tag1 Tag2">

because these two values are in the two nested span.labelsElement-name

How can I do this?


Solution

  • As Lucumt said, jQuery is great for this kind as it makes manipulating pages (the DOM) a snap.

    Using jQuery in a userscript has been covered in numerous posts. See this answer for the most robust way. (Use @require and @grant.)

    A complete script that adds CSS classes based on that tag text is (Just the first gray block):

    // ==UserScript==
    // @name     _Add CSS classes based on select node contents.
    // @match    *://YOUR_SERVER.COM/YOUR_PATH/*
    // @require  https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js
    // @require  https://gist.github.com/raw/2625891/waitForKeyElements.js
    // @grant    GM_addStyle
    // @grant    GM.getValue
    // ==/UserScript==
    //- The @grant directives are needed to restore the proper sandbox.
    
    waitForKeyElements (".labelsElement-name", taggifyParentNode);
    
    function taggifyParentNode (jNode) {
        var tagName = jNode.text ().trim ();
        jNode.closest (".conversation").addClass (tagName);
    }
    /*--------------------------------------*/
    /*--- Simulated target page follows: ---*/
    /*--------------------------------------*/
    .Tag1 {background-color: rgba(0,255,0,0.5); }
    .Tag2 {background-color: rgba(255,0,0,0.5); }
    .Tag1.Tag2 {background-color: rgba(255,255,0,0.5); }
    .conversation, .labels > div {
        margin: 1ex 1em;
        border: 1px solid lightgray;
        border-radius: 0.5ex;
    }
    .labels > div {padding: 1ex 1em;  display: inline-block;}
    <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
    <script src="//greasyfork.org/scripts/2199-waitforkeyelements/code/waitForKeyElements.js"></script>
    <div class="conversation"> <div class="subject">
        <div class="labels">
            <div title="Tag1"><span class="labelsElement-name">Tag1</span></div>
        </div>
    </div></div>
    <div class="conversation"> <div class="subject">
        <div class="labels">
            <div title="Tag2"><span class="labelsElement-name">Tag2</span></div>
        </div>
    </div></div>
    <div class="conversation"> <div class="subject">
        <div class="labels">
            <div title="Tag1"><span class="labelsElement-name">Tag1</span></div>
            <div title="Tag2"><span class="labelsElement-name">Tag2</span></div>
        </div>
    </div></div>

    Run the code snippet to see it in action.

    waitForKeyElements() is used in case the target page is dynamic (AJAX-driven), which seems likely.