| <!-- |
| // Copyright 2015 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| --> |
| <import src="/gen/mojo/services/keyboard/public/interfaces/keyboard.mojom.sky" as="keyboard" /> |
| <import src="shell.sky" as="shell" /> |
| <import src="sky-element/sky-element.sky" as="SkyElement" /> |
| |
| <sky-element name="sky-input" attributes="value:string"> |
| <template> |
| <style> |
| :host { |
| display: flex; |
| border: 1px solid blue; |
| margin: 5px; |
| padding: 4px; |
| } |
| #control { |
| flex: 1; |
| align-self: center; |
| height: 1.2em; |
| white-space: nowrap; |
| overflow: hidden; |
| } |
| </style> |
| <div id="control" contenteditable |
| on-focus="handleFocus" |
| on-blur="handleBlur" |
| on-keydown="handleKeyDown">{{ value }}</div> |
| </template> |
| <script> |
| var keyboard = shell.connectToService("mojo:keyboard", keyboard.Keyboard); |
| module.exports = class extends SkyElement { |
| shadowRootReady() { |
| var control = this.shadowRoot.getElementById('control'); |
| var text = control.firstChild; |
| |
| var observer = new MutationObserver(function() { |
| // contenteditable might remove the text node, but we need to keep it |
| // since that's where the data binding is connected to. |
| if (!text.parentNode) |
| control.appendChild(text); |
| if (this.value == control.textContent) |
| return; |
| this.value = control.textContent; |
| this.dispatchEvent(new CustomEvent('change', { |
| bubbles: true, |
| })); |
| }.bind(this)); |
| |
| observer.observe(control, { |
| subtree: true, |
| characterData: true, |
| childList: true, |
| }); |
| } |
| handleKeyDown(event) { |
| // TODO(abarth): You can still get newlines if the user pastes them. |
| if (event.key == 0xD) |
| event.preventDefault(); |
| } |
| handleFocus(event) { |
| keyboard.show(); |
| } |
| handleBlur(event) { |
| keyboard.hide(); |
| } |
| }.register(); |
| </script> |
| </sky-element> |