Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ Initial PreactBaseElement #25969

Merged
merged 54 commits into from
Jan 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
fa39765
Add new rewrite-imports babel plugin
jridgewell Dec 20, 2019
4c77f96
Simplify ExportDeclaration visitor
jridgewell Dec 20, 2019
3d3c910
Copyright year
jridgewell Dec 20, 2019
664f7c2
Lint
jridgewell Dec 20, 2019
e86b29c
Simplify
jridgewell Dec 21, 2019
f73cb0c
use package.json field to resolve to module
jridgewell Dec 21, 2019
e6c3171
Fix issues with module compilation in single-pass
jridgewell Dec 21, 2019
dfe9e31
Just import from the full worker-dom source
jridgewell Dec 21, 2019
f5989ee
tmp
jridgewell Nov 18, 2019
5bd6187
tmp
jridgewell Nov 21, 2019
28f1c00
tmp
jridgewell Nov 22, 2019
211e217
tmp
jridgewell Nov 22, 2019
dec1edd
Import directly from preact
jridgewell Nov 25, 2019
3f021c8
Use amp-context notify to sync with Resource
jridgewell Dec 10, 2019
82e04cc
Tests
jridgewell Dec 10, 2019
4f6294f
Remove useless break
jridgewell Dec 11, 2019
680c14c
Fix types
jridgewell Dec 12, 2019
ab5e624
Fix defs naming clash
jridgewell Dec 12, 2019
eeec382
Use matches helper
jridgewell Dec 12, 2019
0e193cb
Update validator-amp-date-display.out
jridgewell Dec 12, 2019
7d17b1d
Update copyright year
jridgewell Dec 12, 2019
580d353
Undo example layout change
jridgewell Dec 13, 2019
b144a37
Reorder functions
jridgewell Dec 13, 2019
1702f7d
Remove getContextFromDom
jridgewell Dec 13, 2019
ae77710
Switch to using vsync system
jridgewell Dec 13, 2019
1fad3aa
Simplify preact utils
jridgewell Dec 13, 2019
7098f7f
Require experiment to be on
jridgewell Dec 16, 2019
cbb8f06
fix type
jridgewell Dec 17, 2019
5691d49
Use object-spread
jridgewell Dec 17, 2019
1d0aa97
Flip prop-attrs definition
jridgewell Dec 17, 2019
114a0c9
Separate dom-rendering concern from amp-date-display
jridgewell Dec 19, 2019
df0b668
Fix arguments
jridgewell Dec 19, 2019
ffebeb4
Add required useResourcesNotify
jridgewell Dec 19, 2019
92a4c8f
Fix tests
jridgewell Dec 19, 2019
fa3500d
Add preact modules to the sources list
jridgewell Dec 20, 2019
a21c7ab
Include preact package.json
jridgewell Dec 21, 2019
d25bb39
Fix name mangling of properties
jridgewell Jan 6, 2020
c0720cc
Split out Preact components into their own files
jridgewell Jan 7, 2020
3220352
Move PreactBaseElement into src/preact dir
jridgewell Jan 7, 2020
a939b65
Remove unused code
jridgewell Jan 7, 2020
2052f69
Update copyright years
jridgewell Jan 7, 2020
3d257f9
Types
jridgewell Jan 9, 2020
9ff0a7b
Remove unused imports
jridgewell Jan 9, 2020
c399cb0
Patch preact with types
jridgewell Jan 9, 2020
2280309
Fully type Preact API by using intermediate module
jridgewell Jan 9, 2020
24be8ef
Strengthen types
jridgewell Jan 9, 2020
b6a4bd1
Types and minification
jridgewell Jan 10, 2020
f1f2656
React tests
jridgewell Jan 10, 2020
d10ec85
Fix sinon imports
jridgewell Jan 10, 2020
a6eaf78
Rearrange methods
jridgewell Jan 11, 2020
9916714
Lint
jridgewell Jan 11, 2020
efdab25
Remove file
jridgewell Jan 11, 2020
e484395
Convert PreactBaseElement into a subclass-able subclass
jridgewell Jan 14, 2020
5b60af5
Convert to static fields
jridgewell Jan 14, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build-system/compile/bundles.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,7 @@ exports.extensionBundles = [
},
{
name: 'amp-date-display',
version: '0.1',
version: ['0.1', '0.2'],
latestVersion: '0.1',
type: TYPES.MISC,
},
Expand Down
3 changes: 2 additions & 1 deletion build-system/compile/check-for-unknown-deps.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

const log = require('fancy-log');
const through = require('through2');
const {red, cyan} = require('ansi-colors');
const {red, cyan, yellow} = require('ansi-colors');

/**
* Searches for the identifier "$$module$", which Closure uses to uniquely
Expand All @@ -44,6 +44,7 @@ exports.checkForUnknownDeps = function() {
red('Error:'),
`Unknown dependency ${cyan(match[0])} found in ${cyan(file.relative)}`
);
log(yellow(contents));
const err = new Error('Compilation failed due to unknown dependency');
err.showStack = false;
cb(err, file);
Expand Down
1 change: 1 addition & 0 deletions build-system/compile/compile.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ function compile(
'third_party/web-animations-externs/web_animations.js',
'third_party/moment/moment.extern.js',
'third_party/react-externs/externs.js',
'build-system/externs/preact.extern.js',
];
const define = [`VERSION=${internalRuntimeVersion}`];
if (argv.pseudo_names) {
Expand Down
4 changes: 4 additions & 0 deletions build-system/compile/sources.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ const COMMON_GLOBS = [
'node_modules/@ampproject/animations/dist/animations.mjs',
'node_modules/@ampproject/worker-dom/package.json',
'node_modules/@ampproject/worker-dom/dist/amp/main.mjs',
'node_modules/preact/package.json',
'node_modules/preact/dist/*.js',
'node_modules/preact/hooks/package.json',
'node_modules/preact/hooks/dist/*.js',
];

/**
Expand Down
30 changes: 26 additions & 4 deletions build-system/eslint-rules/no-import.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,41 @@
* limitations under the License.
*/
'use strict';
const imports = ['sinon'];

const imports = [
{import: 'sinon', message: 'Importing sinon is forbidden'},
{
import: 'preact',
message:
"Please import preact from 'src/preact'. This gives us type safety.",
},
{
import: 'preact/hooks',
message:
"Please import preact/hooks from 'src/preact'. This gives us type safety.",
},
];

module.exports = function(context) {
return {
ImportDeclaration(node) {
const comments = context.getCommentsBefore(node);
const comments = context.getCommentsBefore(node.source);
const ok = comments.some(comment => comment.value === 'OK');
if (ok) {
return;
}

const name = node.source.value;
if (imports.includes(name)) {
context.report({node, message: `Importing ${name} is forbidden.`});

for (const forbidden of imports) {
if (name !== forbidden.import) {
continue;
}

context.report({
node,
message: forbidden.message,
});
}
},
};
Expand Down
56 changes: 56 additions & 0 deletions build-system/externs/preact.extern.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/**
* Copyright 2020 The AMP HTML Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS-IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/** @externs */

/** @const */
var Preact = {}

/**
* @typedef {function(!JsonObject):Preact.Renderable}
*/
Preact.FunctionalComponent

/**
* @interface
*/
Preact.VNode = function() {}

/**
* @interface
*/
Preact.Context = function() {}

/**
* @param {!JsonObject} props
* @return {Preact.Renderable}
*/
Preact.Context.prototype.Provider = function(props) {};

/**
* @interface
*/
Preact.Context.prototype.Consumer = function() {};

/**
* @typedef {string|number|boolean|null|undefined}
*/
Preact.SimpleRenderable;

/**
* @typedef {Preact.SimpleRenderable|!Preact.VNode|!Array<Preact.SimpleRenderable|!Preact.VNode|!Array<Preact.SimpleRenderable|!Preact.VNode>>}
*/
Preact.Renderable;
2 changes: 1 addition & 1 deletion build-system/tasks/check-types.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ async function checkTypes() {
{
include3pDirectories: true,
includePolyfills: true,
extraGlobs: ['src/inabox/*.js'],
extraGlobs: ['src/inabox/*.js', '!node_modules/preact'],
typeCheckOnly: true,
}
),
Expand Down
2 changes: 1 addition & 1 deletion examples/amp-date-display.amp.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
overflow: auto;
}
</style>
<script async custom-element="amp-date-display" src="https://cdn.ampproject.org/v0/amp-date-display-0.1.js"></script>
<script async custom-element="amp-date-display" src="https://cdn.ampproject.org/v0/amp-date-display-0.2.js"></script>
jridgewell marked this conversation as resolved.
Show resolved Hide resolved
<script async custom-template="amp-mustache" src="https://cdn.ampproject.org/v0/amp-mustache-0.2.js"></script>
<script async src="https://cdn.ampproject.org/v0.js"></script>
</head>
Expand Down
97 changes: 97 additions & 0 deletions extensions/amp-date-display/0.2/amp-date-display.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/**
* Copyright 2019 The AMP HTML Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS-IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import {AsyncRender} from './async-render';
import {DateDisplay} from './date-display';
import {Fragment, createElement} from '../../../src/preact';
import {PreactBaseElement} from '../../../src/preact/base-element';
import {RenderDomTree} from './render-dom-tree';
import {Services} from '../../../src/services';
import {dict} from '../../../src/utils/object';
import {isExperimentOn} from '../../../src/experiments';
import {isLayoutSizeDefined} from '../../../src/layout';
import {userAssert} from '../../../src/log';

/** @const {string} */
const TAG = 'amp-date-display';

class AmpDateDisplay extends PreactBaseElement {
/** @override */
init() {
const templates = Services.templatesFor(this.win);
let rendered = false;

return dict({
/**
* @param {!JsonObject} data
* @param {*} children
* @return {*}
*/
'render': (data, children) => {
// We only render once in AMP mode, but React mode may rerender
// serveral times.
if (rendered) {
return children;
}
rendered = true;

const host = this.element;
const domPromise = templates
.findAndRenderTemplate(host, data)
.then(rendered => {
const container = document.createElement('div');
container.appendChild(rendered);

return createElement(RenderDomTree, {
'dom': container,
'host': host,
});
});
const asyncRender = createElement(AsyncRender, null, domPromise);
return createElement(Fragment, null, children, asyncRender);
},
});
}

/** @override */
isLayoutSupported(layout) {
userAssert(
isExperimentOn(this.win, 'amp-date-display-v2'),
'expected amp-date-display-v2 experiment to be enabled'
);
return isLayoutSizeDefined(layout);
dvoytenko marked this conversation as resolved.
Show resolved Hide resolved
}
}

/** @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);
});
37 changes: 37 additions & 0 deletions extensions/amp-date-display/0.2/async-render.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* Copyright 2019 The AMP HTML Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS-IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import {useResourcesNotify} from '../../../src/preact/utils';
import {useState} from '../../../src/preact';

/**
* Renders the children prop, waiting for it to resolve if it is a promise.
*
* @param {!JsonObject} props
* @return {Preact.Renderable}
*/
export function AsyncRender(props) {
const children = props['children'];
const {0: state, 1: set} = useState(children);
useResourcesNotify();

if (state && state.then) {
Promise.resolve(children).then(set);
return null;
}

return state;
}
Loading