user556068 user556068 - 3 months ago 9
AppleScript Question

How to replace text on a webpage with javascript and applescript

This following javascript code comes from an answer to this question and works very well for replacing text on a webpage. Using the javascript console in both Safari and Chrome has yielded successful results.

function replaceTextOnPage(from, to){
getAllTextNodes().forEach(function(node){
node.nodeValue = node.nodeValue.replace(new RegExp(quote(from), 'g'), to);
});

function getAllTextNodes(){
var result = [];

(function scanSubTree(node){
if(node.childNodes.length)
for(var i = 0; i < node.childNodes.length; i++)
scanSubTree(node.childNodes[i]);
else if(node.nodeType == Node.TEXT_NODE)
result.push(node);
})(document);

return result;
}

function quote(str){
return (str+'').replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
}
}

replaceTextOnPage('oldtext', 'newtext');


However when I save this as replace_text.js and try to run it with Applescript, in both Safari and Chrome it returns missing value

tell application "Safari"
activate
tell the current tab of window 1 to do JavaScript "/Users/Me/ScriptFolder/replace_text.js"
end tell


I also tried running the javascript directly from a tell block in Script Editor, after escaping the quotes and escaping the escapes, instead of using a replace_text.js file but this also results in missing value.

When I copy and paste the javascript code directly into Script Editor and try running it using the javascript runner, I get Error -2700: Script error.


Error on line 15: ReferenceError: Can't find variable: document


If I define the document within the script as
document = "http://example.com"
I get the error:


Error on line 12: TypeError: undefined is not an object (evaluating 'node.childNodes.length')


Can someone tell me what am I doing wrong? How can I run this same javascript code with Applescript?

Thanks

Answer

The do JavaScript command need a string which contains a JavaScript code, not a file path.

So, you can use:

set myJS to read "/Users/Me/ScriptFolder/replace_text.js" as «class utf8» -- encoding of the file is "utf-8"
tell application "Safari"
    tell the current tab of window 1 to do JavaScript myJS
end tell

Or this:

set myJS to "function replaceTextOnPage(from, to){
    getAllTextNodes().forEach(function(node){
        node.nodeValue = node.nodeValue.replace(new RegExp(quote(from), 'g'), to);
    });
    return 'replaceTextOnPage(), Done' // just for testing, to avoid the missing value from the do JavaScript command
    function getAllTextNodes(){
        var result = [];
        (function scanSubTree(node){
            if(node.childNodes.length) 
                for(var i = 0; i < node.childNodes.length; i++) 
                    scanSubTree(node.childNodes[i]);
            else if(node.nodeType == Node.TEXT_NODE) 
                result.push(node);
        })(document);
        return result;
    }
    function quote(str){
        return (str+'').replace(/([.?*+^$[\\]\\(){}|-])/g, \"\\$1\");
    }
}
replaceTextOnPage('oldtext', 'newtext');"

tell application "Safari"
    activate
    tell the current tab of window 1 to do JavaScript myJS
end tell

The do JavaScript command return missing value when a function return nothing (the replaceTextOnPage function return nothing), it's the normal behaviour.

Comments