13 // this queue handles both animations and io requests |
13 // this queue handles both animations and io requests |
14 this._q = null ; |
14 this._q = null ; |
15 |
15 |
16 this._iPreventClick = false ; // oh really ? |
16 this._iPreventClick = false ; // oh really ? |
17 } |
17 } |
|
18 |
|
19 // Are we on Safari mobile ? |
|
20 var safari_mobile = /iPhone|iPod|iPad/.test(navigator.userAgent); |
|
21 // If so, we must scroll the jQuery UI pane created for Safari mobile instead of the whole document |
|
22 var the_scrolling_part = safari_mobile ? '#maincontainer' : 'document' ; |
|
23 |
|
24 // "Add comment" height and margin, to offset comments' display |
|
25 var add_comment_offset = 30; // px |
18 |
26 |
19 Sync.prototype = { |
27 Sync.prototype = { |
20 init : function (iComment) { |
28 init : function (iComment) { |
21 this._q = new CY.AsyncQueue() ; |
29 this._q = new CY.AsyncQueue() ; |
22 // pr2 this._q = new CY.Queue() ; |
30 // pr2 this._q = new CY.Queue() ; |
387 var topAncestorComment = path[path.length - 1] ; |
395 var topAncestorComment = path[path.length - 1] ; |
388 var topY = 0 ; |
396 var topY = 0 ; |
389 if (comment['start_wrapper'] != -1) |
397 if (comment['start_wrapper'] != -1) |
390 topY = CY.get(".c-id-"+topAncestorComment.id).getY() ; |
398 topY = CY.get(".c-id-"+topAncestorComment.id).getY() ; |
391 else |
399 else |
392 topY = CY.get('document').get('scrollTop') ; |
400 topY = CY.get(the_scrolling_part).get('scrollTop') ; |
393 |
401 |
394 this._showComments([topAncestorComment.id], topY, false) ; |
402 this._showComments([topAncestorComment.id], topY, false) ; |
395 // optim when browsing comments with no reply |
403 // optim when browsing comments with no reply |
396 if (topAncestorComment.replies.length > 0) |
404 if (topAncestorComment.replies.length > 0) |
397 this._animateTo(topY) ; |
405 // SID: let topY param be null to force Y acquisition from comment that |
|
406 // may have previously been set by showComments |
|
407 this._animateTo() ; |
398 } |
408 } |
399 }, |
409 }, |
400 _showFocusSingleComment : function(topComment, focusComment, reply) { |
410 _showFocusSingleComment : function(topComment, focusComment, reply) { |
401 if (topComment != null) { |
411 if (topComment != null) { |
402 var topY = 0 ; |
412 var topY = 0 ; |
403 if (topComment['start_wrapper'] != -1) |
413 if (topComment['start_wrapper'] != -1) |
404 topY = CY.get(".c-id-"+topComment.id).getY() ; |
414 topY = CY.get(".c-id-"+topComment.id).getY() ; |
405 else |
415 else |
406 topY = CY.get('document').get('scrollTop') ; |
416 topY = CY.get(the_scrolling_part).get('scrollTop') ; |
407 |
417 |
408 this._showComments([topComment.id], topY, false) ; |
418 this._showComments([topComment.id], topY, false) ; |
409 // optim when browsing comments with no reply |
419 // optim when browsing comments with no reply |
410 if (topComment.replies.length > 0 || reply) |
420 if (topComment.replies.length > 0 || reply) |
411 this._animateToAndFocus(topY, focusComment.id, reply) ; |
421 this._animateToAndFocus(topY, focusComment.id, reply) ; |
442 var comments = gDb.getThreads(cs) ; |
452 var comments = gDb.getThreads(cs) ; |
443 gIComments.fetch(comments) ; |
453 gIComments.fetch(comments) ; |
444 |
454 |
445 if (commentDbIds.length > 0) { |
455 if (commentDbIds.length > 0) { |
446 if (atDocumentTop) { |
456 if (atDocumentTop) { |
447 CY.get('document').set('scrollTop', 0) ; |
457 CY.get(the_scrolling_part).set('scrollTop', 0) ; |
448 } |
458 } |
449 else { |
459 else { |
450 gIComments.activate(commentDbIds[0]) ; |
460 gIComments.activate(commentDbIds[0]) ; |
451 var scopeStart = CY.get(".c-id-"+commentDbIds[0]) ; |
461 var scopeStart = CY.get(".c-id-"+commentDbIds[0]) ; |
452 if (scopeStart && !scopeStart.inViewportRegion()) { // scopeStart could be null when comment has no scope |
462 |
|
463 // scopeStart could be null when comment has no scope |
|
464 if (scopeStart && !scopeStart.inViewportRegion()) { |
453 scopeStart.scrollIntoView(true) ; |
465 scopeStart.scrollIntoView(true) ; |
|
466 |
454 // Since scrollIntoView scroll the embed ifram *and* the parent window |
467 // Since scrollIntoView scroll the embed ifram *and* the parent window |
455 // restore the position of the toolbar |
468 // restore the position of the toolbar |
456 if (parent) |
469 if (parent) |
457 parent.document.getElementById('outer-north').scrollIntoView(true) ; |
470 parent.document.getElementById('outer-north').scrollIntoView(true) ; |
|
471 |
|
472 // SID: As we scroll via jQuery UI pane while on Safari mobile, we should base comment |
|
473 // position on the result of previous scrollIntoView on the pane, so relatively to that |
|
474 // new top. |
|
475 // On other cases, it's the right place to add an offset on comment tops in order to |
|
476 // avoid them to display under the "Add comment" button. |
|
477 if (safari_mobile) |
|
478 topY = add_comment_offset; |
|
479 else |
|
480 topY += add_comment_offset; |
458 } |
481 } |
459 } |
482 } |
460 } |
483 } |
461 |
484 |
462 gIComments.setPosition([gConf['iCommentLeftPadding'], topY]) ; |
485 gIComments.setPosition([gConf['iCommentLeftPadding'], topY]) ; |
463 |
|
464 gIComments.show() ; |
486 gIComments.show() ; |
465 }}) ; |
487 }}) ; |
466 }, |
488 }, |
467 |
489 |
468 _animateTo : function(topY) { |
490 _animateTo : function(topY) { |
507 return 1 |
529 return 1 |
508 return 0 |
530 return 0 |
509 }); |
531 }); |
510 } |
532 } |
511 // GIB: go down the 'add comment' icon |
533 // GIB: go down the 'add comment' icon |
512 this.showComments(allTopComments, [0,30], true) ; |
534 this.showComments(allTopComments, [0, add_comment_offset], true); |
513 }, this, null) ; |
535 }, this, null) ; |
514 }, |
536 }, |
515 |
537 |
516 showScopeRemovedComments : function() { |
538 showScopeRemovedComments : function() { |
517 checkForOpenedDialog(null, function() { |
539 checkForOpenedDialog(null, function() { |
527 return 1 |
549 return 1 |
528 return 0 |
550 return 0 |
529 }); |
551 }); |
530 } |
552 } |
531 // GIB: go down the 'add comment' icon |
553 // GIB: go down the 'add comment' icon |
532 this.showComments(scopeRemovedCommentIds, [0,30], true) ; |
554 this.showComments(scopeRemovedCommentIds, [0, add_comment_offset], true); |
533 |
555 |
534 }, this, null) ; |
556 }, this, null) ; |
535 }, |
557 }, |
536 |
558 |
537 showComments : function(commentDbIds, mouseXY, atDocumentTop) { |
559 showComments : function(commentDbIds, mouseXY, atDocumentTop) { |
538 checkForOpenedDialog(null, function() { |
560 checkForOpenedDialog(null, function() { |
539 this._q.add({fn:CY.bind(this.setPreventClickOn, this)}) ; |
561 this._q.add({fn:CY.bind(this.setPreventClickOn, this)}) ; |
540 this._showComments(commentDbIds, mouseXY[1], atDocumentTop) ; |
562 this._showComments(commentDbIds, mouseXY[1], atDocumentTop) ; |
541 this._animateTo(mouseXY[1]) ; |
563 // SID: let topY param be null to force Y acquisition from comment that |
|
564 // may have previously been set by showComments |
|
565 this._animateTo() ; |
542 this._q.add({fn:CY.bind(this.setPreventClickOff, this)}) ; |
566 this._q.add({fn:CY.bind(this.setPreventClickOff, this)}) ; |
543 this._q.run(); |
567 this._q.run(); |
544 }, this, null) ; |
568 }, this, null) ; |
545 }, |
569 }, |
546 |
570 |