mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-16 20:11:24 +08:00
Merge pull request #179 from NativeScript/webview-src
Implemented #172.
This commit is contained in:
10
apps/tests/ui/web-view/test.html
Normal file
10
apps/tests/ui/web-view/test.html
Normal file
@ -0,0 +1,10 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>MyTitle</title>
|
||||
<meta charset="utf-8" />
|
||||
</head>
|
||||
<body>
|
||||
<span style="color:red">Test</span>
|
||||
</body>
|
||||
</html>
|
@ -13,9 +13,10 @@ import webViewModule = require("ui/web-view");
|
||||
// ### Declaring a WebView.
|
||||
//```XML
|
||||
// <Page>
|
||||
// <WebView url="{{ someUrl }}" />
|
||||
// <WebView src="{{ someUrl | pathToLocalFile | htmlString }}" />
|
||||
// </Page>
|
||||
//```
|
||||
|
||||
// </snippet>
|
||||
|
||||
var _createWebViewFunc = function (): webViewModule.WebView {
|
||||
@ -76,6 +77,128 @@ export var testLoadExistingUrl = function () {
|
||||
}
|
||||
}
|
||||
|
||||
export var testLoadLocalFile = function () {
|
||||
var newPage: page.Page;
|
||||
var webView = _createWebViewFunc();
|
||||
var pageFactory = function (): page.Page {
|
||||
newPage = new page.Page();
|
||||
newPage.content = webView;
|
||||
return newPage;
|
||||
};
|
||||
|
||||
helper.navigate(pageFactory);
|
||||
|
||||
var testFinished = false;
|
||||
var actualHtml;
|
||||
var actualTitle;
|
||||
var actualError;
|
||||
|
||||
var expectedTitle = 'MyTitle';
|
||||
var expectedHtml = '<span style="color:red">Test</span>';
|
||||
|
||||
// <snippet module="ui/web-view" title="WebView">
|
||||
// ### Using WebView
|
||||
// ``` JavaScript
|
||||
webView.on(webViewModule.WebView.loadFinishedEvent, function (args: webViewModule.LoadEventData) {
|
||||
// <hide>
|
||||
if (webView.ios) {
|
||||
actualHtml = webView.ios.stringByEvaluatingJavaScriptFromString("document.body.innerHTML").trim();
|
||||
} else if (webView.android) {
|
||||
actualTitle = webView.android.getTitle()
|
||||
}
|
||||
|
||||
actualError = args.error;
|
||||
testFinished = true;
|
||||
// </hide>
|
||||
var message;
|
||||
if (!args.error) {
|
||||
message = "WebView finished loading " + args.url;
|
||||
}
|
||||
else {
|
||||
message = "Error loading " + args.url + ": " + args.error;
|
||||
}
|
||||
//console.log(message);
|
||||
});
|
||||
webView.src = "~/ui/web-view/test.html";
|
||||
|
||||
TKUnit.wait(4);
|
||||
|
||||
helper.goBack();
|
||||
|
||||
if (testFinished) {
|
||||
if (webView.ios) {
|
||||
TKUnit.assert(actualHtml === expectedHtml, "File ~/ui/web-view/test.html not loaded properly. Actual: " + actualHtml);
|
||||
} else if (webView.android) {
|
||||
TKUnit.assert(actualTitle === expectedTitle, "File ~/ui/web-view/test.html not loaded properly. Actual: " + actualTitle);
|
||||
}
|
||||
TKUnit.assert(actualError === undefined, actualError);
|
||||
}
|
||||
else {
|
||||
TKUnit.assert(false, "TIMEOUT");
|
||||
}
|
||||
}
|
||||
|
||||
export var testLoadHTMLString = function () {
|
||||
var newPage: page.Page;
|
||||
var webView = _createWebViewFunc();
|
||||
var pageFactory = function (): page.Page {
|
||||
newPage = new page.Page();
|
||||
newPage.content = webView;
|
||||
return newPage;
|
||||
};
|
||||
|
||||
helper.navigate(pageFactory);
|
||||
|
||||
var testFinished = false;
|
||||
var actualHtml;
|
||||
var actualTitle;
|
||||
var actualError;
|
||||
|
||||
var expectedTitle = 'MyTitle';
|
||||
var expectedHtml = '<span style="color:red">Test</span>';
|
||||
|
||||
// <snippet module="ui/web-view" title="WebView">
|
||||
// ### Using WebView
|
||||
// ``` JavaScript
|
||||
webView.on(webViewModule.WebView.loadFinishedEvent, function (args: webViewModule.LoadEventData) {
|
||||
// <hide>
|
||||
if (webView.ios) {
|
||||
actualHtml = webView.ios.stringByEvaluatingJavaScriptFromString("document.body.innerHTML").trim();
|
||||
} else if (webView.android) {
|
||||
actualTitle = webView.android.getTitle()
|
||||
}
|
||||
|
||||
actualError = args.error;
|
||||
testFinished = true;
|
||||
// </hide>
|
||||
var message;
|
||||
if (!args.error) {
|
||||
message = "WebView finished loading " + args.url;
|
||||
}
|
||||
else {
|
||||
message = "Error loading " + args.url + ": " + args.error;
|
||||
}
|
||||
//console.log(message);
|
||||
});
|
||||
webView.src = '<!DOCTYPE html><html><head><title>MyTitle</title><meta charset="utf-8" /></head><body><span style="color:red">Test</span></body></html>';
|
||||
|
||||
TKUnit.wait(4);
|
||||
|
||||
helper.goBack();
|
||||
|
||||
if (testFinished) {
|
||||
if (webView.ios) {
|
||||
TKUnit.assert(actualHtml === expectedHtml, "HTML string not loaded properly. Actual: " + actualHtml);
|
||||
} else if (webView.android) {
|
||||
TKUnit.assert(actualTitle === expectedTitle, "HTML string not loaded properly. Actual: " + actualTitle);
|
||||
}
|
||||
TKUnit.assert(actualError === undefined, actualError);
|
||||
}
|
||||
else {
|
||||
TKUnit.assert(false, "TIMEOUT");
|
||||
}
|
||||
}
|
||||
|
||||
export var testLoadInvalidUrl = function () {
|
||||
var newPage: page.Page;
|
||||
var webView = _createWebViewFunc();
|
||||
|
@ -7,6 +7,8 @@
|
||||
<TabViewItem.view>
|
||||
<StackLayout>
|
||||
|
||||
<WebView src="<html><body><span style='color:red'>Test</span></body></html>" />
|
||||
|
||||
<!--<ToolBar>
|
||||
<ToolBar.items>
|
||||
<ToolBarItem>
|
||||
|
@ -1,11 +1,9 @@
|
||||
import http = require("http");
|
||||
import types = require("utils/types");
|
||||
import utils = require("utils/utils");
|
||||
|
||||
// This is used for definition purposes only, it does not generate JavaScript for it.
|
||||
import definition = require("image-source");
|
||||
|
||||
var RESOURCE_PREFIX = "res://";
|
||||
|
||||
export function fromResource(name: string): definition.ImageSource {
|
||||
var image = new definition.ImageSource();
|
||||
return image.loadFromResource(name) ? image : null;
|
||||
@ -40,18 +38,12 @@ export function fromFileOrResource(path: string): definition.ImageSource {
|
||||
throw new Error("Path \"" + "\" is not a valid file or resource.");
|
||||
}
|
||||
|
||||
if (path.indexOf(RESOURCE_PREFIX) === 0) {
|
||||
return fromResource(path.substr(RESOURCE_PREFIX.length));
|
||||
if (path.indexOf(utils.RESOURCE_PREFIX) === 0) {
|
||||
return fromResource(path.substr(utils.RESOURCE_PREFIX.length));
|
||||
}
|
||||
return fromFile(path);
|
||||
}
|
||||
|
||||
export function isFileOrResourcePath(path: string): boolean {
|
||||
if (!types.isString(path)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return path.indexOf("~/") === 0 || // relative to AppRoot
|
||||
path.indexOf("/") === 0 || // absolute path
|
||||
path.indexOf(RESOURCE_PREFIX) === 0; // resource
|
||||
return utils.isFileOrResourcePath(path);
|
||||
}
|
2
image-source/image-source.d.ts
vendored
2
image-source/image-source.d.ts
vendored
@ -118,7 +118,7 @@ declare module "image-source" {
|
||||
export function fromFileOrResource(path: string): ImageSource;
|
||||
|
||||
/**
|
||||
* Returns true if the specified path points to a resource or local file.
|
||||
* [Obsolete. Please use utils.isFileOrResourcePath instead!] Returns true if the specified path points to a resource or local file.
|
||||
* @param path The path.
|
||||
*/
|
||||
export function isFileOrResourcePath(path: string): boolean
|
||||
|
@ -22,11 +22,31 @@ function onUrlPropertyChanged(data: dependencyObservable.PropertyChangeData) {
|
||||
// register the setNativeValue callback
|
||||
(<proxy.PropertyMetadata>urlProperty.metadata).onSetNativeValue = onUrlPropertyChanged;
|
||||
|
||||
var srcProperty = new dependencyObservable.Property(
|
||||
"src",
|
||||
"WebView",
|
||||
new proxy.PropertyMetadata("")
|
||||
);
|
||||
|
||||
function onSrcPropertyChanged(data: dependencyObservable.PropertyChangeData) {
|
||||
var webView = <WebView>data.object;
|
||||
|
||||
if (webView._suspendLoading) {
|
||||
return;
|
||||
}
|
||||
|
||||
webView._loadSrc(data.newValue);
|
||||
}
|
||||
|
||||
// register the setNativeValue callback
|
||||
(<proxy.PropertyMetadata>srcProperty.metadata).onSetNativeValue = onSrcPropertyChanged;
|
||||
|
||||
export class WebView extends view.View implements definition.WebView {
|
||||
public static loadStartedEvent = "loadStarted";
|
||||
public static loadFinishedEvent = "loadFinished";
|
||||
|
||||
public static urlProperty = urlProperty;
|
||||
public static srcProperty = srcProperty;
|
||||
|
||||
public _suspendLoading: boolean;
|
||||
|
||||
@ -42,6 +62,14 @@ export class WebView extends view.View implements definition.WebView {
|
||||
this._setValue(WebView.urlProperty, value);
|
||||
}
|
||||
|
||||
get src(): string {
|
||||
return this._getValue(WebView.srcProperty);
|
||||
}
|
||||
|
||||
set src(value: string) {
|
||||
this._setValue(WebView.srcProperty, value);
|
||||
}
|
||||
|
||||
public _onLoadFinished(url: string, error?: string) {
|
||||
|
||||
this._suspendLoading = true;
|
||||
@ -73,6 +101,10 @@ export class WebView extends view.View implements definition.WebView {
|
||||
throw new Error("This member is abstract.");
|
||||
}
|
||||
|
||||
public _loadSrc(src: string) {
|
||||
throw new Error("This member is abstract.");
|
||||
}
|
||||
|
||||
get canGoBack(): boolean {
|
||||
throw new Error("This member is abstract.");
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
import common = require("ui/web-view/web-view-common");
|
||||
import trace = require("trace");
|
||||
import utils = require("utils/utils");
|
||||
import fs = require("file-system");
|
||||
|
||||
declare var exports;
|
||||
require("utils/module-merge").merge(common, exports);
|
||||
@ -74,6 +76,31 @@ export class WebView extends common.WebView {
|
||||
this._android.loadUrl(url);
|
||||
}
|
||||
|
||||
public _loadSrc(src: string) {
|
||||
trace.write("WebView._loadSrc(" + src + ")", trace.categories.Debug);
|
||||
|
||||
this._android.stopLoading();
|
||||
this._android.loadUrl("about:blank");
|
||||
|
||||
if (utils.isFileOrResourcePath(src)) {
|
||||
|
||||
if (src.indexOf("~/") === 0) {
|
||||
src = fs.path.join(fs.knownFolders.currentApp().path, src.replace("~/", ""));
|
||||
}
|
||||
|
||||
var file = fs.File.fromPath(src);
|
||||
if (file) {
|
||||
file.readText().then((r) => {
|
||||
this._android.loadData(r, "text/html", null);
|
||||
});
|
||||
}
|
||||
} else if (src.indexOf("http://") === 0 || src.indexOf("https://") === 0) {
|
||||
this._android.loadUrl(src);
|
||||
} else {
|
||||
this._android.loadData(src, "text/html", null);
|
||||
}
|
||||
}
|
||||
|
||||
get canGoBack(): boolean {
|
||||
return this._android.canGoBack();
|
||||
}
|
||||
|
7
ui/web-view/web-view.d.ts
vendored
7
ui/web-view/web-view.d.ts
vendored
@ -36,10 +36,15 @@ declare module "ui/web-view" {
|
||||
ios: UIWebView;
|
||||
|
||||
/**
|
||||
* Gets or sets the url displayed by this instance.
|
||||
* [Obsolete. Please use src instead!] Gets or sets the url displayed by this instance.
|
||||
*/
|
||||
url: string;
|
||||
|
||||
/**
|
||||
* Gets or sets the url, local file path or HTML string.
|
||||
*/
|
||||
src: string;
|
||||
|
||||
/**
|
||||
* Gets a value indicating whether the WebView can navigate back.
|
||||
*/
|
||||
|
@ -1,5 +1,7 @@
|
||||
import common = require("ui/web-view/web-view-common");
|
||||
import trace = require("trace");
|
||||
import utils = require("utils/utils");
|
||||
import fs = require("file-system");
|
||||
|
||||
declare var exports;
|
||||
require("utils/module-merge").merge(common, exports);
|
||||
@ -17,16 +19,16 @@ class UIWebViewDelegateImpl extends NSObject implements UIWebViewDelegate {
|
||||
this._owner = owner;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public webViewShouldStartLoadWithRequestNavigationType(webView: UIWebView, request: NSURLRequest, navigationType: number) {
|
||||
if (request.URL) {
|
||||
trace.write("UIWebViewDelegateClass.webViewShouldStartLoadWithRequestNavigationType(" + request.URL.absoluteString + ", " + navigationType + ")", trace.categories.Debug);
|
||||
this._owner._onLoadStarted(request.URL.absoluteString);
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public webViewDidStartLoad(webView: UIWebView) {
|
||||
trace.write("UIWebViewDelegateClass.webViewDidStartLoad(" + webView.request.URL + ")", trace.categories.Debug);
|
||||
}
|
||||
@ -81,6 +83,32 @@ export class WebView extends common.WebView {
|
||||
this._ios.loadRequest(NSURLRequest.requestWithURL(NSURL.URLWithString(url)));
|
||||
}
|
||||
|
||||
public _loadSrc(src: string) {
|
||||
trace.write("WebView._loadSrc(" + src + ")", trace.categories.Debug);
|
||||
|
||||
if (this._ios.loading) {
|
||||
this._ios.stopLoading();
|
||||
}
|
||||
|
||||
if (utils.isFileOrResourcePath(src)) {
|
||||
|
||||
if (src.indexOf("~/") === 0) {
|
||||
src = fs.path.join(fs.knownFolders.currentApp().path, src.replace("~/", ""));
|
||||
}
|
||||
|
||||
var file = fs.File.fromPath(src);
|
||||
if (file) {
|
||||
file.readText().then((r) => {
|
||||
this._ios.loadHTMLStringBaseURL(r, null);
|
||||
});
|
||||
}
|
||||
} else if (src.indexOf("http://") === 0 || src.indexOf("https://") === 0) {
|
||||
this._ios.loadRequest(NSURLRequest.requestWithURL(NSURL.URLWithString(src)));
|
||||
} else {
|
||||
this._ios.loadHTMLStringBaseURL(src, null);
|
||||
}
|
||||
}
|
||||
|
||||
get canGoBack(): boolean {
|
||||
return this._ios.canGoBack;
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
import types = require("utils/types");
|
||||
|
||||
export var RESOURCE_PREFIX = "res://";
|
||||
|
||||
export function copyFrom(source: any, target: any) {
|
||||
if (types.isDefined(source) && types.isDefined(target)) {
|
||||
var i: number;
|
||||
@ -50,4 +52,14 @@ export module layout {
|
||||
export function getMeasureSpecSize(spec: number): number {
|
||||
return (spec & ~MODE_MASK);
|
||||
}
|
||||
}
|
||||
|
||||
export function isFileOrResourcePath(path: string): boolean {
|
||||
if (!types.isString(path)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return path.indexOf("~/") === 0 || // relative to AppRoot
|
||||
path.indexOf("/") === 0 || // absolute path
|
||||
path.indexOf(RESOURCE_PREFIX) === 0; // resource
|
||||
}
|
8
utils/utils.d.ts
vendored
8
utils/utils.d.ts
vendored
@ -2,6 +2,8 @@
|
||||
import colorModule = require("color");
|
||||
import view = require("ui/core/view");
|
||||
|
||||
export var RESOURCE_PREFIX: string;
|
||||
|
||||
/**
|
||||
* Utility module related to layout.
|
||||
*/
|
||||
@ -132,4 +134,10 @@
|
||||
* An utility function that invokes garbage collection on the JavaScript side.
|
||||
*/
|
||||
export function GC();
|
||||
|
||||
/**
|
||||
* Returns true if the specified path points to a resource or local file.
|
||||
* @param path The path.
|
||||
*/
|
||||
export function isFileOrResourcePath(path: string): boolean
|
||||
}
|
||||
|
Reference in New Issue
Block a user