<!--
// 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 globalAttributesNames = new Set([
  'class',
  'contenteditable',
  'dir',
  'id',
  'lang',
  'spellcheck',
  'tabindex',
  'style',
]);

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 (globalAttributesNames.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, attributes) {
  if (registrations.has(tagName))
    throw new Error('tagName "' + tagName + '" registered twice.');
  var registration = new ElementRegistration(tagName);
  for (var name in attributes) {
    registration.defineAttribute(name, attributes[name]);
  }
  registrations.set(tagName, registration);
  return registration;
}

function getRegistration(tagName) {
  return registrations.get(tagName);
}

function checkAttribute(tagName, attrName) {
  var registration = getRegistration(tagName);

  if (!registration)
    return globalAttributesNames.has(attrName);

  return registration.allowsAttribute(attrName);
}

registerElement('img', {
  'width': 'number',
  'height': 'number',
  // TODO(esprehn): Sky probably doesn't want the crossorign attr.
  'crossorigin': 'string',
  'src': 'string',
});

registerElement('import', {
  'as': 'string',
  'src': 'string',
  'async': 'boolean',
});

registerElement('a', {
  'href': 'string',
  'async': 'boolean',
});

registerElement('content', {
  'select': 'string',
});

registerElement('style', {
  'media': 'string',
});

registerElement('template', {
  'if': 'string',
  'repeat': 'string',
});

module.exports = {
  registerElement: registerElement,
  getRegistration: getRegistration,
  checkAttribute: checkAttribute,
};
</script>
