Как стать автором
Обновить

Получаем данные из Javascript через функции Java

Время на прочтение 3 мин
Количество просмотров 14K

Хоббит или туда и обратно


Некоторое кол-во времени назад мне срочно потребовалось найти возможные способы получения переменных из js и браузера, чтобы передать их значение в моем приложении на java. К сожалению, на хабре данный вопрос не был раскрыт или возможно сила покинула меня и поиск дается уже не так легко.
Как бы то ни было сегодня я постараюсь в какой то мере пролить свет на данный вопрос. Итак приступим!

Задача

В кратце опишу сложившуюся ситуацию — есть некое приложение со страницей редактора, в качетсве редактора имеем бесплатный NiceEdit. Почему именно внешний редактор — мне было необходимо достаточно быстро встроить редактор + данные пользователя представляются как html и писать велосипед было бы достаточно глупо. Были попытки встроить готовый виджет на swt, но или проект устарел или автор покривил душой — работать виджет отказывался.
Основная проблема — пользователь вводит\редактирует данные в редакторе, нажимает чудо кнопочку и наше приложение должно получить то, что только что было написано.

Решение

Как оказалось существует не один вариант решения подобной задачи:
  • Способ номер 1 — JNI
    Самое простое и полезное что пришло в голову — это сделать в html странице редактора, которая загружается встроенным в java браузером, свое текстовое поле и натравить на него редактор:
    <script type="text/javascript">
    var textArea;
    bkLib.onDomLoaded(function() {
    	new nicEditor({fullPanel : true}).panelInstance('area1');
    	var el = document.getElementById('EDITOR').getElementsByTagName('div');
    	textArea = el[el.length-1];
    });
    </script>

    Далее в самом приложении нам нужно написать нативную функцию, которую мы будем вызывать:
    	static class CustomFunction extends BrowserFunction {
    		//CustomFunctionData data = new CustomFunctionData(null);
    		public CustomFunction(Browser browser, String name) {
    			super(browser, name);
    			
    		}
    
    		public Object function(Object[] arguments) {
    			templateText = (String) arguments[0];
    			return null;
    		}
    	}
    создание новой customdata выдает ексепнш, хотя этот способ был описан на stackowerflow
    Создаем объект:
    new CustomFunction(browser, "getTextAreaContent");

    Теперь мы можем гордо вызвать необходимую нам функцию из браузера:
    browser.execute("var cont = textArea.innerHTML; getTextAreaContent(cont);");

  • Способ номер 2 — создание скрипта и вызов через браузер
    Никто не мешает нам создать переменную, записать туда нужный кусок скрипта и выполнить ее через браузер. Причем скрипт будет создавать пользовательский евент, изменяя статус браузера:
    
    final String SELECTIONSCRIPT = 
    			"function handleSelection() { " + 
    			" var selTxt = ''; " + 
    			" if (window.getSelection) { " + 
    			" selTxt = window.getSelection(); " + 
    			" } else if (document.getSelection) { " + 
    			" selTxt = document.getSelection(); " + 
    			" } else if (document.selection) { " + 
    			" selTxt = document.selection.createRange().text; " + 
    			" } " + 
    			" window.status = '::SELECTION::' + selTxt; " + 
    			"} " + 
    			"document.attachEvent('onmouseup', handleSelection); "; 
    	
    final Browser browser = new Browser(shell, SWT.NONE);
    	browser.addStatusTextListener(new StatusTextListener() {
    		public void changed(StatusTextEvent arg0) {
    			if (arg0.text.startsWith("::SELECTION::")) { 
    			String selection = arg0.text.substring("::SELECTION::".length()); 
    			System.out.println(selection);
    			}
    	}});
    	browser.addProgressListener(new ProgressAdapter() {
    		@Override
    		public void completed(ProgressEvent arg0) {
    			browser.execute(SELECTIONSCRIPT);
    		}
    	});
    	

    Правда тут нас ждут некоторые подводные камни, о которых никто не упоминал на разных форумах — не все браузеры позволяют изменять статус окна приложениям без разрешения пользователя. То есть, к примеру, в мозилле нужно поставить флаг dom.disable_window_status_change на false в about:config.

Вот оба способа, которые я знаю и которыми пользовался… Буду рад прочитать новые идеи и замечания к статье. Спасибо за внимание.
Теги:
Хабы:
+15
Комментарии 20
Комментарии Комментарии 20

Публикации

Истории

Работа

Ближайшие события

Московский туристический хакатон
Дата 23 марта – 7 апреля
Место
Москва Онлайн