diff --git a/.gitignore b/.gitignore index f430a1f..a7c0acc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,4 @@ build/* -website_meta_data.txt -website_analytics_data.txt -website_script_data.txt -website_intro_data.txt +plugins/* node_modules __pycache__ diff --git a/source/website/index.js b/source/website/index.js index 2c8a21a..a002063 100644 --- a/source/website/index.js +++ b/source/website/index.js @@ -1,14 +1,11 @@ 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 { Website } from './website.js'; -export function SetWebsiteEventHandler (eventHandler) -{ - SetEventHandler (eventHandler); -} +import { SetEventHandler } from './eventhandler.js'; +export { SetEventHandler }; +import { PluginType, RegisterPlugin } from './pluginregistry.js'; +export { PluginType, RegisterPlugin }; export function StartWebsite (externalLibLocation) { @@ -16,6 +13,7 @@ export function StartWebsite (externalLibLocation) window.addEventListener ('load', () => { let website = new Website ({ headerDiv : document.getElementById ('header'), + headerButtonsDiv : document.getElementById ('header_buttons'), toolbarDiv : document.getElementById ('toolbar'), mainDiv : document.getElementById ('main'), introDiv : document.getElementById ('intro'), @@ -42,15 +40,3 @@ export function StartEmbed (externalLibLocation) 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; -} diff --git a/source/website/pluginregistry.js b/source/website/pluginregistry.js new file mode 100644 index 0000000..84f5d9f --- /dev/null +++ b/source/website/pluginregistry.js @@ -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); + } +} diff --git a/source/website/website.js b/source/website/website.js index c88b7bb..e862b41 100644 --- a/source/website/website.js +++ b/source/website/website.js @@ -2,7 +2,7 @@ import { GetFileExtension, TransformFileHostUrls } from '../engine/io/fileutils. import { InputFilesFromFileObjects, InputFilesFromUrls } from '../engine/import/importerfiles.js'; import { ImportErrorCode, ImportSettings } from '../engine/import/importer.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 { HandleEvent } from './eventhandler.js'; import { HashHandler } from './hashhandler.js'; @@ -14,7 +14,7 @@ import { ThreeModelLoaderUI } from './threemodelloaderui.js'; import { Toolbar } from './toolbar.js'; import { ShowExportDialog } from './exportdialog.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 { ShowSharingDialog } from './sharingdialog.js'; import { HasDefaultMaterial, ReplaceDefaultMaterialColor } from '../engine/model/modelutils.js'; @@ -24,6 +24,7 @@ import { MeasureTool } from './measuretool.js'; import { CloseAllDialogs } from './dialog.js'; import * as THREE from 'three'; +import { EnumeratePlugins, PluginType } from './pluginregistry.js'; export const WebsiteUIState = { @@ -58,6 +59,14 @@ export class Website this.SwitchTheme (this.settings.themeId, false); 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.InitToolbar (); this.InitDragAndDrop (); @@ -776,6 +785,18 @@ export class Website 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 () { let accepted = CookieGetBoolVal ('ov_cookie_consent', false); diff --git a/tools/create_package.py b/tools/create_package.py index efd71a4..caa5229 100644 --- a/tools/create_package.py +++ b/tools/create_package.py @@ -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', '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'] websiteFiles = [ 'o3dv/o3dv.website.min.css', @@ -54,6 +66,7 @@ def CreateDestinationDir (config, rootDir, websiteDir, version, testBuild): replacer = Tools.TokenReplacer (htmlFilePath, False) replacer.ReplaceTokenFileLinks ('', '', websiteLibFiles, version) replacer.ReplaceTokenFileLinks ('', '', websiteFiles, version) + replacer.ReplaceTokenFileLinks ('', '', pluginFiles, version) initScriptContent = '' initScriptContent += '' replacer.ReplaceTokenContent ('', '', initScriptContent) replacer.ReplaceTokenContent ('', '', 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): metaContent = Tools.GetFileContent (metaFile) replacer.ReplaceTokenContent ('', '', 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: analyticsContent = Tools.GetFileContent (analyticsFile) replacer.ReplaceTokenContent ('', '', analyticsContent) - scriptFile = os.path.join (rootDir, 'tools', 'website_script_data.txt') - if os.path.exists (scriptFile): - scriptContent = Tools.GetFileContent (scriptFile) - replacer.ReplaceTokenContent ('', '', scriptContent) - introFile = os.path.join (rootDir, 'tools', 'website_intro_data.txt') + introFile = os.path.join (rootDir, 'plugins', 'website_intro_data.txt') if os.path.exists (introFile): introContent = Tools.GetFileContent (introFile) replacer.ReplaceTokenContent ('', '', introContent) diff --git a/website/embed.html b/website/embed.html index 23eda1a..7ead7af 100644 --- a/website/embed.html +++ b/website/embed.html @@ -28,7 +28,7 @@ + + - - -