Changeset 748 for trunk/src/org/expeditee/io
- Timestamp:
- 01/24/14 11:32:31 (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/expeditee/io/WebParser.java
r734 r748 13 13 import java.util.Arrays; 14 14 15 /* 16 * JavaFX is not on the default java classpath until Java 8 (but is still included with Java 7), so your IDE will probably complain that the imports below can't be resolved. 17 * In Eclipse hitting'Proceed' when told 'Errors exist in project' should allow you to run Expeditee without any issues (although the JFX Browser widget will not display), 18 * or you can just exclude JfxBrowser, WebParser and JfxbrowserActions from the build path. 19 * 20 * If you are using Ant to build/run, 'ant build' will try to build with JavaFX jar added to the classpath. 21 * If this fails, 'ant build-nojfx' will build with the JfxBrowser, WebParser and JfxbrowserActions excluded from the build path. 22 */ 23 24 import javafx.animation.AnimationTimer; 25 import javafx.application.Platform; 26 import javafx.beans.value.ChangeListener; 27 import javafx.beans.value.ObservableValue; 28 import javafx.concurrent.Worker.State; 29 import javafx.scene.web.WebEngine; 30 15 31 import javax.imageio.ImageIO; 16 32 import javax.swing.JComponent; 33 34 import netscape.javascript.JSObject; 17 35 18 36 import org.expeditee.gui.Frame; … … 26 44 import org.expeditee.items.Picture; 27 45 import org.expeditee.items.Text; 28 import org.expeditee.reflection.JavaFX;29 46 import org.w3c.dom.Node; 30 47 import org.w3c.dom.html.HTMLBodyElement; … … 49 66 public static void parseURL(final String URL, final Frame frame) { 50 67 try { 51 JavaFX.PlatformRunLater.invoke(null,new Runnable() {68 Platform.runLater(new Runnable() { 52 69 @Override 53 70 public void run() { 54 71 try { 55 Object webEngine = JavaFX.WebEngineConstructor.newInstance(URL);72 WebEngine webEngine = new WebEngine(URL); 56 73 loadPage(webEngine, frame); 57 74 } catch (Exception e) { … … 65 82 } 66 83 67 protected static void loadPage(final Object webEngine, final Frame frame) throws Exception { 68 JavaFX.ReadOnlyObjectPropertyAddListener.invoke(JavaFX.WorkerStateProperty.invoke(JavaFX.WebEngineGetLoadWorker 69 .invoke(webEngine)), java.lang.reflect.Proxy.newProxyInstance( 70 JavaFX.ChangeListener.getClassLoader(), new java.lang.Class[] { JavaFX.ChangeListener }, 71 new java.lang.reflect.InvocationHandler() { 72 @Override 73 public Object invoke(Object proxy, java.lang.reflect.Method method, Object[] args) 74 throws java.lang.Throwable { 75 String method_name = method.getName(); 76 // Class<?>[] classes = method.getParameterTypes(); 77 // public void changed(ObservableValue ov, State oldState, State newState) 78 if (method_name.equals("changed")) { 79 // changed takes 3 args 80 if (args == null || args.length != 3) { 81 return null; 82 } 83 // args[0] is the ObservableValue 84 // args[2] is the new State 85 if (args[2].getClass() == JavaFX.State) { 86 int id = JavaFX.StateConstants.indexOf(args[2]); 87 switch (id) { 88 case 0: // READY 89 // MessageBay.displayMessage("WebEngine ready"); 90 break; 91 case 1: // SCHEDULED 92 // MessageBay.displayMessage("Scheduled page load"); 93 break; 94 case 2: // RUNNING 95 System.out.println("Loading page!"); 96 // MessageBay.displayMessage("WebEngine running"); 97 break; 98 case 3: // SUCCEEDED 99 // MessageBay.displayMessage("Finished loading page"); 100 System.out.println("Parsing page!"); 101 JavaFX.WebEngineExecuteScript.invoke(webEngine, "window.resizeTo(800, 800);" 102 + "document.body.style.width = '1000px'"); 103 parsePage(webEngine, frame); 104 System.out.println("Parsed page!"); 105 break; 106 case 4: // CANCELLED 107 MessageBay.displayMessage("Cancelled loading page"); 108 break; 109 case 5: // FAILED 110 MessageBay.displayMessage("Failed to load page"); 111 break; 112 } 113 } 114 System.out.println("\n"); 115 } 116 return null; 117 } 118 })); 84 protected static void loadPage(final WebEngine webEngine, final Frame frame) throws Exception { 85 webEngine.getLoadWorker().stateProperty().addListener(new ChangeListener<State>() { 86 87 @Override 88 public void changed(ObservableValue<? extends State> ov, State oldState, State newState) { 89 90 switch (newState) { 91 case READY: // READY 92 // MessageBay.displayMessage("WebEngine ready"); 93 break; 94 case SCHEDULED: // SCHEDULED 95 // MessageBay.displayMessage("Scheduled page load"); 96 break; 97 case RUNNING: // RUNNING 98 System.out.println("Loading page!"); 99 // MessageBay.displayMessage("WebEngine running"); 100 break; 101 case SUCCEEDED: // SUCCEEDED 102 // MessageBay.displayMessage("Finished loading page"); 103 System.out.println("Parsing page!"); 104 webEngine.executeScript("window.resizeTo(800, 800);" 105 + "document.body.style.width = '1000px'"); 106 parsePage(webEngine, frame); 107 System.out.println("Parsed page!"); 108 break; 109 case CANCELLED: // CANCELLED 110 MessageBay.displayMessage("Cancelled loading page"); 111 break; 112 case FAILED: // FAILED 113 MessageBay.displayMessage("Failed to load page"); 114 break; 115 } 116 } 117 }); 119 118 } 120 119 … … 127 126 * The Expeditee frame to output the converted page to 128 127 */ 129 public static void parsePage(final ObjectwebEngine, final Frame frame) {128 public static void parsePage(final WebEngine webEngine, final Frame frame) { 130 129 try { 131 JavaFX.PlatformRunLater.invoke(null,new Runnable() {130 Platform.runLater(new Runnable() { 132 131 @Override 133 132 public void run() { … … 135 134 Progress progressBar = MessageBay.displayProgress("Converting web page"); 136 135 137 HTMLBodyElement doc = (HTMLBodyElement) JavaFX.WebEngineExecuteScript.invoke(webEngine,"document.body");138 139 Object window = JavaFX.WebEngineExecuteScript.invoke(webEngine,"window");140 141 frame.setBackgroundColor(rgbStringToColor((String) JavaFX.JSObjectCall.invoke(JavaFX.JSObjectCall.invoke(window, "getComputedStyle", new Object[] { doc }),"getPropertyValue",136 Node doc = (Node) webEngine.executeScript("document.body"); 137 138 JSObject window = (JSObject) webEngine.executeScript("window"); 139 140 frame.setBackgroundColor(rgbStringToColor((String) ((JSObject) (window.call("getComputedStyle", new Object[] { doc }))).call("getPropertyValue", 142 141 new Object[] { "background-color" }))); 143 142 144 143 // Functions to be used later in JavaScript 145 JavaFX.WebEngineExecuteScript.invoke(webEngine, "" 144 webEngine.executeScript("" 145 + "function addToSpan(text) {" 146 + " span = document.createElement('wordSpan');" 147 + " span.textContent = text;" 148 + " par.insertBefore(span, refNode);" 149 // Checking if the current word is on a new line (i.e. lower than the previous word) 150 + " if (prevSpan !== null && span.getBoundingClientRect().top > prevSpan.getBoundingClientRect().top) {" 151 // If it is, prepend a new line character to it. The new line characters doesn't affect the rendered HTML 152 + " span.textContent = '\\n' + span.textContent;" 153 154 // Checking if the previous word is horizontally aligned with the one before it. 155 // If it is, merge the text of the two spans 156 + " if ( prevPrevSpan !== null && prevPrevSpan.getBoundingClientRect().left == prevSpan.getBoundingClientRect().left) {" 157 + " prevPrevSpan.textContent = prevPrevSpan.textContent + prevSpan.textContent;" 158 + " par.removeChild(prevSpan);" 159 + " } else {" 160 + " prevPrevSpan = prevSpan;" 161 + " }" 162 + " prevSpan = span;" 163 + " } else if ( prevSpan !== null) {" 164 // Word is on the same line as the previous one, so merge the second into the span of the first 165 + " prevSpan.textContent = prevSpan.textContent + span.textContent;" 166 + " par.removeChild(span);" 167 + " } else {" 168 + " prevSpan = span;" 169 + " }" 170 + "}" 171 172 + "function splitIntoWords(toSplit) {" 173 + " var words = [];" 174 + " var pattern = /\\s+/g;" 175 + " var words = toSplit.split(pattern);" 176 + "" 177 + " for (var i = 0; i < words.length - 1; i++) {" 178 + " words[i] = words[i] + ' ';" 179 + " }" 180 + " return words;" 181 + "}" 182 ); 183 184 // Using Javascript to get an array of all the text nodes in the document so they can be wrapped in spans. Have to 185 // loop through twice (once to build the array and once actually going through the array, otherwise when the 186 // textnode is removed from the document items end up being skipped) 187 JSObject textNodes = (JSObject) webEngine.executeScript("" 188 + "function getTextNodes(rootNode){" 189 + "var node;" 190 + "var textNodes=[];" 191 + "var walk = document.createTreeWalker(rootNode, NodeFilter.SHOW_TEXT);" 192 + "while(node=walk.nextNode()) {" 193 + "if((node.textContent.trim().length > 0)) { " 194 + "textNodes.push(node);" 195 + "}" 196 + "}" 197 + "return textNodes;" 198 + "}; " 199 + "getTextNodes(document.body)" 200 ); 201 202 int nodesLength = (Integer) textNodes.getMember("length"); 203 204 // Looping through all the text nodes in the document 205 for (int j = 0; j < nodesLength; j++) { 206 Node currentNode = (Node) textNodes.getSlot(j); 207 208 // Making the current node accessible in JavaScript 209 window.setMember("currentNode", currentNode); 210 211 webEngine.executeScript("" 212 + "var span = null, prevSpan = null, prevPrevSpan = null;" 213 214 // Removing repeated whitespace from the text node's content then splitting it into individual words 215 + "var textContent = currentNode.textContent.replace(/\\n|\\r/g, '').replace(/\\s+/g, ' ');" 216 + "var words = splitIntoWords(textContent);" 217 218 + "var refNode = currentNode.nextSibling;" 219 + "var par = currentNode.parentElement;" 220 + "currentNode.parentElement.removeChild(currentNode);" 221 222 + "for (var i = 0; i < words.length; i++) {" 223 + " addToSpan(words[i]);" 224 + "}" 225 226 + "if (prevPrevSpan !== null && prevPrevSpan.getBoundingClientRect().left == prevSpan.getBoundingClientRect().left) {" 227 + " prevPrevSpan.textContent = prevPrevSpan.textContent + prevSpan.textContent;" 228 + " par.removeChild(prevSpan);" 229 + "}" 230 ); 231 232 // Will never reach 100% here, as the processing is not quite finished - progress is set to 100% at the end of 233 // the addPageToFrame loop below 234 progressBar.set((100 * (j)) / nodesLength); 235 } 236 237 // Finding all links within the page, then setting the href attribute of all their descendants to be the same 238 // link/URL. 239 // This is needed because there is no apparent and efficient way to check if an element is a child of a link when 240 // running through the document when added each element to Expeditee 241 webEngine.executeScript("" 242 + "var anchors = document.getElementsByTagName('a');" 243 + "" 244 + "for (var i = 0; i < anchors.length; i++) {" 245 + "var currentAnchor = anchors.item(i);" 246 + "var anchorDescendants = currentAnchor.querySelectorAll('*');" 247 + "for (var j = 0; j < anchorDescendants.length; j++) {" 248 + "anchorDescendants.item(j).href = currentAnchor.href;" 249 + "}" 250 + "}" 251 ); 252 253 WebParser.addPageToFrame(doc, window, webEngine, frame); 254 255 progressBar.set(100); 256 257 } catch (Exception e) { 258 e.printStackTrace(); 259 } 260 System.out.println("Parsed frame"); 261 FrameUtils.Parse(frame); 262 frame.setChanged(true); 263 FrameIO.SaveFrame(frame); 264 } 265 }); 266 } catch (Exception e) { 267 e.printStackTrace(); 268 } 269 } 270 271 /** 272 * Converts a loaded page to Expeditee frame(s) 273 * 274 * @param webEngine 275 * The JavaFX WebEngine in which the page to be converted is loaded 276 * @param frame 277 * The Expeditee frame to output the converted page to 278 */ 279 public static void parsePageSimple(final WebEngine webEngine, final Object webView, final JComponent jfxPanel, final Frame frame) { 280 try { 281 final Object notifier = new Object(); 282 final MutableBool bottomReached = new MutableBool(false); 283 284 final Progress progressBar = MessageBay.displayProgress("Converting web page"); 285 286 AnimationTimer timer = new AnimationTimer() { 287 288 int frameCount = 0; 289 Frame frameToAddTo = frame; 290 291 @Override 292 public void handle(long arg0) { 293 // Must wait 2 frames before taking a snapshot of the webview, otherwise JavaFX won't have redrawn 294 if (frameCount++ > 1) { 295 frameCount = 0; 296 this.stop(); 297 298 BufferedImage image = new BufferedImage(jfxPanel.getWidth(), jfxPanel.getHeight(), BufferedImage.TYPE_INT_ARGB); 299 300 Graphics graphics = image.createGraphics(); 301 302 // Drawing the JfxPanel (containing the webview) to the image 303 jfxPanel.paint(graphics); 304 305 try { 306 int hashcode = Arrays.hashCode(image.getData().getPixels(0, 0, image.getWidth(), image.getHeight(), (int[]) null)); 307 308 File out = new File(FrameIO.IMAGES_PATH + "webpage-" + Integer.toHexString(hashcode) + ".png"); 309 out.mkdirs(); 310 ImageIO.write(image, "png", out); 311 312 Text link = new Text("Next"); 313 link.setPosition(500, 20); 314 frameToAddTo.addItem(link); 315 316 FrameIO.SaveFrame(frameToAddTo); 317 318 frameToAddTo = FrameIO.CreateFrame(frame.getFramesetName(), Integer.toHexString(hashcode), null); 319 320 link.setLink(frameToAddTo.getName()); 321 322 // Adding the image 323 frameToAddTo.addText(0, 0, "@i: " + out.getName(), null); 324 325 // Button to go to the next page 326 Text nextButton = (Text) FrameCreator.createButton("Next", null, null, 10F, 10F); 327 nextButton.setID(frameToAddTo.getNextItemID()); 328 nextButton.addAction("next"); 329 frameToAddTo.addItem(nextButton); 330 331 FrameIO.SaveFrame(frameToAddTo); 332 System.out.println("C"); 333 334 } catch (IOException e) { 335 e.printStackTrace(); 336 } 337 338 339 graphics.dispose(); 340 image.flush(); 341 342 synchronized (notifier) { 343 notifier.notify(); 344 } 345 346 try { 347 Platform.runLater(new Runnable() { 348 @Override 349 public void run() { 350 try { 351 HTMLBodyElement doc = (HTMLBodyElement) webEngine.executeScript("document.body"); 352 353 JSObject window = (JSObject) webEngine.executeScript("window"); 354 355 System.out.println("adding"); 356 WebParser.addPageToFrame(doc, window, webEngine, frameToAddTo); 357 } catch (Exception ex) { 358 ex.printStackTrace(); 359 } 360 } 361 }); 362 } catch (Exception ex) { 363 ex.printStackTrace(); 364 } 365 } 366 } 367 }; 368 369 Platform.runLater(new Runnable() { 370 @Override 371 public void run() { 372 try { 373 374 webEngine.executeScript("" 375 // Initializing the counter used when scrolling the page 376 + "var scrollCounter = 0;" 377 378 // Setting all text to be hidden 379 + "var css = document.createElement('style');" 380 + "css.type = 'text/css';" 381 + "var style = 'WordSpan { visibility: hidden }';" 382 + "css.appendChild(document.createTextNode(style));" 383 + "document.getElementsByTagName('head')[0].appendChild(css);"); 384 385 HTMLBodyElement doc = (HTMLBodyElement) webEngine.executeScript("document.body"); 386 387 JSObject window = (JSObject) webEngine.executeScript("window"); 388 389 frame.setBackgroundColor(rgbStringToColor((String) ((JSObject) (window.call("getComputedStyle", new Object[] { doc }))).call("getPropertyValue", 390 new Object[] { "background-color" }))); 391 392 // Functions to be used later in JavaScript 393 webEngine.executeScript("" 146 394 + "function addToSpan(text) {" 147 395 + " span = document.createElement('wordSpan');" … … 180 428 // loop through twice (once to build the array and once actually going through the array, otherwise when the 181 429 // textnode is removed from the document items end up being skipped) 182 Object textNodes = JavaFX.WebEngineExecuteScript.invoke(webEngine,""430 JSObject textNodes = (JSObject) webEngine.executeScript("" 183 431 + "function getTextNodes(rootNode){" 184 432 + "var node;" … … 195 443 ); 196 444 197 int nodesLength = (Integer) JavaFX.JSObjectGetMember.invoke(textNodes,"length");445 int nodesLength = (Integer) textNodes.getMember("length"); 198 446 199 447 // Looping through all the text nodes in the document 200 448 for (int j = 0; j < nodesLength; j++) { 201 Node currentNode = (Node) JavaFX.JSObjectGetSlot.invoke(textNodes,j);449 Node currentNode = (Node) textNodes.getSlot(j); 202 450 203 451 // Making the current node accessible in JavaScript 204 JavaFX.JSObjectSetMember.invoke(window,"currentNode", currentNode);452 window.setMember("currentNode", currentNode); 205 453 206 JavaFX.WebEngineExecuteScript.invoke(webEngine,""454 webEngine.executeScript("" 207 455 + "var span = null, prevSpan = null, prevPrevSpan = null;" 208 456 … … 234 482 // This is needed because there is no apparent and efficient way to check if an element is a child of a link when 235 483 // running through the document when added each element to Expeditee 236 JavaFX.WebEngineExecuteScript.invoke(webEngine,""484 webEngine.executeScript("" 237 485 + "var anchors = document.getElementsByTagName('a');" 238 486 + "" … … 246 494 ); 247 495 248 WebParser.addPageToFrame(doc, window, webEngine, frame);249 250 progressBar.set(100);251 252 } catch (Exception e) {253 e.printStackTrace();254 }255 System.out.println("Parsed frame");256 FrameUtils.Parse(frame);257 frame.setChanged(true);258 FrameIO.SaveFrame(frame);259 }260 });261 } catch (Exception e) {262 e.printStackTrace();263 }264 }265 266 /**267 * Converts a loaded page to Expeditee frame(s)268 *269 * @param webEngine270 * The JavaFX WebEngine in which the page to be converted is loaded271 * @param frame272 * The Expeditee frame to output the converted page to273 */274 public static void parsePageSimple(final Object webEngine, final Object webView, final JComponent jfxPanel, final Frame frame) {275 try {276 final Object notifier = new Object();277 final MutableBool notAtBottom = new MutableBool(true);278 279 JavaFX.PlatformRunLater.invoke(null, new Runnable() {280 @Override281 public void run() {282 try {283 // Initializing the counter used when scrolling the page284 JavaFX.WebEngineExecuteScript.invoke(webEngine, "var scrollCounter = 0");285 496 } catch (Exception ex) { 286 497 ex.printStackTrace(); … … 303 514 } 304 515 305 int tick = 0; 306 Frame frameToAddTo = frame; 307 308 while (notAtBottom.getValue()) { 309 JavaFX.PlatformRunLater.invoke(null, new Runnable() { 516 while (!bottomReached.getValue()) { 517 Platform.runLater(new Runnable() { 310 518 @Override 311 519 public void run() { 312 520 try { 313 521 // Scrolling down the page 314 JavaFX.WebEngineExecuteScript.invoke(webEngine,""522 webEngine.executeScript("" 315 523 + "window.scrollTo(0, scrollCounter * window.innerHeight);" 316 524 + "scrollCounter = scrollCounter+1;"); 317 318 notAtBottom.setValue((Boolean) JavaFX.WebEngineExecuteScript.invoke(webEngine, "(window.pageYOffset + window.innerHeight < document.documentElement.scrollHeight)")); 525 526 System.out.println('B'); 527 528 bottomReached.setValue((boolean) webEngine.executeScript("(window.pageYOffset + window.innerHeight >= document.documentElement.scrollHeight)")); 319 529 320 530 synchronized (notifier) { … … 338 548 } 339 549 340 BufferedImage image = new BufferedImage(jfxPanel.getWidth(), jfxPanel.getHeight(), BufferedImage.TYPE_INT_ARGB); 341 342 Graphics graphics = image.createGraphics(); 343 344 // Drawing the JfxPanel (containing the webview) to the image 345 jfxPanel.paint(graphics); 346 347 try { 348 int hashcode = Arrays.hashCode(image.getData().getPixels(0, 0, image.getWidth(), image.getHeight(), (int[]) null)); 349 350 File out = new File(FrameIO.IMAGES_PATH + "webpage-" + Integer.toHexString(hashcode) + ".png"); 351 out.mkdirs(); 352 ImageIO.write(image, "png", out); 353 354 Text link = new Text("Next"); 355 link.setPosition(500, 20); 356 frameToAddTo.addItem(link); 357 358 frameToAddTo = FrameIO.CreateFrame(frame.getFramesetName(), Integer.toHexString(hashcode), null); 359 360 link.setLink(frameToAddTo.getName()); 361 362 // Adding the image 363 frameToAddTo.addText(0, 0, "@i: " + out.getName(), null); 364 365 // Button to go to the next page 366 Text nextButton = (Text) FrameCreator.createButton("Next", null, null, 10F, 10F); 367 nextButton.setID(frameToAddTo.getNextItemID()); 368 nextButton.addAction("next"); 369 frameToAddTo.addItem(nextButton); 370 371 FrameIO.SaveFrame(frameToAddTo); 372 373 } catch (IOException e) { 374 e.printStackTrace(); 550 timer.start(); 551 552 synchronized (notifier) { 553 try { 554 // Waiting for the timer thread to finish before looping again 555 notifier.wait(); 556 } catch (InterruptedException e) { 557 // TODO Auto-generated catch block 558 e.printStackTrace(); 559 } 375 560 } 376 graphics.dispose();377 image.flush();378 379 System.out.println("C");380 381 synchronized (notifier) {382 notifier.notify();383 }384 385 tick = 0;386 561 387 562 } … … 442 617 * @throws IllegalAccessException 443 618 */ 444 private static void addPageToFrame(Node rootElement, Object window, ObjectwebEngine, Frame frame) throws InvocationTargetException, IllegalAccessException,619 private static void addPageToFrame(Node rootElement, JSObject window, WebEngine webEngine, Frame frame) throws InvocationTargetException, IllegalAccessException, 445 620 IllegalArgumentException { 446 621 … … 449 624 if (currentNode.getNodeType() == Node.TEXT_NODE || currentNode.getNodeType() == Node.ELEMENT_NODE) { 450 625 451 Object style;452 Object bounds;626 JSObject style; 627 JSObject bounds; 453 628 454 629 if (currentNode.getNodeType() == Node.TEXT_NODE) { 455 630 // CSS style for the element 456 style = JavaFX.JSObjectCall.invoke(window,"getComputedStyle", new Object[] { currentNode.getParentNode() });631 style = (JSObject) window.call("getComputedStyle", new Object[] { currentNode.getParentNode() }); 457 632 458 633 // Getting a rectangle that represents the area and position of the element 459 bounds = JavaFX.JSObjectCall.invoke(currentNode.getParentNode(),"getBoundingClientRect", new Object[] {});634 bounds = (JSObject) ((JSObject) currentNode.getParentNode()).call("getBoundingClientRect", new Object[] {}); 460 635 } else { 461 style = JavaFX.JSObjectCall.invoke(window,"getComputedStyle", new Object[] { currentNode });462 463 bounds = JavaFX.JSObjectCall.invoke(currentNode,"getBoundingClientRect", new Object[] {});636 style = (JSObject) window.call("getComputedStyle", new Object[] { currentNode }); 637 638 bounds = (JSObject) ((JSObject) currentNode).call("getBoundingClientRect", new Object[] {}); 464 639 } 465 640 … … 467 642 // TODO: This doesn't check if an element or any of its parent elements have position:fixed set - the only 468 643 // way to check seems to be to walking through the element's parents until the document root is reached 469 float x = Float.valueOf(JavaFX.JSObjectGetMember.invoke(bounds, "left").toString()) 470 + Float.valueOf(JavaFX.WebEngineExecuteScript.invoke(webEngine, "window.pageXOffset").toString()); 471 float y = Float.valueOf(JavaFX.JSObjectGetMember.invoke(bounds, "top").toString()) 472 + Float.valueOf(JavaFX.WebEngineExecuteScript.invoke(webEngine, "window.pageYOffset").toString()); 473 474 float width = Float.valueOf(JavaFX.JSObjectGetMember.invoke(bounds, "width").toString()); 475 float height = Float.valueOf(JavaFX.JSObjectGetMember.invoke(bounds, "height").toString()); 644 float x = Float.valueOf(bounds.getMember("left").toString()) + Float.valueOf(webEngine.executeScript("window.pageXOffset").toString()); 645 float y = Float.valueOf(bounds.getMember("top").toString()) + Float.valueOf(webEngine.executeScript("window.pageYOffset").toString()); 646 647 float width = Float.valueOf(bounds.getMember("width").toString()); 648 float height = Float.valueOf(bounds.getMember("height").toString()); 476 649 477 650 // Checking if the element is actually visible on the page … … 480 653 // Filtering the node type, starting with text nodes 481 654 if (currentNode.getNodeType() == Node.TEXT_NODE) { 482 String fontSize = ((String) JavaFX.JSObjectCall.invoke(style, "getPropertyValue", new Object[] { "font-size" })); 655 656 String fontSize = ((String) style.call("getPropertyValue", new Object[] { "font-size" })); 483 657 484 658 // Trimming off the units (always px) from the font size … … 486 660 487 661 // Always returns in format "rgb(x,x,x)" or "rgba(x,x,x,x)" 488 String color = (String) JavaFX.JSObjectCall.invoke(style,"getPropertyValue", new Object[] { "color" });662 String color = (String) style.call("getPropertyValue", new Object[] { "color" }); 489 663 490 664 // Always returns in format "rgb(x,x,x)" or "rgba(x,x,x,x)" 491 String bgColorString = (String) JavaFX.JSObjectCall.invoke(style,"getPropertyValue", new Object[] { "background-color" });492 493 String align = (String) JavaFX.JSObjectCall.invoke(style,"getPropertyValue", new Object[] { "text-align" });665 String bgColorString = (String) style.call("getPropertyValue", new Object[] { "background-color" }); 666 667 String align = (String) style.call("getPropertyValue", new Object[] { "text-align" }); 494 668 495 669 // Returns comma-separated list of typefaces 496 String typeface = (String) JavaFX.JSObjectCall.invoke(style,"getPropertyValue", new Object[] { "font-family" });670 String typeface = (String) style.call("getPropertyValue", new Object[] { "font-family" }); 497 671 498 672 String[] typefaces = typeface.split(", |,"); 499 673 500 String weight = (String) JavaFX.JSObjectCall.invoke(style,"getPropertyValue", new Object[] { "font-weight" });674 String weight = (String) style.call("getPropertyValue", new Object[] { "font-weight" }); 501 675 502 String fontStyle = (String) JavaFX.JSObjectCall.invoke(style,"getPropertyValue", new Object[] { "font-style" });676 String fontStyle = (String) style.call("getPropertyValue", new Object[] { "font-style" }); 503 677 504 678 // Returns "normal" or a value in pixels (e.g. "10px") 505 String letterSpacing = (String) JavaFX.JSObjectCall.invoke(style,"getPropertyValue", new Object[] { "letter-spacing" });679 String letterSpacing = (String) style.call("getPropertyValue", new Object[] { "letter-spacing" }); 506 680 507 681 // Returns a value in pixels (e.g. "10px") 508 String lineHeight = (String) JavaFX.JSObjectCall.invoke(style,"getPropertyValue", new Object[] { "line-height" });509 510 String textTransform = (String) JavaFX.JSObjectCall.invoke(style,"getPropertyValue", new Object[] { "text-transform" });511 512 String linkUrl = (String) JavaFX.JSObjectGetMember.invoke(currentNode.getParentNode(),"href");682 String lineHeight = (String) style.call("getPropertyValue", new Object[] { "line-height" }); 683 684 String textTransform = (String) style.call("getPropertyValue", new Object[] { "text-transform" }); 685 686 String linkUrl = (String) ((JSObject) currentNode.getParentNode()).getMember("href"); 513 687 514 688 Boolean fontFound = false; … … 632 806 633 807 // Always returns in format "rgb(x,x,x)" or "rgba(x,x,x,x)" 634 String bgColorString = (String) JavaFX.JSObjectCall.invoke(style,"getPropertyValue", new Object[] { "background-color" });808 String bgColorString = (String) style.call("getPropertyValue", new Object[] { "background-color" }); 635 809 636 810 Color bgColor = rgbStringToColor(bgColorString); … … 645 819 // may also return gradients, data, etc. (not handled yet). Only need to add bg image on 646 820 // 'ELEMENT_NODE' (and not 'TEXT_NODE' otherwise there would be double-ups 647 String bgImage = (String) JavaFX.JSObjectCall.invoke(style,"getPropertyValue", new Object[] { "background-image" });821 String bgImage = (String) style.call("getPropertyValue", new Object[] { "background-image" }); 648 822 649 String linkUrl = (String) JavaFX.JSObjectGetMember.invoke(currentNode,"href");823 String linkUrl = (String) ((JSObject) currentNode).getMember("href"); 650 824 651 825 if (bgImage.startsWith("url(")) { 652 826 bgImage = bgImage.substring(4, bgImage.length() - 1); 653 827 654 String bgSize = ((String) JavaFX.JSObjectCall.invoke(style,"getPropertyValue", new Object[] { "background-size" })).toLowerCase();655 String bgRepeat = ((String) JavaFX.JSObjectCall.invoke(style,"getPropertyValue", new Object[] { "background-repeat" })).toLowerCase();828 String bgSize = ((String) style.call("getPropertyValue", new Object[] { "background-size" })).toLowerCase(); 829 String bgRepeat = ((String) style.call("getPropertyValue", new Object[] { "background-repeat" })).toLowerCase(); 656 830 657 831 // Returns "[x]px [y]px", "[x]% [y]%", "[x]px [y]%" or "[x]% [y]px" 658 String bgPosition = ((String) JavaFX.JSObjectCall.invoke(style,"getPropertyValue", new Object[] { "background-position" })).toLowerCase();832 String bgPosition = ((String) style.call("getPropertyValue", new Object[] { "background-position" })).toLowerCase(); 659 833 660 834 String[] bgOffsetCoords = bgPosition.split(" "); … … 720 894 String imgSrc; 721 895 722 if (currentNode.getNodeName().toLowerCase().equals("img") && (imgSrc = JavaFX.JSObjectGetMember.invoke(currentNode,"src").toString()) != null) {896 if (currentNode.getNodeName().toLowerCase().equals("img") && (imgSrc = ((JSObject) currentNode).getMember("src").toString()) != null) { 723 897 try { 724 898 WebParser.addImageFromUrl(imgSrc, linkUrl, frame, x, y, (int) width, null, null, null, null, null, 0, 0); … … 743 917 } 744 918 745 private static boolean elementVisible(float x, float y, float width, float height, Object style) {919 private static boolean elementVisible(float x, float y, float width, float height, JSObject style) { 746 920 try { 747 if (width <= 0 || height <= 0 || x + width <= 0 || y + height <= 0 || ((String) JavaFX.JSObjectCall.invoke(style,"getPropertyValue", new Object[] { "visibility" })).equals("hidden")748 || ((String) JavaFX.JSObjectCall.invoke(style,"getPropertyValue", new Object[] { "display" })).equals("none")) {921 if (width <= 0 || height <= 0 || x + width <= 0 || y + height <= 0 || ((String) style.call("getPropertyValue", new Object[] { "visibility" })).equals("hidden") 922 || ((String) style.call("getPropertyValue", new Object[] { "display" })).equals("none")) { 749 923 return false; 750 924 } else {
Note:
See TracChangeset
for help on using the changeset viewer.