From 44b47229dbcbdd038818bbecd252a6ec459b336f Mon Sep 17 00:00:00 2001 From: Mattes Mohr Date: Tue, 31 Dec 2024 11:48:38 +0100 Subject: [PATCH] Make the sandbox modifier accept an enum (#167) * Make the sandbox modifier accept an enum * Assign the sandbox attribute to the inlineframe element --- .../Attributes/BasicAttributes.swift | 33 +++++++++++-- .../Abstraction/Elements/BodyElements.swift | 14 +++++- .../Abstraction/Tokens/ValueTokens.swift | 46 +++++++++++++++++++ Tests/HTMLKitTests/AttributesTests.swift | 14 +++++- 4 files changed, 101 insertions(+), 6 deletions(-) diff --git a/Sources/HTMLKit/Abstraction/Attributes/BasicAttributes.swift b/Sources/HTMLKit/Abstraction/Attributes/BasicAttributes.swift index c33bf45c..08f1f17f 100644 --- a/Sources/HTMLKit/Abstraction/Attributes/BasicAttributes.swift +++ b/Sources/HTMLKit/Abstraction/Attributes/BasicAttributes.swift @@ -2191,16 +2191,41 @@ extension RowSpanAttribute where Self: EmptyNode { } } -/// The protocol provides the element with the sandbox handler. +/// A type that provides the `sandbox` modifier. +/// +/// > Note: Currently, this protocol is only applicable to `InlineFrame`. @_documentation(visibility: internal) public protocol SandboxAttribute: Attribute { - /// The function represents the html-attribute 'sandbox'. + /// Define the permissions for the element. /// - /// ```html - /// + /// ```swift + /// InlineFrame { + /// } + /// .source("https://...") + /// .sandbox() /// ``` func sandbox() -> Self + + /// Define the permissions for the element. + /// + /// ```swift + /// InlineFrame { + /// } + /// .source("https://...") + /// .sandbox(.allowDownloads) + /// ``` + func sandbox(_ value: Values.Permission) -> Self + + /// Define the permissions for the element. + /// + /// ```swift + /// InlineFrame { + /// } + /// .source("https://...") + /// .sandbox([.allowDownloads, .allowPopups]) + /// ``` + func sandbox(_ values: OrderedSet) -> Self } extension SandboxAttribute where Self: ContentNode { diff --git a/Sources/HTMLKit/Abstraction/Elements/BodyElements.swift b/Sources/HTMLKit/Abstraction/Elements/BodyElements.swift index b7278831..f88be770 100644 --- a/Sources/HTMLKit/Abstraction/Elements/BodyElements.swift +++ b/Sources/HTMLKit/Abstraction/Elements/BodyElements.swift @@ -15956,7 +15956,7 @@ public struct InlineFrame: ContentNode, HtmlElement, BodyElement, FormElement, F } } -extension InlineFrame: GlobalAttributes, GlobalEventAttributes, GlobalAriaAttributes, SourceAttribute, NameAttribute, WidthAttribute, HeightAttribute, ReferrerPolicyAttribute & LoadingAttribute { +extension InlineFrame: GlobalAttributes, GlobalEventAttributes, GlobalAriaAttributes, SourceAttribute, NameAttribute, WidthAttribute, HeightAttribute, ReferrerPolicyAttribute & LoadingAttribute & SandboxAttribute { public func accessKey(_ value: Character) -> InlineFrame { return mutate(accesskey: value) @@ -16085,6 +16085,18 @@ extension InlineFrame: GlobalAttributes, GlobalEventAttributes, GlobalAriaAttrib return self } + public func sandbox() -> InlineFrame { + return mutate(sandbox: "sandbox") + } + + public func sandbox(_ value: Values.Permission) -> InlineFrame { + return mutate(sandbox: value.rawValue) + } + + public func sandbox(_ values: OrderedCollections.OrderedSet) -> InlineFrame { + return mutate(sandbox: values.map { $0.rawValue }.joined(separator: " ")) + } + public func source(_ value: String) -> InlineFrame { return mutate(source: value) } diff --git a/Sources/HTMLKit/Abstraction/Tokens/ValueTokens.swift b/Sources/HTMLKit/Abstraction/Tokens/ValueTokens.swift index 6657f9eb..2279857b 100644 --- a/Sources/HTMLKit/Abstraction/Tokens/ValueTokens.swift +++ b/Sources/HTMLKit/Abstraction/Tokens/ValueTokens.swift @@ -1188,4 +1188,50 @@ public enum Values { /// Expects a url for instant messaging case messagingProtocol = "impp" } + + /// A enumeration of extra permission + /// + /// ```swift + /// InlineFrame { + /// } + /// .sandbox([.allowDownloads, .allowForms]) + /// ``` + public enum Permission: String { + + /// Permits downloads + case allowDownloads = "allow-downloads" + + /// Permits form submissions within the content + case allowForms = "allow-forms" + + /// Permits to open modals + case allowModals = "allow-modals" + + /// Permits to lock the screen orientation + case allowOrientationLock = "allow-orientation-lock" + + /// Permits the use of the pointer lock API + case allowPointerLock = "allow-pointer-lock" + + /// Permits to open popups + case allowPopups = "allow-popups" + + /// Permits popups to open new windows without inheriting the sandboxing + case allowPopupsToEscapeSandbox = "allow-popups-to-escape-sandbox" + + /// Permits to start a presentation session + case allowPresentation = "allow-presentation" + + /// Permits the content to be treated as being from the same origin + case allowSameOrigin = "allow-same-origin" + + /// Permits script execution + case allowScripts = "allow-scripts" + + /// Permits the content to navigate its top-level browsing context + case allowTopNavigation = "allow-top-navigation" + + /// Permits the content to navigate its top-level browsing context, but only if initiated by user + case allowTopNavigationByUserActivation = "allow-top-navigation-by-user-activation" + } } diff --git a/Tests/HTMLKitTests/AttributesTests.swift b/Tests/HTMLKitTests/AttributesTests.swift index 49b4c143..f0f2bcd5 100644 --- a/Tests/HTMLKitTests/AttributesTests.swift +++ b/Tests/HTMLKitTests/AttributesTests.swift @@ -439,6 +439,14 @@ final class AttributesTests: XCTestCase { return self.mutate(sandbox: "sandbox") } + func sandbox(_ value: Values.Permission) -> Tag { + return self.mutate(sandbox: value.rawValue) + } + + func sandbox(_ values: OrderedSet) -> Tag { + return self.mutate(sandbox: values.map { $0.rawValue }.joined(separator: " ")) + } + func scope(_ value: Values.Scope) -> Tag { return self.mutate(scope: value.rawValue) } @@ -1834,11 +1842,15 @@ final class AttributesTests: XCTestCase { let view = TestView { Tag {}.sandbox() + Tag {}.sandbox(.allowDownloads) + Tag {}.sandbox([.allowDownloads, .allowForms]) } XCTAssertEqual(try renderer.render(view: view), """ - + \ + \ + """ ) }