craft-native 0.0.467 → 0.0.471
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/ios/src/index.js +1 -0
- package/dist/ios/templates/CraftFramePacingLog.swift +18 -0
- package/dist/ios/templates/CraftHybrid.swift +5 -5
- package/dist/ios/templates/CraftNativeScreen.swift +4 -0
- package/dist/ios/templates/testing/DriverTests.swift.template +27 -3
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -3228,7 +3228,7 @@ function pinCraftNativeDependency(packagePath, craftVersion) {
|
|
|
3228
3228
|
`);
|
|
3229
3229
|
}
|
|
3230
3230
|
// package.json
|
|
3231
|
-
var version = "0.0.
|
|
3231
|
+
var version = "0.0.471";
|
|
3232
3232
|
|
|
3233
3233
|
// bin/cli.ts
|
|
3234
3234
|
var spawnedFrom = process6.env[CRAFT_CLI_SPAWN_MARKER];
|
package/dist/index.cjs
CHANGED
package/dist/index.js
CHANGED
package/dist/ios/src/index.js
CHANGED
|
@@ -1615,6 +1615,7 @@ function writeShell(output, config) {
|
|
|
1615
1615
|
writeSource(join4(output, "Sources", "CraftVoiceRecording.swift"), readFileSync3(join4(TEMPLATES_DIR, "CraftVoiceRecording.swift"), "utf8"));
|
|
1616
1616
|
writeSource(join4(output, "Sources", "CraftWebAudio.swift"), readFileSync3(join4(TEMPLATES_DIR, "CraftWebAudio.swift"), "utf8"));
|
|
1617
1617
|
writeSource(join4(output, "Sources", "CraftHybrid.swift"), readFileSync3(join4(TEMPLATES_DIR, "CraftHybrid.swift"), "utf8"));
|
|
1618
|
+
writeSource(join4(output, "Sources", "CraftFramePacingLog.swift"), readFileSync3(join4(TEMPLATES_DIR, "CraftFramePacingLog.swift"), "utf8"));
|
|
1618
1619
|
writeSource(join4(output, "Sources", "CraftCrashReporter.swift"), readFileSync3(join4(TEMPLATES_DIR, "CraftCrashReporter.swift"), "utf-8").replace(/\{\{CRAFT_VERSION\}\}/g, CRAFT_VERSION));
|
|
1619
1620
|
writeSource(join4(output, "Sources", "CraftLiveActivities.swift"), readFileSync3(join4(TEMPLATES_DIR, "CraftLiveActivities.swift"), "utf8"));
|
|
1620
1621
|
writeSource(join4(output, "Shared", "CraftActivityAttributes.swift"), readFileSync3(join4(TEMPLATES_DIR, "CraftActivityAttributes.swift"), "utf8"));
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
|
|
3
|
+
/// The opt-in frame trace shares one append-only file for this app process.
|
|
4
|
+
enum CraftFramePacingLog {
|
|
5
|
+
static func open(in directory: URL) throws -> FileHandle {
|
|
6
|
+
let manager = FileManager.default
|
|
7
|
+
try manager.createDirectory(at: directory, withIntermediateDirectories: true)
|
|
8
|
+
let url = directory.appendingPathComponent("craft-frame-pacing.log")
|
|
9
|
+
if !manager.fileExists(atPath: url.path),
|
|
10
|
+
!manager.createFile(atPath: url.path, contents: nil) {
|
|
11
|
+
throw NSError(domain: NSCocoaErrorDomain, code: NSFileWriteUnknownError,
|
|
12
|
+
userInfo: [NSFilePathErrorKey: url.path])
|
|
13
|
+
}
|
|
14
|
+
let handle = try FileHandle(forWritingTo: url)
|
|
15
|
+
_ = try handle.seekToEnd()
|
|
16
|
+
return handle
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -2703,11 +2703,11 @@ final class CraftFramePacing: NSObject {
|
|
|
2703
2703
|
private let output = DispatchQueue(label: "craft.frame-pacing", qos: .utility)
|
|
2704
2704
|
private lazy var file: FileHandle? = {
|
|
2705
2705
|
guard let caches = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first else { return nil }
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2706
|
+
do { return try CraftFramePacingLog.open(in: caches) }
|
|
2707
|
+
catch {
|
|
2708
|
+
NSLog("[craft frames] trace file unavailable: %@", String(describing: error))
|
|
2709
|
+
return nil
|
|
2710
|
+
}
|
|
2711
2711
|
}()
|
|
2712
2712
|
|
|
2713
2713
|
private func write(_ line: String) {
|
|
@@ -10779,6 +10779,10 @@ final class CraftNativeScreenController: UIViewController, UIScrollViewDelegate,
|
|
|
10779
10779
|
// beneath the screen's floating chrome.
|
|
10780
10780
|
let overflow = style["overflow"] as? String
|
|
10781
10781
|
view.clipsToBounds = overflow == "hidden"
|
|
10782
|
+
// A single-line editor owns a text viewport. Its private label
|
|
10783
|
+
// can be wider than the control while editing or showing a URL;
|
|
10784
|
+
// inherited visible overflow must not open that viewport.
|
|
10785
|
+
|| view is UITextField
|
|
10782
10786
|
|| (view is UIScrollView && overflow != "visible")
|
|
10783
10787
|
|| (view is UILabel && (view.craftRequestedCornerRadius ?? 0) > 0)
|
|
10784
10788
|
|| ((view is UIImageView || view is CraftNativePositionedImageView) && (borderRadius > 0 || hasCornerRadii))
|
|
@@ -182,6 +182,30 @@ final class DriverTests: XCTestCase {
|
|
|
182
182
|
return nil
|
|
183
183
|
}
|
|
184
184
|
|
|
185
|
+
/// Safari's web view extends behind its browser bars. Those regions accept
|
|
186
|
+
/// touches for the bars, not for page controls reported inside the web view.
|
|
187
|
+
func browserContentFrame(_ frame: CGRect, topBar: CGRect?, bottomBar: CGRect?) -> CGRect {
|
|
188
|
+
var top = frame.minY
|
|
189
|
+
var bottom = frame.maxY
|
|
190
|
+
if let bar = topBar, bar.contains(CGPoint(x: frame.midX, y: bar.midY)), bar.intersects(frame) {
|
|
191
|
+
top = max(top, bar.maxY)
|
|
192
|
+
}
|
|
193
|
+
if let bar = bottomBar, bar.contains(CGPoint(x: frame.midX, y: bar.midY)), bar.intersects(frame) {
|
|
194
|
+
bottom = min(bottom, bar.minY)
|
|
195
|
+
}
|
|
196
|
+
return CGRect(x: frame.minX, y: top, width: frame.width, height: max(0, bottom - top))
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
func scrollViewport() -> CGRect {
|
|
200
|
+
let webView = app.webViews.firstMatch
|
|
201
|
+
let topBar = app.otherElements["TopBrowserBar"]
|
|
202
|
+
let bottomBar = app.toolbars["BottomBrowserToolbar"]
|
|
203
|
+
guard webView.exists, topBar.exists || bottomBar.exists else { return app.frame }
|
|
204
|
+
return browserContentFrame(webView.frame.intersection(app.frame),
|
|
205
|
+
topBar: topBar.exists ? topBar.frame : nil,
|
|
206
|
+
bottomBar: bottomBar.exists ? bottomBar.frame : nil)
|
|
207
|
+
}
|
|
208
|
+
|
|
185
209
|
/// A short target fits entirely; an oversized target fills the viewport.
|
|
186
210
|
func visibleScrollFrame(_ target: CGRect, in viewport: CGRect) -> Bool {
|
|
187
211
|
let visible = target.intersection(viewport)
|
|
@@ -192,7 +216,7 @@ final class DriverTests: XCTestCase {
|
|
|
192
216
|
|
|
193
217
|
func scrollTargetVisible(_ target: XCUIElement?) -> Bool {
|
|
194
218
|
guard let target, target.exists, target.isHittable,
|
|
195
|
-
visibleScrollFrame(target.frame, in:
|
|
219
|
+
visibleScrollFrame(target.frame, in: scrollViewport()) else { return false }
|
|
196
220
|
// Hittable alone accepts controls clipped by the scroll view's edge.
|
|
197
221
|
// Only an ancestor scroll view clips this target, not its siblings.
|
|
198
222
|
// One that does not overlap the target is not its ancestor, whatever
|
|
@@ -220,7 +244,7 @@ final class DriverTests: XCTestCase {
|
|
|
220
244
|
/// below the screen while drawing it over the lower half - and it stops
|
|
221
245
|
/// short of a keyboard whose frame is known.
|
|
222
246
|
func scrollPage(towardTop: Bool) {
|
|
223
|
-
let frame =
|
|
247
|
+
let frame = scrollViewport()
|
|
224
248
|
var lower = frame.minY + frame.height * 0.55
|
|
225
249
|
let keyboard = app.keyboards.firstMatch
|
|
226
250
|
if keyboard.exists, !keyboard.frame.isEmpty, keyboard.frame.minY < frame.maxY {
|
|
@@ -719,7 +743,7 @@ final class DriverTests: XCTestCase {
|
|
|
719
743
|
var found = element(containing: arg)
|
|
720
744
|
var drags = 0
|
|
721
745
|
while !scrollTargetVisible(found) && drags < 12 {
|
|
722
|
-
let towardTop = found.map { !$0.frame.isEmpty && $0.frame.midY <
|
|
746
|
+
let towardTop = found.map { !$0.frame.isEmpty && $0.frame.midY < scrollViewport().midY } ?? false
|
|
723
747
|
scrollPage(towardTop: towardTop)
|
|
724
748
|
drags += 1
|
|
725
749
|
found = element(containing: arg)
|