ScriptControllerIconView: Update to reflect policy type
This commit is contained in:
@@ -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?) {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user