Skip to content
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

HY-4649 track loaded fonts and add methods to unload fonts #10

Merged
merged 15 commits into from
Mar 29, 2017

Conversation

robbecker-wf
Copy link
Member

@robbecker-wf robbecker-wf commented Mar 24, 2017

Problem

There is no way to unload fonts once they are loaded

Solution

Track loaded fonts by key and group and provide a way to unload a single font by unique key or multiple fonts by group.
Bonus changes: each font is loaded with a separate style tag with attributes for key, group, and the number of uses.

Areas of Impact

  • Font loading and unloading.

Test Overview (+10 Instructions)

  • pub get and pub serve test
  • open http://localhost:8080/unload.html
  • Open dev tools and follow instructions.
  • expand the head element watch style elements be added and removed

Versioning

  • Major
    • This change removes part of the public API or modifies it in an incompatible manner
      • Justification for not being backwards-compatible:
  • Minor
    • This change adds something to the public API in a backwards-compatible manner
    • This change deprecates a part of the public API
  • Patch
    • This change does not affect the public API
    • This change fixes existing incorrect behavior
    • This change only affects tests (and not any exported test API, like test ids)

@aviary2-wf
Copy link

Raven

Number of Findings: 0

@rmconsole-wf
Copy link
Contributor

rmconsole-wf commented Mar 24, 2017

General Information

Ticket(s):

Code Review(s): #10

Additional Information

Reviewers: patkujawa-wf, tomconnell-wf
Watchlist Notifications: None

	When this pull is merged I will use the following information:
	Version: font_face_observer 1.0.2
	Release Ticket(s): HY-4420


Last updated on Wednesday, March 29 12:07 PM CST

@@ -23,7 +23,6 @@ const int DEFAULT_TIMEOUT = 3000;
const String DEFAULT_TEST_STRING = 'BESbswy';
const String _NORMAL = 'normal';
const int _NATIVE_FONT_LOADING_CHECK_INTERVAL = 50;
const String _FONT_FACE_CSS_ID = 'FONT_FACE_CSS';
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

constant for css class names moved to ruler.dart

@robbecker-wf robbecker-wf changed the title WIP track, and add methods to unload fonts track loaded fonts and add methods to unload Mar 27, 2017
@rmconsole2-wf rmconsole2-wf changed the title track loaded fonts and add methods to unload HY-4649 WIP track, and add methods to unload fonts Mar 27, 2017
@patkujawa-wf patkujawa-wf changed the title HY-4649 WIP track, and add methods to unload fonts HY-4649 track, and add methods to unload fonts Mar 27, 2017
int get uses => _uses;
void set uses(int new_uses) {
_uses = new_uses;
element.attributes['uses'] = _uses.toString();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be data-uses, but meh.

Copy link
Member Author

@robbecker-wf robbecker-wf Mar 27, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I kinda like the data attributes especially since this isn't a custom element. I'll revamp to use that.

@robbecker-wf
Copy link
Member Author

Ok, updated to use data attributes. Dart makes it super easy to read/write data attributes with the dataset Map on Element. so #winning.

@robbecker-wf robbecker-wf changed the title HY-4649 track, and add methods to unload fonts HY-4649 track loaded fonts and add methods to unload fonts Mar 27, 2017
@@ -70,6 +71,55 @@ main() {
expect(result.isLoaded, isTrue);
});

test('should not leave temp DOM nodes after detecting', () async {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which part of this test is "detecting"? ffo.load? isLoaded?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.load loads the fonts and waits for it to be loaded. Should I change the wording in the test desc to "load" ?

expect(styleElement.dataset['uses'],'1');


});

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be nice to unload multiple times and see if count goes negative.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will be removed once it is less than 1 and is covered by the test test('should unload a font by key', () async {

var loadedFont = _loadedFonts[k];
if (loadedFont.group == group ||
(group == "" && loadedFont.group == null)) {
keysToRemove.add(k);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's very surprising that passing null into this function will unload all fonts that were created without specifying a group. We chatted offline about this.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I updated to require a group, it uses a default value if you specify none.

return loadedFont != null && loadedFont.uses > 0;
}

static int unloadGroup(String group) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

docstrings pls. Specifically, what should the return value represent? And what are invalid inputs for group?

FontLoadResult r = await _result.future;
if (r.isLoaded) {
_LoadedFont loadedFont = _getLoadedFont(url);
loadedFont.uses++;
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, what if the result isn't loaded? Should this add a then to increment uses when it is loaded?

String get testString => _testString;

_LoadedFont _getLoadedFont(String url) {
var styleElement;
Copy link

@patkujawa-wf patkujawa-wf Mar 27, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice to have this typed, even as just Object or dynamic. EDIT: Why is it even outside the scope of the else?


FontFaceObserver(String this.family,
{String this.style: _NORMAL,
String this.weight: _NORMAL,
String this.stretch: _NORMAL,
String testString: DEFAULT_TEST_STRING,
int this.timeout: DEFAULT_TIMEOUT,
bool this.useSimulatedLoadEvents: false}) {
bool this.useSimulatedLoadEvents: false,
String this.group: ""}) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we discussed offline, use a default group and then add validation if group is customized that it must not be null or empty.

Copy link

@patkujawa-wf patkujawa-wf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's clean up grouping, plus some docstrings, then g2g.

bool get isLoaded {
var loadedFont = _loadedFonts[key];
return loadedFont != null && loadedFont.uses > 0;
}

/// A list of font keys for all currently loaded fonts
static List<String> get loadedFontKeys {
return _loadedFonts.keys.toList(growable: false);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably better to return this as a Set, because won't users most likely do a membership check? Or, asking another way, does the order really matter? If not, a set would be a more efficient way to check if a font is in the list of loaded keys.

loadedGroups.add(loadedFont.group);
}
});
return loadedGroups;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this function returned a Set, it would be easier to code (no need to check if it already contains), plus it would guarantee that the groups are unique (and thus no need for the docstring addendum).

/// A list of font keys for all currently loaded fonts
static List<String> get loadedFontKeys {
return _loadedFonts.keys.toList(growable: false);
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should return a Set too

@patkujawa-wf
Copy link

+1 CR with suggestions to use a Set

@patkujawa-wf
Copy link

+1 still

}

/// A list of groups that the currently loaded fonts are in
/// There will not be duplicate group entries if there are multiple fonts
/// in the same group.
static Iterable<String> get loadedGroups {
List<String> loadedGroups = [];
Set<String> loadedGroups = new Set<String>();
_loadedFonts.keys.forEach((k) {
var loadedFont = _loadedFonts[k];
if (!loadedGroups.contains(loadedFont.group)) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to do this check now that it's a Set

@patkujawa-wf
Copy link

+1 CR :shipit:

@tomconnell-wf
Copy link
Member

+10

Style elements get added and removed. Memory and nodes go down a little bit, but not all the way back down. (There is still one font that wouldn't unload.)

320908309

@tomconnell-wf
Copy link
Member

QA +1

  • Testing instruction
  • Dev +1's
  • Dev/QA +10 with detail of what was tested
  • Unit test created/updated
  • All unit tests pass
  • Rosie has run with clean dependency checks

Merging into master.

@tomconnell-wf
Copy link
Member

@Workiva/release-management-pp - Rosie, will you automerge?

@rmconsole-wf
Copy link
Contributor

+1 from RM

@rmconsole-wf rmconsole-wf merged commit c3f376e into master Mar 29, 2017
@rmconsole-wf rmconsole-wf deleted the unload_fonts branch March 29, 2017 17:07
@tomconnell-wf
Copy link
Member

run_merge_script

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants