5

I have a script that translates a Russian forum word by word using TreeWalker, but there are one kind of div element that I couldn't change its text and that's my question, how do I change that? As the forum requires registration I'm going to try to provide every detail of code I can below.


the webpage specific code where I'm trying to change the text:

<div class="sp-wrap">
    <div class="sp-head folded clickable">Скриншоты</div> //once clicked unhide the div below to show images and by clicking it again hides.
    <div class="sp-body inited" title="" style="display: none;"> //hidden div
        <div class="clear"></div>
        <h3 class="sp-title">Скриншofы</h3>
        <span class="post-align" style="text-align: center;">
        <div class="clear"></div>
        <div class="sp-fold clickable">[свернуть]</div>
    </div>
</div>
  • I'm trying to change Скриншоты for Images from the class sp-head, which is the one I click to show the images.

the CSS code for that class:

.sp-head {
    border-width: 0;
    color: #2a2a2a;
    cursor: pointer;
    font-size: 11px;
    font-weight: bold;
    line-height: 15px;
    margin-left: 6px;
    padding: 1px 14px 3px;
}

my code below:

//... header
// @require     https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js
// @grant       GM_addStyle
// ==/UserScript==

$('div.sp-wrap > div:first').each( function (){ //div:contains("Скрин") div.sp-head.folded.clickable

    var jThis = $(this);
    var jText = jThis.textContent;
    var jhtml = jThis.html();

    console.log(jText);
    console.log(jThis);
    //console.log(jhtml);

    jText = jText.replace(/Скрин(лист|шоты)/ig, "Images");

});

var textWalker   = document.createTreeWalker (
    document.body,
    NodeFilter.SHOW_TEXT,
    {   acceptNode: function (node) {
        // Skip whitespace-only nodes
        if (node.nodeValue.trim() )
            return NodeFilter.FILTER_ACCEPT;

        return NodeFilter.FILTER_SKIP;
    }
    },
    false
);

var textNode;

while (textNode  = textWalker.nextNode() ) {
    var oldText  = textNode.nodeValue;
    var newText  = oldText.replace (/Главная/ig, "Home");
    newText      = newText.replace (/Скрин(лист|шоты)/ig, "Images");
    newText      = newText.replace (/Последние поблагодарившие/ig, "Last Who Thank");
    //...
    //repeats word by word until ends at the line below     
    textNode.nodeValue = newText;
}

What I've tried

I've already tried a bunch of jQuery filters that could get that div child, but it is as it was not there.

When I select the div itself using:

$('div.sp-head.folded.clickable')

The console result is blank.

When I run the code I've posted here (under my code below header) the result is

console log

for jText and jThis vars respectively

And finally when I try

$('div.sp-wrap div:contains("Скрин")').each( function (){ 

    var jThis = $(this);
    var jText = jThis.text();
    jThis.text("Images");

});

I get the word Images replacing the real Images

wrong result

Also fails when I tried to use

$('div.sp-wrap div:contains("Скрин")').each( function (){ 

    var jThis = $(this);
    var jText = jThis.text();
    jThis.parent().text("Images");

});

Resulting in a destroyed wrap

wrong result again


As it is a text like the other ones replaced, I could not figure it out why TreeWalker does not "see" that kind of div text.


  • Added for clarify comments

image about the suggestion made in comments

All span tags looks closed, even the one wrapped on the image is closed.

Community
  • 1
  • 1
Commentator
  • 640
  • 1
  • 6
  • 22
  • 1
    Seems that there is a started a `` that wasn't closed. I'm wondering if that could cause problems. – Spencer Wieczorek Jul 09 '16 at 07:27
  • @SpencerWieczorek There are 2 span right above it, but they are closed. I've added a image of that. – Commentator Jul 09 '16 at 17:42
  • source html doesn't always equal rendered html, especially if there are invalid closing tags and the browser tries to be forgiving - can you supply a JSFiddle – Steve Jul 09 '16 at 18:29
  • I saved source code and look into an IDE searching for errors on tags without close, all span tags on the are closed. – Commentator Jul 09 '16 at 19:17

3 Answers3

1

Yesterday I figured out the solution and couldn't post here before. The wrap content is AJAXed, for that reason the element to be selected is not ready when the script runs. In order to handle that, I've used WaitForKeyElements(). I was able to detect the issue after analyzing the "last who thanked" list and could not believe I haven't seen it before.

Solution:

//...header
// @require     https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js
// @require     https://gist.github.com/raw/2625891/waitForKeyElements.js
// @grant       GM_addStyle
// ==/UserScript==


waitForKeyElements ("div.sp-head.folded.clickable", translateDiv);


function translateDiv (jNode) {

    var jText  = jNode.text();
    var reg    = /Скрин(лист|шоты)/ig;

    if (reg.test (jText) ) {

        jNode.text( jText.replace(/Скрин(лист|шоты)/ig, "Images") );

    } else if (jText.indexOf("Последние поблагодарившие") != -1) {

        jNode.text("Last Who Thanks");

    }

}
Community
  • 1
  • 1
Commentator
  • 640
  • 1
  • 6
  • 22
0

It appears you can find the text inside the body, but not the collapsible title

What ever JavaScript is invoked to make the panel collapsible would be changing the markup so you would need to inspect the new markup in the F12 tools after the collapsible has been initialized. I cannot determine what framework you are using but JQuery.UI tends to change the DOM a ton.

Suggest you add a JSFiddle or Plunker.

Steve
  • 1,995
  • 2
  • 16
  • 25
  • I didn't get it. Do you want I paste the code that is here on JSFiddle to see if it works there? – Commentator Jul 09 '16 at 19:34
  • If you put the code is JSFiddle then you can share that link and people on stackoverflow can play with your code to help you more – Steve Jul 09 '16 at 20:12
0

From what I understand so far, you are trying to replace the div tags with Russian text content such as 'Скриншоты' into the English 'Images' value, and you are trying to do it using jQuery and TreeWalker traversals, so here is the code that works for each one respectively:

Replace Text Content Using jQuery:

$('div.sp-wrap > div:first').each( function (){ 

    var jThis = $(this);
    var jText = jThis.text();
    var jhtml = jThis.html();

    console.log(jText);
    console.log(jThis);   

    jText = jText.replace(/Скрин(лист|шоты)/ig, "Images");
   $(jThis).text(jText);

});

Replace Text Content Using TreeWalker

var textWalker   = document.createTreeWalker (
    document.body,
    NodeFilter.SHOW_TEXT,
    {   acceptNode: function (node) {
        // Skip whitespace-only nodes
        if (node.nodeValue.trim() )
            return NodeFilter.FILTER_ACCEPT;

        return NodeFilter.FILTER_SKIP;
    }
    },
    false
);



while (textWalker.nextNode() ) {
    var textNode = textWalker.currentNode;    
    var oldText  = textNode.nodeValue;
    var newText  = oldText.replace (/Главная/ig, "Home");
    newText      = newText.replace (/Скрин(лист|шоты)/ig, "Images");
    newText      = newText.replace (/Последние поблагодарившие/ig, "Last Who Thank");
    //...
    //repeats word by word until ends at the line below     
    textNode.nodeValue = newText;
}

I don't see the benefit of using both methods to replace text as either one of them works.

Shadi Shaaban
  • 1,670
  • 1
  • 10
  • 17
  • It should work, but it does not. I had no intention to use jQuery I used because treewalker failed to do it. As treewalker does not find the text to be replaced, jQuery does not return the first div element I want to select also. – Commentator Jul 09 '16 at 19:27
  • The result of the code you posted it http://puu.sh/pW0j1/76c7437113.png – Commentator Jul 09 '16 at 19:30
  • Actually, here is a demo of the result of the jQuery version: http://jsbin.com/tavizujugi/edit?html,js,output and here is another one using TreeWalker: http://jsbin.com/nepejowiji/1/edit?html,js,output and in both versions I see the text gets replaced, if so, you may want to double check if these codes are being executed at all. – Shadi Shaaban Jul 09 '16 at 19:49