-
Notifications
You must be signed in to change notification settings - Fork 3.5k
[cross_file] [web] Separate "Save As" implementation details from XFile web class #10397
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
[cross_file] [web] Separate "Save As" implementation details from XFile web class #10397
Conversation
…le web class - fixes #91400
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request refactors the 'Save As' functionality for the web implementation of XFile. The implementation details are moved from the XFile class into a new saveFileAs helper function in web_helpers.dart, which improves separation of concerns. The testing mechanism is also updated to use a global override instead of passing an override object.
My review includes suggestions to improve the new helper function for efficiency and clarity, and to ensure test hygiene by properly cleaning up the global test override.
| helpers.anchorElementOverride = (_, __) => mockAnchor; | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a good practice to clean up global state modifications within tests to prevent them from affecting other tests. Using addTearDown ensures that the override is reset even if the test fails.
addTearDown(() => helpers.anchorElementOverride = null);
helpers.anchorElementOverride = (_, __) => mockAnchor;| /// Saves the given [XFile] to user's device ("Save As" dialog). | ||
| Future<void> saveFileAs(XFile file, String path) async { | ||
| // Create container element. | ||
| final Element target = ensureInitialized('__x_file_dom_element'); | ||
|
|
||
| // Create <a> element. | ||
| final HTMLAnchorElement element = | ||
| anchorElementOverride != null | ||
| ? anchorElementOverride!(file.path, file.name) | ||
| : createAnchorElement(file.path, file.name); | ||
|
|
||
| // Clear existing children before appending new one. | ||
| while (target.children.length > 0) { | ||
| target.removeChild(target.children.item(0)!); | ||
| } | ||
|
|
||
| // Add and click. | ||
| addElementToContainerAndClick(target, element); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function can be improved for clarity and efficiency. The path parameter is unused and can be removed. Additionally, clearing the target element's children can be done more efficiently and expressively using replaceChildren. This also removes the need for the addElementToContainerAndClick helper for this use case. Remember to update the call site in XFile.saveTo.
/// Saves the given [XFile] to user's device ("Save As" dialog).
Future<void> saveFileAs(XFile file) async {
// Create container element.
final Element target = ensureInitialized('__x_file_dom_element');
// Create <a> element.
final HTMLAnchorElement element =
anchorElementOverride != null
? anchorElementOverride!(file.path, file.name)
: createAnchorElement(file.path, file.name);
// The new element replaces all the existing children of the container.
target.replaceChildren(element);
// Click the element to trigger the download.
element.click();
}
fixes Issue #91400
Replace this paragraph with a description of what this PR is changing or adding, and why. Consider including before/after screenshots.
List which issues are fixed by this PR. You must list at least one issue.
Pre-Review Checklist
[shared_preferences]pubspec.yamlwith an appropriate new version according to the [pub versioning philosophy], or I have commented below to indicate which [version change exemption] this PR falls under[^1].CHANGELOG.mdto add a description of the change, [following repository CHANGELOG style], or I have commented below to indicate which [CHANGELOG exemption] this PR falls under[^1].///).