Dynamically add a WebComponent in Dart? - dart

I was attempting to follow the code found here:
component_created_in_code_test.html
component_created_in_code.dart
However, when I get the dependencies and run the code in dartium, I get the following error. This error occurs when calling the create() method of ComponentItem (in the .dart code):
Breaking on exception: Class 'SayHello' has no instance method 'created_autogenerated'.
I rewrote them ever so slightly below (code is identical except main has been moved to be dart code rather than inlined):
<!-- component_created_in_code_test.html -->
<!doctype html>
<!--
Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
for details. All rights reserved. Use of this source code is governed by a
BSD-style license that can be found in the LICENSE file.
-->
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<script src="packages/web_ui/testing/testing.js"></script>
</head>
<body>
<element name="say-hello">
<template>Hello {{name}}!</template>
<script type='application/dart' src="component_created_in_code.dart">
</script>
</element>
<say-hello name="component create in html"></say-hello>
</body>
</html>
and the following dart code,
//component_created_in_code.dart
library component_created_in_code;
import 'dart:async';
import 'dart:html';
import 'package:web_ui/web_ui.dart';
class SayHello extends WebComponent {
String name;
}
void main() {
Timer.run(() {
var hello = new SayHello()
..host = new DivElement()
..name = 'component created in code';
// "hello" is the DOM node.
// "hello.xtag" is your SayHello object.
// We are working on making these be the same object.
// If the component uses data-binding, we need to make sure the
// "lifecycle" methods get called. We are working to make this be
// automatic too.
var lifecycleCaller = new ComponentItem(hello)..create();
document.body.nodes.add(hello.host);
lifecycleCaller.insert();
window.postMessage('done', '*');
});
}
It would appear that this dart-lang example has a problem. Am I missing something or is the code just borked?
After getting this question answered, I packaged up the working solution to the problem.
component_created_in_code
Simply pull from git, and then import into dartEditor. Then 'pub install' and 'reanalyze source' (never hurts) from the editor, then right click "Run in Dartium" on "web/component_created_in_code.html".

It sounds like you need to run the Web UI compiler first. Either run packages/web_ui/dwc.dart on your HTML file, or write a build.dart along these lines:
import 'dart:io';
import 'package:web_ui/component_build.dart';
void main() {
build(new Options().arguments, ['web/component_created_in_code_test.html']);
}

I tested the same with build 0.5.13_r23552 editor & SDK and run into the same problem when running in Dartium. If I do the dart2js (Run as Javascript/Generate javascript) however, it works.
However, be aware of the following (based on my experience):
Try to change to the SDK version that it has been tested and verified with.
It seems the tests are updated to run with 0.5.15; while the SDK delivered with the editor on the dartlang site is only 0.5.13. Maybe clone the bleeding edge version to make it work?
Dart is constantly evolved. Always do pub update on your project after updating to the newest editor, if you are using dependencies and not a specific library version.
Add the build.dart to your project to make sure that code is generated on changes (See bottom of this page: Build.dart setup)

Related

invokescriptasync HRESULT: 0x80020101' script runs fine in chrome and IE

I'm still trying to make the invokescriptasync work. I'm trying the following test on facebook.com and it fails with a HRESULT: 0x80020101' which normally means the script has an error in it, but I tried running the simple javascript in Chrome and IE without any problem.
private async void WebView_OnNavigationCompleted(WebView sender, WebViewNavigationCompletedEventArgs args)
{
await _webView.InvokeScriptAsync("eval", new[]
{
"document.getElementById('blueBarDOMInspector').innerHTML = '';"
});
}
Thanks
I have tested your code and the error is thrown only in case the blueBarDOMInspector is not found. I used the following simple HTML:
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head></head>
<body>
<p id="blueBarDOMInspector"></p>
</body>
</html>
You can confirm that the script works as expected with this HTML. So I suspect the problem is rather on HTML side than on side of UWP.
As for ScriptNotify not working - the website must be HTTPS and be added as trusted to appxmanifest. Better solution is web allowed object. A great example was posted in a question yesterday on SO or here as a sample project. Basically you have to create a Windows Runtime Component with a class marked as [WebAllowed] and then inject it in the WebView using AddWebAllowedObject method.
For your invoking JavaScript code issue,I've checked your code, it's simple, the possible issue might be the 'blueBarDOMInspector' object, please make sure that you could get the 'blueBarDOMInspector' object successfully when the OnNavigationCompleted is fired.
For your second question:
I can invoke the script : "window.external.notify('something');" but it doesn't raise the event ScriptNotify which is another problem :-(
Please check the document:
To enable an external web page to fire the ScriptNotify event when calling window.external.notify, you must include the page's Uniform Resource Identifier (URI) in the ApplicationContentUriRules section of the app manifest.

Script tags to embed Dart into HTML

Normally Dart is connected to HTML by means of this code:
<script type="application/dart" src="script.dart"></script>
<script src="packages/browser/dart.js"></script>
By running Build, IntellijIdea transforms the first line into <script src="script.dart.js"> and eliminates the second line, OK. But there are some problems to me:
After Build file has been created, my indentation is broken.
Google PageSpeed Insight test says "Too much http requests", or something like that.
I solved the problem this way. No Build file anymore, I use Dart2js + Terminal to create script.dart.js. As to the HTML code, I've written this little thing below instead.
<script type="application/dart" src="script.dart" id="dart-script"></script>
<script>
(function() {
if (navigator.userAgent.indexOf('(Dart)') === -1) {
var dartScript = document.querySelector('#dart-script');
dartScript.type = 'application/javascript';
dartScript.src = 'script.dart.js';
}
})();
</script>
It works very well. What do you think of it?
I haven't heard of any such problems with the Dart script tags.
Using the transformer of https://pub.dartlang.org/packages/dart_to_js_script_rewriter
removes the Dart script tag which is only required by browsers that support Dart directly, which is only Dartium, which is not supposed to be used to access the web (only for development purposes), therefore for deployment this script tag is irrelevant.
Dart plugin is the same in IntelliJ IDEA, WebStorm and other JetBrains' IDEs. And it doesn't do anything with your source code on build, it only calls pub build as if you ran it from command line (assume you are talking about 'Pub: build' action in context of pubspec.yaml file).
I'll stop here my delirium with this new polyvalent code of my own.
<script>
(function() {
var elem = document.createElement('script');
document.querySelector('body').appendChild(elem);
if (navigator.userAgent.indexOf('(Dart)') === -1) {
elem.type = 'application/javascript';
elem.src = 'script.dart.js';
}
else {
elem.type = 'application/dart';
elem.src = 'script.dart';
}
})();
</script>
Thank you for applause, that's all folks!

Can't get Library in Dart to work properly

I have some files and I want them in one library. But it just doesnt work or throws Exceptions.
Let's say I have these files.
Lib.dart, 1.dart, 2.dart, 3.dart and for each of them also an html file, which defines the polymer element.
// Lib.dart
library testLib;
import 'dart:html';
part '1.dart';
part '2.dart';
part '3.dart';
/* ... Code ... */
and
// 1.dart 2.dart and 3.dart
part of testLib;
/* ... Code ... */
It didnt work and i got the message:
'http://localhost:8080/1.dart': error: line 7 pos 6: url expected
part of testLib;
^: http://localhost:8080/1.dart
So I saw this answer: Dart editor: expected url
and I changed my 1.html, 2.html and 3.html to:
// 1.html, 2.html and 3.html
/* ... */
<script type="application/dart" src="Lib.dart"></script>
But now i get this Exception:
Breaking on exception: Already registered (Polymer) prototype for element my-Lib
I dont know why it does not work or what I did wrong there.
I wonder why your part of is on line 7. Do you have a library statement or imports or other code above par of? You can only have comments before part of.
As far as I know currently there is still the limitation that you should have one library for one polymer element.

Missing definition for <polymer-element> core-overlay

I noticed this when I run my dart app both with 1.7.0-dev4.3 and dev-4.1
Missing definition for <polymer-element>, please add the following HTML import at the top of this file: <link rel="import" href="../../../../packages/polymer/polymer.html">. (more details)
lib/src/core-overlay/core-overlay-layer.html:10:1
<polymer
-element name="core-overlay-layer">
I have not used any core-overlay-layer in my app so far and this seems to be one of the polymer-core components.
I have just done a clean install of the latest Dart dev SDK with the same result.

Link rel='import' breaks Router

I'm experimenting with dart-polymer apps and have run into a few issues.
Is there a way to inject template declaration of a custom element through code? The docs currently specify the following method:
<link rel="import" href="my_element.html">
I'm trying to use the Route package (specifically 'package:route/client.dart'), and importing an html module via this method seems to break the router, so:
main() {
var router = new Router()
..addHandler(homeUrl, showHome)
..addHandler(signinUrl, showSignin)
..listen();
}
fails to execute the handlers when I navigate to the Url specified. If I remove the html import, the Router works fine.
Any way around this?

Resources