Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Anchor scroll offset #9517

Merged
merged 3 commits into from
Oct 12, 2014

Conversation

petebacondarwin
Copy link
Contributor

No description provided.

@tbosch tbosch self-assigned this Oct 9, 2014
.config(['$locationProvider', function($locationProvider) {
$locationProvider.html5Mode(true).hashPrefix('!');
}]);
}]);
Copy link
Contributor

Choose a reason for hiding this comment

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

Missing newline

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed

});


// TODO: Add tests for <body> with:
Copy link
Contributor

Choose a reason for hiding this comment

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

Will you add those tests? Is there a problem?

var mockedDoc = {};
docSpies = {};

initialReadyState = initialReadyState || 'complete';
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't think we need this line as it is covered below when assigning the mockedDoc.readyState, no?

Copy link
Member

Choose a reason for hiding this comment

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

True. Will remove it.

var rect = elem.getBoundingClientRect();
var top = rect.top;
var height = rect.height;
offset = top + height;
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not use rect.bottom?

Copy link
Member

Choose a reason for hiding this comment

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

Why indeed ?! (Changed it.)

@petebacondarwin petebacondarwin added this to the 1.3.0-rc.6 milestone Oct 9, 2014

elmSpy[identifier] = spyOn(elm, 'scrollIntoView');
jqLite(document.body).append(jqElm);
jqLite($window.document.body).append(jqElm);
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we remove those elements from the document at the end of the tests?

Copy link
Member

Choose a reason for hiding this comment

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

I don't think so. We do dealoc($document), but that doesn't remove them if I am not mistaken.
Do we need to remove them ? They don't seem to stay in the DOM anyway (and the original "pre-yOffset" tests didn't remove them either).

Copy link
Contributor

Choose a reason for hiding this comment

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

So then dealoc($document) seems to work...

@tbosch tbosch mentioned this pull request Oct 9, 2014
addElements('id=some1', 'id=some2'),
function($window) {
// Make sure the elements are just a little shorter than the viewport height
var viewportHeight = $window.document.documentElement.clientHeight;
Copy link
Contributor

Choose a reason for hiding this comment

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

Could we just mock out getBoundingClientRect so that we don't have to deal with css sizing here? This would make the test more robust...

Copy link
Member

Choose a reason for hiding this comment

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

Now that the expression for calculating necessaryOffset only depends on getBoundingClientRect(), we can indeed mock that. But what's the fun in it ?

I believe at some point it would make sense to have some e2e tests for this (but putting it in the docs app is kind of too much). Maybe when this #9527 gets implemented, we could add some e2e tests and make these unit tests more "unit"-y (and robust).
For now I think it's a good thing that we have some minimal interaction with the actual functions.

WDYT ?

Copy link
Contributor

Choose a reason for hiding this comment

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

Let's keep it simple for now and don't do an integration test, as this would also make the test simpler. We did the same for $browser, and so far it turned out to be a good thing.

But yes, we should create a new issue to add e2e tests (reference #9527 in it) for the whole $anchorScroll service, where we also test the scrolling itself, and not just the calculation of the scroll position.

Copy link
Member

Choose a reason for hiding this comment

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

Sorry, I am not sure what yu mean: Shall we mock getBoundingClientRect() or keep the current approach (for now at least) ?

Copy link
Contributor

Choose a reason for hiding this comment

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

Please mock it.

@tbosch
Copy link
Contributor

tbosch commented Oct 9, 2014

@petebacondarwin I left all of my ideas as comments. Could you ping me when they are resolved?
Btw, where is the up to date PR?


expect(windowSpies.removeEventListener.callCount).toBe(1);
expect(windowSpies.removeEventListener).
toHaveBeenCalledWith('load', jasmine.any(Function), false);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

These checks are not really valid since jqLite actually passes its own callback which it then uses to iterates through all the handlers it knows about so if another party had added an event handler too then removeEventListener would not be called.

Copy link
Member

Choose a reason for hiding this comment

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

Indeed :(
Right now this is not the case (I tried it and it works (with Igor's fix), but we wouldn't want to rely on this as it might break any time.

Personally, I believe that switching to the load event (instead of readystatechange) compicates things with no tangible benefit (so far).
But I am not too familiar with jqLite, so there is a good chance I am missing something.
Suggestions very welcome :)

scrollTo: (windowSpies.scrollTo = jasmine.createSpy('$window.scrollTo')),
scrollBy: (windowSpies.scrollBy = jasmine.createSpy('$window.scrollBy')),
document: createMockDocument(initialReadyState),
navigator: {},
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think we need this

Copy link
Member

Choose a reason for hiding this comment

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

This was added in 7b739c9.
Not sure if it is still needed.

@petebacondarwin petebacondarwin force-pushed the anchorScroll-offset branch 2 times, most recently from 3561f13 to a08249d Compare October 10, 2014 21:53
document: document,
navigator: {}
});
function simulateWindowLoadEvent() {
Copy link
Contributor

Choose a reason for hiding this comment

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

Those two simulate functions don't do the same. Can we inline this function, as it is only used in one place?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I pulled them out so that their function names made the tests easier to read rather than to DRY up the code. Are you sure it is better to put it inline?

Copy link
Contributor

Choose a reason for hiding this comment

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

So I only meant the second one. If we leave it as a separate function we should rename it though. E.g. fireWindowLoadEvent...

This helper function can be used to execute a callback only after the
document has completed its loading, i.e. after the `load` event fires
or immediately if the page has already loaded and
`document.readyState === 'complete'`.
Add support for a configurable vertical scroll offset to `$anchorScroll`.

The offset can be defined by a specific number of pixels, a callback function
that returns the number of pixels on demand or a jqLite/JQuery wrapped DOM
element whose height and position are used if it has fixed position.

The offset algorithm takes into account items that are near the bottom of
the page preventing over-zealous offset correction.

Closes angular#9368
Closes angular#2070
Closes angular#9360
@petebacondarwin petebacondarwin merged commit 353de4f into angular:master Oct 12, 2014
@petebacondarwin petebacondarwin deleted the anchorScroll-offset branch November 24, 2016 09:20
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants