Wicket Strange behaviour of URL with ajax - javascript

I have issue that have strange steps. I have ajax behave rendered on Head render stage
final AbstractDefaultAjaxBehavior behave = new AbstractDefaultAjaxBehavior() {
protected void respond(final AjaxRequestTarget target) {
boolean undoEn = getRequest().getQueryParameters().getParameterValue("undoEn").toBoolean();
if (undoEn) {
mSaveButton.setEnabled(true);
target.add(mSaveButton);
}
}
};
public String getCallbackName() {
return "saveButtonVisibilityToggle";
}
#Override
public void renderHead(IHeaderResponse response) {
String script = getCallbackName() + " = function (e) { Wicket.Ajax.ajax({\"u\": \"" + behave.getCallbackUrl() + " + &undoEn=\"+e+\"\" });}";
response.render(OnDomReadyHeaderItem.forScript(script));
}
Everything works well this behave called every time node changed in tinyMCE editor
settings.addCustomSetting(" setup: function(editor) {" +
" editor.on('NodeChange', function(e) {" +
" editor.save();" +
getCallbackName() + "(editor.undoManager.hasUndo())" +
" });" +
" }");
But sometimes when i leave browser tab, change few tabs (chrome) then use other app for few minutes, and turn back to our tab, ajax url have accidently appeared in browser url.
http://localhost:8080/wicket/bookmarkable/com.tac.kulik.pages.SomePage?3-1.IBehaviorListener.0-contentPanel&entityId=2+++&undoEn=true
this is also quite strange that instead normap parameter pass it's ++++ signs added
by the way this sighns recognized as "2 " so for some reason '+' changed to whitespace
UPDATE 1
Using #svenmeier answer i've page start's infinite loop refreshing. with logs
org.apache.wicket.core.request.mapper.StalePageException: A request to
page '[Page class = x.x.x.CardPage, id = 25, render count = 1]' has been
made with stale 'renderCount'. The page will be re-rendered.
and really for some reason behave link has renderCount 1, but form has 0.
the request from browser
jquery-1.12.4-ver-1476216952000.js:10254 XHR finished loading: GET "http://localhost:8080/wicket/bookmarkable/com.tac.pages.ca…?4-0.IBehaviorListener.0-contentPanel&cardId=1&_=1476873175645&undoEn=true"
I ve add some set of JS to prevent cicling refreshing, But i'we still has Stale exception
"if (editor.undoManager.hasUndo()) { " +
" console.debug('Behave called ');" +
behave.getCallbackScript() +
" }" +
this is my behave
final AbstractDefaultAjaxBehavior behave = new AbstractDefaultAjaxBehavior() {
protected void respond(final AjaxRequestTarget target) {
log.info("Behave called");
boolean undoEn = getRequest().getQueryParameters().getParameterValue("undoEn").toBoolean();
if (undoEn) {
mSaveButton.setEnabled(true);
target.add(mSaveButton);
}
}
//
#Override
protected void updateAjaxAttributes(AjaxRequestAttributes attributes) {
super.updateAjaxAttributes(attributes);
String undoEn = "return {'undoEn': editor.undoManager.hasUndo()};";
attributes.getDynamicExtraParameters().add(undoEn);
}
};
And there is no difference, it could be behave without any realization, page behaviour the same((
final AbstractDefaultAjaxBehavior behave = new AbstractDefaultAjaxBehavior() {
#Override
protected void respond(AjaxRequestTarget target) {
}
};

You should rework your behavior to use dynamic extra parameters instead.
#Override
protected void updateAjaxAttributes(AjaxRequestAttributes attributes)
{
super.updateAjaxAttributes(attributes);
String undoEn = "return {'undoEn': editor.undoManager.hasUndo()}";
attributes.getDynamicExtraParameters().add(undoEn);
}
And:
settings.addCustomSetting(
"setup: function(editor) {" +
" editor.on('NodeChange', function(e) {" +
" editor.save();" +
" " + getCallbackScript() + ";" +
" });" +
"}");

Related

JavaScript injection in Android webview

I have written Javascript code that contain callback handler to my android app and inject it from my android code. It fires call back event when we perform play/pause action of video in webview and return event in callback. We are injecting Javascript code form both plateform (iOS and Android)
But unfortunately in iOS, all event value data is getting but in Android it is showing "undefined"
Below is my JavaScript code that is injecting from Android
webView.addJavascriptInterface(new Object() {
#JavascriptInterface
public void getEvent(String data) {
Toast.makeText(getContext(), data , Toast.LENGTH_SHORT).show();
Log.w("TAGGG", "callBackEvent: " + data.toString() );
}
}, "abc");
#Override
public void onPageFinished(WebView view, String url) {
tvErrorMessage.setVisibility(View.INVISIBLE);
String scriptThree = "javascript:window.myApp_event =(function() {" +
"function notifyApp(event) {" +
"var myCallback = console.log(event);"+
"abc.getEvent(event);" + // This is callback for Android
"}" +
"var oExistingEvents = window.myApp_event || [];" +
"oExistingEvents.forEach(notifyApp);" +
"return {" +
"push: function(event) {" +
"notifyApp(event);" +
"}" +
"}" +
"})();";
webView.loadUrl(scriptThree);
}
How can we get that event name that is get in iOS but not in Android?

Using Javascript in android WebView to call a function

Background:-
I am trying to call a #JavascriptInterface annotated method processVideo() form the loadUrl() of webview to get callback when someone click on any video on the webpage.
The following is my approach and it's working perfectly
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_download);
webView = findViewById(R.id.web_view_facebook);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setPluginState(WebSettings.PluginState.ON);
webView.getSettings().setBuiltInZoomControls(true);
webView.getSettings().setDisplayZoomControls(true);
webView.getSettings().setUseWideViewPort(true);
webView.getSettings().setLoadWithOverviewMode(true);
webView.addJavascriptInterface(this, "Downloader");
webView.setWebViewClient(new WebViewClient() {
#Override
public void onLoadResource(WebView view, String url) {
webView.loadUrl("javascript:(function prepareVideo() { "
+ "var el = document.querySelectorAll('div[data-sigil]');"
+ "for(var i=0;i<el.length; i++)"
+ "{"
+ "var sigil = el[i].dataset.sigil;"
+ "if(sigil.indexOf('inlineVideo') > -1){"
+ "delete el[i].dataset.sigil;"
+ "console.log(i);"
+ "var jsonData = JSON.parse(el[i].dataset.store);"
+ "el[i].addEventListener('click',function(){Downloader.processVideo(jsonData['src'],jsonData['videoID']);});"
+ "}" + "}" + "})()");
}
});
webView.loadUrl("https://m.facebook.com");
}
#JavascriptInterface
public void processVideo(final String vidData, final String vidID) {
try {
Toast.makeText(this, "Download Started", Toast.LENGTH_LONG).show();
} catch (Exception e) {
Toast.makeText(this, "Download Failed: " + e.toString(), Toast.LENGTH_LONG).show();
}
}}
Now The Problem:-
But as i load custom javascript function in loadUrl(), i lost the ability to play video on click.
i think it will happen as i intercepted and load my custom code
So what i want to achieve is when any user click on video, then the video should play and also i get the callback that i wanted at first place
What i have tried so far:-
to play the video on click, i used
addEventListener('click',function(){
var video = document.getElementById(jsonData['videoID']);
video.play(); }
This one is working perfectly to play the video.
but when i use this solution with my callback like following
addEventListener('click',function(){
Downloader.processVideo(jsonData['src'],jsonData['videoID']);
var video = document.getElementById(jsonData['videoID']);
video.play(); }
then I am not able to get callback in my processVideo().
If i use them individually, both functionality (callback and play video) working perfectly inside addEventListener(), but not working together.
This code line: var video = document.getElementById('jsonData['videoID']') throws an error because you used more than two 's in one argument.
Try replacing by var video = document.getElementById(jsonData['videoID']).
Hope this helps.
I have solved this issue and i am pasting complete code here:
webView.setWebViewClient(new WebViewClient()
{
#Override
public void onPageFinished(WebView view, String url)
{
//query_string = "" + url;
// view.loadUrl("javascript:(function() { document.getElementsByTagName('video')[0].play(); })()");
}
#Override
public void onLoadResource(WebView view, String url)
{
// query_string=""+url;
webView.loadUrl("javascript:(function prepareVideo() " +
"{ "
+ "var el = document.querySelectorAll('div[data-sigil]');"
+"var ID;"
+"var SRC;"
+ "for(var i=0;i<el.length; i++)"
+ "{"
+ "var sigil = el[i].dataset.sigil;"
+ "if(sigil.indexOf('inlineVideo') > -1)" +
"{"
+ "delete el[i].dataset.sigil;"
+ "console.log(i);"
+ "var jsonData = JSON.parse(el[i].dataset.store);"
+"ID=jsonData['videoID'];"
+"SRC=jsonData['src'];"
// +"document.getElementsByTagName(\"'+jsonData['videoID']+'\")[0].play();"
+ "el[i].setAttribute('onClick','FBDownloader.processVideo(\"'+jsonData['src']+'\",\"'+jsonData['videoID']+'\");');"
+ "}"
+ "}"
+ "})()");
}
});
JAVA ACTIVITY FUNCTION WHICH IS CALL FROM JAVASCRIPT WEBVIEW
public void processVideo(final String vidData, final String vidID)
{
this.vidData=vidData;
this.vidID=vidID;
Get_Download_Permission();
showtoast("video ID ="+this.vidID);
webView.loadUrl("https://www.facebook.com/video/embed?video_id="+this.vidID);//193766537709747/");
}

Angular 2 - Open URL in New Window with POST

I currently have a component that requires to have a pop up upon submit. The response from the API provides a redirectURL and redirectParams to be used as the popped up window.
Simply using window.open defaults its method to GET and not POST. This causes a Not Found page whenever it is loaded this way.
This is how I currently do it:
protected makeDepositPopup(depositRequest: PaymentRequest) {
this.depositService.requestDepositPopup(depositRequest)
.subscribe(
(depositEvent: RedirectData | SuccessfulDepositPopup) => this.handleDepositPopupEvent(depositEvent),
(error: EcommError) => this.handleDepositError(error),
() => this.eventService.depositAttempt.emit()
);
}
then the event is handled via the handleDeposit event:
protected handleDepositPopupEvent(depositEvent: RedirectData | SuccessfulDepositPopup) {
if (depositEvent instanceof RedirectData) {
this.handleRedirect(depositEvent);
} else {
this.handleDepositSuccessPopup(depositEvent, this.redirectParams);
}
}
As soon as it succeeds, it then tries to open a window with the corresponding URL and parameters provided by the API response:
protected handleDepositSuccessPopup(depositEvent: SuccessfulDepositPopup, redirectParams: string): void {
redirectParams = ""; // to remove undefined value
depositEvent.params.forEach(function (data, index) {
if(index == 0) {
redirectParams += "?" + data["key"] + "=" + data["value"];
} else {
redirectParams += "&" + data["key"] + "=" + data["value"];
}
});
window.open(depositEvent.url + redirectParams);
this.router.navigate(
["deposit", this.route.snapshot.data["instrumentTypeCode"], "deposit-details", depositEvent.id], {
relativeTo: this.route.parent.parent
});
}
How do I convert this in such a way that the depositEvent.url and its appended redirectParams to open a new window with a POST method to get a successful page response?

How to autofill data inside webview?

I am stucked in one functionality. I am storing login credentials in my app for website. And there is one LOGIN button is there. When I hit that button, it will redirect to webview with website. And if there is any email and password, my login credentials will be filled there.
Example: I have stored facebook credentials in my app. And my webview is loading with https://m.facebook.com and when it will finish loading my stored login credentials will be filled there. So I just need to hit login button from webview to move forward.
For my app I am using following code. Which is not working for most website. Can anyone help me how to figure out this issue? Or does anyone has better idea to achieve this kind of functionality?
wvAutofill.loadUrl("https://mobile.twitter.com/login");
wvAutofill.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
final String js = "javascript: var x = document.getElementsByTagName(\"form\")[0].getElementsByTagName('input');" +
"for (var i = 0; i < x.length; i++) {" +
"\nconsole.log(x[i].type);" +
"var type = x[i].type;" +
"if (type=='text'){" +
"x[i].value=\"abc#gmail.com\";" +
"};" +
"if (type == 'password'){\n" +
"x[i].value=\"abc123\";" +
"}; " +
"if (type == 'button' || type == 'submit' || document.getElementsByTagName(\"button\")[0].tagName == \"button\"){" +
"x[i].click();" +
"}; " +
"}";
view.loadUrl(js);
}
});

Website Login by using WebView Javascript Android

On Button click:
public void login(View v) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(rlayout.getWindowToken(), 0);
loginWebView.loadUrl("https://example.de");
loginWebView.setVisibility(View.INVISIBLE);
loginWebView.setWebViewClient(new WebViewClient() {
public void onPageFinished(WebView view, String url) {
loginWebView.loadUrl("javascript: {" +
"document.getElementById('login_act').value = '" + "USNAME" + "';" +
"document.getElementById('login_pwd').value = '" + "PWD" + "';" +
"document.getElementById('submit').click();" +
"};");
}
public void onPageFinished2(WebView view, String url) {
loginWebView.loadUrl(url);
}
});
loginWebView.clearCache(true);
loginWebView.clearHistory();
WebView view = (WebView) this.findViewById(R.id.mainwebView);
String url = "https://example.de";
view.loadUrl(url);
}
On Button click:
1- 1. WebView Login
2- 2. WebView show Page
3- Ready
At my first try all worked. No Error, no problems. The only thing was, that the WebView loaded with the page, where i was not logged in.
How can i log in and what went wrong ?
Try to replace:
public void onPageFinished(WebView view, String url) {
loginWebView.loadUrl("javascript: {" +
"document.getElementById('login_act').value = '" + "USNAME" + "';" +
"document.getElementById('login_pwd').value = '" + "PWD" + "';" +
"document.getElementById('submit').click();" +
"};");
}
With:
public void onPageFinished(WebView view, String url) {
loginWebView.loadUrl("javascript:{" +
"ins=document.getElementsByTagName('input');" +
"ins[0].value='usrn';" +
"ins[1].value='pwd';" +
"ins[2].value=true;" +
"document.getElementsByTagName('form')[0].submit();" +
"};" );
}
Replace for usrn your username and replace for pwd your password. Use ins[2].value=true to hit "remember me". (If there no "remember me" checkbox delete it)
The last entry hit the submit Button.
Main Sourcecode by Jonas w - https://stackoverflow.com/users/5260024/jonas-w
(Just an advanced comment):
"javascript:{
ins=document.getElementsByTagName('input');
ins[0].value='username';
ins[1].value='password';
ins[2].value=true;
document.getElementsByTagName('form')[0].submit();
}"
Das schreibt username ins erste, passwort ins zweite und setzt das Dritte auf true und schickt das erste formular ab...

Categories

Resources