1

I have the following Javascript executed in a webengine. Source: Execute a Javascript function for a WebView from a JavaFX program

This Javascript highlights a specific word on a website.

WebView webView = new WebView();
final WebEngine engine = webView.getEngine();
engine.load("https://stackoverflow.com/questions/14029964/execute-a-javascript-function-for-a-webview-from-a-javafx-program");

engine.getLoadWorker().stateProperty().addListener(new ChangeListener<State>() {
    @Override
    public void changed(ObservableValue ov, State oldState, State newState) {
        if (newState == State.SUCCEEDED) {
            engine.executeScript(
                "function highlightWord(root,word){"
                + "  textNodesUnder(root).forEach(highlightWords);"
                + ""
                + "  function textNodesUnder(root){"
                + "    var n,a=[],w=document.createTreeWalker(root,NodeFilter.SHOW_TEXT,null,false);"
                + "    while(n=w.nextNode()) a.push(n);"
                + "    return a;"
                + "  }"
                + ""
                + "  function highlightWords(n){"
                + "    for (var i; (i=n.nodeValue.indexOf(word,i)) > -1; n=after){"
                + "      var after = n.splitText(i+word.length);"
                + "      var highlighted = n.splitText(i);"
                + "      var span = document.createElement('span');"
                + "      span.style.backgroundColor='#f00';"
                + "      span.appendChild(highlighted);"
                + "      after.parentNode.insertBefore(span,after);"
                + "    }"
                + "  }"
                + "}"
                + "\n"
                + "highlightWord(document.body,'function');");
        }
    }
});

I want to check, whether a website contains a specific word and I thought this code is a good starting point, since it worked fine and highlights words. What I need now is, that the Javascript should count when highlighting. Then, if a word is contained (counter >= 1), I want to get a boolean return value, that I can access in JavaFX.

I tried some things but I really dont know how to midify the Script to add a counter and a return value that can be accessed outside the script.

Thank you all for reading.

Community
  • 1
  • 1
atljp
  • 21
  • 1
  • 4

1 Answers1

0

When using executeScript the evaluation result is returned based on the rules written in the javadoc of the method. Also the javadoc of WebEngine informs you about this possibility.

execution result, converted to a Java object using the following rules:

  • JavaScript Int32 is converted to java.lang.Integer
  • Other JavaScript numbers to java.lang.Double
  • JavaScript string to java.lang.String
  • JavaScript boolean to java.lang.Boolean
  • JavaScript null to null
  • Most JavaScript objects get wrapped as netscape.javascript.JSObject
  • JavaScript JSNode objects get mapped to instances of netscape.javascript.JSObject, that also implement org.w3c.dom.Node

  • A special case is the JavaScript class JavaRuntimeObject which is used to wrap a Java object as a JavaScript value - in this case we just extract the original Java value.

So, if the javascript script returns an Int32, you can get it like:

Integer executeScript = (Integer) engine.executeScript(...);

Your updated example (for example):

Integer numOfHighlights = (Integer) engine.executeScript(
    "function highlightWord(root,word){"
    + "  count = 0;"
    + "  textNodesUnder(root).forEach(highlightWords);"
    + ""
    + "  function textNodesUnder(root){"
    + "    var n,a=[],w=document.createTreeWalker(root,NodeFilter.SHOW_TEXT,null,false);"
    + "    while(n=w.nextNode()) a.push(n);"
    + "    return a;"
    + "  }"
    + ""
    + "  function highlightWords(n){"
    + "    for (var i; (i=n.nodeValue.indexOf(word,i)) > -1; n=after){"
    + "      var after = n.splitText(i+word.length);"
    + "      var highlighted = n.splitText(i);"
    + "      var span = document.createElement('span');"
    + "      span.style.backgroundColor='#f00';"
    + "      span.appendChild(highlighted);"
    + "      after.parentNode.insertBefore(span,after);"
    + "      count = count + 1;"
    + "    }"
    + "  }"
    + "  return count;"
    + "}"
    + "\n"
    + "highlightWord(document.body,'execute');");

System.out.println("Number of highlights are: " + numOfHighlights);

Outputs

Number of highlights are: 9

I have only added a counter variable that is incremented for every highlighted item and then finally this variables is returned.

DVarga
  • 21,311
  • 6
  • 55
  • 60