Changeset 767
- Timestamp:
- 01/28/14 17:06:51 (10 years ago)
- Location:
- trunk/src/org/expeditee
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/expeditee/io/WebParser.java
r753 r767 11 11 import java.net.MalformedURLException; 12 12 import java.net.URL; 13 import java.text.SimpleDateFormat; 13 14 import java.util.Arrays; 14 15 … … 22 23 */ 23 24 25 26 import java.util.Date; 27 24 28 import javafx.animation.AnimationTimer; 25 29 import javafx.application.Platform; … … 27 31 import javafx.beans.value.ObservableValue; 28 32 import javafx.concurrent.Worker.State; 33 import javafx.scene.transform.Rotate; 29 34 import javafx.scene.web.WebEngine; 30 35 … … 34 39 import netscape.javascript.JSObject; 35 40 41 import org.expeditee.gui.DisplayIO; 36 42 import org.expeditee.gui.Frame; 37 43 import org.expeditee.gui.FrameCreator; 44 import org.expeditee.gui.FrameGraphics; 38 45 import org.expeditee.gui.FrameIO; 39 46 import org.expeditee.gui.FrameUtils; 40 47 import org.expeditee.gui.MessageBay; 41 48 import org.expeditee.gui.MessageBay.Progress; 49 import org.expeditee.importer.FrameDNDTransferHandler; 42 50 import org.expeditee.items.ItemUtils; 43 51 import org.expeditee.items.Justification; … … 46 54 import org.w3c.dom.Node; 47 55 import org.w3c.dom.html.HTMLBodyElement; 56 57 import com.sun.org.apache.bcel.internal.generic.NEW; 48 58 49 59 /** … … 282 292 final MutableBool bottomReached = new MutableBool(false); 283 293 294 String pageTitle = webEngine.getTitle(); 295 296 String framesetName = FrameIO.ConvertToValidFramesetName((new SimpleDateFormat("yy-MM-dd-HH-mm-ss").format(new Date())) + pageTitle); 297 284 298 final Progress progressBar = MessageBay.displayProgress("Converting web page"); 285 299 300 final Frame frameset = FrameIO.CreateNewFrameset(framesetName); 301 302 frameset.setTitle(pageTitle); 303 frameset.getTitleItem().setSize(14); 304 305 Text link = new Text(DisplayIO.getCurrentFrame().getNextItemID(), webEngine.getTitle()); 306 307 link.setPosition(100, 100); 308 309 DisplayIO.getCurrentFrame().addItem(link); 310 311 link.setLink(framesetName + "1"); 312 313 // Timer that fires every time JFX is redrawn. After a few redraws, the handle method of this takes a screenshot of the page, 314 // adds it to the frame, then adds the text on top 286 315 AnimationTimer timer = new AnimationTimer() { 287 316 288 317 int frameCount = 0; 289 Frame frameToAddTo = frame ;318 Frame frameToAddTo = frameset; 290 319 291 320 @Override 292 321 public void handle(long arg0) { 322 System.out.println(frameCount); 293 323 // Must wait 2 frames before taking a snapshot of the webview, otherwise JavaFX won't have redrawn 294 if (frameCount++ > 1) {324 if (frameCount++ > 3) { 295 325 frameCount = 0; 296 326 this.stop(); … … 304 334 305 335 try { 336 frameToAddTo = FrameIO.CreateFrame(frameToAddTo.getFramesetName(), null, null); 337 306 338 int hashcode = Arrays.hashCode(image.getData().getPixels(0, 0, image.getWidth(), image.getHeight(), (int[]) null)); 307 339 … … 310 342 ImageIO.write(image, "png", out); 311 343 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 344 // Adding the image 323 345 frameToAddTo.addText(0, 0, "@i: " + out.getName(), null); 346 347 Text thumb = frameset.addText(100, 100, "@i: " + out.getName() + " " + 200, null); 348 thumb.setLink(frameToAddTo.getName()); 324 349 325 350 // Button to go to the next page … … 330 355 331 356 FrameIO.SaveFrame(frameToAddTo); 332 System.out.println("C"); 357 FrameIO.SaveFrame(frameset); 358 359 System.out.println("Screenshot taken and added " + frameToAddTo.getName()); 333 360 334 361 } catch (IOException e) { … … 336 363 } 337 364 338 339 365 graphics.dispose(); 340 366 image.flush(); 341 342 synchronized (notifier) {343 notifier.notify();344 }345 367 346 368 try { … … 353 375 JSObject window = (JSObject) webEngine.executeScript("window"); 354 376 355 System.out.println("adding"); 356 WebParser.addPageToFrame(doc, window, webEngine, frameToAddTo); 377 int visibleWidth = (int) webEngine.executeScript("window.innerWidth"); 378 int visibleHeight = (int) webEngine.executeScript("window.innerHeight"); 379 380 System.out.println("Adding text " + frameToAddTo.getName()); 381 WebParser.addTextToFrame(doc, visibleWidth, visibleHeight, window, webEngine, frameToAddTo); 382 FrameIO.SaveFrame(frameToAddTo); 383 System.out.println("Added text " + frameToAddTo.getName()); 357 384 } catch (Exception ex) { 358 385 ex.printStackTrace(); 386 } 387 388 synchronized (notifier) { 389 notifier.notify(); 359 390 } 360 391 } … … 371 402 public void run() { 372 403 try { 373 374 404 webEngine.executeScript("" 375 405 // Initializing the counter used when scrolling the page … … 521 551 // Scrolling down the page 522 552 webEngine.executeScript("" 523 + "window.scrollTo(0, scrollCounter * window.innerHeight);"553 + "window.scrollTo(0, scrollCounter * 0.9 * window.innerHeight);" 524 554 + "scrollCounter = scrollCounter+1;"); 525 555 526 System.out.println( 'B');556 System.out.println("Scrolling"); 527 557 528 558 bottomReached.setValue((Boolean) webEngine.executeScript("(window.pageYOffset + window.innerHeight >= document.documentElement.scrollHeight)")); … … 918 948 919 949 private static boolean elementVisible(float x, float y, float width, float height, JSObject style) { 920 try { 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")) { 923 return false; 924 } else { 925 return true; 926 } 927 } catch (Exception e) { 928 e.printStackTrace(); 950 if (width <= 0 || height <= 0 || x + width <= 0 || y + height <= 0 || ((String) style.call("getPropertyValue", new Object[] { "visibility" })).equals("hidden") 951 || ((String) style.call("getPropertyValue", new Object[] { "display" })).equals("none")) { 929 952 return false; 953 } else { 954 return true; 930 955 } 931 956 } … … 1063 1088 } 1064 1089 1090 /** 1091 * @param rootElement 1092 * Element that will be converted (including all sub-elements) 1093 * @param backgroundColor 1094 * String to be used as the background color of this element when added. In the format "rgb(x,x,x)" or "rgba(x,x,x,x)" 1095 * @param window 1096 * 'window' from Javascript 1097 * @param webEngine 1098 * Web engine that the page is loaded in 1099 * @param frame 1100 * Expeditee frame to add the converted page to 1101 * @throws IllegalArgumentException 1102 * @throws IllegalAccessException 1103 */ 1104 private static void addTextToFrame(Node rootElement, int visibleWidth, int visibleHeight, JSObject window, WebEngine webEngine, Frame frame) throws InvocationTargetException, 1105 IllegalAccessException, IllegalArgumentException { 1106 1107 Node currentNode = rootElement; 1108 1109 if (currentNode.getNodeType() == Node.TEXT_NODE) { 1110 1111 JSObject style; 1112 JSObject bounds; 1113 1114 1115 // CSS style for the element 1116 style = (JSObject) window.call("getComputedStyle", new Object[] { currentNode.getParentNode() }); 1117 1118 // Getting a rectangle that represents the area and position of the element 1119 bounds = (JSObject) ((JSObject) currentNode.getParentNode()).call("getBoundingClientRect", new Object[] {}); 1120 1121 1122 // Bounding rectangle position is relative to the current view, so scroll position must be added to x/y 1123 // TODO: This doesn't check if an element or any of its parent elements have position:fixed set - the only 1124 // way to check seems to be to walking through the element's parents until the document root is reached 1125 float x = Float.valueOf(bounds.getMember("left").toString()); 1126 float y = Float.valueOf(bounds.getMember("top").toString()); 1127 1128 float width = Float.valueOf(bounds.getMember("width").toString()); 1129 float height = Float.valueOf(bounds.getMember("height").toString()); 1130 1131 // Checking if the element is actually visible on the page 1132 if (width > 0 && height > 0 && x + width > 0 && y + height > 0 && x <= visibleWidth && y <= visibleHeight 1133 && !(((String) style.call("getPropertyValue", new Object[] { "display" })).equals("none"))) { 1134 1135 String fontSize = ((String) style.call("getPropertyValue", new Object[] { "font-size" })); 1136 1137 // Trimming off the units (always px) from the font size 1138 fontSize = fontSize.substring(0, fontSize.length() - 2); 1139 1140 // Always returns in format "rgb(x,x,x)" or "rgba(x,x,x,x)" 1141 String color = (String) style.call("getPropertyValue", new Object[] { "color" }); 1142 1143 // Always returns in format "rgb(x,x,x)" or "rgba(x,x,x,x)" 1144 String bgColorString = (String) style.call("getPropertyValue", new Object[] { "background-color" }); 1145 1146 String align = (String) style.call("getPropertyValue", new Object[] { "text-align" }); 1147 1148 // Returns comma-separated list of typefaces 1149 String typeface = (String) style.call("getPropertyValue", new Object[] { "font-family" }); 1150 1151 String[] typefaces = typeface.split(", |,"); 1152 1153 String weight = (String) style.call("getPropertyValue", new Object[] { "font-weight" }); 1154 1155 String fontStyle = (String) style.call("getPropertyValue", new Object[] { "font-style" }); 1156 1157 // Returns "normal" or a value in pixels (e.g. "10px") 1158 String letterSpacing = (String) style.call("getPropertyValue", new Object[] { "letter-spacing" }); 1159 1160 // Returns a value in pixels (e.g. "10px") 1161 String lineHeight = (String) style.call("getPropertyValue", new Object[] { "line-height" }); 1162 1163 String textTransform = (String) style.call("getPropertyValue", new Object[] { "text-transform" }); 1164 1165 String linkUrl = (String) ((JSObject) currentNode.getParentNode()).getMember("href"); 1166 1167 Boolean fontFound = false; 1168 Font font = new Font(null); 1169 1170 // Looping through all font-families listed in the element's CSS until one that is installed is 1171 // found, or the end of the list is reached, in which case the default font is used 1172 for (int j = 0; j < typefaces.length && !fontFound; j++) { 1173 if (typefaces[j].toLowerCase().equals("sans-serif")) { 1174 typefaces[j] = "Arial Unicode MS"; 1175 } else if (typefaces[j].toLowerCase().equals("serif")) { 1176 typefaces[j] = "Times New Roman"; 1177 } else if ((typefaces[j].toLowerCase().equals("arial"))) { 1178 // Have to use Arial Unicode, otherwise unicode characters display incorrectly 1179 typefaces[j] = "Arial Unicode MS"; 1180 } 1181 1182 // Regex will remove any inverted commas surrounding multi-word typeface names 1183 font = new Font(typefaces[j].replaceAll("^'|'$", ""), Font.PLAIN, 12); 1184 1185 // If the font isn't found, Java just uses Font.DIALOG, so this check checks whether the font was found 1186 if (!(font.getFamily().toLowerCase().equals(Font.DIALOG.toLowerCase()))) { 1187 fontFound = true; 1188 } 1189 } 1190 1191 if (font.getFamily().toLowerCase().equals(Font.DIALOG.toLowerCase())) { 1192 font = new Font("Times New Roman", Font.PLAIN, 12); 1193 } 1194 1195 String fontStyleComplete = ""; 1196 1197 int weightInt = 0; 1198 1199 try { 1200 weightInt = Integer.parseInt(weight); 1201 } catch (NumberFormatException nfe) { 1202 // Use default value as set above 1203 } 1204 1205 // checking if font is bold - i.e. 'bold', 'bolder' or weight over 500 1206 if (weight.toLowerCase().startsWith("bold") || weightInt > 500) { 1207 fontStyleComplete = fontStyleComplete.concat("bold"); 1208 } 1209 1210 if (fontStyle.toLowerCase().equals("italic") || fontStyle.toLowerCase().equals("oblique")) { 1211 fontStyleComplete = fontStyleComplete.concat("italic"); 1212 } 1213 1214 float fontSizeFloat = 12; 1215 1216 try { 1217 fontSizeFloat = Float.valueOf(fontSize); 1218 } catch (NumberFormatException nfe) { 1219 // Use default value as set above 1220 } 1221 1222 float letterSpacingFloat = -0.008f; 1223 1224 try { 1225 letterSpacingFloat = (Integer.parseInt(letterSpacing.substring(0, letterSpacing.length() - 2)) / (fontSizeFloat)); 1226 } catch (NumberFormatException nfe) { 1227 // Use default value as set above 1228 } 1229 1230 float lineHeightInt = -1; 1231 1232 try { 1233 lineHeightInt = (Float.parseFloat(lineHeight.substring(0, lineHeight.length() - 2))); 1234 } catch (NumberFormatException nfe) { 1235 // Use default value as set above 1236 } 1237 1238 Text t; 1239 1240 String textContent = currentNode.getTextContent().replaceAll("[^\\S\\n]+", " "); 1241 textContent = textContent.replaceAll("^(\\s)(\\n|\\r)", ""); 1242 1243 if (textTransform.equals("uppercase")) { 1244 textContent = textContent.toUpperCase(); 1245 } else if (textTransform.equals("lowercase")) { 1246 textContent = textContent.toUpperCase(); 1247 } 1248 1249 // Adding the text to the frame. Expeditee text seems to be positioned relative to the baseline of the first line, so 1250 // the font size has to be added to the y-position 1251 t = frame.addText(Math.round(x), Math.round(y + fontSizeFloat), textContent, null); 1252 1253 t.setColor(rgbStringToColor(color)); 1254 t.setBackgroundColor(rgbStringToColor(bgColorString)); 1255 t.setFont(font); 1256 t.setSize(fontSizeFloat); 1257 t.setFontStyle(fontStyleComplete); 1258 t.setLetterSpacing(letterSpacingFloat); 1259 1260 // Removing any spacing between lines allowing t.getLineHeight() to be used to get the actual height 1261 // of just the characters (i.e. distance from ascenders to descenders) 1262 t.setSpacing(0); 1263 1264 t.setSpacing(lineHeightInt - t.getLineHeight()); 1265 1266 if (align.equals("left")) { 1267 t.setJustification(Justification.left); 1268 } else if (align.equals("right")) { 1269 t.setJustification(Justification.right); 1270 } else if (align.equals("center")) { 1271 t.setJustification(Justification.center); 1272 } else if (align.equals("justify")) { 1273 t.setJustification(Justification.full); 1274 } 1275 1276 // Font size is added to the item width to give a little breathing room 1277 t.setWidth(Math.round(width + (t.getSize()))); 1278 1279 if (!linkUrl.equals("undefined")) { 1280 t.setAction("gotourl " + linkUrl); 1281 t.setActionMark(false); 1282 } 1283 } 1284 1285 } else if (currentNode.getNodeType() == Node.ELEMENT_NODE) { 1286 Node childNode = currentNode.getFirstChild(); 1287 1288 while (childNode != null) { 1289 addTextToFrame(childNode, visibleWidth, visibleHeight, window, webEngine, frame); 1290 childNode = childNode.getNextSibling(); 1291 } 1292 } 1293 } 1294 1065 1295 private static class MutableBool { 1066 1296 private boolean value; -
trunk/src/org/expeditee/items/widgets/JfxBrowser.java
r766 r767 528 528 529 529 public void getFrameNew() { 530 // this.setSize(1000, 1000 00);530 // this.setSize(1000, 1000); 531 531 // this._browser.setBounds(getX(), getY(), getWidth(), getHeight()); 532 533 532 // this.layout(this._browser); 533 534 534 try { 535 WebParser.parsePageSimple( this._browser.webEngine, this._browser.webview, (JComponent)this._browser.jfxPanel, DisplayIO.getCurrentFrame());535 WebParser.parsePageSimple(JfxBrowser.this._browser.webEngine, JfxBrowser.this._browser.webview, (JComponent) JfxBrowser.this._browser.jfxPanel, DisplayIO.getCurrentFrame()); 536 536 } catch (Exception e) { 537 537 e.printStackTrace();
Note:
See TracChangeset
for help on using the changeset viewer.