Changeset 767


Ignore:
Timestamp:
01/28/14 17:06:51 (10 years ago)
Author:
ngw8
Message:

Updates to new webparser/converter - now gives a tidier, more usable conversion. A lot of the code is copied from the old parser, so still need to go through and make it more efficient (and tidier) for the new approach.

Location:
trunk/src/org/expeditee
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/expeditee/io/WebParser.java

    r753 r767  
    1111import java.net.MalformedURLException;
    1212import java.net.URL;
     13import java.text.SimpleDateFormat;
    1314import java.util.Arrays;
    1415
     
    2223 */
    2324
     25
     26import java.util.Date;
     27
    2428import javafx.animation.AnimationTimer;
    2529import javafx.application.Platform;
     
    2731import javafx.beans.value.ObservableValue;
    2832import javafx.concurrent.Worker.State;
     33import javafx.scene.transform.Rotate;
    2934import javafx.scene.web.WebEngine;
    3035
     
    3439import netscape.javascript.JSObject;
    3540
     41import org.expeditee.gui.DisplayIO;
    3642import org.expeditee.gui.Frame;
    3743import org.expeditee.gui.FrameCreator;
     44import org.expeditee.gui.FrameGraphics;
    3845import org.expeditee.gui.FrameIO;
    3946import org.expeditee.gui.FrameUtils;
    4047import org.expeditee.gui.MessageBay;
    4148import org.expeditee.gui.MessageBay.Progress;
     49import org.expeditee.importer.FrameDNDTransferHandler;
    4250import org.expeditee.items.ItemUtils;
    4351import org.expeditee.items.Justification;
     
    4654import org.w3c.dom.Node;
    4755import org.w3c.dom.html.HTMLBodyElement;
     56
     57import com.sun.org.apache.bcel.internal.generic.NEW;
    4858
    4959/**
     
    282292                        final MutableBool bottomReached = new MutableBool(false);
    283293
     294                        String pageTitle = webEngine.getTitle();
     295
     296                        String framesetName = FrameIO.ConvertToValidFramesetName((new SimpleDateFormat("yy-MM-dd-HH-mm-ss").format(new Date())) + pageTitle);
     297
    284298                        final Progress progressBar = MessageBay.displayProgress("Converting web page");
    285299
     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
    286315                        AnimationTimer timer = new AnimationTimer() {
    287316
    288317                                int frameCount = 0;
    289                                 Frame frameToAddTo = frame;
     318                                Frame frameToAddTo = frameset;
    290319
    291320                                @Override
    292321                                public void handle(long arg0) {
     322                                        System.out.println(frameCount);
    293323                                        // 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) {
    295325                                                frameCount = 0;
    296326                                                this.stop();
     
    304334
    305335                                                try {
     336                                                        frameToAddTo = FrameIO.CreateFrame(frameToAddTo.getFramesetName(), null, null);
     337
    306338                                                        int hashcode = Arrays.hashCode(image.getData().getPixels(0, 0, image.getWidth(), image.getHeight(), (int[]) null));
    307339
     
    310342                                                        ImageIO.write(image, "png", out);
    311343
    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 
    322344                                                        // Adding the image
    323345                                                        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());
    324349
    325350                                                        // Button to go to the next page
     
    330355
    331356                                                        FrameIO.SaveFrame(frameToAddTo);
    332                                                         System.out.println("C");
     357                                                        FrameIO.SaveFrame(frameset);
     358
     359                                                        System.out.println("Screenshot taken and added " + frameToAddTo.getName());
    333360
    334361                                                } catch (IOException e) {
     
    336363                                                }
    337364
    338 
    339365                                                graphics.dispose();
    340366                                                image.flush();
    341 
    342                                                 synchronized (notifier) {
    343                                                         notifier.notify();
    344                                                 }
    345367
    346368                                                try {
     
    353375                                                                                JSObject window = (JSObject) webEngine.executeScript("window");
    354376
    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());
    357384                                                                        } catch (Exception ex) {
    358385                                                                                ex.printStackTrace();
     386                                                                        }
     387
     388                                                                        synchronized (notifier) {
     389                                                                                notifier.notify();
    359390                                                                        }
    360391                                                                }
     
    371402                                public void run() {
    372403                                        try {
    373                                                
    374404                                                webEngine.executeScript(""
    375405                                                                // Initializing the counter used when scrolling the page
     
    521551                                                        // Scrolling down the page
    522552                                                        webEngine.executeScript(""
    523                                                                         + "window.scrollTo(0, scrollCounter * window.innerHeight);"
     553                                                                        + "window.scrollTo(0, scrollCounter * 0.9 * window.innerHeight);"
    524554                                                                        + "scrollCounter = scrollCounter+1;");
    525555
    526                                                         System.out.println('B');
     556                                                        System.out.println("Scrolling");
    527557
    528558                                                        bottomReached.setValue((Boolean) webEngine.executeScript("(window.pageYOffset + window.innerHeight >= document.documentElement.scrollHeight)"));
     
    918948
    919949        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")) {
    929952                        return false;
     953                } else {
     954                        return true;
    930955                }
    931956        }
     
    10631088        }
    10641089
     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
    10651295        private static class MutableBool {
    10661296                private boolean value;
  • trunk/src/org/expeditee/items/widgets/JfxBrowser.java

    r766 r767  
    528528
    529529        public void getFrameNew() {
    530                 // this.setSize(1000, 100000);
     530                // this.setSize(1000, 1000);
    531531                // this._browser.setBounds(getX(), getY(), getWidth(), getHeight());
    532 
    533532                // this.layout(this._browser);
     533
    534534                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());
    536536                } catch (Exception e) {
    537537                        e.printStackTrace();
Note: See TracChangeset for help on using the changeset viewer.