diff --git a/public/res/extensions/scrollSync.js b/public/res/extensions/scrollSync.js
index 1c5bf3bd..4e272a3f 100644
--- a/public/res/extensions/scrollSync.js
+++ b/public/res/extensions/scrollSync.js
@@ -91,7 +91,6 @@ define([
var isScrollPreview = false;
var isEditorMoving = false;
var isPreviewMoving = false;
- var scrollingHelper = $('
');
function getDestScrollTop(srcScrollTop, srcSectionList, destSectionList) {
// Find the section corresponding to the offset
var sectionIndex;
@@ -108,6 +107,34 @@ define([
return destSection.startOffset + destSection.height * posInSection;
}
+ var timeoutId;
+ var currentEndCb;
+ function animate(elt, startValue, endValue, stepCb, endCb) {
+ if(currentEndCb) {
+ clearTimeout(timeoutId);
+ currentEndCb();
+ }
+ currentEndCb = endCb;
+ var diff = endValue - startValue;
+ var startTime = Date.now();
+ function tick() {
+ var currentTime = Date.now();
+ var progress = (currentTime - startTime) / 200;
+ if(progress < 1) {
+ var scrollTop = startValue + diff * Math.cos((1 - progress) * Math.PI / 2 );
+ elt.scrollTop = scrollTop;
+ stepCb(scrollTop);
+ timeoutId = setTimeout(tick, 1);
+ }
+ else {
+ currentEndCb = undefined;
+ elt.scrollTop = endValue;
+ endCb();
+ }
+ }
+ tick();
+ }
+
var doScrollSync = _.throttle(function() {
if(!isPreviewVisible || mdSectionList.length === 0 || mdSectionList.length !== htmlSectionList.length) {
return;
@@ -134,24 +161,12 @@ define([
lastPreviewScrollTop = previewScrollTop;
return;
}
- scrollingHelper.stop('scrollSyncFx', true).css('value', 0).animate({
- value: destScrollTop - previewScrollTop
- }, {
- easing: 'easeOutSine',
- duration: 200,
- queue: 'scrollSyncFx',
- step: function(now) {
- isPreviewMoving = true;
- lastPreviewScrollTop = previewScrollTop + now;
- $previewElt.scrollTop(lastPreviewScrollTop);
- },
- done: function() {
- setTimeout(function() {
- isPreviewMoving = false;
- }, 10);
- },
- }).dequeue('scrollSyncFx');
-
+ animate($previewElt[0], previewScrollTop, destScrollTop, function(currentScrollTop) {
+ isPreviewMoving = true;
+ lastPreviewScrollTop = currentScrollTop;
+ }, function() {
+ isPreviewMoving = false;
+ });
}
else if(isScrollPreview === true) {
if(Math.abs(previewScrollTop - lastPreviewScrollTop) <= 9) {
@@ -170,23 +185,12 @@ define([
lastEditorScrollTop = editorScrollTop;
return;
}
- scrollingHelper.stop('scrollSyncFx', true).css('value', 0).animate({
- value: destScrollTop - editorScrollTop
- }, {
- easing: 'easeOutSine',
- duration: 200,
- queue: 'scrollSyncFx',
- step: function(now) {
- isEditorMoving = true;
- lastEditorScrollTop = editorScrollTop + now;
- $editorElt.scrollTop(lastEditorScrollTop);
- },
- done: function() {
- setTimeout(function() {
- isEditorMoving = false;
- }, 10);
- },
- }).dequeue('scrollSyncFx');
+ animate($editorElt[0], editorScrollTop, destScrollTop, function(currentScrollTop) {
+ isEditorMoving = true;
+ lastEditorScrollTop = currentScrollTop;
+ }, function() {
+ isEditorMoving = false;
+ });
}
}, 100);
diff --git a/public/res/helpers/googleHelper.js b/public/res/helpers/googleHelper.js
index 535a7ee1..f1d46ebf 100644
--- a/public/res/helpers/googleHelper.js
+++ b/public/res/helpers/googleHelper.js
@@ -108,6 +108,7 @@ define([
'https://www.googleapis.com/auth/photos'
]
};
+ var oauthIframes = [];
function authenticate(task, permission, accountId) {
var authorizationMgr = authorizationMgrMap[accountId];
if(!authorizationMgr) {
@@ -161,6 +162,16 @@ define([
immediate: immediate,
authuser: immediate === false ? '' : authuser
}, function(authResult) {
+
+ // Hack to clean window from old oauth iframes
+ authorizationMgr.$oauthIframe && authorizationMgr.$oauthIframe.remove();
+ var currentOauthIframes = _.filter(document.querySelectorAll('iframe'), function(iframe) {
+ var src = iframe.getAttribute('src');
+ return src && src.indexOf('https://accounts.google.com/o/oauth2/auth') === 0;
+ });
+ authorizationMgr.$oauthIframe = $(_.difference(currentOauthIframes, oauthIframes));
+ oauthIframes = currentOauthIframes;
+
newToken = gapi.auth.getToken();
gapi.auth.setToken(currentToken);
if(!authResult || authResult.error) {
@@ -257,7 +268,7 @@ define([
var headers = {
'Content-Type': 'multipart/mixed; boundary="' + boundary + '"',
};
-
+
var base64Data = utils.encodeBase64(content);
var multipartRequestBody = [
delimiter,