[Designer] Implement Designer as PWA (#7473)

* In progess: Designer as PWA update

* Update to PWA services for designer

* Refactor to use workbox for serviceworker

* Disable header in css and update icon

* Rename config file and update manifest

* Minor updates to PWA

* Minor formatting fixes

* Update source/nodejs/adaptivecards-site/themes/adaptivecards/layout/designer.ejs

Co-authored-by: Aaron Gustafson <aaron@easy-designs.net>

* Update package.json scripts

* Minify service worker

* Update url references for pipeline

* Dynamic manifest file

* Update designer.ejs

Remove debug description

* Add method to service-worker and add comments

* Use local workbox files

* Update workbox path

* Revert 'Dynamic manifest file'

* Update manifest file paths

* Move workbox ingestion to come in through hexo generator

Co-authored-by: Aaron Gustafson <aaron@easy-designs.net>
Co-authored-by: Paul Campbell <paulcam@microsoft.com>
This commit is contained in:
anna-dingler 2022-06-08 16:34:06 -07:00 коммит произвёл GitHub
Родитель 1141a99ca8
Коммит 25efe9d138
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
8 изменённых файлов: 8654 добавлений и 356 удалений

8622
source/nodejs/adaptivecards-site/package-lock.json сгенерированный

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -4,12 +4,13 @@
"private": true,
"scripts": {
"clean": "hexo clean",
"build": "hexo generate",
"build": "hexo generate && npm run generate-sw",
"release-deps": "npx lerna run --scope @microsoft/adaptivecards-site --include-dependencies release --stream",
"generate-md-ac": "node node_modules/marked-schema/bin/marked-schema ../../../schemas/adaptive-card.json ./schema-explorer-toc.yml -r AdaptiveCard",
"generate-md-hc": "node node_modules/marked-schema/bin/marked-schema ../../../schemas/host-config.json ./schema-hostconfig-toc.yml -r AdaptiveCardConfig",
"release": "hexo clean && hexo generate",
"start": "hexo server"
"release": "hexo clean && hexo generate && npm run generate-sw",
"start": "hexo server",
"generate-sw": "npx workbox-cli injectManifest workbox-config.json"
},
"hexo": {
"version": "5.4.0"
@ -49,6 +50,7 @@
"monaco-editor": "^0.29.1",
"request": "^2.88.2",
"request-promise": "^4.2.5",
"workbox-cli": "^6.5.3",
"yaml-front-matter": "^4.1.0"
}
}

Просмотреть файл

@ -0,0 +1,75 @@
// Used pwa-builder as reference: https://github.com/pwa-builder/pwabuilder-serviceworkers/blob/master/serviceWorker5/pwabuilder-sw.js
importScripts("node_modules/workbox/workbox-sw.js");
workbox.setConfig({
modulePathPrefix: "node_modules/workbox/"
});
// Precache all files from workbox-config
workbox.precaching.precacheAndRoute(self.__WB_MANIFEST);
const HTML_CACHE = "html";
const JS_CACHE = "javascript";
const STYLE_CACHE = "stylesheets";
const IMAGE_CACHE = "images";
const FONT_CACHE = "fonts";
const DEFAULT_CACHE = "default";
// Need separeate caching for our cross origin styling references
workbox.routing.registerRoute(
({ url }) => {
return (
url.href ===
"https://www.microsoft.com/onerfstatics/marketingsites-wcus-prod/west-european/shell/_scrf/css/themes=default.device=uplevel_web_pc/59-469920/ad-9005a4/bd-292223/26-13ca9e/b7-1464e7/8e-a868c0/58-faa810/34-4fda9f?ver=2.0" ||
url.href ===
"https://statics-marketingsites-wcus-ms-com.akamaized.net/statics/override.css?c=7"
);
},
new workbox.strategies.CacheFirst({
plugins: [
new workbox.cacheableResponse.CacheableResponsePlugin({
statuses: [0, 200]
})
]
})
);
// TODO: could register routes with regex if we want to be more precise with caching
workbox.routing.registerRoute(
({ event }) => {
return event.request.destination === "document";
},
new workbox.strategies.NetworkFirst({
cacheName: HTML_CACHE,
plugins: [
new workbox.expiration.ExpirationPlugin({
maxEntries: 10
})
]
})
);
function registerStaleWhileRevalidate(destinationType, cache, entries) {
workbox.routing.registerRoute(
({ event }) => {
return event.request.destination === destinationType;
},
new workbox.strategies.StaleWhileRevalidate({
cacheName: cache,
plugins: [
new workbox.expiration.ExpirationPlugin({
maxEntries: entries
})
]
})
);
}
registerStaleWhileRevalidate("script", JS_CACHE, 15);
registerStaleWhileRevalidate("style", STYLE_CACHE, 15);
registerStaleWhileRevalidate("image", IMAGE_CACHE, 15);
registerStaleWhileRevalidate("font", FONT_CACHE, 15);
// This route mostly caches payloads
// We allow for a high cache so the sample cards and data are stored
registerStaleWhileRevalidate("", DEFAULT_CACHE, 100);

Просмотреть файл

@ -23,6 +23,10 @@
<link rel="alternate" href="<%- url_for(config.feed.path) %>" title="<%= config.title %>" type="application/atom+xml">
<link rel="icon" href="<%- url_for('content/favicon.ico') %>">
<% if(is_current("designer")) { %>
<link rel="manifest" href="<%- url_for('manifest.json') %>">
<% } %>
<% if(is_post()) { %>
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Adaptive Cards | <%- page.title %>">
@ -47,6 +51,7 @@
<% /* from UHF MSDocsHeader-AdaptiveCards */ %>
<link rel="stylesheet" href="https://www.microsoft.com/onerfstatics/marketingsites-wcus-prod/west-european/shell/_scrf/css/themes=default.device=uplevel_web_pc/59-469920/ad-9005a4/bd-292223/26-13ca9e/b7-1464e7/8e-a868c0/58-faa810/34-4fda9f?ver=2.0" type="text/css" media="all" />
<link rel='stylesheet' href='https://statics-marketingsites-wcus-ms-com.akamaized.net/statics/override.css?c=7' type='text/css' />
<script src="https://www.microsoft.com/onerfstatics/marketingsites-wcus-prod/shell/_scrf/js/themes=default/54-af9f9f/c0-247156/de-099401/e1-a50eee/e7-954872/d8-97d509/f0-251fe2/46-be1318/77-04a268/11-240c7b/63-077520/a4-34de62/1b-c96630/db-bc0148/dc-7e9864/78-4c7d22/39-97e6ff/16-4c1a9d/cd-23d3b0/6d-1e7ed0/b7-cadaa7/ca-40b7b0/4e-ee3a55/3e-f5c39b/c3-6454d7/f9-7592d3/92-10345d/79-499886/7e-cda2d3/62-95a6e7/93-283c2d/e0-3c9860/91-97a04f/1f-100dea/33-abe4df/f2-fae105?ver=2.0&iife=1"></script>

Просмотреть файл

@ -45,8 +45,27 @@
.acd-icon-scopeTemplate::before {
content: "\F2B0";
}
@media all and (display-mode: standalone) {
.header-holder {
display: none;
}
}
</style>
<script type="text/javascript">
// Register the service worker for PWA
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('<%- config.root %>service-worker.js', {scope: '<%- config.root %>designer/'}).then(registration => {
console.log('SW registered: ', registration);
}).catch(registrationError => {
console.log('SW registration failed: ', registrationError);
});
});
}
</script>
<script type="text/javascript">

Просмотреть файл

@ -12,129 +12,159 @@ var md5 = require("md5");
// These are the flat asset files that will be copied into the output folder
// and available to reference in HTML templates
var simpleAssets = [
"node_modules/adaptivecards/dist/*.*",
"node_modules/adaptive-expressions/lib/*.*",
"node_modules/adaptivecards-designer/dist/*.*",
"node_modules/adaptivecards-templating/dist/*.*",
"node_modules/@fortawesome/fontawesome-free/css/all.min.css",
"node_modules/@fortawesome/fontawesome-free/webfonts/*.*",
"node_modules/highlightjs/highlight.pack.min.js",
"node_modules/highlightjs/styles/default.css",
"node_modules/jquery/dist/jquery.min.js",
"node_modules/markdown-it/dist/markdown-it.min.js"
"node_modules/adaptivecards/dist/*.*",
"node_modules/adaptive-expressions/lib/*.*",
"node_modules/adaptivecards-designer/dist/*.*",
"node_modules/adaptivecards-templating/dist/*.*",
"node_modules/@fortawesome/fontawesome-free/css/all.min.css",
"node_modules/@fortawesome/fontawesome-free/webfonts/*.*",
"node_modules/highlightjs/highlight.pack.min.js",
"node_modules/highlightjs/styles/default.css",
"node_modules/jquery/dist/jquery.min.js",
"node_modules/markdown-it/dist/markdown-it.min.js"
];
// These are the other asset files that need to be copied into a specific location
// the dest param describes the dir/filename used in the output destination
var customAssets = [
{
// Sample payloads
path: "../../../samples/v1.*/**/*.json",
dest: function (p) { return "payloads/" + path.basename(p); }
},
{
// Sample template payloads
path: "../../../samples/Templates/**/*.json",
dest: function (p) { return "payloads/" + path.basename(p); }
},
{
// Unversioned JSON schema URL, set to the 1.3 (current) version as versioned schema paths are not in use.
// May be deprecated in the future in favor of versioned schema paths.
path: "../../../schemas/1.5.0/adaptive-card.json",
dest: function (p) { return "schemas/adaptive-card.json"; }
},
{
path: "../../../schemas/*/adaptive-card.json",
dest: function (p) {
// Keep the last 2 path portions... 1.2.0/adaptive-card.json, and put it in the schemas folder
return "schemas/" + p.split("/").slice(-2).join("/");
}
},
{
// CSS used for samples on the site
path: "node_modules/adaptivecards-designer/dist/containers/outlook-container.css",
dest: function (p) { return "css/outlook.css"; }
},
{
// designer module (hashing not working for CSS files; the designer expects certain filenames)
path: "node_modules/adaptivecards-designer/dist/containers/*.*",
dest: function (p) { return p; },
noHash: true
},
{
// designer module (hashing not working for CSS files; the designer expects certain filenames)
path: "node_modules/adaptivecards-designer/dist/adaptivecards-designer.css",
dest: function (p) { return p; },
noHash: true
},
{
// monaco-editor module
path: "node_modules/monaco-editor/min/vs/**/*.*",
dest: function (p) { return p; },
noHash: true
},
{
// monaco-editor module maps, for science
path: "node_modules/monaco-editor/min-maps/vs/**/*.*",
dest: function (p) { return p; },
noHash: true
},
{
// site CSS
path: "themes/adaptivecards/source/css/*.css",
dest: function (p) { return "css/" + path.basename(p) }
},
{
// site JS
path: "themes/adaptivecards/source/js/*.js",
dest: function (p) { return "js/" + path.basename(p) }
}
{
// Sample payloads
path: "../../../samples/v1.*/**/*.json",
dest: function (p) {
return "payloads/" + path.basename(p);
}
},
{
// Sample template payloads
path: "../../../samples/Templates/**/*.json",
dest: function (p) {
return "payloads/" + path.basename(p);
}
},
{
// Unversioned JSON schema URL, set to the 1.3 (current) version as versioned schema paths are not in use.
// May be deprecated in the future in favor of versioned schema paths.
path: "../../../schemas/1.5.0/adaptive-card.json",
dest: function (p) {
return "schemas/adaptive-card.json";
}
},
{
path: "../../../schemas/*/adaptive-card.json",
dest: function (p) {
// Keep the last 2 path portions... 1.2.0/adaptive-card.json, and put it in the schemas folder
return "schemas/" + p.split("/").slice(-2).join("/");
}
},
{
// CSS used for samples on the site
path: "node_modules/adaptivecards-designer/dist/containers/outlook-container.css",
dest: function (p) {
return "css/outlook.css";
}
},
{
// designer module (hashing not working for CSS files; the designer expects certain filenames)
path: "node_modules/adaptivecards-designer/dist/containers/*.*",
dest: function (p) {
return p;
},
noHash: true
},
{
// designer module (hashing not working for CSS files; the designer expects certain filenames)
path: "node_modules/adaptivecards-designer/dist/adaptivecards-designer.css",
dest: function (p) {
return p;
},
noHash: true
},
{
// monaco-editor module
path: "node_modules/monaco-editor/min/vs/**/*.*",
dest: function (p) {
return p;
},
noHash: true
},
{
// monaco-editor module maps, for science
path: "node_modules/monaco-editor/min-maps/vs/**/*.*",
dest: function (p) {
return p;
},
noHash: true
},
{
// site CSS
path: "themes/adaptivecards/source/css/*.css",
dest: function (p) {
return "css/" + path.basename(p);
}
},
{
// site JS
path: "themes/adaptivecards/source/js/*.js",
dest: function (p) {
return "js/" + path.basename(p);
}
},
{
path: "node_modules/workbox-!(cli|build)/build/*",
dest: function (p) {
return "node_modules/workbox/" + path.basename(p);
},
noHash: true
}
];
hexo.extend.generator.register("generator-adaptiveassets", function (locals) {
let allAssets = [];
let hashExtensions = [".css", ".js"];
let hashedAssets = [];
let allAssets = [];
let hashExtensions = [".css", ".js"];
let hashedAssets = [];
simpleAssets.forEach(function (a) {
customAssets.push({
path: a,
dest: function (p) {
return p;
}
});
});
simpleAssets.forEach(function (a) {
customAssets.push({
path: a,
dest: function (p) { return p; }
});
});
customAssets.forEach(function (asset) {
var g = glob.sync(asset.path, { nocase: false }).map(function (sourcePath) {
let destPath = asset.dest(sourcePath);
customAssets.forEach(function (asset) {
var g = glob.sync(asset.path, { nocase: false }).map(function (sourcePath) {
if (!asset.noHash && hashExtensions.includes(path.extname(destPath))) {
// For cache-busting append the md5 hash of our script and CSS content
// EXAMPLE: adaptivecards.js => adaptivecards.c66a8322.js
let originalDestPath = destPath;
let hash = md5(fs.readFileSync(sourcePath)).substring(0, 6);
let hashedFilename =
path.basename(destPath, path.extname(destPath)) + "." + hash + path.extname(destPath);
let destPath = asset.dest(sourcePath);
destPath = path.dirname(destPath) + "/" + hashedFilename;
hashedAssets.push({
originalPath: originalDestPath,
hashedPath: destPath
});
}
if (!asset.noHash && hashExtensions.includes(path.extname(destPath))) {
// For cache-busting append the md5 hash of our script and CSS content
// EXAMPLE: adaptivecards.js => adaptivecards.c66a8322.js
let originalDestPath = destPath;
let hash = md5(fs.readFileSync(sourcePath)).substring(0, 6);
let hashedFilename = path.basename(destPath, path.extname(destPath)) + "." + hash + path.extname(destPath);
return {
path: destPath,
data: function () {
return fs.createReadStream(sourcePath);
}
};
});
destPath = path.dirname(destPath) + "/" + hashedFilename;
hashedAssets.push({
originalPath: originalDestPath,
hashedPath: destPath
});
}
g.forEach(function (item) {
allAssets.push(item);
});
});
return {
path: destPath,
data: function () {
return fs.createReadStream(sourcePath);
}
}
});
hexo.locals.set("hashedAssets", () => hashedAssets);
g.forEach(function (item) { allAssets.push(item); });
});
hexo.locals.set("hashedAssets", () => hashedAssets);
return allAssets;
return allAssets;
});

Просмотреть файл

@ -0,0 +1,17 @@
{
"lang": "en-us",
"name": "Adaptive Cards Designer",
"short_name": "ACDesigner",
"description": "A PWA for the Adaptive Cards Designer",
"start_url": "designer/",
"background_color": "#3A96DD",
"theme_color": "#3A96DD",
"orientation": "any",
"display": "standalone",
"icons": [
{
"src": "content/icons_blue/blue-512.png",
"sizes": "512x512"
}
]
}

Просмотреть файл

@ -0,0 +1,16 @@
{
"globDirectory": "public",
"globPatterns": [
"content/icons/*",
"content/icons_blue/*",
"content/icons_transparent/*",
"content/icons_white",
"samples/*.html",
"schemas/**",
"**/*.css",
"designer/*",
"manifest.json"
],
"swDest": "public/service-worker.js",
"swSrc": "service-worker.js"
}