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

Add front page and legacy Via URL support #443

Merged
merged 2 commits into from
Apr 19, 2021
Merged

Add front page and legacy Via URL support #443

merged 2 commits into from
Apr 19, 2021

Conversation

seanh
Copy link
Contributor

@seanh seanh commented Apr 16, 2021

See #424
TODO:

  • The front page needs to be optional. LMS's Via shouldn't have one
  • Add options to disable the LMS lockdown: Add Via 3 & Via HTML options to disable the LMS-only lockdown checkmate#99
  • Make sure that the via.hypothes.is URL isn't used as the annotation's target URL (for either PDFs or HTML) (this needs to be done before we can release this to users but I'll probably create a separate issue for it, we can deploy and test this PR without fixing this)

Known issues:

  • The URL in the location bar won't change if the iframe is navigated. For example if the third-party URL returns a redirect. I think this is different from how legacy Via behaves. But I'm not completely sure it's actually a problem. I might propose to open an issue to track this but not fix it unless we decide we have to.

    In theory I think this is fixable by adding a bit of JavaScript to either poll or get notified of changes to the iframe's URL and push new URLs onto the location bar without triggering page reloads.

Comment on lines 9 to 25
body {
margin: 0;
padding: 0;
}

.iframe {
position:fixed;
top:0;
left:0;
bottom:0;
right:0;
width:100%;
height:100%;
border:none;
margin:0;
padding:0;
overflow:hidden;
z-index:999999;
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@robertknight @lyzadanger What's the right way to create an invisible "full-screen" iframe? This seems to work

Comment on lines -14 to -19
def test_get_front_page(self, test_app):
response = test_app.get("/", status=404)

assert dict(response.headers) == Any.dict.containing(
{"Content-Type": Any.string.containing("text/plain")}
)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The front page is no longer a 404. Also it's not served as static content anymore

Comment on lines +8 to +70
<style>
body {
font-family: "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
height: 100vh;
padding: 0;
margin: 0;
}

.content {
align-items: center;
display: flex;
flex-direction: column;
height: 100%;
justify-content: center;
max-height: 70vh;
}

.url-form {
align-items: center;
display: flex;
flex-direction: column;
max-width: 400px;
width: 95%;
}

/* Input field for URL to annotate. */
.url-field {
align-self: stretch;
border-radius: 3px;
border: 1px solid #ccc;
font-size: 20px;
margin-bottom: 20px;
margin-top: 20px;
min-height: 45px;
padding-bottom: 5px;
padding-left: 16px;
padding-right: 16px;
padding-top: 5px;
}

.url-field:focus {
border-color: #3f3f3f;
}

/* Button that takes the user to the proxied page. */
.annotate-btn {
background-color: #3f3f3f;
border-radius: 3px;
border: none;
color: #fff;
cursor: pointer;
font-size: 20px;
font-weight: 700;
padding-bottom: 10px;
padding-left: 15px;
padding-right: 15px;
padding-top: 10px;
}

.annotate-btn:hover {
background-color: #d00032;
}
</style>
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This CSS is all as-in legacy Via

Comment on lines +74 to +83
<a href="https://hypothes.is">
<svg xmlns="http://www.w3.org/2000/svg"
width="100"
height="100"
viewBox="0 0 24 28"
aria-labelledby="logo-title">
<title id="logo-title">Hypothesis homepage</title>
<g fill="none" fill-rule="evenodd"><path fill="#FFF" fill-rule="nonzero" d="M3.886 3.945H21.03v16.047H3.886z"/><path d="M0 2.005C0 .898.897 0 2.005 0h19.99C23.102 0 24 .897 24 2.005v19.99A2.005 2.005 0 0 1 21.995 24H2.005A2.005 2.005 0 0 1 0 21.995V2.005zM9 24h6l-3 4-3-4zM7.008 4H4v16h3.008v-4.997C7.008 12.005 8.168 12.01 9 12c1 .007 2.019.06 2.019 2.003V20h3.008v-6.891C14.027 10 12 9.003 10 9.003c-1.99 0-2 0-2.992 1.999V4zM19 19.987c1.105 0 2-.893 2-1.994A1.997 1.997 0 0 0 19 16c-1.105 0-2 .892-2 1.993s.895 1.994 2 1.994z" fill="#3F3F3F"/></g>
</svg>
</a>
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Logo as in legacy Via

Comment on lines +95 to +103
<p>
Via is a closed proxy that lets you annotate web pages and PDFs with
Hypothesis. Only a small number of known sites can be annotated. If you'd
like to annotate a site that isn't allowed please
<a href="https://web.hypothes.is/via-request/">ask us to add it to the allowed list.</a>
See our
<a href="https://web.hypothes.is/help/what-is-the-via-proxy/">help article</a>
for more information.
</p>
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Same exact notice as from legacy Via

renderer="via:templates/exception.html.jinja2",
# Match any page *except* the front page ("/").
# We don't want our fancy error page to be used on the front page.
path_info=not_(r"^\/$"),
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We actually do want to apply the exception view to the front page now

Copy link
Member

Choose a reason for hiding this comment

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

Can you clarify when this would be used in the context of the front page?

Copy link
Contributor Author

@seanh seanh Apr 19, 2021

Choose a reason for hiding this comment

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

Actually I don't think that it can be used, since the views for the front page never raise anything, but the the exception was put here originally when we removed Via 3's front page (to hide Via 3 from abusers because we didn't want the resulting 404 for via3.hypothes.is requests to cause the fancy error page to kick in. Now that we're putting the front page back it's no longer needed

Comment on lines +4 to +13
@view_config(route_name="proxy", renderer="via:templates/proxy.html.jinja2")
def proxy(request):
url = request.path[1:] # Strip the leading "/" from the path.

# Let people just type in "example.com" or link to
# via.hypothes.is/example.com and have that proxy https://example.com.
if not (url.startswith("http://") or url.startswith("https://")):
url = "https://" + url

return {"src": request.route_url("route_by_content", _query={"url": url})}
Copy link
Contributor Author

@seanh seanh Apr 16, 2021

Choose a reason for hiding this comment

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

This is the view that implements the legacy Via-style URLs. It accepts requests to via.hypothes.is/<URL_TO_BE_PROXIED> and renders a page containing an iframe whose src is via.hypothes.is/route?url=<URL_TO_BE_PROXIED>. That iframe will then get redirect to either /pdf or to Via HTML as appropriate, but the user isn't seeing the iframe's URL in the location bar so the /route, /pdf and Via HTML URLs are hidden from the user

Copy link
Member

Choose a reason for hiding this comment

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

It would be nice to save that extra redirect from the flow, since that involves an extra roundtrip between the user's browser and Via.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Maybe caching?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Actually, the new view can also do the same PDF-or-HTML check that the /route view does and inject the /pdf or Via HTML URL directly, so we should be able to remove the extra round trip

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Made an issue for this #451

Comment on lines 10 to 16
@staticmethod
@view_config(request_method="GET", renderer="via:templates/index.html.jinja2")
def get():
return {}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The front page. Renders the form where you can enter a URL that you want to annotate

Comment on lines 15 to 27
@view_config(request_method="POST")
def post(self):
return HTTPFound(
self.request.route_url(
route_name="proxy", url=self.request.params.get("url", "")
)
)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is the view for POST requests to the front page. Accepts form submissions and redirects to the legacy Via-style URL for proxying the URL that was submitted in the form.

If there is no url param or if it's an empty string this ends up redirecting back to the front page.

If url isn't a valid URL that'll trigger the existing nice error page when we try to proxy it. There's no need for this view to validate URLs.

@seanh seanh changed the title Add front page Add front page and legacy Via URL support Apr 16, 2021
@seanh seanh marked this pull request as ready for review April 16, 2021 17:13
@seanh seanh requested a review from robertknight April 16, 2021 17:13
@robertknight
Copy link
Member

Make sure that the via.hypothes.is URL isn't used as the annotation's target URL (for either PDFs or HTML)

For PDFs this was addressed by #427. For HTML documents this is handled by a <link rel="canonical"> in the page. See https://github.com/hypothesis/viahtml/blob/eee5fb4a6bbc59cdd7ba1066ad350ff0c10fb3cd/viahtml/templates/banner.html#L2.

@robertknight
Copy link
Member

robertknight commented Apr 19, 2021

In theory I think this is fixable by adding a bit of JavaScript to either poll or get notified of changes to the iframe's URL and push new URLs onto the location bar without triggering page reloads.

Yes, something like the following in the viahtml iframe:

// Is this a top-level iframe embedded inside Via?
if (window.top !== window && window.top === window.parent) {
  window.top.postMessage({
    type: 'via:urlChange',
    url: window.location.href,
  }, '*');
}

And then corresponding code in the Via 3 frame that uses the history API to update the URL.

The most obvious and immediate deficiency from a user's point of view though is that the document title is not set. We could notify Via about that in a similar way.

Copy link
Member

@robertknight robertknight left a comment

Choose a reason for hiding this comment

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

LGTM with some minor feedback and queries on the CSS.

From the user's perspective the most obvious issue with the iframe approach from initial testing is that the proxied document's title, favicon and loading status are not reflected in the tab state. Reflecting basic document metadata (or some variant of it) is something that can be solved. I'm not sure about the loading status. We might want to consider displaying some kind of placeholder in the blank frame until it has loaded.

<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>via.hypothes.is</title>
<link rel="icon" href="favicon.ico" type="image/x-icon" />
Copy link
Member

Choose a reason for hiding this comment

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

If we're going the iframe route I do think we'll need to work on updating at least some of the parent page metadata (eg. title) to make tabs distinguishable from one another. A bonus here is that we can easily add some indicator that the frame is being proxied through Via to make it easily distinguishable from the original page in bookmarks etc.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh yeah, that's nice. I think we probably actually want the favicon to be the Hypothesis one not the third-party one. But we could set the tab title to something like Via - <title of third-party page> (or perhaps Hypothesis - ?)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Made an issue for this: hypothesis/viahtml#154

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Note that I don't think we want the favicon to change (even though it does with legacy Via)

autofocus
class="url-field"
name="url"
placeholder="Paste a link to annotate"
Copy link
Member

Choose a reason for hiding this comment

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

Legacy Via has a slightly different placeholder which reads "Paste a link to create or view annotations".

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes I know, I thought I'd sneak this change in :) "Create or view annotations" is pretty awkward, typical Hypothesis-speak. Maybe it should say "Create or view annotations, highlights and page notes" :)

margin: 0;
padding: 0;
overflow: hidden;
z-index: 999999;
Copy link
Member

Choose a reason for hiding this comment

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

What is the z-index for? There is nothing that the iframe needs to be positioned on top of.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not sure, it doesn't seem to be necessary so I'll try removing it

border: none;
margin: 0;
padding: 0;
overflow: hidden;
Copy link
Member

Choose a reason for hiding this comment

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

What is overflow for? An iframe can't overflow its container AFAIK so there is no need for that.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Again not sure, I'll try removing it

padding: 0;
}

.iframe {
Copy link
Member

Choose a reason for hiding this comment

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

Can you give this class a more meaningful name. Say proxied-content-iframe.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

👍

renderer="via:templates/exception.html.jinja2",
# Match any page *except* the front page ("/").
# We don't want our fancy error page to be used on the front page.
path_info=not_(r"^\/$"),
Copy link
Member

Choose a reason for hiding this comment

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

Can you clarify when this would be used in the context of the front page?

# Let people just type in "example.com" or link to
# via.hypothes.is/example.com and have that proxy https://example.com.
if not (url.startswith("http://") or url.startswith("https://")):
url = "https://" + url
Copy link
Member

Choose a reason for hiding this comment

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

IIRC legacy via used to default to http:// but I think https:// is the right choice in the modern era. We'll have to keep an eye out for this.

Comment on lines +4 to +13
@view_config(route_name="proxy", renderer="via:templates/proxy.html.jinja2")
def proxy(request):
url = request.path[1:] # Strip the leading "/" from the path.

# Let people just type in "example.com" or link to
# via.hypothes.is/example.com and have that proxy https://example.com.
if not (url.startswith("http://") or url.startswith("https://")):
url = "https://" + url

return {"src": request.route_url("route_by_content", _query={"url": url})}
Copy link
Member

Choose a reason for hiding this comment

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

It would be nice to save that extra redirect from the flow, since that involves an extra roundtrip between the user's browser and Via.

@seanh
Copy link
Contributor Author

seanh commented Apr 19, 2021

We might want to consider displaying some kind of placeholder in the blank frame until it has loaded.

That might actually be quite a nice UX, as it can signal to the user that via.hypothes.is has loaded and they're now waiting for example.com to load/proxy. Created an issue for this: hypothesis/viahtml#155

@seanh
Copy link
Contributor Author

seanh commented Apr 19, 2021

Make sure that the via.hypothes.is URL isn't used as the annotation's target URL (for either PDFs or HTML)

For PDFs this was addressed by #427. For HTML documents this is handled by a <link rel="canonical"> in the page. See https://github.com/hypothesis/viahtml/blob/eee5fb4a6bbc59cdd7ba1066ad350ff0c10fb3cd/viahtml/templates/banner.html#L2.

Ok, sounds like this is handled for both Via 3 and Via HTML, so nothing to do.

@seanh
Copy link
Contributor Author

seanh commented Apr 19, 2021

Known issues:

The URL in the location bar won't change if the iframe is navigated. For example if the third-party URL returns a redirect. I think this is different from how legacy Via behaves. But I'm not completely sure it's actually a problem. I might propose to open an issue to track this but not fix it unless we decide we have to.

In theory I think this is fixable by adding a bit of JavaScript to either poll or get notified of changes to the iframe's URL and push new URLs onto the location bar without triggering page reloads.

Opened an issue for this: hypothesis/viahtml#156

@seanh seanh merged commit 7c73a2c into master Apr 19, 2021
@seanh seanh deleted the add-front-page branch April 19, 2021 14:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants