ScriptControllerIconView: Update to reflect policy type

This commit is contained in:
James Magahern
2021-10-21 15:08:04 -07:00
parent fc7380ed21
commit 291abfcd6a
8 changed files with 96 additions and 32 deletions

View File

@@ -513,17 +513,20 @@ class BrowserViewController: UIViewController
numBlockedScripts += 1
}
var scriptsAllowedForHost = false
if let url = webView.url, let host = url.host, policyManager.allowedOriginsForScriptResources().contains(host) {
scriptsAllowedForHost = true
var policy: ScriptPolicy? = nil
if let url = webView.url, let host = url.host {
policy = policyManager.scriptPolicy(forOrigin: host)
}
let iconView = toolbarController.scriptControllerIconView
iconView.shieldsDown = tab.javaScriptEnabled
iconView.someScriptsAllowed = scriptsAllowedForHost
iconView.setBlockedScriptsNumber(numBlockedScripts)
// iconView.setBlockedScriptsNumber(numBlockedScripts)
// iconView.isEnabled = (webView.url != nil)
if let policy = policy {
iconView.currentPolicy = policy
}
iconView.isEnabled = (webView.url != nil)
}
public func createNewTab(withURL url: URL?) {

View File

@@ -125,11 +125,13 @@ class ReliefButton: UIButton
override func imageRect(forContentRect contentRect: CGRect) -> CGRect {
let ratio = CGFloat(0.45)
let constantSize = round(ratio * contentRect.width)
return CGRect(
origin: .zero,
size: CGSize(
width: ratio * contentRect.width,
height: ratio * contentRect.width
// Ensure multiple of two for proper centering.
width: constantSize + constantSize.truncatingRemainder(dividingBy: 2),
height: constantSize + constantSize.truncatingRemainder(dividingBy: 2)
)
).centered(inRect: contentRect)
}

View File

@@ -13,17 +13,16 @@ class ScriptControllerIconView: ReliefButton
didSet { setNeedsLayout() }
}
public var someScriptsAllowed: Bool = false {
didSet { setNeedsLayout() }
}
@Invalidating(.layout)
public var currentPolicy: ScriptPolicy = ScriptPolicy(securityOrigin: "", policyType: .alpha)
private let labelView = UILabel(frame: .zero)
private let policyImageView = UIImageView(frame: .zero)
private let shieldsDownImage = UIImage(systemName: "shield.slash")
private let shieldsUpImage = UIImage(systemName: "shield")
private let shieldsPartiallyUpImage = UIImage(systemName: "shield.lefthalf.fill")
override init() {
super.init()
@@ -37,6 +36,8 @@ class ScriptControllerIconView: ReliefButton
labelView.font = .boldSystemFont(ofSize: 8)
labelView.textColor = .white
policyImageView.contentMode = .scaleAspectFit
setBlockedScriptsNumber(0)
}
@@ -62,13 +63,34 @@ class ScriptControllerIconView: ReliefButton
labelView.center = CGPoint(x: bounds.center.x + 10, y: bounds.center.y + 10)
labelView.bounds = labelView.bounds.insetBy(dx: -3.0, dy: -2.0)
let policyImageWidth = round(bounds.width / 3)
let policyImageSize = CGSize(
// Make multiple of 2 to ensure proper centering
width: policyImageWidth - policyImageWidth.truncatingRemainder(dividingBy: 2),
height: policyImageWidth - policyImageWidth.truncatingRemainder(dividingBy: 2)
)
if let imageView = imageView {
imageView.addSubview(policyImageView)
policyImageView.frame = CGRect(origin: .zero, size: policyImageSize)
.centered(inRect: imageView.bounds)
.offsetBy(dx: 0.0, dy: -1.0)
}
if shieldsDown {
setImage(shieldsDownImage, for: .normal)
} else {
if someScriptsAllowed {
setImage(shieldsPartiallyUpImage, for: .normal)
} else {
setImage(shieldsUpImage, for: .normal)
if isEnabled {
policyImageView.isHidden = false
policyImageView.image = ScriptPolicy.iconRepresentation(forPolicyType: currentPolicy.policyType, configuration: ScriptPolicy.IconConfiguration(
size: policyImageSize,
foregroundColor: .label,
backgroundColor: .clear
))
} else {
policyImageView.isHidden = true
}
}
}

View File

@@ -51,10 +51,16 @@ class ScriptPolicyViewController: UIViewController, UICollectionViewDelegate
let scriptPolicyRegistry = UICollectionView.CellRegistration<UICollectionViewListCell, Item> { (listCell, indexPath, item) in
guard case let Item.policy(policyType) = item else { return }
let iconSize = CGSize(width: 24.0, height: 24.0)
var config = listCell.defaultContentConfiguration()
config.text = ScriptPolicy.title(forPolicyType: policyType)
config.secondaryText = ScriptPolicy.localizedDescription(forPolicyType: policyType)
config.image = ScriptPolicy.iconRepresentation(forPolicyType: policyType, size: CGSize(width: 24.0, height: 24.0))
config.image = ScriptPolicy.iconRepresentation(forPolicyType: policyType, configuration: ScriptPolicy.IconConfiguration(
size: iconSize,
foregroundColor: .white,
backgroundColor: .black
))
config.textProperties.font = UIFont.boldSystemFont(ofSize: 14.0)

View File

@@ -6,10 +6,11 @@
//
#import <Foundation/Foundation.h>
#import <QuartzCore/QuartzCore.h>
NS_ASSUME_NONNULL_BEGIN
@class UIImage;
@class UIImage, UIColor;
typedef NS_ENUM(NSInteger, SBRScriptOriginPolicyType) {
SBRScriptOriginPolicyTypeAlpha,
@@ -19,6 +20,15 @@ typedef NS_ENUM(NSInteger, SBRScriptOriginPolicyType) {
SBRScriptOriginPolicyTypeEcho,
} NS_SWIFT_NAME(ScriptPolicy.PolicyType);
NS_SWIFT_NAME(ScriptPolicy.IconConfiguration)
@interface SBRScriptPolicyIconConfiguration : NSObject
@property (nonatomic, readwrite) CGSize size;
@property (nonatomic, strong, nullable) UIColor *foregroundColor;
@property (nonatomic, strong, nullable) UIColor *backgroundColor;
- (instancetype)initWithSize:(CGSize)size foregroundColor:(nullable UIColor *)foregroundColor backgroundColor:(nullable UIColor *)backgroundColor;
@end
NS_SWIFT_NAME(ScriptPolicy)
@interface SBRScriptPolicy : NSObject <NSSecureCoding>
@property (nonatomic, copy) NSString *origin;
@@ -30,8 +40,8 @@ NS_SWIFT_NAME(ScriptPolicy)
+ (NSString *)localizedDescriptionForPolicyType:(SBRScriptOriginPolicyType)policyType
NS_SWIFT_NAME(localizedDescription(forPolicyType:));
+ (UIImage *)iconRepresentationForPolicyType:(SBRScriptOriginPolicyType)policyType withSize:(CGSize)size
NS_SWIFT_NAME(iconRepresentation(forPolicyType:size:));
+ (UIImage *)iconRepresentationForPolicyType:(SBRScriptOriginPolicyType)policyType withConfiguration:(SBRScriptPolicyIconConfiguration *)configuration
NS_SWIFT_NAME(iconRepresentation(forPolicyType:configuration:));
- (instancetype)initWithSecurityOrigin:(NSString *)origin policyType:(SBRScriptOriginPolicyType)policyType;

View File

@@ -10,6 +10,10 @@
// For icon drawing
#import <UIKit/UIKit.h>
static CGFloat RoundToScale(CGFloat v, CGFloat s) {
return round(v * s) / s;
}
@implementation SBRScriptPolicy
+ (NSSet<NSString *> *)_commonCDNOrigins {
@@ -70,17 +74,20 @@
}
}
+ (UIImage *)iconRepresentationForPolicyType:(SBRScriptOriginPolicyType)policyType withSize:(CGSize)size
+ (UIImage *)iconRepresentationForPolicyType:(SBRScriptOriginPolicyType)policyType withConfiguration:(nonnull SBRScriptPolicyIconConfiguration *)configuration
{
const CGSize size = [configuration size];
UIFont *font = [UIFont boldSystemFontOfSize:size.height - 2];
NSDictionary<NSAttributedStringKey, id> *attrs = @{
NSFontAttributeName : font,
NSForegroundColorAttributeName : [UIColor whiteColor]
NSForegroundColorAttributeName : [configuration foregroundColor] ?: [UIColor whiteColor],
};
const CGFloat scale = UIScreen.mainScreen.scale;
const CGRect rect = (CGRect) { .origin = CGPointZero, .size = size };
UIGraphicsBeginImageContextWithOptions(size, NO, UIScreen.mainScreen.scale);
UIGraphicsBeginImageContextWithOptions(size, NO, scale);
[([configuration backgroundColor] ?: [UIColor blackColor]) setFill];
UIBezierPath *backgroundPath = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:4.0];
[backgroundPath fill];
@@ -98,7 +105,10 @@
character = @"𝝴"; break;
}
const CGSize charSize = [character sizeWithAttributes:attrs];
CGSize charSize = [character sizeWithAttributes:attrs];
charSize.width = RoundToScale(charSize.width, scale);
charSize.height = RoundToScale(charSize.height, scale);
const CGRect charRect = (CGRect) {
.origin = (CGPoint) {
.x = (size.width - charSize.width) / 2,
@@ -203,3 +213,18 @@
}
@end
@implementation SBRScriptPolicyIconConfiguration
- (instancetype)initWithSize:(CGSize)size foregroundColor:(nullable UIColor *)foregroundColor backgroundColor:(nullable UIColor *)backgroundColor
{
if (self = [super init]) {
_size = size;
_foregroundColor = foregroundColor;
_backgroundColor = backgroundColor;
}
return self;
}
@end

View File

@@ -711,7 +711,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
@@ -767,7 +767,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = iphoneos.internal;
@@ -789,12 +789,10 @@
CURRENT_PROJECT_VERSION = 2;
DEVELOPMENT_TEAM = DQQH5H6GBD;
INFOPLIST_FILE = "App/Supporting Files/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 10.15;
MARKETING_VERSION = 2.0;
PRODUCT_BUNDLE_IDENTIFIER = net.buzzert.rosslerattix;
PRODUCT_NAME = "rossler attix";
@@ -819,12 +817,10 @@
CURRENT_PROJECT_VERSION = 2;
DEVELOPMENT_TEAM = DQQH5H6GBD;
INFOPLIST_FILE = "App/Supporting Files/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 10.15;
MARKETING_VERSION = 2.0;
PRODUCT_BUNDLE_IDENTIFIER = net.buzzert.rosslerattix;
PRODUCT_NAME = "rossler attix";

View File

@@ -32,8 +32,8 @@
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
selectedDebuggerIdentifier = ""
selectedLauncherIdentifier = "Xcode.IDEFoundation.Launcher.PosixSpawn"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"