Skip to content

Commit

Permalink
Convert to static fields
Browse files Browse the repository at this point in the history
  • Loading branch information
jridgewell committed Jan 14, 2020
1 parent 8023b82 commit 7e74e2e
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 75 deletions.
40 changes: 16 additions & 24 deletions extensions/amp-date-display/0.2/amp-date-display.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,31 +28,7 @@ import {userAssert} from '../../../src/log';
/** @const {string} */
const TAG = 'amp-date-display';

const props = {
'displayIn': {attr: 'display-in'},
'offsetSeconds': {attr: 'offset-seconds', type: 'number'},
'locale': {attr: 'locale'},
'datetime': {attr: 'datetime'},
'timestampMs': {attr: 'timestamp-ms', type: 'number'},
'timestampSeconds': {attr: 'timestamp-seconds', type: 'number'},
};

class AmpDateDisplay extends PreactBaseElement {
/** @override */
static Component() {
return DateDisplay;
}

/** @override */
static passthrough() {
return true;
}

/** @override */
static props() {
return props;
}

/** @override */
init() {
const templates = Services.templatesFor(this.win);
Expand Down Expand Up @@ -100,6 +76,22 @@ class AmpDateDisplay extends PreactBaseElement {
}
}

/** @override */
AmpDateDisplay.Component = DateDisplay;

/** @override */
AmpDateDisplay.passthrough = true;

/** @override */
AmpDateDisplay.props = {
'displayIn': {attr: 'display-in'},
'offsetSeconds': {attr: 'offset-seconds', type: 'number'},
'locale': {attr: 'locale'},
'datetime': {attr: 'datetime'},
'timestampMs': {attr: 'timestamp-ms', type: 'number'},
'timestampSeconds': {attr: 'timestamp-seconds', type: 'number'},
};

AMP.extension(TAG, '0.2', AMP => {
AMP.registerElement(TAG, AmpDateDisplay);
});
99 changes: 48 additions & 51 deletions src/preact/base-element.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,52 +81,6 @@ export class PreactBaseElement extends AMP.BaseElement {
this.mounted_ = true;
}

/**
* Override to provide the Component definition.
*
* @return {!Preact.FunctionalComponent}
*/
static Component() {
devAssert(false, 'Must provide Component');
return () => null;
}

/**
* An override to specify an exact className prop to Preact.
*
* @return {string}
*/
static className() {
return '';
}

/**
* Enabling passthrough mode alters the children slotting to use a single
* `<slot>` element for all children. This is in contrast to children mode,
* which creates a new named `<slot>` for every child.
*
* @return {boolean}
*/
static passthrough() {
return false;
}

/**
* Provides a mapping of Preact prop to AmpElement DOM attributes.
*
* @return {!Object<string, !AmpElementPropDef>}
*/
static props() {
return {};
}

/**
* @return {!Object<string, !ChildDef>|null}
*/
static children() {
return null;
}

/**
* A chance to initialize default Preact props for the element.
*
Expand Down Expand Up @@ -217,7 +171,7 @@ export class PreactBaseElement extends AMP.BaseElement {
// While this "creates" a new element, diffing will not create a second
// instance of Component. Instead, the existing one already rendered into
// this element will be reused.
const cv = createElement(Ctor.Component(), props);
const cv = createElement(Ctor.Component, props);

const v = createElement(withAmpContext, this.context_, cv);

Expand All @@ -231,6 +185,45 @@ export class PreactBaseElement extends AMP.BaseElement {
}
}

// Ideally, these would be Static Class Fields. But Closure can't even.

/**
* Override to provide the Component definition.
*
* @protected {!Preact.FunctionalComponent}
*/
PreactBaseElement.Component = function() {
devAssert(false, 'Must provide Component');
};

/**
* An override to specify an exact className prop to Preact.
*
* @protected {string}
*/
PreactBaseElement.className = '';

/**
* Enabling passthrough mode alters the children slotting to use a single
* `<slot>` element for all children. This is in contrast to children mode,
* which creates a new named `<slot>` for every child.
*
* @protected {boolean}
*/
PreactBaseElement.passthrough = false;

/**
* Provides a mapping of Preact prop to AmpElement DOM attributes.
*
* @protected {!Object<string, !AmpElementPropDef>}
*/
PreactBaseElement.props = {};

/**
* @protected {!Object<string, !ChildDef>|null}
*/
PreactBaseElement.children = null;

/**
* @param {typeof PreactBaseElement} Ctor
* @param {!AmpElement} element
Expand All @@ -240,14 +233,19 @@ export class PreactBaseElement extends AMP.BaseElement {
function collectProps(Ctor, element, defaultProps) {
const props = /** @type {!JsonObject} */ ({...defaultProps});

const {
className,
props: propDefs,
passthrough,
children: childrenDefs,
} = Ctor;

// Class.
const className = Ctor.className();
if (className) {
props['className'] = className;
}

// Props.
const propDefs = Ctor.props();
for (const name in propDefs) {
const def = propDefs[name];
const value = element.getAttribute(def.attr);
Expand All @@ -271,8 +269,7 @@ function collectProps(Ctor, element, defaultProps) {
// as separate properties. Thus in a carousel the plain "children" are
// slides, and the "arrowNext" children are passed via a "arrowNext"
// property.
const childrenDefs = Ctor.children();
if (Ctor.passthrough()) {
if (passthrough) {
devAssert(
!childrenDefs,
'only one of "passthrough" or "children" may be given'
Expand Down

0 comments on commit 7e74e2e

Please sign in to comment.