diff --git a/source/engine/io/fileutils.js b/source/engine/io/fileutils.js index 3d81295..5391a0d 100644 --- a/source/engine/io/fileutils.js +++ b/source/engine/io/fileutils.js @@ -116,3 +116,10 @@ export function TransformFileHostUrls (urls) } } } + +export function IsUrl (str) +{ + const regex = /^https?:\/\/\S+$/g; + const match = str.match (regex); + return match !== null; +} diff --git a/source/engine/main.js b/source/engine/main.js index fde0dec..e1633c9 100644 --- a/source/engine/main.js +++ b/source/engine/main.js @@ -40,7 +40,7 @@ import { BinaryReader } from './io/binaryreader.js'; import { BinaryWriter } from './io/binarywriter.js'; import { ArrayBufferToUtf8String, ArrayBufferToAsciiString, AsciiStringToArrayBuffer, Utf8StringToArrayBuffer, Base64DataURIToArrayBuffer, GetFileExtensionFromMimeType, CreateObjectUrl, CreateObjectUrlWithMimeType, RevokeObjectUrl } from './io/bufferutils.js'; import { SetExternalLibLocation, GetExternalLibPath, LoadExternalLibrary } from './io/externallibs.js'; -import { GetFileName, GetFileExtension, RequestUrl, ReadFile, TransformFileHostUrls, FileSource, FileFormat } from './io/fileutils.js'; +import { GetFileName, GetFileExtension, RequestUrl, ReadFile, TransformFileHostUrls, IsUrl, FileSource, FileFormat } from './io/fileutils.js'; import { TextWriter } from './io/textwriter.js'; import { Color, ColorComponentFromFloat, ColorFromFloatComponents, SRGBToLinear, LinearToSRGB, IntegerToHexString, ColorToHexString, HexStringToColor, ArrayToColor, ColorIsEqual } from './model/color.js'; import { GeneratorParams, Generator, GeneratorHelper, GenerateCuboid, GenerateCone, GenerateCylinder, GenerateSphere, GeneratePlatonicSolid } from './model/generator.js'; @@ -188,6 +188,7 @@ export { RequestUrl, ReadFile, TransformFileHostUrls, + IsUrl, FileSource, FileFormat, TextWriter, diff --git a/source/website/sidebardetailspanel.js b/source/website/sidebardetailspanel.js index 1875943..29cacbd 100644 --- a/source/website/sidebardetailspanel.js +++ b/source/website/sidebardetailspanel.js @@ -6,7 +6,7 @@ import { Property, PropertyType } from '../engine/model/property.js'; import { AddDiv, AddDomElement, ClearDomElement } from '../engine/viewer/domutils.js'; import { SidebarPanel } from './sidebarpanel.js'; import { CreateInlineColorCircle } from './utils.js'; -import { GetFileName } from '../engine/io/fileutils.js'; +import { GetFileName, IsUrl } from '../engine/io/fileutils.js'; import { MaterialType } from '../engine/model/material.js'; import { ColorToHexString } from '../engine/model/color.js'; @@ -157,29 +157,35 @@ export class SidebarDetailsPanel extends SidebarPanel DisplayPropertyValue (property, targetDiv) { ClearDomElement (targetDiv); - let valueText = null; + let valueHtml = null; + let valueTitle = null; if (property.type === PropertyType.Text) { - valueText = property.value; + if (IsUrl (property.value)) { + valueHtml = '' + property.value + ''; + valueTitle = property.value; + } else { + valueHtml = property.value; + } } else if (property.type === PropertyType.Integer) { - valueText = property.value.toLocaleString (); + valueHtml = property.value.toLocaleString (); } else if (property.type === PropertyType.Number) { - valueText = property.value.toLocaleString (undefined, { + valueHtml = property.value.toLocaleString (undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 }); } else if (property.type === PropertyType.Boolean) { - valueText = property.value ? 'True' : 'False'; + valueHtml = property.value ? 'True' : 'False'; } else if (property.type === PropertyType.Percent) { - valueText = parseInt (property.value * 100, 10).toString () + '%'; + valueHtml = parseInt (property.value * 100, 10).toString () + '%'; } else if (property.type === PropertyType.Color) { let hexString = '#' + ColorToHexString (property.value); let colorCircle = CreateInlineColorCircle (property.value); targetDiv.appendChild (colorCircle); AddDomElement (targetDiv, 'span', null, hexString); } - if (valueText !== null) { - targetDiv.innerHTML = valueText; - targetDiv.setAttribute ('title', valueText); + if (valueHtml !== null) { + targetDiv.innerHTML = valueHtml; + targetDiv.setAttribute ('title', valueTitle !== null ? valueTitle : valueHtml); } } } diff --git a/test/tests/fileutils_test.js b/test/tests/fileutils_test.js index 64cf1d7..0f6151c 100644 --- a/test/tests/fileutils_test.js +++ b/test/tests/fileutils_test.js @@ -42,6 +42,20 @@ describe ('File Utils', function () { assert.deepStrictEqual (GetLines ('apple\r\n'), ['apple']); assert.deepStrictEqual (GetLines ('\r\napple\r\n'), ['apple']); }); + + it ('Is URL', function () { + assert.ok (!OV.IsUrl ('')); + assert.ok (!OV.IsUrl ('google')); + assert.ok (!OV.IsUrl ('google.com')); + assert.ok (!OV.IsUrl ('the http://google.com')); + assert.ok (!OV.IsUrl ('http://google.com the')); + assert.ok (OV.IsUrl ('http://google.com')); + assert.ok (OV.IsUrl ('https://google.com')); + assert.ok (OV.IsUrl ('http://www.google.com')); + assert.ok (OV.IsUrl ('https://www.google.com')); + assert.ok (OV.IsUrl ('https://www.google.com#param1=a¶m2=b')); + assert.ok (OV.IsUrl ('https://www.google.com?param1=a¶m2=a')); + }); }); }