Add plugin technology to add header buttons.

This commit is contained in:
kovacsv 2022-11-03 21:05:37 +01:00
parent 499c867f4c
commit bf3b045ff0
7 changed files with 75 additions and 37 deletions

5
.gitignore vendored
View File

@ -1,7 +1,4 @@
build/* build/*
website_meta_data.txt plugins/*
website_analytics_data.txt
website_script_data.txt
website_intro_data.txt
node_modules node_modules
__pycache__ __pycache__

View File

@ -1,14 +1,11 @@
import { SetExternalLibLocation } from '../engine/io/externallibs.js'; import { SetExternalLibLocation } from '../engine/io/externallibs.js';
import { CreateDomElement } from '../engine/viewer/domutils.js';
import { AddSvgIconElement, InstallTooltip } from './utils.js';
import { SetEventHandler } from './eventhandler.js';
import { Embed } from './embed.js'; import { Embed } from './embed.js';
import { Website } from './website.js'; import { Website } from './website.js';
export function SetWebsiteEventHandler (eventHandler) import { SetEventHandler } from './eventhandler.js';
{ export { SetEventHandler };
SetEventHandler (eventHandler); import { PluginType, RegisterPlugin } from './pluginregistry.js';
} export { PluginType, RegisterPlugin };
export function StartWebsite (externalLibLocation) export function StartWebsite (externalLibLocation)
{ {
@ -16,6 +13,7 @@ export function StartWebsite (externalLibLocation)
window.addEventListener ('load', () => { window.addEventListener ('load', () => {
let website = new Website ({ let website = new Website ({
headerDiv : document.getElementById ('header'), headerDiv : document.getElementById ('header'),
headerButtonsDiv : document.getElementById ('header_buttons'),
toolbarDiv : document.getElementById ('toolbar'), toolbarDiv : document.getElementById ('toolbar'),
mainDiv : document.getElementById ('main'), mainDiv : document.getElementById ('main'),
introDiv : document.getElementById ('intro'), introDiv : document.getElementById ('intro'),
@ -42,15 +40,3 @@ export function StartEmbed (externalLibLocation)
embed.Load (); embed.Load ();
}); });
} }
export function CreateHeaderButton (parentElement, iconName, title, link)
{
let buttonLink = CreateDomElement ('a');
buttonLink.setAttribute ('href', link);
buttonLink.setAttribute ('target', '_blank');
buttonLink.setAttribute ('rel', 'noopener noreferrer');
InstallTooltip (buttonLink, title);
AddSvgIconElement (buttonLink, iconName, 'header_button');
parentElement.appendChild (buttonLink);
return buttonLink;
}

View File

@ -0,0 +1,26 @@
let plugins = new Map ();
export const PluginType =
{
Header : 1
};
export function RegisterPlugin (type, plugin)
{
if (!plugins.has (type)) {
plugins.set (type, []);
}
let typedPlugins = plugins.get (type);
typedPlugins.push (plugin);
}
export function EnumeratePlugins (type, onPlugin)
{
if (!plugins.has (type)) {
return;
}
let typedPlugins = plugins.get (type);
for (let typedPlugin of typedPlugins) {
onPlugin (typedPlugin);
}
}

View File

@ -2,7 +2,7 @@ import { GetFileExtension, TransformFileHostUrls } from '../engine/io/fileutils.
import { InputFilesFromFileObjects, InputFilesFromUrls } from '../engine/import/importerfiles.js'; import { InputFilesFromFileObjects, InputFilesFromUrls } from '../engine/import/importerfiles.js';
import { ImportErrorCode, ImportSettings } from '../engine/import/importer.js'; import { ImportErrorCode, ImportSettings } from '../engine/import/importer.js';
import { CameraMode, Viewer } from '../engine/viewer/viewer.js'; import { CameraMode, Viewer } from '../engine/viewer/viewer.js';
import { AddDiv, AddDomElement, ShowDomElement, SetDomElementOuterHeight } from '../engine/viewer/domutils.js'; import { AddDiv, AddDomElement, ShowDomElement, SetDomElementOuterHeight, CreateDomElement } from '../engine/viewer/domutils.js';
import { CalculatePopupPositionToScreen, ShowListPopup } from './dialogs.js'; import { CalculatePopupPositionToScreen, ShowListPopup } from './dialogs.js';
import { HandleEvent } from './eventhandler.js'; import { HandleEvent } from './eventhandler.js';
import { HashHandler } from './hashhandler.js'; import { HashHandler } from './hashhandler.js';
@ -14,7 +14,7 @@ import { ThreeModelLoaderUI } from './threemodelloaderui.js';
import { Toolbar } from './toolbar.js'; import { Toolbar } from './toolbar.js';
import { ShowExportDialog } from './exportdialog.js'; import { ShowExportDialog } from './exportdialog.js';
import { ShowSnapshotDialog } from './snapshotdialog.js'; import { ShowSnapshotDialog } from './snapshotdialog.js';
import { AddSmallWidthChangeEventListener, GetFilesFromDataTransfer, IsSmallWidth } from './utils.js'; import { AddSmallWidthChangeEventListener, AddSvgIconElement, GetFilesFromDataTransfer, InstallTooltip, IsSmallWidth } from './utils.js';
import { ShowOpenUrlDialog } from './openurldialog.js'; import { ShowOpenUrlDialog } from './openurldialog.js';
import { ShowSharingDialog } from './sharingdialog.js'; import { ShowSharingDialog } from './sharingdialog.js';
import { HasDefaultMaterial, ReplaceDefaultMaterialColor } from '../engine/model/modelutils.js'; import { HasDefaultMaterial, ReplaceDefaultMaterialColor } from '../engine/model/modelutils.js';
@ -24,6 +24,7 @@ import { MeasureTool } from './measuretool.js';
import { CloseAllDialogs } from './dialog.js'; import { CloseAllDialogs } from './dialog.js';
import * as THREE from 'three'; import * as THREE from 'three';
import { EnumeratePlugins, PluginType } from './pluginregistry.js';
export const WebsiteUIState = export const WebsiteUIState =
{ {
@ -58,6 +59,14 @@ export class Website
this.SwitchTheme (this.settings.themeId, false); this.SwitchTheme (this.settings.themeId, false);
HandleEvent ('theme_on_load', this.settings.themeId === Theme.Light ? 'light' : 'dark'); HandleEvent ('theme_on_load', this.settings.themeId === Theme.Light ? 'light' : 'dark');
EnumeratePlugins (PluginType.Header, (plugin) => {
plugin.registerButtons ({
createHeaderButton : (icon, title, link) => {
this.CreateHeaderButton (icon, title, link);
}
});
});
this.InitViewer (); this.InitViewer ();
this.InitToolbar (); this.InitToolbar ();
this.InitDragAndDrop (); this.InitDragAndDrop ();
@ -776,6 +785,18 @@ export class Website
this.sidebar.ShowPanels (showSidebar); this.sidebar.ShowPanels (showSidebar);
} }
CreateHeaderButton (icon, title, link)
{
let buttonLink = CreateDomElement ('a');
buttonLink.setAttribute ('href', link);
buttonLink.setAttribute ('target', '_blank');
buttonLink.setAttribute ('rel', 'noopener noreferrer');
InstallTooltip (buttonLink, title);
AddSvgIconElement (buttonLink, icon, 'header_button');
this.parameters.headerButtonsDiv.appendChild (buttonLink);
return buttonLink;
}
InitCookieConsent () InitCookieConsent ()
{ {
let accepted = CookieGetBoolVal ('ov_cookie_consent', false); let accepted = CookieGetBoolVal ('ov_cookie_consent', false);

View File

@ -36,6 +36,18 @@ def CreateDestinationDir (config, rootDir, websiteDir, version, testBuild):
shutil.copytree (os.path.join (rootDir, 'website', 'css', 'O3DVIcons'), os.path.join (websiteDir, 'o3dv', 'O3DVIcons')) shutil.copytree (os.path.join (rootDir, 'website', 'css', 'O3DVIcons'), os.path.join (websiteDir, 'o3dv', 'O3DVIcons'))
shutil.copytree (os.path.join (rootDir, 'website', 'info'), os.path.join (websiteDir, 'info')) shutil.copytree (os.path.join (rootDir, 'website', 'info'), os.path.join (websiteDir, 'info'))
pluginFiles = []
pluginsDir = os.path.join (rootDir, 'plugins')
if os.path.exists (pluginsDir):
for pluginFile in os.listdir (pluginsDir):
if os.path.splitext (pluginFile)[1] != '.js':
continue
websitePluginsDir = os.path.join (websiteDir, 'plugins');
if not os.path.exists (websitePluginsDir):
os.makedirs (websitePluginsDir)
shutil.copy2 (os.path.join (pluginsDir, pluginFile), os.path.join (websitePluginsDir, pluginFile))
pluginFiles.append ('plugins/' + pluginFile)
websiteLibFiles = config['website_lib_files'] websiteLibFiles = config['website_lib_files']
websiteFiles = [ websiteFiles = [
'o3dv/o3dv.website.min.css', 'o3dv/o3dv.website.min.css',
@ -54,6 +66,7 @@ def CreateDestinationDir (config, rootDir, websiteDir, version, testBuild):
replacer = Tools.TokenReplacer (htmlFilePath, False) replacer = Tools.TokenReplacer (htmlFilePath, False)
replacer.ReplaceTokenFileLinks ('<!-- website libs start -->', '<!-- website libs end -->', websiteLibFiles, version) replacer.ReplaceTokenFileLinks ('<!-- website libs start -->', '<!-- website libs end -->', websiteLibFiles, version)
replacer.ReplaceTokenFileLinks ('<!-- website start -->', '<!-- website end -->', websiteFiles, version) replacer.ReplaceTokenFileLinks ('<!-- website start -->', '<!-- website end -->', websiteFiles, version)
replacer.ReplaceTokenFileLinks ('<!-- plugins start -->', '<!-- plugins end -->', pluginFiles, version)
initScriptContent = '' initScriptContent = ''
initScriptContent += '<script type="text/javascript">' + replacer.eolChar initScriptContent += '<script type="text/javascript">' + replacer.eolChar
initScriptContent += ' OV.StartWebsite (\'libs\');' + replacer.eolChar initScriptContent += ' OV.StartWebsite (\'libs\');' + replacer.eolChar
@ -64,19 +77,15 @@ def CreateDestinationDir (config, rootDir, websiteDir, version, testBuild):
embedInitScriptContent += '</script>' embedInitScriptContent += '</script>'
replacer.ReplaceTokenContent ('<!-- website init start -->', '<!-- website init end -->', initScriptContent) replacer.ReplaceTokenContent ('<!-- website init start -->', '<!-- website init end -->', initScriptContent)
replacer.ReplaceTokenContent ('<!-- embed init start -->', '<!-- embed init end -->', embedInitScriptContent) replacer.ReplaceTokenContent ('<!-- embed init start -->', '<!-- embed init end -->', embedInitScriptContent)
metaFile = os.path.join (rootDir, 'tools', 'website_meta_data.txt') metaFile = os.path.join (rootDir, 'plugins', 'website_meta_data.txt')
if os.path.exists (metaFile): if os.path.exists (metaFile):
metaContent = Tools.GetFileContent (metaFile) metaContent = Tools.GetFileContent (metaFile)
replacer.ReplaceTokenContent ('<!-- meta start -->', '<!-- meta end -->', metaContent) replacer.ReplaceTokenContent ('<!-- meta start -->', '<!-- meta end -->', metaContent)
analyticsFile = os.path.join (rootDir, 'tools', 'website_analytics_data.txt') analyticsFile = os.path.join (rootDir, 'plugins', 'website_analytics_data.txt')
if os.path.exists (analyticsFile) and not testBuild: if os.path.exists (analyticsFile) and not testBuild:
analyticsContent = Tools.GetFileContent (analyticsFile) analyticsContent = Tools.GetFileContent (analyticsFile)
replacer.ReplaceTokenContent ('<!-- analytics start -->', '<!-- analytics end -->', analyticsContent) replacer.ReplaceTokenContent ('<!-- analytics start -->', '<!-- analytics end -->', analyticsContent)
scriptFile = os.path.join (rootDir, 'tools', 'website_script_data.txt') introFile = os.path.join (rootDir, 'plugins', 'website_intro_data.txt')
if os.path.exists (scriptFile):
scriptContent = Tools.GetFileContent (scriptFile)
replacer.ReplaceTokenContent ('<!-- script start -->', '<!-- script end -->', scriptContent)
introFile = os.path.join (rootDir, 'tools', 'website_intro_data.txt')
if os.path.exists (introFile): if os.path.exists (introFile):
introContent = Tools.GetFileContent (introFile) introContent = Tools.GetFileContent (introFile)
replacer.ReplaceTokenContent ('<!-- intro start -->', '<!-- intro end -->', introContent) replacer.ReplaceTokenContent ('<!-- intro start -->', '<!-- intro end -->', introContent)

View File

@ -28,7 +28,7 @@
<!-- analytics start --> <!-- analytics start -->
<script type="text/javascript"> <script type="text/javascript">
OV.SetWebsiteEventHandler ((eventName, eventLabel, eventParams) => { OV.SetEventHandler ((eventName, eventLabel, eventParams) => {
console.log ({ console.log ({
eventName : eventName, eventName : eventName,
eventLabel : eventLabel, eventLabel : eventLabel,

View File

@ -30,10 +30,12 @@
<link rel="stylesheet" type="text/css" href="css/embed.css"> <link rel="stylesheet" type="text/css" href="css/embed.css">
<script type="text/javascript" src="../build/o3dv.website.min-dev.js"></script> <script type="text/javascript" src="../build/o3dv.website.min-dev.js"></script>
<!-- website end --> <!-- website end -->
<!-- plugins start -->
<!-- plugins end -->
<!-- analytics start --> <!-- analytics start -->
<script type="text/javascript"> <script type="text/javascript">
OV.SetWebsiteEventHandler ((eventName, eventLabel, eventParams) => { OV.SetEventHandler ((eventName, eventLabel, eventParams) => {
console.log ({ console.log ({
eventName : eventName, eventName : eventName,
eventLabel : eventLabel, eventLabel : eventLabel,
@ -49,9 +51,6 @@
</script> </script>
<!-- website init end --> <!-- website init end -->
<!-- script start -->
<!-- script end -->
</head> </head>
<body> <body>