Nik Graf
Nik Graf

Reputation: 3739

How to identify if my Polymer.dart Component is still the document.activeElement?

I have a CustomPassword component and want to provide a method isActive that allows you to retrieve if the component is still the active element on this website.

Example Code:

custom_password.html

<polymer-element name="custom-password">
  <template>
    <div>Other things here</div>
    <input id="password-field" type="password" value="{{value}}">
  </template>
  <script type="application/dart" src="custom_password.dart"></script>
</polymer-element>

custom_password.dart

import 'package:polymer/polymer.dart';

@CustomTag('custom-password')
class CustomPassword extends PolymerElement {

  @published
  String value;

  CustomPassword.created() : super.created() {
  }

  bool isActive() {
    // TODO figure out if the CustomPassword element is still active.
    return false;
  }
}

Upvotes: 4

Views: 200

Answers (2)

Nik Graf
Nik Graf

Reputation: 3739

With a help from the Polymer Group I was able to come up with a solution:

For browsers with shadow DOM support it works out of the box by comparing the hashCode of the document.activeElement with the components hashCode.

For browsers without shadow DOM support the password field will be the active element. The trick here is to wrap the document.activeElement in order to compare it to the wrapped passwordField.

Example:

custom_password.dart

import 'package:polymer/polymer.dart';
import 'dart:html';
import 'dart:js' as js;

@CustomTag('custom-password')
class CustomPassword extends PolymerElement {

  @published
  String value;

  CustomPassword.created() : super.created() {
  }

  bool isActive() {
      var passwordField = $['password-field'];
      var activeElement = js.context.callMethod('wrap', [document.activeElement]);

      // For Browsers with shadow DOM support the shadowRoot.host matches while
      // for Browsers without shadow DOM support the password field match.
      if (activeElement.hashCode != hashCode &&
          activeElement.hashCode != passwordField.hashCode) {
        return false;
      } else {
        return true;
      }
  }
}

Upvotes: 7

G&#252;nter Z&#246;chbauer
G&#252;nter Z&#246;chbauer

Reputation: 657486

bool isActive(event) {
  return document.activeElement == this;
}

This only works in browsers with native Shadow DOM support.
I haven't tested it but this probably only works when your <custom-password> element is in the light DOM and not inside the <template> of another polymer element like <app-element> if you use one.

The current polyfill seems not to work correctly and you get the input element back instead of the Polymer element.

These issues contains information about how activeElement works with Polymer elements
- https://github.com/Polymer/ShadowDOM/issues/478
- https://code.google.com/p/dart/issues/detail?id=18982
- https://code.google.com/p/dart/issues/detail?id=20165

and also this paragraph - http://www.w3.org/TR/shadow-dom/#active-element

Upvotes: 3

Related Questions