Headless webview - ios

Is there a way to create a headless WebView instance in Nativescript (Vue) for use with nativescript-webview-interface (which expects a Nativescript view)? How can I instantiate the Vue component so it creates the native webview in the background (similar to document.createElement on web)?

Try the core way of creating elements
import { WebView } from "tns-core-modules/ui/web-view";
...
methods: {
createWebView: function() {
const webView = new WebView();
// Remember to pass in context in case of android
wv._setupAsRootView({});
wv.onLoaded();
...
}
}
...

Related

MvvmCross Xamarin.Forms Modal Dialogs

I'm just trying to make my first app with MvvmCross but I already encounter a problem for my app and can't find anything on the web for that. I want to open a specific page as a modal dialog on supported devices (eg. iPads). For my non MvvmCross applications I do this with Rg.Plugin.Popup but I do not want it this way this time. I found a few solutions on how it can be done with native and MvvmCross but nothing about how it is done with Xamarin.Forms in combination to MvvmCross. Did I need to implement a own presenter and filter on the type of my page (because this page should always be modal on supported devices)? And if I do so, is there any example for this?
Using MvvmCross 5.2.0, the following worked for me (on iOS at least; haven't tested on Android):
var bundle = new MvxBundle(new Dictionary<string, string>{ { MvxFormsPagePresenter.ModalPresentationParameter, "true" } });
await _navService.Navigate<MyViewModel>(bundle);
This uses the stock-standard MvxFormsPagePresenter, so you don't have to create your own presenter.
I'm using MVVMCross 7.1.2 here, this was tested on Android only.
In your Views code behind implement IMvxOverridePresentationAttribute with code similar to this.
public MvxBasePresentationAttribute PresentationAttribute(MvxViewModelRequest request)
{
if (request.PresentationValues == null) return null;
if (request.PresentationValues.ContainsKey("NavigationMode") &&
request.PresentationValues["NavigationMode"] == "Modal")
{
return new MvxModalPresentationAttribute
{
WrapInNavigationPage = true,
Animated = false,
NoHistory = true
};
}
return null;
}
All you need to do now, is when Navigating to the view model is just pass a key value pair as the parameter like this
await NavigationService.Navigate<MainViewModel>(new MvxBundle(new Dictionary<string, string> { { "NavigationMode", "Modal" } }));
That's it... easy as that !

Add webview in Xamarin gtk form

I want to use Webview in Xamarin gtk Form. The problem is that i can't find Webview in toolbox.
Looking at this example i added some code in default MainWindow.cs code.
using System;
using Gtk;
using Xamarin.Forms;
public partial class MainWindow: Gtk.Window
{
public MainWindow () : base (Gtk.WindowType.Toplevel)
{
Build ();
WebView webView = new WebView
{
Source = new UrlWebViewSource
{
Url = "http://blog.xamarin.com/",
},
VerticalOptions = LayoutOptions.FillAndExpand
};
vbox2.Add (webView); //giving error since it webview is not widget.
}
protected void OnDeleteEvent (object sender, DeleteEventArgs a)
{
Gtk.Application.Quit ();
a.RetVal = true;
}
}
I am new to Xamarin and i don't know i can i create a xamarin gtk# tool that can run on OSX and windows.
I also want to fill htmlDocument and invoke click. Is it possible with xamarin gtk# webview

Xamarin Forms WebView Check When Website Address Changed

I have the following code that sets up a WebView inside my Xamarin.Forms Cross Platform application:
ReportsListWebView = new WebView()
{
VerticalOptions = LayoutOptions.FillAndExpand,
HorizontalOptions = LayoutOptions.FillAndExpand,
BackgroundColor = Xamarin.Forms.Color.Transparent
};
URLReportsListWebView = new UrlWebViewSource
{
Url = "http://192.168.0.96/MyWebsite/App/MiniMyWebsite?ActionType=Listing&Params=Reports"
};
ReportsListWebView.Source = URLReportsListWebView;
grid.Children.Add(ReportsListWebView, 0, 4, 0, 1);
The situation is that there is listing within the website that I am referencing in the WebView. When the user selects an item in the listing on the webpage it has javascript that changes the url of the website (appends #SelectedItem=1 to the url). I just want to be able to recognize this change from within the application.
I've checked the URLReportsListWebView.Url but it doesn't seem to update with the latest changes. Any ideas on how to achieve this?
Thanks
This ended up being a limitation on the xamarin forms webview control. The work around was to create a custom renderer which the Xamarin support provided me a great same showing how to accomplish this at github.com/jgold6/XFormsWebViewCustomRenderer/tree/master
When I've done a few tests against http://www.yahoo.com it appears to be updating the WebView.Source property ok, even with query string attribues.
Are you just updating the location of the current webpage rather than navigating to a new page?
Maybe this could be the reason why its not working for you?
If so, after the change, you will then be able to monitor the .Source property for the newly navigated webpage as there is no event handler or anything to hook into to get notified when a page has been navigated to / fully loaded.
Update 1:-
Try the following that is working for me.
It should produce updates similar to the following:-
http://www.yahoo.com
https://fr.yahoo.com/?p=us
https://fr.news.yahoo.com/syrie-jihadistes-exécutent-160-soldats-43-casques-bleus-050134941.html
http://www.tv3g.bouquettv.mobi/wap/landing/landing2.asp?c=LFYAH_TVGREEN_AAAMMM&IDLanding=16972&tag=0&Alea=7.906741E-02&Al=MM201408290946299694
Code:-
StackLayout objStackLayout = new StackLayout()
{
};
//
WebView objWebView1 = new WebView();
objWebView1.HeightRequest = 300;
objStackLayout.Children.Add(objWebView1);
//
UrlWebViewSource objUrlToNavigateTo = new UrlWebViewSource()
{
Url = "http://www.yahoo.com"
};
objWebView1.Source = objUrlToNavigateTo;
//
//
Button cmdButton1 = new Button();
cmdButton1.Text = "Show Me Current Url";
objStackLayout.Children.Add(cmdButton1);
//
cmdButton1.Clicked += ((o2, e2) =>
{
System.Diagnostics.Debug.WriteLine((objWebView1.Source as UrlWebViewSource).Url);
});
//
//
this.Content = objStackLayout;
If you don't yet have a custom renderer, you'll need to refer to Xamarin documentation to learn how to custom render Xamarin.Forms WebView.
If you already have the custom renderer, inside the CustomRenderer object, you should access the NativeWebview object and assign HandleShouldStartLoad to its ShouldStartLoad event handler. My mistake was that I assigned HandleShouldStartLoad to the event handler of the renderer itself, which won't work.

Adobe AIR, IOS, and Multiple SWFs - Returning to a previously loaded SWF

I am developing an IOS app using Adobe AIR, Flash and ActionScript 3 and I have divided sections up into separate SWF files. I have successfully gotten the app to load external SWFs and execute their ActionScript using the following code:
var proloader:ProLoader = new ProLoader();
proloader.load(new URLRequest("file.swf"), new LoaderContext(false, ApplicationDomain.currentDomain, null));
addChild(proloader);
Now, I would like to add a reset button that allows the user to return to the start of the first SWF from any other SWF file to restart the app. Unfortunately, it seems that whenever I try to load a SWF that has previously been loaded, nothing happens. I have read that unloading and reloading SWFs is not permitted on IOS and the fact that you are limited to one ApplicationDomain on IOS makes things difficult. However, I am still thinking there must be some workaround. I'd be okay with not ever unloading the external SWFs if that is the only way, but I still can't figure out a way to return to a SWF that was previously loaded.
Does anyone know of a way to return to a SWF that was previously loaded in IOS with Adobe Air?
You could have a static class that functions as a cache.
The cache might look something like this that I made for a menu system:
package com.rs2014.managers{
import flash.display.MovieClip;
import flash.utils.Dictionary;
import flash.events.Event;
import flash.events.EventDispatcher;
import com.events.MenuManagerEvent;
import com.menus.MenuBase;
import com.components.MenuLoader;
import com.MenuIdents;
public class MenuManager extends EventDispatcher
{
private static var instance:MenuManager
private static var allowInstantiation:Boolean = true;
public static function getInstance():MenuManager
{
if(!instance)
{
instance = new MenuManager();
allowInstantiation = false;
}
return instance
}
private const MAX_MENUS:uint = 8;
private var menuCache:Dictionary = new Dictionary()
public function MenuManager()
{
if(!allowInstantiation)
{
throw(new Error("please use the getInstance() method to obtain a handle to this singleton"));
}
}
public function getMenu(menu:String):void
{
if(menuCache[menu])
{
//This pulls from the cache if it's already been loaded before
dispatchMenu(null, menuCache[menu]);
}
else
{
//MenuLoader is a simple wrapper for Loader
var newLoader:MenuLoader = new MenuLoader();
menuCache[menu] = newLoader;
newLoader.addEventListener(Event.COMPLETE, dispatchMenu);
newLoader.source = menu;
//trace("setting up loader with source = "+menu);
}
}
private function dispatchMenu(e:Event = null, menu:MenuBase = null):void
{
if(e)
{
e.target.removeEventListener(Event.COMPLETE, dispatchMenu);
//trace(e.target.content);
//trace(e.target.content as MenuBase);
menuCache[e.target.source] = menu = e.target.content as MenuBase;
//trace(menu);
}
if(!menu)
{
throw(new Error("MenuManager Error: dispatchMenu called without menu to dispatch"));
}
this.dispatchEvent(new MenuManagerEvent(MenuManagerEvent.MENU_READY, menu))
}
}
}
I was able to solve the problem of reloading SWF's w/o ABC (no code!), I explain it all on my blog (http://www.eqsim.com/blog/?p=400) but also simply give the code on StackOverflow: Load and reload external SWF in AIR for iOS wf-in-air-for-ios/22046009#22046009
Now Adobe has a solution for separating code from the SWF, and loading the SWF externally. However, we addressed it prior to AIR 3.5 by making a class for the code only, then loading the SWF and in the code class, setting a link to the loaded SWF. When we needed to update to 4.0, the SWF reloading, even pure SWF assets, was not working in all situations, so we plugged away to find the solution I reference above.

xpcom/jetpack observe all document loads

I write a Mozilla Jetpack based add-on that has to run whenever a document is loaded. For "toplevel documents" this mostly works using this code (OserverService = require('observer-service')):
this.endDocumentLoadCallback = function (subject, data) {
console.log('loaded: '+subject.location);
try {
server.onEndDocumentLoad(subject);
}
catch (e) {
console.error(formatTraceback(e));
}
};
ObserverService.add("EndDocumentLoad", this.endDocumentLoadCallback);
But the callback doesn't get called when the user opens a new tab using middle click or (more importantly!) for frames. And even this topic I only got through reading the source of another extension and not through the documentation.
So how do I register a callback that really gets called every time a document is loaded?
Edit: This seems to do what I want:
function callback (event) {
// this is the content document of the loaded page.
var doc = event.originalTarget;
if (doc instanceof Ci.nsIDOMNSHTMLDocument) {
// is this an inner frame?
if (doc.defaultView.frameElement) {
// Frame within a tab was loaded.
console.log('!!! loaded frame:',doc.location.href);
}
else {
console.log('!!! loaded top level document:',doc.location.href);
}
}
}
var wm = Cc["#mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
var mainWindow = wm.getMostRecentWindow("navigator:browser");
mainWindow.gBrowser.addEventListener("load", callback, true);
Got it partially from here: https://developer.mozilla.org/en/XUL_School/Intercepting_Page_Loads
#kizzx2 you are better served with #jetpack
To the original question: why don't you use tab-browser module. Something like this:
var browser = require("tab-browser");
exports.main = function main(options, callbacks) {
initialize(function (config) {
browser.whenContentLoaded(
function(window) {
// something to do with the window
// e.g., if (window.locations.href === "something")
}
);
});
Much cleaner than what you do IMHO and (until we have official pageMods module) the supported way how to do this.
As of Addon SDK 1.0, the proper way to do this is to use the page-mod module.
(Under the hood it's implemented using the document-element-inserted observer service notification, you can use it in a regular extension or if page-mod doesn't suit you.)

Resources