AMP

https://amp.dev/zh_cn/

PWA

AMP Playground

https://playground.amp.dev/?runtime=amp4email

<!doctype html>
<html 4email>
<head>
<meta charset="utf-8">
<script async src="https://cdn.ampproject.org/v0.js"></script>
<style amp4email-boilerplate>body{visibility:hidden}</style>
<style amp-custom>
h1 {
margin: 1rem;
}
</style>
</head>
<body>
<h1>Hello, I am an AMP EMAIL!</h1>
</body>
</html>

custom-element

https://github.com/ampproject

<!doctype html>
<html amp lang="en">
<head>
<meta charset="utf-8">
<script async src="https://cdn.ampproject.org/v0.js"></script>
<title>Hello, AMPs</title>
<link rel="canonical" href="https://amp.dev/zh_cn/documentation/guides-and-tutorials/start/create/basic_markup/">
<meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1">
<script type="application/ld+json">
{
"@context": "http://schema.org",
"@type": "NewsArticle",
"headline": "Open-source framework for publishing content",
"datePublished": "2015-10-07T12:02:41Z",
"image": [
"logo.jpg"
]
}
</script>
<style amp-boilerplate>body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}</style><noscript><style amp-boilerplate>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style></noscript>
</head>
<body>
<h1>Welcome to the mobile web</h1>
</body>
</html>

Chrome Devtools

https://developers.google.com/web/updates/2020/03/devtools

Grid Layout



/**
* Copyright 2017 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 {ElementStub, stubbedElements} from '../element-stub';
import {createCustomElementClass} from '../custom-element';
import {extensionScriptsInNode} from '../element-service';
import {reportError} from '../error';
import {userAssert} from '../log'; /**
* @param {!Window} win
* @return {!Object<string, typeof ../base-element.BaseElement>}
*/
function getExtendedElements(win) {
if (!win.__AMP_EXTENDED_ELEMENTS) {
win.__AMP_EXTENDED_ELEMENTS = {};
}
return win.__AMP_EXTENDED_ELEMENTS;
} /**
* Registers an element. Upgrades it if has previously been stubbed.
* @param {!Window} win
* @param {string} name
* @param {typeof ../base-element.BaseElement} toClass
*/
export function upgradeOrRegisterElement(win, name, toClass) {
const knownElements = getExtendedElements(win);
if (!knownElements[name]) {
registerElement(win, name, toClass);
return;
}
if (knownElements[name] == toClass) {
// Already registered this instance.
return;
}
userAssert(
knownElements[name] == ElementStub,
'%s is already registered. The script tag for ' +
'%s is likely included twice in the page.',
name,
name
);
knownElements[name] = toClass;
for (let i = 0; i < stubbedElements.length; i++) {
const stub = stubbedElements[i];
// There are 3 possible states here:
// 1. We never made the stub because the extended impl. loaded first.
// In that case the element won't be in the array.
// 2. We made a stub but the browser didn't attach it yet. In
// that case we don't need to upgrade but simply switch to the new
// implementation.
// 3. A stub was attached. We upgrade which means we replay the
// implementation.
const {element} = stub;
if (
element.tagName.toLowerCase() == name &&
element.ownerDocument.defaultView == win
) {
tryUpgradeElement_(element, toClass);
// Remove element from array.
stubbedElements.splice(i--, 1);
}
}
} /**
* This method should not be inlined to prevent TryCatch deoptimization.
* @param {Element} element
* @param {typeof ../base-element.BaseElement} toClass
* @private
* @noinline
*/
function tryUpgradeElement_(element, toClass) {
try {
element.upgrade(toClass);
} catch (e) {
reportError(e, element);
}
} /**
* Stub extended elements missing an implementation. It can be called multiple
* times and on partial document in order to start stubbing as early as
* possible.
* @param {!./ampdoc-impl.AmpDoc} ampdoc
*/
export function stubElementsForDoc(ampdoc) {
const extensions = extensionScriptsInNode(ampdoc.getHeadNode());
extensions.forEach((name) => {
ampdoc.declareExtension(name);
stubElementIfNotKnown(ampdoc.win, name);
});
} /**
* Stub element if not yet known.
* @param {!Window} win
* @param {string} name
*/
export function stubElementIfNotKnown(win, name) {
const knownElements = getExtendedElements(win);
if (!knownElements[name]) {
registerElement(win, name, ElementStub);
}
} /**
* Copies the specified element to child window (friendly iframe). This way
* all implementations of the AMP elements are shared between all friendly
* frames.
* @param {!Window} parentWin
* @param {!Window} childWin
* @param {string} name
*/
export function copyElementToChildWindow(parentWin, childWin, name) {
const toClass = getExtendedElements(parentWin)[name];
registerElement(childWin, name, toClass || ElementStub);
} /**
* Registers a new custom element with its implementation class.
* @param {!Window} win The window in which to register the elements.
* @param {string} name Name of the custom element
* @param {typeof ../base-element.BaseElement} implementationClass
*/
export function registerElement(win, name, implementationClass) {
const knownElements = getExtendedElements(win);
knownElements[name] = implementationClass;
const klass = createCustomElementClass(win);
win['customElements'].define(name, klass);
} /**
* In order to provide better error messages we only allow to retrieve
* services from other elements if those elements are loaded in the page.
* This makes it possible to mark an element as loaded in a test.
* @param {!Window} win
* @param {string} elementName Name of an extended custom element.
* @visibleForTesting
*/
export function markElementScheduledForTesting(win, elementName) {
const knownElements = getExtendedElements(win);
if (!knownElements[elementName]) {
knownElements[elementName] = ElementStub;
}
} /**
* Resets our scheduled elements.
* @param {!Window} win
* @param {string} elementName Name of an extended custom element.
* @visibleForTesting
*/
export function resetScheduledElementForTesting(win, elementName) {
if (win.__AMP_EXTENDED_ELEMENTS) {
delete win.__AMP_EXTENDED_ELEMENTS[elementName];
}
} /**
* Returns a currently registered element class.
* @param {!Window} win
* @param {string} elementName Name of an extended custom element.
* @return {?function()}
* @visibleForTesting
*/
export function getElementClassForTesting(win, elementName) {
const knownElements = win.__AMP_EXTENDED_ELEMENTS;
return (knownElements && knownElements[elementName]) || null;
}

refs



xgqfrms 2012-2020

www.cnblogs.com 发布文章使用:只允许注册用户才可以访问!


随机推荐

  1. Avoid catching exceptions inside atomic! You may need to manually revert model state when rolling back a transaction. 避免异常程序不抛错误 回滚 导致 自增id不连续。

    https://docs.djangoproject.com/en/3.0/topics/db/transactions/ You may need to manually revert model ...

  2. P4826

    总的来说, 这道题只考查了单纯的建图和最大生成树 但这却是蓝题(问号 题意 题意的理解比较麻烦 简单说就是 n 支队伍比赛,i 号队伍和 j 号队伍比赛可获得 i ^ j 的分数,然后其中一支队伍会输 ...

  3. Docker私服搭建--Harbor

    Docker私服搭建--Harbor Harbor概述 Harbor的安全机制 Harbor的镜像同步 Harbor的镜像同步机制 Harbor的多级部署 一.安装 1.1 docker安装 1.2 ...

  4. 前台console调试技巧

    前台console调试技巧 一.console.log() 二.console.warn() 三.console.dir() 四.console.table() 五.console.assert() ...

  5. Jenkins (1、自动化发布war包、2、自动化发布nodejs)

    1.持续集成javaweb 首先咱们需要安装一个 Jenkins,这个就不必多说了,晚上一搜索一大把,然后安装各种插件,配置各种环境变量, 今天我的实验环境是 使用Jenkins 拉取gitlap上项 ...

  6. DDD领域驱动设计:CQRS

    1 前置阅读 在阅读本文章之前,你可以先阅读: DDD领域驱动设计是什么 DDD领域驱动设计:实体.值对象.聚合根 DDD领域驱动设计:仓储 MediatR一个优秀的.NET中介者框架 2 什么是CQ ...

  7. CF-1445 C - Division 数论,质因数,唯一分解定理

    题意 给定一个 \(p (p\le 10^{18})\), 一个 \(q(q \le 10^9)\), 要找到一个最大的 \(x\) 满足: \(p \%x = 0\) \(q \% x \neq 0 ...

  8. 前n项余数个数和

    一:O(n) 计算贡献:前n项中,能被i(1~n)整除的数的个数为(n/i)个,,也就是 i 给前n项中(n/i)个数做了余数 #include<iostream> using names ...

  9. 【noi 2.6_9280】&【bzoj 1089】严格n元树(DP+高精度+重载运算符)

    题意:定义一棵树的所有非叶节点都恰好有n个儿子为严格n元树.问深度为d的严格n元树数目. 解法:f[i]表示深度为<=i的严格n元树数目.f[i]-f[i-1]表示深度为i的严格n元树数目.f[ ...

  10. Atcoder ABC155_C中有关c++ STL map的用法

    题目:https://atcoder.jp/contests/abc155/tasks/abc155_c 这道题的题意是给我们n个string,让我们统计每个string出现的次数,并输出次数最多的一 ...