Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(16)

Unified Diff: sky/framework/sky-element/element-registry.sky

Issue 856693002: Combine element registries from sky-binder and sky-element. (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | sky/framework/sky-element/sky-binder.sky » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sky/framework/sky-element/element-registry.sky
diff --git a/sky/framework/sky-element/element-registry.sky b/sky/framework/sky-element/element-registry.sky
new file mode 100644
index 0000000000000000000000000000000000000000..8af18534585bdf73d9fc6d40e9650b3b9c960ef3
--- /dev/null
+++ b/sky/framework/sky-element/element-registry.sky
@@ -0,0 +1,148 @@
+<!--
+// Copyright 2014 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="sky-binder.sky" as="binder" />
+<script>
+// TODO(esprehn): It would be nice if these were exposed by the platform so
+// the framework didn't need to hard code a list.
+var defaultAttributesNames = new Set([
+ 'accesskey',
+ 'alt',
+ 'as',
+ 'async',
+ 'class',
+ 'contenteditable',
+ 'crossorigin',
+ 'dir',
+ 'height',
+ 'href',
+ 'id',
+ 'is',
+ 'lang',
+ 'media',
+ 'name',
+ 'rel',
+ 'select',
+ 'sizes',
+ 'spellcheck',
+ 'src',
+ 'srcset',
+ 'style',
+ 'tabindex',
+ 'title',
+ 'type',
+ 'width',
+]);
+
+var attributeConverters = {
+ boolean: function(value) {
+ if (typeof value == 'string')
+ return value == 'true';
+ return !!value;
+ },
+ number: function(value) {
+ return Number(value);
+ },
+ string: function(value) {
+ if (value === null)
+ return '';
+ return String(value);
+ },
+};
+
+function eventHandlerCallback(event) {
+ var element = event.currentTarget;
+ var registration = getRegistration(element.localName);
+ var method = registration.eventHandlers.get(event.type);
+ var handler = element[method];
+ if (!(typeof handler == 'function')) {
+ throw new Error('Element ' + element.localName +
+ ' specifies invalid event handler "' + method + '"');
+ }
+ handler.call(element, event);
+}
+
+class ElementRegistration {
+ constructor(tagName) {
+ this.tagName = tagName;
+ this.attributes = new Map();
+ this.eventHandlers = new Map();
+ this.template = null;
+ Object.preventExtensions(this);
+ }
+
+ allowsAttribute(name) {
+ if (name.startsWith('data-'))
+ return true;
+ if (defaultAttributesNames.has(name))
+ return true;
+ if (this.attributes.has(name))
+ return true;
+ return false;
+ }
+
+ defineAttribute(name, type) {
+ var converter = attributeConverters[type];
+
+ if (!converter) {
+ console.error('Invalid attribute type "' + type + '", type must be one'
+ + ' of boolean, number or string.');
+ return;
+ }
+
+ this.attributes.set(name, converter);
+ }
+
+ synthesizeAttributes(prototype) {
+ this.attributes.forEach(function(converter, name) {
+ Object.defineProperty(prototype, name, {
+ get: function() {
+ return converter(this.getAttribute(name));
+ },
+ set: function(newValue) {
+ this.setAttribute(name, converter(newValue));
+ },
+ enumerable: true,
+ configurable: true,
+ });
+ });
+ }
+
+ addInstanceEventListeners(instance) {
+ for (var eventName of this.eventHandlers.keys()) {
+ instance.addEventListener(eventName, eventHandlerCallback);
+ }
+ }
+}
+
+var registrations = new Map();
+
+function registerElement(tagName) {
+ if (registrations.has(tagName))
+ throw new Error('tagName "' + tagName + '" registered twice.');
+ var registration = new ElementRegistration(tagName);
+ registrations.set(tagName, registration);
+ return registration;
+}
+
+function getRegistration(tagName) {
+ return registrations.get(tagName);
+}
+
+function checkAttribute(tagName, attrName) {
+ var registration = getRegistration(tagName);
+
+ if (!registration)
+ return defaultAttributesNames.has(attrName);
+
+ return registration.allowsAttribute(attrName);
+}
+
+module.exports = {
+ registerElement: registerElement,
+ getRegistration: getRegistration,
+ checkAttribute: checkAttribute,
+};
+</script>
« no previous file with comments | « no previous file | sky/framework/sky-element/sky-binder.sky » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698