1 /*******************************************************************************
2  * Copyright (c) 2018 Red Hat and others. All rights reserved.
3  * The contents of this file are made available under the terms
4  * of the GNU Lesser General Public License (LGPL) Version 2.1 that
5  * accompanies this distribution (lgpl-v21.txt).  The LGPL is also
6  * available at http://www.gnu.org/licenses/lgpl.html.  If the version
7  * of the LGPL at http://www.gnu.org is different to the version of
8  * the LGPL accompanying this distribution and there is any conflict
9  * between the two license versions, the terms of the LGPL accompanying
10  * this distribution shall govern.
11  *
12  * Contributors:
13  *     Red Hat - initial API and implementation
14  *******************************************************************************/
15 package org.eclipse.swt.tests.gtk.snippets;
16 
17 import org.eclipse.swt.SWT;
18 import org.eclipse.swt.browser.Browser;
19 import org.eclipse.swt.browser.BrowserFunction;
20 import org.eclipse.swt.events.KeyAdapter;
21 import org.eclipse.swt.events.KeyEvent;
22 import org.eclipse.swt.events.SelectionAdapter;
23 import org.eclipse.swt.events.SelectionEvent;
24 import org.eclipse.swt.events.SelectionListener;
25 import org.eclipse.swt.layout.GridData;
26 import org.eclipse.swt.layout.GridLayout;
27 import org.eclipse.swt.widgets.Button;
28 import org.eclipse.swt.widgets.Display;
29 import org.eclipse.swt.widgets.Shell;
30 import org.eclipse.swt.widgets.Text;
31 
32 /*
33  * Title:  Bug 536141: [Webkit2][Gtk] BrowserFunction lost after page reload on Linux/GTK
34  * How to run: Read the instructions printed in the console
35  * Bug description: N/A
36  * Expected results: BrowserFunctions should be added/removed as expected, see instructions for details
37  * GTK Version(s):
38  */
39 public class Bug536141_BrowserFunctionLostReload {
40 
41 	static int count = 0;
42 
main(String[] args)43 	public static void main(String[] args) {
44 		Display display = new Display();
45 		Shell shell = new Shell(display);
46 		shell.setSize(500, 600);
47 
48 		GridLayout gridLayout = new GridLayout();
49 		shell.setLayout(gridLayout);
50 
51 		final Text jsConsole = new Text(shell, SWT.BORDER);
52 //		jsConsole.setText("document.body.innerHTML = theJavaFunction(123, 'hello', null, true)");
53 		jsConsole.setText("document.body.innerHTML = theJavaFunction()"); // Case where there are no paramaters.
54 		jsConsole.setSelection(jsConsole.getText().length());
55 		GridData data = new GridData(SWT.FILL, SWT.BEGINNING, true, false);
56 		jsConsole.setLayoutData(data);
57 
58 		final Browser browser = new Browser(shell, SWT.NONE);
59 		browser.setText("hello <b>world!</b>");
60 		data = new GridData(SWT.FILL, SWT.FILL, true, true);
61 		browser.setLayoutData(data);
62 
63 		jsConsole.addKeyListener(new KeyAdapter() {
64 			@Override
65 			public void keyPressed(KeyEvent e) {
66 				if (e.keyCode == 13) { // 13 = Enter
67 					browser.execute(jsConsole.getText());
68 				}
69 			}
70 		});
71 
72 		Button loadNewPage = new Button(shell, SWT.PUSH);
73 		loadNewPage.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
74 		loadNewPage.setText("Load new page");
75 		loadNewPage.addSelectionListener(new SelectionAdapter() {
76 			@Override
77 			public void widgetSelected(SelectionEvent e) {
78 				browser.setText("New page!" + count++);
79 			}
80 		});
81 
82 
83 		// BrowserFunction Code
84 		final BrowserFunction function = new CustomFunction (browser, "theJavaFunction");
85 
86 		Button create = new Button (shell, SWT.PUSH);
87 		create.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
88 		create.setText("Create function");
89 		create.addSelectionListener(new SelectionListener () {
90 			@Override
91 			public void widgetDefaultSelected(SelectionEvent e) {}
92 			@Override
93 			public void widgetSelected(SelectionEvent e) {
94 				System.out.println("creating function");
95 				@SuppressWarnings("unused")
96 				final BrowserFunction function2 = new CustomFunction (browser, "theJavaFunction2");
97 			}
98 		});
99 
100 		Button destroy = new Button (shell, SWT.PUSH);
101 		destroy.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
102 		destroy.setText("Destroy function");
103 		destroy.addSelectionListener(new SelectionListener () {
104 			@Override
105 			public void widgetDefaultSelected(SelectionEvent e) {}
106 			@Override
107 			public void widgetSelected(SelectionEvent e) {
108 				System.out.println("destroying function");
109 				function.dispose();
110 			}
111 		});
112 		shell.open();
113 		System.out.println("INSTRUCTIONS: pressing the \"Create function\" button will create a function called theJavaFunction2.");
114 		System.out.println("Pressing the \"Destroy function\" button will destory the function called theJavaFunction.");
115 		System.out.println("To test that theJavaFunction2 was created, add the \"2\""
116 				+ " at the end of theJavaFunction in the console and press enter.");
117 		System.out.println("To test that theJavaFunction was deleted, remove the \"2\""
118 				+ " at the end of theJavaFunction in the console and press enter.");
119 		while (!shell.isDisposed()) {
120 			if (!display.readAndDispatch())
121 				display.sleep();
122 		}
123 		display.dispose();
124 	}
125 
126 	static class CustomFunction extends BrowserFunction { // copied from snippet 307
CustomFunction(Browser browser, String name)127 		CustomFunction (Browser browser, String name) {
128 			super (browser, name);
129 		}
130 		@Override
function(Object[] arguments)131 		public Object function (Object[] arguments) {
132 			System.out.println ("theJavaFunction() called from javascript with args:");
133 			for (int i = 0; i < arguments.length; i++) {
134 				Object arg = arguments[i];
135 				if (arg == null) {
136 					System.out.println ("\t-->null");
137 				} else {
138 					System.out.println ("\t-->" + arg.getClass ().getName () + ": " + arg.toString ());
139 				}
140 			}
141 			return arguments;
142 //			return new Point(1, 2);
143 
144 //			Object returnValue = new Object[] {
145 //					new Short ((short)3),
146 //					new Boolean (true),
147 //					null,
148 //					new Object[] {"a string", new Boolean (false)},
149 //					"hi",
150 //					new Float (2.0f / 3.0f),
151 //				};
152 //			return returnValue;
153 
154 //			return new Double(42.0);
155 		}
156 	}
157 }
158