dart clipboardData always null - dart

The following
main.html
<!DOCTYPE html>
<html>
<head>
<title>test</title>
</head>
<body>
<p id="test" draggable="true">hello world</p>
<script type="application/dart" src="main.dart"></script>
<!-- for this next line to work, your pubspec.yaml file must have a dependency on 'browser' -->
<script src="packages/browser/dart.js"></script>
</body>
</html>
and main.dart
import 'dart:html';
void main() {
var elem = query('#test');
elem.onDragStart.listen((evt) {
evt.clipboardData.setData('text/html', elem.innerHtml);
});
}
are producing the exception
The null object does not have a method 'setData'.
NoSuchMethodError : method not found: 'setData'
Receiver: null
Arguments: ["text/html", "hello world"]
I've searched, but can find no relevant information about what I could possibly be doing wrong, or about clipboardData in dart at all (even the API is silent on the issue, and the source dart:html file just points to "native code"

(From my comment to the original question)
Use this instead:
evt.dataTransfer.setData('text/html', elem.innerHtml);
It is an attribute on MouseEvent (api ref) rather than the base Event class, and you can get autocomplete and remove editor warnings by explicitly declaring that evt is of type MouseEvent:
elem.onDragStart.listen((MouseEvent evt) {
evt.dataTransfer.setData('text/html', elem.innerHtml);
});

clipboardData seems to have been deprecated without warning. In web_ui components (where I first observed this), the dataTransfer attribute is not recognised by the editor as a valid attribute on instances of Event. I can't find any reference on the web as to why this change was made (the API docs don't say anything on the matter and I couldn't find any recent posts on the discussion board)...

Related

Access the DOM in Dart unit tests

I am trying to write a test for the Pirate Badge tutorial thats meant to get people started using Dart.
I have the following directory structure:
The code in 6-piratebadge is an untouched version of what comes in the tutorial.
What I have added is the test package.
test/test.html contains:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<script type="application/dart" src="test.dart"></script>
<script type="text/javascript" src="packages/unittest/test_controller.js"></script>
</body>
</html>
and test/test.dart contains:
import 'package:unittest/unittest.dart';
import 'package:unittest/html_config.dart';
import 'dart:html';
import '../6-piratebadge/piratebadge.dart' as app;
void main() {
useHtmlConfiguration();
app.main();
var button = querySelector("#generateButton");
test('button text', (){
expect(button.text, equals('Aye! Gimme a name!'));
});
}
I run the test like this, from the directory above web:
Content\ Shell web/test/test.html
And I get "Error: Script error." (I am deliberately not using --dump-render-tree so I can inspect the output in the console of the launched browser). The essence of it seems to be this message:
5500:1287:0827/110337:24546692395575:INFO:CONSOLE(0)] "Exception: The null object does not have a getter 'onInput'.
NoSuchMethodError: method not found: 'onInput'
Receiver: null
Arguments: []", source: file:///Users/mikehogan/projects/learning/one-hour-codelab-master/web/6-piratebadge/piratebadge.dart (0)
This is occurring on in these lines of the piratebadge.dart:
void main() {
InputElement inputField = querySelector('#inputName');
inputField.onInput.listen(updateBadge);
So I guess the input with ID "inputName" is not being found.
Its is in piratebadge.html though:
<div>
<input type="text" id="inputName" maxlength="15" disabled>
</div>
Any idea what I am doing wrong?
piratebadge.html is only a file in the same package but not related to your unit test in any way.
'#inputName' wasn't found because the test.html file doesn't contain it.
You can try attempts discussed in this question DART - exception in unit testing

Polymer.dart not loading when compiled to JavaScript

I am experiencing some very odd problems with Polymer.dart when compiled to javascript. It works fine in Dartium. This app did work a couple of months ago. However Polymer has undergone lots of changes since then, so I have had to make loads of changes just to get it to compile. I have tried this in polymer 3.2 through to the latest build in pub, all behave the same. I am running an up to date Dart install on the stable branch.
I get the following Javascript error:
TypeError: $document.register is not a function
On the last line of the js below. The tag variable is "polymer-element".
})(H.convertDartClosureToJS(W._callAttributeChanged$closure(), 4)))};
proto = Object.create(baseConstructor.prototype, properties);
t2 = H.makeLeafDispatchRecord(interceptor);
Object.defineProperty(proto, init.dispatchPropertyName, {value: t2, enumerable: false, writable: true, configurable: true});
options = {prototype: proto};
if (!t1)
options.extends = extendsTagName;
$document.register(tag, options);
From what I can see the polyfills aren't loading so the document.register method hasn't been declared.
Below is from my HTML File
<head>
<script src="index.dart" type="application/dart"></script>
<script src="packages/browser/dart.js"></script>
<script src="packages/browser/interop.js"></script>
</head>
My index.dart looks like
void main() {
window.alert("Dart Lives!");
initPolymer().run(() => initPresentation());
}
void initPresentation() {
//Show the first screen
}
When running under Javascript I get the alert box showing followed by the Javascript error. So I don't think there is anything wrong with the basic dart environment.
EDIT
This has changed.
An up-to-date answer is here
Polymer querySelector working on DartVM but not in Chrome after compile
OLD
Hard to tell.
I think index.dart should look like
<head>
<script type='application/dart'>
export 'index.dart';
</script>
</head>
or
<body>
...
<script type='application/dart' src='index.dart'></script>
</body>
see https://code.google.com/p/dart/issues/detail?id=17546#c16

Repeating over a list Polymer broken

Update: problem with bleeding edge editor not being compatible with the version of serialization/polymer on pub. Need to install versions from SVN.
Repeating over a list appears to have been broken to me.
https://github.com/sethladd/dart-polymer-dart-examples/blob/master/web/bind_and_repeat_over_list_of_primitives/
This is the simplest example I could find and I get the same error:
Internal error: 'package:serialization/src/serialization_helpers.dart': Error: line 212 pos 7: unresolved implicit call to super constructor 'LinkedHashMap()'
class IdentityMap extends LinkedHashMap {
^
Probably this update from #dartlang 10 Sep 2013 :-
'New Dart release with search improvements in Editor, and more.
SDK changes include:
HashMap and LinkedHashmap cannot be extended anymore......'
Looks as though Polymer needs updating for this.
You can modify the code slightly and make it work.
Change the index.html file to look like this:
<!DOCTYPE html>
<html>
<head>
<title>index</title>
<script src="packages/polymer/boot.js"></script>
</head>
<body>
<ul>
<template id="tmpl" bind>
<template repeat="{{}}">
<li>{{}}</li>
</template>
</template>
</ul>
<script type="application/dart" src="index.dart"></script>
</body>
</html>
And your index.dart should look like this (it is unchanged):
import 'dart:html';
main() {
List fruits = ['apples', 'oranges', 'pears'];
query('#tmpl').model = fruits;
}
You bind to a template that contains the template where the repeat is registered. the {{}} in repeat="{{}}"refers to the bound value. The {{}} in the <li>{{}}</li> refers to each item in the list.
Hope this helps.

Simple Dart Web Component Not Working

Short Version: The custom web component example in the first link isn't working for me. Why not? I'm running this in Dartium.
Long Version:
I copied and pasted this Dart Web UI example from this tutorial into the Dart Editor and tried to run it. Nothing showed up on the page. I've used dart before but not with web components, so I noticed that one difference between this code and other code I've written is that there was no <script src="packages/browser/dart.js"></script>, so I added that at the bottom. Now I got the error:
Internal error: Dart_Invoke: did not find top-level function 'main'.
I put a print statement in the main() function, and the text was printed before the error, which is strange. I guessed and tried adding main() {} inside the <script> tag that was in the custom component. That is, the script tag looked like:
<script type="application/dart">
import 'package:web_ui/web_ui.dart';
main() {print("in main in component");}
class CounterComponent extends WebComponent {
int count = 0;
void increment() { count++; }
}
</script>
Now that error goes away, and both print statements are printed, but nothing happens.
Here is the original tutorial code for your convenience:
<!DOCTYPE html>
<!--
Copyright (c) 2012, 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">
<link rel="stylesheet"
href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.1/css/bootstrap.css">
</head>
<body>
<element name="click-counter" constructor="CounterComponent" extends="div">
<template>
<button on-click="increment()">Click me</button>
<span>(click count: {{count}})</span>
</template>
<script type="application/dart">
import 'package:web_ui/web_ui.dart';
class CounterComponent extends WebComponent {
int count = 0;
void increment() { count++; }
}
</script>
</element>
<div class="well">
<div is="click-counter"></div>
</div>
<script type="application/dart">
main(){}
</script>
</body>
</html>
Web UI applications need to be "built" (usually by a script called build.dart in the project root, see this article for more details).
If I go to the Dart Editor, create a new test project using the wizard and selecting the Web Project (using the web_ui library) option, this creates the boilerplate including the build script.
Open up the html file and paste in the code from the github tutorial, replacing what is there already. When you save the file, the build.dart will be invoked, outputting the build version to /web/out/
Hit the run button, and the Dart Editor will open the app in Dartium (it knows to add /out/ to the URL).

When is the removed lifecycle method called for Dart web components?

Latest edit:
This is an open issue in web-ui: https://github.com/dart-lang/web-ui/issues/245
Previously:
I'm trying to figure out how to get removed() from the web component lifecycle methods to be called. Looking through the generated code for my below example, I see there's a call to autogenerated.dispatch(); after replaceElement() which I hoped would be what calls removed(), but I don't see my print statement output.
Maybe related: I glanced through the spec trying to understand what the output of build.dart is doing for the lifecycle methods. Perhaps the spec is out of date? I still don't see composeChildren() listed in the instantiation section of the spec (which is mentioned in this web-ui issue comment) even though composeChildren() gets called in the autogenerated code from build.dart.
The reason behind this question is my interest in a Dart webapp able to load and unload web components within a single parent html file programmatically (via the instantiation instructions in the spec), instead of having to declare web components in the html. I'm running with web_ui-0.2.11. Thanks!
webcomponent:
<!DOCTYPE html>
<html><body>
<element name="x-lifecycle-test" constructor="LifecycleTest" extends="div">
<template> {{foo}} </template>
<script type="application/dart">
import 'dart:html';
import 'package:web_ui/web_ui.dart';
var foo = "testing lifecycle methods";
class LifecycleTest extends WebComponent{
inserted() => print("inserted");
removed() => print("removed");
}
</script>
</element>
</body></html>
Parent html file:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"><title>Lifecycle</title>
<link rel="components" href="lifecycle_test.html">
</head>
<body>
<div>
<button on-click="replaceElement()">replace element</button>
</div>
<div id='holder'>
<x-lifecycle-test></x-lifecycle-test>
</div>
<script type="application/dart">
import 'dart:html';
void replaceElement() {
query('#holder').replaceWith(new DivElement()
..id = 'holder'
..text = 'replaced');
}
main() {}
</script>
<script type='text/javascript' src="https://dart.googlecode.com/svn/branches/bleeding_edge/dart/client/dart.js"></script>
</body>
</html>
Adding an answer here for completeness: web components are used in Dart using Polymer. When an instance of a custom element is removed from the DOM, the leftView life cycle method triggers. You can read more about this at https://www.dartlang.org/docs/tutorials/polymer-intro/#life-cycle-methods.

Resources