- 22 Dec, 2015 5 commits
-
-
Robert Knight authored
Date.toLocaleDateString() with options is extremely slow, creating and re-using an Intl.DateTimeFormat object is two orders of magnitude faster (see #2820) Fixes #2820
-
Sean Hammond authored
Update annotation timestamp when creating and editing annotations
-
Robert Knight authored
-
Robert Knight authored
When a new highlight is saved, updateViewModel() was called immediately after making the request to the server to save the highlight, but not after the response from the server is received, when additional properties such as the last-updated timestamp for the highlight, will have been set.
-
Robert Knight authored
There were two problems here: 1. The periodic interval for updating the timestamp was never started for new annotations because the initial call to updateTimestamp() was a no-op for annotations that had no timestamp yet. 2. domainModel.updated was never updated after an annotation was saved to the server and hence the call to updateTimestamp() re-used the old timestamp. (1) is fixed now by restarting the interval using the current last-updated timestamp whenever the view model is updated. (2) is fixed indirectly now by moving the logic to update the timestamp into updateViewModel(), so that all updates to it happen in one place. When an annotation is updated, the updated domain model returned by the server is the one passed into updateViewModel() to update it. * Separate out the logic for creating a decaying interval whose frequency depends on the age of some input timestamp, and updating the timestamp string on each interval. The decaying interval is now handled by 'time.decayingInterval' * Trigger a restart of the interval whenever the view model is updated in response to a change to the annotation Fixes #2819 Fixes #2822
-
- 18 Dec, 2015 15 commits
-
-
Robert Knight authored
Clear selection before creating new annotation
-
Sean Hammond authored
Use Angular 1.3.x+ one-time bindings
-
Robert Knight authored
Use one-time bindings in the annotation component's template for expressions whose values cannot change during the lifetime of an annotation card. Testing using the default /stream view, without scrolling: Initial status as of 1ceb5fcefd7fa057bdbcf1f73df57d007289531f averaged over 30+ digest cycles: Digest cycle: ~30ms Watchers: 1686 With this commit: Digest cycle: ~26ms Watchers: 1649
-
Nick Stenning authored
Remove Moment.js
-
Sean Hammond authored
Clear any selection that exists in the sidebar before creating a new annotation. Otherwise the new annotation with its form open for the user to type in won't be visible because it's not part of the selection.
-
Nick Stenning authored
Add --debug arg to hypothesis-buildext
-
Nick Stenning authored
Consolidate /app and /app/features endpoints
-
Robert Knight authored
Fix video embeds in Firefox < 45
-
Sean Hammond authored
innerText is non-standard and not supported in Firefox < 45. Use textContent instead.
-
Sean Hammond authored
Enable video embeds to be shown fullscreen
-
Robert Knight authored
Improve a code comment
-
Sean Hammond authored
-
Robert Knight authored
Experience has taught us that the client needs the session data (current user, list of groups) and set of enabled feature flags at the same time, and also needs to invalidate them in the same scenarios (eg. account switching). Fetching this data via two separate requests made it more complicated to ensure the client had a consistent view of session and feature-flag data. To simplify things and also same a network request: * On the server, put the feature flag data into the session data payload. * On the client, use the existing central storage and cache management for the session data payload to manage feature flags as well. The features service now becomes a thin wrapper around part of the session state.
-
Robert Knight authored
A downside of using the browser intl APIs to avoid the overhead of Moment.js is that the output is implementation dependent. Use toLocaleString()'s options argument where supported (Firefox, Chrome, Edge, IE 11) for more control over formatting of dates in annotation last-updated tooltips. Safari is the only modern browser currently lacking support for this option. For Safari, use toDateString() and toLocaleDateString() which generates the most similar format.
-
Robert Knight authored
The 'allowfullscreen' attribute must be set on both the embed's <iframe> and the parent sidebar <iframe> when the embed's main script is loaded to enable fullscreen support.
-
- 17 Dec, 2015 5 commits
-
-
Robert Knight authored
Add media embeds feature
-
Sean Hammond authored
Client-side, replace any links to YouTube or Vimeo videos in annotation body texts with <iframe> video embeds for those same videos. Behind a new feature flag. markdown.coffee: after rendering the user's markdown text to HTML and sanitizing it, compile the HTML string into a DOM element and insert it into the DOM using innerHTML from JavaScript, instead of using Angular's ng-bind-html to insert the HTML string into the DOM. This means that our CoffeeScript code in markdown.coffee has the rendered annotation body as a DOM element, and can use the DOM API to modify it before inserting it into the DOM. Take advantage of this to find video links in the HTML and replace them with embeds. This is done by a standalone media-embedder.js module that markdown.coffee calls. This module is designed to allow functions for generating embeds for different kinds of URLs to be plugged in. So far functions for a few different kinds of YouTube and Vimeo URLs are implemented, but further functions for more media types can be added.
-
Robert Knight authored
Moment.js is only used in a single place, for converting ISO8601 date-time strings from the annotation's 'updated' field to user-friendly date strings (eg. 'Wednesday 17 Dec, 18:59') for the tooltips for the last-updated link in the annotation card. Replacing this with functions from the built-in Date object saves 167KB from the generated bundle size (see moment/min/moment-with-locales.min.js) and also speeds up the digest cycle. For 20 annotation cards in the /stream view, generating the date string used to take 6-7ms with Moment. It takes <2ms with the built in functions in a current build of Chrome. This still shows up as the most expensive watch expression, so we might want to add caching as well.
-
Robert Knight authored
jscs: Require `function () {}`
-
Sean Hammond authored
Change jscs's required style from `function()` to `function ()`. We always require a space after the `function` keyword, and before {} braces, but we do not allow a space between a function name and its () braces: var foo1 = function () {}; // Right. var foo2 = function() {}; // Wrong. var foo3 = function (){}; // Wrong. var foo4 = function foo4() {}; // Right. var foo5 = function foo5 () {}; // Wrong. var foo6 = function foo6(){}; // Wrong. function foo7() {} // Right. function foo8 () {} // Wrong. function foo9(){} // Wrong. This deviates from the Google style guide and jscs presets that we use.
-
- 16 Dec, 2015 1 commit
-
-
Nick Stenning authored
Don't crash on non-JSON body
-
- 15 Dec, 2015 3 commits
-
-
Robert Knight authored
Enable showdown's literalMidWordUnderscores
-
Sean Hammond authored
This stops showdown from interpreting underscores in the middle of words as <em> and <strong>, instead it treats them as literal underscores. Example: some text with__underscores__in middle will be parsed as <p>some text with__underscores__in middle</p> Fixes #2598 (URLs with _'s in them were getting <em> tags inserted into them, breaking the links). Also see <https://github.com/showdownjs/showdown/issues/211>.
-
Nick Stenning authored
Small tweaks to the header for re-use in the blog
-
- 14 Dec, 2015 11 commits
-
-
Robert Knight authored
Don't update annotations with contents of others
-
Sean Hammond authored
When listening to the 'annotationUpdated' event, AnnotationController needs to check that it's this annotation that the event refers to before acting on it. Fixes #2799.
-
Robert Knight authored
Annotation controller domain model view model refactor
-
Sean Hammond authored
-
Sean Hammond authored
-
Sean Hammond authored
If the user creates annotations while signed out and then signs in, we want those annotations to still be present in the sidebar after sign in, rather than being lost. Commit 7a1b5ca8d99252d3a086a8a8103fca4702521d06 had inadvertently broken this. The problem is that app.coffee destroys all AnnotationController instances on sign in, and only creates new instances for those annotations that have drafts. 7a1b5ca8d99252d3a086a8a8103fca4702521d06 removed a spurious call to saveToDrafts() in vm.edit() but it turns out that this call was (apparently inadvertently) the only thing that was causing drafts of annotations created while signed out to be saved, and hence the only thing causing these annotations to persist across sign ins. So add a listener for the USER_CHANGED event and save drafts of annotations on sign in, just before the AnnotationControllers get destroyed.
-
Sean Hammond authored
-
Sean Hammond authored
Update AnnotationController's view model on the "annotationUpdated" event. This fixes an issue that "live updates" were not being shown on annotation cards. The "annotationUpdated" event is fired by AnnotationController itself after successfully saving updates to an already-saved annotation. It's also fired by annotationMapper after received an updated annotation from the server (that was updated by a different client - the "live updates" feature). Subscribing to this event allows one function in AnnotationController to handle updating the view model in both cases.
-
Sean Hammond authored
Update AnnotationController's view model (vm) after successfully saving a new annotation to the server for the first time. This fixes two issues: 1. vm.annotationURI (which depends on the annotation's id, which is not present until the save to the server succeeds) was not being set correctly after successful save, so the annotation permalinks were not correct until you reload them. 2. If you created a highlight while logged out, then logged in, (AnnotationController automatically saves the highlight to the server for you on login) the "Only Me" icon was not being shown on the highlight until you reloaded it because vm.isPrivate wasn't set.
-
Sean Hammond authored
We only need to save an annotation to drafts when the focused group changes while editing it, and not at other times (e.g. when opening the editor??). We only need to restore an annotation from drafts when editing it, and not at other random times. Also, don't call updateViewModel() in init() after calling edit(), because this will overwrite the draft changes that you just restored.
-
Sean Hammond authored
Don't change the value of domainModel.group when the focused group changes. Instead, change it to groups.focusedGroup() in updatedDomainModel() before the annotation is sent to the server. This fits with the idea that domainModel is a read-only copy of the annotation that we received from the server, and vm is the read-write copy. But there's no vm.group as this would always be the same as groups.focusedGroup().
-