2015-10-11 13:02:57 +10:30
/* jshint browser: true */
( function ( ) {
// The properties that we copy into a mirrored div.
// Note that some browsers, such as Firefox,
// do not concatenate properties, i.e. padding-top, bottom etc. -> padding,
// so we have to do every single property specifically.
var properties = [
'direction' , // RTL support
'boxSizing' ,
'width' , // on Chrome and IE, exclude the scrollbar, so the mirror div wraps exactly as the textarea does
'height' ,
'overflowX' ,
'overflowY' , // copy the scrollbar for IE
'borderTopWidth' ,
'borderRightWidth' ,
'borderBottomWidth' ,
'borderLeftWidth' ,
'borderStyle' ,
'paddingTop' ,
'paddingRight' ,
'paddingBottom' ,
'paddingLeft' ,
// https://developer.mozilla.org/en-US/docs/Web/CSS/font
'fontStyle' ,
'fontVariant' ,
'fontWeight' ,
'fontStretch' ,
'fontSize' ,
'fontSizeAdjust' ,
'lineHeight' ,
'fontFamily' ,
'textAlign' ,
'textTransform' ,
'textIndent' ,
'textDecoration' , // might not make a difference, but better be safe
'letterSpacing' ,
'wordSpacing' ,
'tabSize' ,
'MozTabSize'
] ;
2016-01-20 20:18:55 +01:00
var isBrowser = ( typeof window !== 'undefined' ) ;
var isFirefox = ( isBrowser && window . mozInnerScreenX != null ) ;
function getCaretCoordinates ( element , position , options ) {
if ( ! isBrowser ) {
throw new Error ( 'textarea-caret-position#getCaretCoordinates should only be called in a browser' ) ;
}
var debug = options && options . debug || false ;
if ( debug ) {
var el = document . querySelector ( '#input-textarea-caret-position-mirror-div' ) ;
if ( el ) { el . parentNode . removeChild ( el ) ; }
}
2015-10-11 13:02:57 +10:30
// mirrored div
var div = document . createElement ( 'div' ) ;
div . id = 'input-textarea-caret-position-mirror-div' ;
document . body . appendChild ( div ) ;
var style = div . style ;
var computed = window . getComputedStyle ? getComputedStyle ( element ) : element . currentStyle ; // currentStyle for IE < 9
// default textarea styles
style . whiteSpace = 'pre-wrap' ;
if ( element . nodeName !== 'INPUT' )
style . wordWrap = 'break-word' ; // only for textarea-s
// position off-screen
style . position = 'absolute' ; // required to return coordinates properly
2016-01-20 20:18:55 +01:00
if ( ! debug )
style . visibility = 'hidden' ; // not 'display: none' because we want rendering
2015-10-11 13:02:57 +10:30
// transfer the element's properties to the div
properties . forEach ( function ( prop ) {
style [ prop ] = computed [ prop ] ;
} ) ;
if ( isFirefox ) {
// Firefox lies about the overflow property for textareas: https://bugzilla.mozilla.org/show_bug.cgi?id=984275
if ( element . scrollHeight > parseInt ( computed . height ) )
style . overflowY = 'scroll' ;
} else {
style . overflow = 'hidden' ; // for Chrome to not render a scrollbar; IE keeps overflowY = 'scroll'
}
div . textContent = element . value . substring ( 0 , position ) ;
// the second special handling for input type="text" vs textarea: spaces need to be replaced with non-breaking spaces - http://stackoverflow.com/a/13402035/1269037
if ( element . nodeName === 'INPUT' )
2016-01-20 20:18:55 +01:00
div . textContent = div . textContent . replace ( /\s/g , '\u00a0' ) ;
2015-10-11 13:02:57 +10:30
var span = document . createElement ( 'span' ) ;
// Wrapping must be replicated *exactly*, including when a long word gets
// onto the next line, with whitespace at the end of the line before (#7).
// The *only* reliable way to do that is to copy the *entire* rest of the
// textarea's content into the <span> created at the caret position.
// for inputs, just '.' would be enough, but why bother?
span . textContent = element . value . substring ( position ) || '.' ; // || because a completely empty faux span doesn't render at all
div . appendChild ( span ) ;
var coordinates = {
top : span . offsetTop + parseInt ( computed [ 'borderTopWidth' ] ) ,
left : span . offsetLeft + parseInt ( computed [ 'borderLeftWidth' ] )
} ;
2016-01-20 20:18:55 +01:00
if ( debug ) {
span . style . backgroundColor = '#aaa' ;
} else {
document . body . removeChild ( div ) ;
}
2015-10-11 13:02:57 +10:30
return coordinates ;
}
2016-01-20 20:18:55 +01:00
if ( typeof module != 'undefined' && typeof module . exports != 'undefined' ) {
2015-10-11 13:02:57 +10:30
module . exports = getCaretCoordinates ;
2016-01-20 20:18:55 +01:00
} else if ( isBrowser ) {
2015-10-11 13:02:57 +10:30
window . getCaretCoordinates = getCaretCoordinates ;
}
} ( ) ) ;
2015-11-03 10:03:33 +10:30
;
2016-03-18 09:33:14 +10:30
'use strict' ;
2015-10-11 13:02:57 +10:30
2016-05-15 22:42:15 +09:00
System . register ( 'flarum/mentions/addComposerAutocomplete' , [ 'flarum/extend' , 'flarum/components/ComposerBody' , 'flarum/helpers/avatar' , 'flarum/helpers/username' , 'flarum/helpers/highlight' , 'flarum/utils/KeyboardNavigatable' , 'flarum/utils/string' , 'flarum/mentions/components/AutocompleteDropdown' ] , function ( _export , _context ) {
2016-06-02 15:44:04 +04:30
"use strict" ;
2016-05-15 22:42:15 +09:00
var extend , ComposerBody , avatar , usernameHelper , highlight , KeyboardNavigatable , truncate , AutocompleteDropdown ;
2015-10-11 13:02:57 +10:30
function addComposerAutocomplete ( ) {
extend ( ComposerBody . prototype , 'config' , function ( original , isInitialized ) {
if ( isInitialized ) return ;
var composer = this ;
var $container = $ ( '<div class="ComposerBody-mentionsDropdownContainer"></div>' ) ;
var dropdown = new AutocompleteDropdown ( { items : [ ] } ) ;
2016-01-19 16:52:55 +10:30
var $textarea = this . $ ( 'textarea' ) . wrap ( '<div class="ComposerBody-mentionsWrapper"></div>' ) ;
2015-10-11 13:02:57 +10:30
var searched = [ ] ;
2016-03-18 09:33:14 +10:30
var mentionStart = void 0 ;
var typed = void 0 ;
var searchTimeout = void 0 ;
2015-10-11 13:02:57 +10:30
var applySuggestion = function applySuggestion ( replacement ) {
var insert = replacement + ' ' ;
var content = composer . content ( ) ;
composer . editor . setValue ( content . substring ( 0 , mentionStart - 1 ) + insert + content . substr ( $textarea [ 0 ] . selectionStart ) ) ;
var index = mentionStart - 1 + insert . length ;
composer . editor . setSelectionRange ( index , index ) ;
dropdown . hide ( ) ;
} ;
2016-05-15 22:42:15 +09:00
this . navigator = new KeyboardNavigatable ( ) ;
this . navigator . when ( function ( ) {
return dropdown . active ;
} ) . onUp ( function ( ) {
return dropdown . navigate ( - 1 ) ;
} ) . onDown ( function ( ) {
return dropdown . navigate ( 1 ) ;
} ) . onSelect ( dropdown . complete . bind ( dropdown ) ) . onCancel ( dropdown . hide . bind ( dropdown ) ) . bindTo ( $textarea ) ;
$textarea . after ( $container ) . on ( 'click keyup' , function ( e ) {
2015-10-11 13:02:57 +10:30
var _this = this ;
// Up, down, enter, tab, escape, left, right.
if ( [ 9 , 13 , 27 , 40 , 38 , 37 , 39 ] . indexOf ( e . which ) !== - 1 ) return ;
var cursor = this . selectionStart ;
if ( this . selectionEnd - cursor > 0 ) return ;
// Search backwards from the cursor for an '@' symbol, without any
// intervening whitespace. If we find one, we will want to show the
// autocomplete dropdown!
var value = this . value ;
mentionStart = 0 ;
for ( var i = cursor - 1 ; i >= 0 ; i -- ) {
var character = value . substr ( i , 1 ) ;
if ( /\s/ . test ( character ) ) break ;
if ( character === '@' ) {
mentionStart = i + 1 ;
break ;
}
}
dropdown . hide ( ) ;
dropdown . active = false ;
if ( mentionStart ) {
( function ( ) {
typed = value . substring ( mentionStart , cursor ) . toLowerCase ( ) ;
var makeSuggestion = function makeSuggestion ( user , replacement , content ) {
var className = arguments . length <= 3 || arguments [ 3 ] === undefined ? '' : arguments [ 3 ] ;
var username = usernameHelper ( user ) ;
if ( typed ) {
username . children [ 0 ] = highlight ( username . children [ 0 ] , typed ) ;
}
return m (
'button' ,
{ className : 'PostPreview ' + className ,
2016-03-18 09:33:14 +10:30
onclick : function onclick ( ) {
2015-10-11 13:02:57 +10:30
return applySuggestion ( replacement ) ;
} ,
2016-03-18 09:33:14 +10:30
onmouseenter : function onmouseenter ( ) {
2015-10-11 13:02:57 +10:30
dropdown . setIndex ( $ ( this ) . parent ( ) . index ( ) ) ;
} } ,
m (
'span' ,
{ className : 'PostPreview-content' } ,
avatar ( user ) ,
username ,
' ' ,
' ' ,
content
)
) ;
} ;
var buildSuggestions = function buildSuggestions ( ) {
var suggestions = [ ] ;
// If the user is replying to a discussion, or if they are editing a
// post, then we can suggest other posts in the discussion to mention.
// We will add the 5 most recent comments in the discussion which
// match any username characters that have been typed.
var composerPost = composer . props . post ;
var discussion = composerPost && composerPost . discussion ( ) || composer . props . discussion ;
if ( discussion ) {
discussion . posts ( ) . filter ( function ( post ) {
return post && post . contentType ( ) === 'comment' && ( ! composerPost || post . number ( ) < composerPost . number ( ) ) ;
} ) . sort ( function ( a , b ) {
return b . time ( ) - a . time ( ) ;
} ) . filter ( function ( post ) {
var user = post . user ( ) ;
return user && user . username ( ) . toLowerCase ( ) . substr ( 0 , typed . length ) === typed ;
} ) . splice ( 0 , 5 ) . forEach ( function ( post ) {
var user = post . user ( ) ;
2015-10-27 12:16:54 +10:30
suggestions . push ( makeSuggestion ( user , '@' + user . username ( ) + '#' + post . id ( ) , [ app . translator . trans ( 'flarum-mentions.forum.composer.reply_to_post_text' , { number : post . number ( ) } ) , ' — ' , truncate ( post . contentPlain ( ) , 200 ) ] , 'MentionsDropdown-post' ) ) ;
2015-10-11 13:02:57 +10:30
} ) ;
}
// If the user has started to type a username, then suggest users
// matching that username.
if ( typed ) {
app . store . all ( 'users' ) . forEach ( function ( user ) {
if ( user . username ( ) . toLowerCase ( ) . substr ( 0 , typed . length ) !== typed ) return ;
suggestions . push ( makeSuggestion ( user , '@' + user . username ( ) , '' , 'MentionsDropdown-user' ) ) ;
} ) ;
}
if ( suggestions . length ) {
dropdown . props . items = suggestions ;
m . render ( $container [ 0 ] , dropdown . render ( ) ) ;
dropdown . show ( ) ;
var coordinates = getCaretCoordinates ( _this , mentionStart ) ;
var width = dropdown . $ ( ) . outerWidth ( ) ;
var height = dropdown . $ ( ) . outerHeight ( ) ;
2016-03-18 09:33:14 +10:30
var parent = dropdown . $ ( ) . offsetParent ( ) ;
2015-10-11 13:02:57 +10:30
var left = coordinates . left ;
2016-03-18 09:33:14 +10:30
var top = coordinates . top + 15 ;
if ( top + height > parent . height ( ) ) {
top = coordinates . top - height - 15 ;
2015-10-11 13:02:57 +10:30
}
2016-03-18 09:33:14 +10:30
if ( left + width > parent . width ( ) ) {
left = parent . width ( ) - width ;
2015-10-11 13:02:57 +10:30
}
2016-03-18 09:33:14 +10:30
dropdown . show ( left , top ) ;
2015-10-11 13:02:57 +10:30
}
} ;
buildSuggestions ( ) ;
dropdown . setIndex ( 0 ) ;
dropdown . $ ( ) . scrollTop ( 0 ) ;
dropdown . active = true ;
clearTimeout ( searchTimeout ) ;
if ( typed ) {
searchTimeout = setTimeout ( function ( ) {
var typedLower = typed . toLowerCase ( ) ;
if ( searched . indexOf ( typedLower ) === - 1 ) {
app . store . find ( 'users' , { q : typed , page : { limit : 5 } } ) . then ( function ( ) {
if ( dropdown . active ) buildSuggestions ( ) ;
} ) ;
searched . push ( typedLower ) ;
}
} , 250 ) ;
}
} ) ( ) ;
}
} ) ;
} ) ;
}
2016-03-18 09:33:14 +10:30
_export ( 'default' , addComposerAutocomplete ) ;
2015-10-11 13:02:57 +10:30
return {
setters : [ function ( _flarumExtend ) {
2016-03-18 09:33:14 +10:30
/*global getCaretCoordinates*/
2015-10-11 13:02:57 +10:30
extend = _flarumExtend . extend ;
} , function ( _flarumComponentsComposerBody ) {
2016-03-18 09:33:14 +10:30
ComposerBody = _flarumComponentsComposerBody . default ;
2015-10-11 13:02:57 +10:30
} , function ( _flarumHelpersAvatar ) {
2016-03-18 09:33:14 +10:30
avatar = _flarumHelpersAvatar . default ;
2015-10-11 13:02:57 +10:30
} , function ( _flarumHelpersUsername ) {
2016-03-18 09:33:14 +10:30
usernameHelper = _flarumHelpersUsername . default ;
2015-10-11 13:02:57 +10:30
} , function ( _flarumHelpersHighlight ) {
2016-03-18 09:33:14 +10:30
highlight = _flarumHelpersHighlight . default ;
2016-05-15 22:42:15 +09:00
} , function ( _flarumUtilsKeyboardNavigatable ) {
KeyboardNavigatable = _flarumUtilsKeyboardNavigatable . default ;
2015-10-11 13:02:57 +10:30
} , function ( _flarumUtilsString ) {
truncate = _flarumUtilsString . truncate ;
} , function ( _flarumMentionsComponentsAutocompleteDropdown ) {
2016-03-18 09:33:14 +10:30
AutocompleteDropdown = _flarumMentionsComponentsAutocompleteDropdown . default ;
2015-10-11 13:02:57 +10:30
} ] ,
execute : function ( ) { }
} ;
2015-11-03 10:03:33 +10:30
} ) ; ;
2016-03-18 09:33:14 +10:30
'use strict' ;
2015-10-11 13:02:57 +10:30
2016-03-18 09:33:14 +10:30
System . register ( 'flarum/mentions/addMentionedByList' , [ 'flarum/extend' , 'flarum/Model' , 'flarum/models/Post' , 'flarum/components/CommentPost' , 'flarum/components/PostPreview' , 'flarum/helpers/punctuateSeries' , 'flarum/helpers/username' , 'flarum/helpers/icon' ] , function ( _export , _context ) {
2016-06-02 15:44:04 +04:30
"use strict" ;
2015-10-11 13:02:57 +10:30
var extend , Model , Post , CommentPost , PostPreview , punctuateSeries , username , icon ;
function addMentionedByList ( ) {
Post . prototype . mentionedBy = Model . hasMany ( 'mentionedBy' ) ;
extend ( CommentPost . prototype , 'footerItems' , function ( items ) {
var _this = this ;
var post = this . props . post ;
var replies = post . mentionedBy ( ) ;
if ( replies && replies . length ) {
2016-03-18 09:33:14 +10:30
var _ret = function ( ) {
2015-10-11 13:02:57 +10:30
// If there is only one reply, and it's adjacent to this post, we don't
// really need to show the list.
if ( replies . length === 1 && replies [ 0 ] . number ( ) === post . number ( ) + 1 ) {
return {
2016-03-18 09:33:14 +10:30
v : void 0
2015-10-11 13:02:57 +10:30
} ;
}
var hidePreview = function hidePreview ( ) {
_this . $ ( '.Post-mentionedBy-preview' ) . removeClass ( 'in' ) . one ( 'transitionend' , function ( ) {
$ ( this ) . hide ( ) ;
} ) ;
} ;
var config = function config ( element , isInitialized ) {
if ( isInitialized ) return ;
var $this = $ ( element ) ;
2016-03-18 09:33:14 +10:30
var timeout = void 0 ;
2015-10-11 13:02:57 +10:30
var $preview = $ ( '<ul class="Dropdown-menu Post-mentionedBy-preview fade"/>' ) ;
$this . append ( $preview ) ;
$this . children ( ) . hover ( function ( ) {
clearTimeout ( timeout ) ;
timeout = setTimeout ( function ( ) {
if ( ! $preview . hasClass ( 'in' ) && $preview . is ( ':visible' ) ) return ;
// When the user hovers their mouse over the list of people who have
// replied to the post, render a list of reply previews into a
// popup.
m . render ( $preview [ 0 ] , replies . map ( function ( reply ) {
return m (
'li' ,
{ 'data-number' : reply . number ( ) } ,
PostPreview . component ( {
post : reply ,
onclick : hidePreview
} )
) ;
} ) ) ;
$preview . show ( ) ;
setTimeout ( function ( ) {
return $preview . off ( 'transitionend' ) . addClass ( 'in' ) ;
} ) ;
} , 500 ) ;
} , function ( ) {
clearTimeout ( timeout ) ;
timeout = setTimeout ( hidePreview , 250 ) ;
} ) ;
// Whenever the user hovers their mouse over a particular name in the
// list of repliers, highlight the corresponding post in the preview
// popup.
$this . find ( '.Post-mentionedBy-summary a' ) . hover ( function ( ) {
$preview . find ( '[data-number="' + $ ( this ) . data ( 'number' ) + '"]' ) . addClass ( 'active' ) ;
} , function ( ) {
$preview . find ( '[data-number]' ) . removeClass ( 'active' ) ;
} ) ;
} ;
2015-10-27 12:16:54 +10:30
var users = [ ] ;
var repliers = replies . sort ( function ( reply ) {
return reply . user ( ) === app . session . user ? - 1 : 0 ;
} ) . filter ( function ( reply ) {
2015-10-11 13:02:57 +10:30
var user = reply . user ( ) ;
2015-10-27 12:16:54 +10:30
if ( users . indexOf ( user ) === - 1 ) {
users . push ( user ) ;
2015-10-11 13:02:57 +10:30
return true ;
}
} ) ;
2015-10-27 12:16:54 +10:30
var limit = 4 ;
var overLimit = repliers . length > limit ;
// Create a list of unique users who have replied. So even if a user has
// replied twice, they will only be in this array once.
var names = repliers . slice ( 0 , overLimit ? limit - 1 : limit ) . map ( function ( reply ) {
2015-10-11 13:02:57 +10:30
var user = reply . user ( ) ;
return m (
'a' ,
{ href : app . route . post ( reply ) ,
config : m . route ,
onclick : hidePreview ,
'data-number' : reply . number ( ) } ,
2015-10-27 12:16:54 +10:30
app . session . user === user ? app . translator . trans ( 'flarum-mentions.forum.post.you_text' ) : username ( user )
2015-10-11 13:02:57 +10:30
) ;
} ) ;
2015-10-27 12:16:54 +10:30
// If there are more users that we've run out of room to display, add a "x
// others" name to the end of the list. Clicking on it will display a modal
// with a full list of names.
if ( overLimit ) {
var count = repliers . length - names . length ;
names . push ( app . translator . transChoice ( 'flarum-mentions.forum.post.others_text' , count , { count : count } ) ) ;
}
2015-10-11 13:02:57 +10:30
items . add ( 'replies' , m (
'div' ,
{ className : 'Post-mentionedBy' , config : config } ,
m (
'span' ,
{ className : 'Post-mentionedBy-summary' } ,
icon ( 'reply' ) ,
2015-10-27 12:16:54 +10:30
app . translator . transChoice ( 'flarum-mentions.forum.post.mentioned_by' + ( replies [ 0 ] === app . session . user ? '_self' : '' ) + '_text' , names . length , {
2015-10-11 13:02:57 +10:30
count : names . length ,
users : punctuateSeries ( names )
} )
)
) ) ;
2016-03-18 09:33:14 +10:30
} ( ) ;
2015-10-11 13:02:57 +10:30
2016-03-18 09:33:14 +10:30
if ( ( typeof _ret === 'undefined' ? 'undefined' : babelHelpers . typeof ( _ret ) ) === "object" ) return _ret . v ;
2015-10-11 13:02:57 +10:30
}
} ) ;
}
2016-03-18 09:33:14 +10:30
_export ( 'default' , addMentionedByList ) ;
2015-10-11 13:02:57 +10:30
return {
setters : [ function ( _flarumExtend ) {
extend = _flarumExtend . extend ;
} , function ( _flarumModel ) {
2016-03-18 09:33:14 +10:30
Model = _flarumModel . default ;
2015-10-11 13:02:57 +10:30
} , function ( _flarumModelsPost ) {
2016-03-18 09:33:14 +10:30
Post = _flarumModelsPost . default ;
2015-10-11 13:02:57 +10:30
} , function ( _flarumComponentsCommentPost ) {
2016-03-18 09:33:14 +10:30
CommentPost = _flarumComponentsCommentPost . default ;
2015-10-11 13:02:57 +10:30
} , function ( _flarumComponentsPostPreview ) {
2016-03-18 09:33:14 +10:30
PostPreview = _flarumComponentsPostPreview . default ;
2015-10-11 13:02:57 +10:30
} , function ( _flarumHelpersPunctuateSeries ) {
2016-03-18 09:33:14 +10:30
punctuateSeries = _flarumHelpersPunctuateSeries . default ;
2015-10-11 13:02:57 +10:30
} , function ( _flarumHelpersUsername ) {
2016-03-18 09:33:14 +10:30
username = _flarumHelpersUsername . default ;
2015-10-11 13:02:57 +10:30
} , function ( _flarumHelpersIcon ) {
2016-03-18 09:33:14 +10:30
icon = _flarumHelpersIcon . default ;
2015-10-11 13:02:57 +10:30
} ] ,
execute : function ( ) { }
} ;
2015-11-03 10:03:33 +10:30
} ) ; ;
2016-03-18 09:33:14 +10:30
'use strict' ;
2015-10-11 13:02:57 +10:30
2016-03-18 09:33:14 +10:30
System . register ( 'flarum/mentions/addPostMentionPreviews' , [ 'flarum/extend' , 'flarum/components/CommentPost' , 'flarum/components/PostPreview' , 'flarum/components/LoadingIndicator' ] , function ( _export , _context ) {
2016-06-02 15:44:04 +04:30
"use strict" ;
2015-10-11 13:02:57 +10:30
var extend , CommentPost , PostPreview , LoadingIndicator ;
function addPostMentionPreviews ( ) {
extend ( CommentPost . prototype , 'config' , function ( ) {
var contentHtml = this . props . post . contentHtml ( ) ;
if ( contentHtml === this . oldPostContentHtml || this . isEditing ( ) ) return ;
this . oldPostContentHtml = contentHtml ;
var parentPost = this . props . post ;
var $parentPost = this . $ ( ) ;
this . $ ( '.UserMention, .PostMention' ) . each ( function ( ) {
m . route . call ( this , this , false , { } , { attrs : { href : this . getAttribute ( 'href' ) } } ) ;
} ) ;
this . $ ( '.PostMention' ) . each ( function ( ) {
var $this = $ ( this ) ;
var id = $this . data ( 'id' ) ;
2016-03-18 09:33:14 +10:30
var timeout = void 0 ;
2015-10-11 13:02:57 +10:30
// Wrap the mention link in a wrapper element so that we can insert a
// preview popup as its sibling and relatively position it.
var $preview = $ ( '<ul class="Dropdown-menu PostMention-preview fade"/>' ) ;
$parentPost . append ( $preview ) ;
var getPostElement = function getPostElement ( ) {
return $ ( '.PostStream-item[data-id="' + id + '"]' ) ;
} ;
var showPreview = function showPreview ( ) {
// When the user hovers their mouse over the mention, look for the
// post that it's referring to in the stream, and determine if it's
// in the viewport. If it is, we will "pulsate" it.
var $post = getPostElement ( ) ;
var visible = false ;
if ( $post . length ) {
2016-03-18 09:33:14 +10:30
var top = $post . offset ( ) . top ;
2015-10-11 13:02:57 +10:30
var scrollTop = window . pageYOffset ;
2016-03-18 09:33:14 +10:30
if ( top > scrollTop && top + $post . height ( ) < scrollTop + $ ( window ) . height ( ) ) {
2015-10-11 13:02:57 +10:30
$post . addClass ( 'pulsate' ) ;
visible = true ;
}
}
// Otherwise, we will show a popup preview of the post. If the post
// hasn't yet been loaded, we will need to do that.
if ( ! visible ) {
( function ( ) {
// Position the preview so that it appears above the mention.
// (The offsetParent should be .Post-body.)
var positionPreview = function positionPreview ( ) {
2016-03-28 13:33:46 +10:30
var previewHeight = $preview . outerHeight ( true ) ;
var offset = 0 ;
// If the preview goes off the top of the viewport, reposition it to
// be below the mention.
if ( $this . offset ( ) . top - previewHeight < $ ( window ) . scrollTop ( ) + $ ( '#header' ) . outerHeight ( ) ) {
offset += $this . outerHeight ( true ) ;
} else {
offset -= previewHeight ;
}
$preview . show ( ) . css ( 'top' , $this . offset ( ) . top - $parentPost . offset ( ) . top + offset ) . css ( 'left' , $this . offsetParent ( ) . offset ( ) . left - $parentPost . offset ( ) . left ) . css ( 'max-width' , $this . offsetParent ( ) . width ( ) ) ;
2015-10-11 13:02:57 +10:30
} ;
var showPost = function showPost ( post ) {
var discussion = post . discussion ( ) ;
m . render ( $preview [ 0 ] , [ discussion !== parentPost . discussion ( ) ? m (
'li' ,
null ,
m (
'span' ,
{ className : 'PostMention-preview-discussion' } ,
discussion . title ( )
)
) : '' , m (
'li' ,
null ,
PostPreview . component ( { post : post } )
) ] ) ;
positionPreview ( ) ;
} ;
var post = app . store . getById ( 'posts' , id ) ;
if ( post && post . discussion ( ) ) {
showPost ( post ) ;
} else {
m . render ( $preview [ 0 ] , LoadingIndicator . component ( ) ) ;
app . store . find ( 'posts' , id ) . then ( showPost ) ;
positionPreview ( ) ;
}
setTimeout ( function ( ) {
return $preview . off ( 'transitionend' ) . addClass ( 'in' ) ;
} ) ;
} ) ( ) ;
}
} ;
var hidePreview = function hidePreview ( ) {
getPostElement ( ) . removeClass ( 'pulsate' ) ;
if ( $preview . hasClass ( 'in' ) ) {
$preview . removeClass ( 'in' ) . one ( 'transitionend' , function ( ) {
return $preview . hide ( ) ;
} ) ;
}
} ;
$this . on ( 'touchstart' , function ( e ) {
return e . preventDefault ( ) ;
} ) ;
$this . add ( $preview ) . hover ( function ( ) {
clearTimeout ( timeout ) ;
timeout = setTimeout ( showPreview , 250 ) ;
} , function ( ) {
clearTimeout ( timeout ) ;
getPostElement ( ) . removeClass ( 'pulsate' ) ;
timeout = setTimeout ( hidePreview , 250 ) ;
} ) . on ( 'touchend' , function ( e ) {
showPreview ( ) ;
e . stopPropagation ( ) ;
} ) ;
$ ( document ) . on ( 'touchend' , hidePreview ) ;
} ) ;
} ) ;
}
2016-03-18 09:33:14 +10:30
_export ( 'default' , addPostMentionPreviews ) ;
2015-10-11 13:02:57 +10:30
return {
setters : [ function ( _flarumExtend ) {
extend = _flarumExtend . extend ;
} , function ( _flarumComponentsCommentPost ) {
2016-03-18 09:33:14 +10:30
CommentPost = _flarumComponentsCommentPost . default ;
2015-10-11 13:02:57 +10:30
} , function ( _flarumComponentsPostPreview ) {
2016-03-18 09:33:14 +10:30
PostPreview = _flarumComponentsPostPreview . default ;
2015-10-11 13:02:57 +10:30
} , function ( _flarumComponentsLoadingIndicator ) {
2016-03-18 09:33:14 +10:30
LoadingIndicator = _flarumComponentsLoadingIndicator . default ;
2015-10-11 13:02:57 +10:30
} ] ,
execute : function ( ) { }
} ;
2015-11-03 10:03:33 +10:30
} ) ; ;
2016-03-18 09:33:14 +10:30
'use strict' ;
2015-10-11 13:02:57 +10:30
2016-06-02 15:44:04 +04:30
System . register ( 'flarum/mentions/addPostQuoteButton' , [ 'flarum/extend' , 'flarum/components/CommentPost' , 'flarum/mentions/components/PostQuoteButton' , 'flarum/mentions/utils/selectedText' ] , function ( _export , _context ) {
"use strict" ;
var extend , CommentPost , PostQuoteButton , selectedText ;
2016-04-16 00:44:33 +04:30
function addPostQuoteButton ( ) {
extend ( CommentPost . prototype , 'config' , function ( original , isInitialized ) {
2016-03-18 09:33:14 +10:30
var post = this . props . post ;
2015-10-11 13:02:57 +10:30
2016-04-16 00:44:33 +04:30
if ( isInitialized || post . isHidden ( ) || app . session . user && ! post . discussion ( ) . canReply ( ) ) return ;
2015-10-11 13:02:57 +10:30
2016-06-02 15:44:04 +04:30
var $postBody = this . $ ( '.Post-body' ) ;
2015-10-11 13:02:57 +10:30
2016-04-16 00:44:33 +04:30
// Wrap the quote button in a wrapper element so that we can render
// button into it.
var $container = $ ( '<div class="Post-quoteButtonContainer"></div>' ) ;
2016-01-20 20:18:55 +01:00
2016-04-16 00:44:33 +04:30
this . $ ( ) . after ( $container ) . on ( 'mouseup' , function ( e ) {
setTimeout ( function ( ) {
2016-06-02 15:44:04 +04:30
var content = selectedText ( $postBody ) ;
if ( content ) {
var button = new PostQuoteButton ( { post : post , content : content } ) ;
m . render ( $container [ 0 ] , button . render ( ) ) ;
var rects = window . getSelection ( ) . getRangeAt ( 0 ) . getClientRects ( ) ;
var firstRect = rects [ 0 ] ;
if ( e . clientY < firstRect . bottom && e . clientX - firstRect . right < firstRect . left - e . clientX ) {
button . showStart ( firstRect . left , firstRect . top ) ;
} else {
var lastRect = rects [ rects . length - 1 ] ;
button . showEnd ( lastRect . right , lastRect . bottom ) ;
2016-04-16 00:44:33 +04:30
}
}
} , 1 ) ;
} ) ;
} ) ;
}
_export ( 'default' , addPostQuoteButton ) ;
return {
setters : [ function ( _flarumExtend ) {
extend = _flarumExtend . extend ;
} , function ( _flarumComponentsCommentPost ) {
CommentPost = _flarumComponentsCommentPost . default ;
} , function ( _flarumMentionsComponentsPostQuoteButton ) {
PostQuoteButton = _flarumMentionsComponentsPostQuoteButton . default ;
2016-06-02 15:44:04 +04:30
} , function ( _flarumMentionsUtilsSelectedText ) {
selectedText = _flarumMentionsUtilsSelectedText . default ;
2016-04-16 00:44:33 +04:30
} ] ,
execute : function ( ) { }
} ;
} ) ; ;
'use strict' ;
2016-06-02 15:44:04 +04:30
System . register ( 'flarum/mentions/addPostReplyAction' , [ 'flarum/extend' , 'flarum/components/Button' , 'flarum/components/CommentPost' , 'flarum/mentions/utils/reply' , 'flarum/mentions/utils/selectedText' ] , function ( _export , _context ) {
"use strict" ;
var extend , Button , CommentPost , reply , selectedText ;
2016-04-16 00:44:33 +04:30
_export ( 'default' , function ( ) {
extend ( CommentPost . prototype , 'actionItems' , function ( items ) {
2016-06-02 15:44:04 +04:30
var _this = this ;
2016-04-16 00:44:33 +04:30
var post = this . props . post ;
if ( post . isHidden ( ) || app . session . user && ! post . discussion ( ) . canReply ( ) ) return ;
2015-10-11 13:02:57 +10:30
2016-03-18 09:33:14 +10:30
items . add ( 'reply' , Button . component ( {
className : 'Button Button--link' ,
children : app . translator . trans ( 'flarum-mentions.forum.post.reply_link' ) ,
onclick : function onclick ( ) {
2016-06-02 15:44:04 +04:30
reply ( post , selectedText ( _this . $ ( '.Post-body' ) ) ) ;
2016-03-18 09:33:14 +10:30
}
} ) ) ;
} ) ;
} ) ;
return {
setters : [ function ( _flarumExtend ) {
extend = _flarumExtend . extend ;
} , function ( _flarumComponentsButton ) {
Button = _flarumComponentsButton . default ;
} , function ( _flarumComponentsCommentPost ) {
CommentPost = _flarumComponentsCommentPost . default ;
2016-04-16 00:44:33 +04:30
} , function ( _flarumMentionsUtilsReply ) {
reply = _flarumMentionsUtilsReply . default ;
2016-06-02 15:44:04 +04:30
} , function ( _flarumMentionsUtilsSelectedText ) {
selectedText = _flarumMentionsUtilsSelectedText . default ;
2016-03-18 09:33:14 +10:30
} ] ,
execute : function ( ) { }
2015-10-11 13:02:57 +10:30
} ;
2015-11-03 10:03:33 +10:30
} ) ; ;
2016-03-18 09:33:14 +10:30
'use strict' ;
2015-10-11 13:02:57 +10:30
2016-03-18 09:33:14 +10:30
System . register ( 'flarum/mentions/components/AutocompleteDropdown' , [ 'flarum/Component' ] , function ( _export , _context ) {
2016-06-02 15:44:04 +04:30
"use strict" ;
2015-10-11 13:02:57 +10:30
var Component , AutocompleteDropdown ;
return {
setters : [ function ( _flarumComponent ) {
2016-03-18 09:33:14 +10:30
Component = _flarumComponent . default ;
2015-10-11 13:02:57 +10:30
} ] ,
execute : function ( ) {
2016-03-18 09:33:14 +10:30
AutocompleteDropdown = function ( _Component ) {
2015-10-11 13:02:57 +10:30
babelHelpers . inherits ( AutocompleteDropdown , _Component ) ;
function AutocompleteDropdown ( ) {
babelHelpers . classCallCheck ( this , AutocompleteDropdown ) ;
2016-03-18 09:33:14 +10:30
return babelHelpers . possibleConstructorReturn ( this , Object . getPrototypeOf ( AutocompleteDropdown ) . apply ( this , arguments ) ) ;
2015-10-11 13:02:57 +10:30
}
babelHelpers . createClass ( AutocompleteDropdown , [ {
2015-10-22 10:52:07 +02:00
key : 'init' ,
value : function init ( ) {
this . active = false ;
this . index = 0 ;
this . keyWasJustPressed = false ;
}
} , {
2015-10-11 13:02:57 +10:30
key : 'view' ,
value : function view ( ) {
return m (
'ul' ,
{ className : 'Dropdown-menu MentionsDropdown' } ,
this . props . items . map ( function ( item ) {
return m (
'li' ,
null ,
item
) ;
} )
) ;
}
} , {
key : 'show' ,
value : function show ( left , top ) {
this . $ ( ) . show ( ) . css ( {
left : left + 'px' ,
top : top + 'px'
} ) ;
this . active = true ;
}
} , {
key : 'hide' ,
value : function hide ( ) {
this . $ ( ) . hide ( ) ;
this . active = false ;
}
} , {
key : 'navigate' ,
2016-05-15 22:42:15 +09:00
value : function navigate ( delta ) {
2016-03-18 09:33:14 +10:30
var _this2 = this ;
2015-10-11 13:02:57 +10:30
2016-05-15 22:42:15 +09:00
this . keyWasJustPressed = true ;
this . setIndex ( this . index + delta , true ) ;
clearTimeout ( this . keyWasJustPressedTimeout ) ;
this . keyWasJustPressedTimeout = setTimeout ( function ( ) {
return _this2 . keyWasJustPressed = false ;
} , 500 ) ;
}
} , {
key : 'complete' ,
value : function complete ( ) {
this . $ ( 'li' ) . eq ( this . index ) . find ( 'button' ) . click ( ) ;
2015-10-11 13:02:57 +10:30
}
} , {
key : 'setIndex' ,
value : function setIndex ( index , scrollToItem ) {
if ( this . keyWasJustPressed && ! scrollToItem ) return ;
var $dropdown = this . $ ( ) ;
var $items = $dropdown . find ( 'li' ) ;
var rangedIndex = index ;
if ( rangedIndex < 0 ) {
rangedIndex = $items . length - 1 ;
} else if ( rangedIndex >= $items . length ) {
rangedIndex = 0 ;
}
this . index = rangedIndex ;
var $item = $items . removeClass ( 'active' ) . eq ( rangedIndex ) . addClass ( 'active' ) ;
if ( scrollToItem ) {
var dropdownScroll = $dropdown . scrollTop ( ) ;
var dropdownTop = $dropdown . offset ( ) . top ;
var dropdownBottom = dropdownTop + $dropdown . outerHeight ( ) ;
var itemTop = $item . offset ( ) . top ;
var itemBottom = itemTop + $item . outerHeight ( ) ;
2016-03-18 09:33:14 +10:30
var scrollTop = void 0 ;
2015-10-11 13:02:57 +10:30
if ( itemTop < dropdownTop ) {
scrollTop = dropdownScroll - dropdownTop + itemTop - parseInt ( $dropdown . css ( 'padding-top' ) , 10 ) ;
} else if ( itemBottom > dropdownBottom ) {
scrollTop = dropdownScroll - dropdownBottom + itemBottom + parseInt ( $dropdown . css ( 'padding-bottom' ) , 10 ) ;
}
if ( typeof scrollTop !== 'undefined' ) {
$dropdown . stop ( true ) . animate ( { scrollTop : scrollTop } , 100 ) ;
}
}
}
} ] ) ;
return AutocompleteDropdown ;
2016-03-18 09:33:14 +10:30
} ( Component ) ;
2015-10-11 13:02:57 +10:30
_export ( 'default' , AutocompleteDropdown ) ;
}
} ;
2015-11-03 10:03:33 +10:30
} ) ; ;
2016-03-18 09:33:14 +10:30
'use strict' ;
2016-02-23 10:15:43 +09:00
2016-03-18 09:33:14 +10:30
System . register ( 'flarum/mentions/components/MentionsUserPage' , [ 'flarum/components/PostsUserPage' ] , function ( _export , _context ) {
2016-06-02 15:44:04 +04:30
"use strict" ;
2016-02-23 10:15:43 +09:00
var PostsUserPage , MentionsUserPage ;
return {
setters : [ function ( _flarumComponentsPostsUserPage ) {
2016-03-18 09:33:14 +10:30
PostsUserPage = _flarumComponentsPostsUserPage . default ;
2016-02-23 10:15:43 +09:00
} ] ,
execute : function ( ) {
2016-03-18 09:33:14 +10:30
MentionsUserPage = function ( _PostsUserPage ) {
2016-02-23 10:15:43 +09:00
babelHelpers . inherits ( MentionsUserPage , _PostsUserPage ) ;
function MentionsUserPage ( ) {
babelHelpers . classCallCheck ( this , MentionsUserPage ) ;
2016-03-18 09:33:14 +10:30
return babelHelpers . possibleConstructorReturn ( this , Object . getPrototypeOf ( MentionsUserPage ) . apply ( this , arguments ) ) ;
2016-02-23 10:15:43 +09:00
}
babelHelpers . createClass ( MentionsUserPage , [ {
key : 'loadResults' ,
value : function loadResults ( offset ) {
return app . store . find ( 'posts' , {
filter : {
type : 'comment' ,
mentioned : this . user . id ( )
} ,
page : { offset : offset , limit : this . loadLimit } ,
sort : '-time'
} ) ;
}
} ] ) ;
return MentionsUserPage ;
2016-03-18 09:33:14 +10:30
} ( PostsUserPage ) ;
2016-02-23 10:15:43 +09:00
_export ( 'default' , MentionsUserPage ) ;
}
} ;
} ) ; ;
2016-03-18 09:33:14 +10:30
'use strict' ;
2015-10-11 13:02:57 +10:30
2016-03-18 09:33:14 +10:30
System . register ( 'flarum/mentions/components/PostMentionedNotification' , [ 'flarum/components/Notification' , 'flarum/helpers/username' , 'flarum/helpers/punctuateSeries' ] , function ( _export , _context ) {
2016-06-02 15:44:04 +04:30
"use strict" ;
2015-10-27 12:16:54 +10:30
var Notification , username , punctuateSeries , PostMentionedNotification ;
2015-10-11 13:02:57 +10:30
return {
setters : [ function ( _flarumComponentsNotification ) {
2016-03-18 09:33:14 +10:30
Notification = _flarumComponentsNotification . default ;
2015-10-11 13:02:57 +10:30
} , function ( _flarumHelpersUsername ) {
2016-03-18 09:33:14 +10:30
username = _flarumHelpersUsername . default ;
2015-10-27 12:16:54 +10:30
} , function ( _flarumHelpersPunctuateSeries ) {
2016-03-18 09:33:14 +10:30
punctuateSeries = _flarumHelpersPunctuateSeries . default ;
2015-10-11 13:02:57 +10:30
} ] ,
execute : function ( ) {
2016-03-18 09:33:14 +10:30
PostMentionedNotification = function ( _Notification ) {
2015-10-11 13:02:57 +10:30
babelHelpers . inherits ( PostMentionedNotification , _Notification ) ;
function PostMentionedNotification ( ) {
babelHelpers . classCallCheck ( this , PostMentionedNotification ) ;
2016-03-18 09:33:14 +10:30
return babelHelpers . possibleConstructorReturn ( this , Object . getPrototypeOf ( PostMentionedNotification ) . apply ( this , arguments ) ) ;
2015-10-11 13:02:57 +10:30
}
babelHelpers . createClass ( PostMentionedNotification , [ {
key : 'icon' ,
value : function icon ( ) {
return 'reply' ;
}
} , {
key : 'href' ,
value : function href ( ) {
var notification = this . props . notification ;
var post = notification . subject ( ) ;
var auc = notification . additionalUnreadCount ( ) ;
var content = notification . content ( ) ;
return app . route . discussion ( post . discussion ( ) , auc ? post . number ( ) : content && content . replyNumber ) ;
}
} , {
key : 'content' ,
value : function content ( ) {
var notification = this . props . notification ;
var auc = notification . additionalUnreadCount ( ) ;
var user = notification . sender ( ) ;
2015-10-27 12:16:54 +10:30
return app . translator . transChoice ( 'flarum-mentions.forum.notifications.post_mentioned_text' , auc + 1 , {
2015-10-11 13:02:57 +10:30
user : user ,
2015-10-27 12:16:54 +10:30
username : auc ? punctuateSeries ( [ username ( user ) , app . translator . transChoice ( 'flarum-mentions.forum.notifications.others_text' , auc , { count : auc } ) ] ) : undefined
2015-10-11 13:02:57 +10:30
} ) ;
}
} , {
key : 'excerpt' ,
value : function excerpt ( ) {
return this . props . notification . subject ( ) . contentPlain ( ) ;
}
} ] ) ;
return PostMentionedNotification ;
2016-03-18 09:33:14 +10:30
} ( Notification ) ;
2015-10-11 13:02:57 +10:30
_export ( 'default' , PostMentionedNotification ) ;
}
} ;
2015-11-03 10:03:33 +10:30
} ) ; ;
2016-03-18 09:33:14 +10:30
'use strict' ;
2015-10-11 13:02:57 +10:30
2016-04-16 00:44:33 +04:30
System . register ( 'flarum/mentions/components/PostQuoteButton' , [ 'flarum/components/Button' , 'flarum/utils/extract' , 'flarum/mentions/utils/reply' ] , function ( _export , _context ) {
2016-06-02 15:44:04 +04:30
"use strict" ;
2016-04-16 00:44:33 +04:30
var Button , extract , reply , PostQuoteButton ;
return {
setters : [ function ( _flarumComponentsButton ) {
Button = _flarumComponentsButton . default ;
} , function ( _flarumUtilsExtract ) {
extract = _flarumUtilsExtract . default ;
} , function ( _flarumMentionsUtilsReply ) {
reply = _flarumMentionsUtilsReply . default ;
} ] ,
execute : function ( ) {
PostQuoteButton = function ( _Button ) {
babelHelpers . inherits ( PostQuoteButton , _Button ) ;
function PostQuoteButton ( ) {
babelHelpers . classCallCheck ( this , PostQuoteButton ) ;
return babelHelpers . possibleConstructorReturn ( this , Object . getPrototypeOf ( PostQuoteButton ) . apply ( this , arguments ) ) ;
}
babelHelpers . createClass ( PostQuoteButton , [ {
key : 'view' ,
value : function view ( ) {
var _this2 = this ;
var post = extract ( this . props , 'post' ) ;
var content = extract ( this . props , 'content' ) ;
this . props . className = 'Button PostQuoteButton' ;
this . props . icon = 'quote-left' ;
this . props . children = app . translator . trans ( 'flarum-mentions.forum.post.quote_button' ) ;
this . props . onclick = function ( ) {
_this2 . hide ( ) ;
reply ( post , content ) ;
} ;
this . props . onmousedown = function ( e ) {
return e . stopPropagation ( ) ;
} ;
return babelHelpers . get ( Object . getPrototypeOf ( PostQuoteButton . prototype ) , 'view' , this ) . call ( this ) ;
}
} , {
key : 'config' ,
value : function config ( isInitialized ) {
if ( isInitialized ) return ;
$ ( document ) . on ( 'mousedown' , this . hide . bind ( this ) ) ;
}
} , {
2016-05-22 14:05:38 +09:30
key : 'showStart' ,
value : function showStart ( left , top ) {
var $this = this . $ ( ) ;
$this . show ( ) . css ( 'left' , left ) . css ( 'top' , $ ( window ) . scrollTop ( ) + top - $this . outerHeight ( ) - 5 ) ;
}
} , {
key : 'showEnd' ,
value : function showEnd ( right , bottom ) {
2016-04-16 00:44:33 +04:30
var $this = this . $ ( ) ;
2016-05-22 14:05:38 +09:30
$this . show ( ) . css ( 'left' , right - $this . outerWidth ( ) ) . css ( 'top' , $ ( window ) . scrollTop ( ) + bottom + 5 ) ;
2016-04-16 00:44:33 +04:30
}
} , {
key : 'hide' ,
value : function hide ( ) {
this . $ ( ) . hide ( ) ;
}
} ] ) ;
return PostQuoteButton ;
} ( Button ) ;
_export ( 'default' , PostQuoteButton ) ;
}
} ;
} ) ; ;
'use strict' ;
2016-03-18 09:33:14 +10:30
System . register ( 'flarum/mentions/components/UserMentionedNotification' , [ 'flarum/components/Notification' ] , function ( _export , _context ) {
2016-06-02 15:44:04 +04:30
"use strict" ;
2015-10-11 13:02:57 +10:30
var Notification , UserMentionedNotification ;
return {
setters : [ function ( _flarumComponentsNotification ) {
2016-03-18 09:33:14 +10:30
Notification = _flarumComponentsNotification . default ;
2015-10-11 13:02:57 +10:30
} ] ,
execute : function ( ) {
2016-03-18 09:33:14 +10:30
UserMentionedNotification = function ( _Notification ) {
2015-10-11 13:02:57 +10:30
babelHelpers . inherits ( UserMentionedNotification , _Notification ) ;
function UserMentionedNotification ( ) {
babelHelpers . classCallCheck ( this , UserMentionedNotification ) ;
2016-03-18 09:33:14 +10:30
return babelHelpers . possibleConstructorReturn ( this , Object . getPrototypeOf ( UserMentionedNotification ) . apply ( this , arguments ) ) ;
2015-10-11 13:02:57 +10:30
}
babelHelpers . createClass ( UserMentionedNotification , [ {
key : 'icon' ,
value : function icon ( ) {
return 'at' ;
}
} , {
key : 'href' ,
value : function href ( ) {
var post = this . props . notification . subject ( ) ;
return app . route . discussion ( post . discussion ( ) , post . number ( ) ) ;
}
} , {
key : 'content' ,
value : function content ( ) {
var user = this . props . notification . sender ( ) ;
2015-10-27 12:16:54 +10:30
return app . translator . trans ( 'flarum-mentions.forum.notifications.user_mentioned_text' , { user : user } ) ;
2015-10-11 13:02:57 +10:30
}
} , {
key : 'excerpt' ,
value : function excerpt ( ) {
return this . props . notification . subject ( ) . contentPlain ( ) ;
}
} ] ) ;
return UserMentionedNotification ;
2016-03-18 09:33:14 +10:30
} ( Notification ) ;
2015-10-11 13:02:57 +10:30
_export ( 'default' , UserMentionedNotification ) ;
}
} ;
2015-11-03 10:03:33 +10:30
} ) ; ;
2016-03-18 09:33:14 +10:30
'use strict' ;
2015-11-03 10:03:33 +10:30
2016-04-16 00:44:33 +04:30
System . register ( 'flarum/mentions/main' , [ 'flarum/extend' , 'flarum/app' , 'flarum/components/NotificationGrid' , 'flarum/utils/string' , 'flarum/mentions/addPostMentionPreviews' , 'flarum/mentions/addMentionedByList' , 'flarum/mentions/addPostReplyAction' , 'flarum/mentions/addPostQuoteButton' , 'flarum/mentions/addComposerAutocomplete' , 'flarum/mentions/components/PostMentionedNotification' , 'flarum/mentions/components/UserMentionedNotification' , 'flarum/components/UserPage' , 'flarum/components/LinkButton' , 'flarum/mentions/components/MentionsUserPage' ] , function ( _export , _context ) {
2016-06-02 15:44:04 +04:30
"use strict" ;
2016-04-16 00:44:33 +04:30
var extend , app , NotificationGrid , getPlainContent , addPostMentionPreviews , addMentionedByList , addPostReplyAction , addPostQuoteButton , addComposerAutocomplete , PostMentionedNotification , UserMentionedNotification , UserPage , LinkButton , MentionsUserPage ;
2015-11-03 10:03:33 +10:30
return {
setters : [ function ( _flarumExtend ) {
extend = _flarumExtend . extend ;
} , function ( _flarumApp ) {
2016-03-18 09:33:14 +10:30
app = _flarumApp . default ;
2015-11-03 10:03:33 +10:30
} , function ( _flarumComponentsNotificationGrid ) {
2016-03-18 09:33:14 +10:30
NotificationGrid = _flarumComponentsNotificationGrid . default ;
2015-11-03 10:03:33 +10:30
} , function ( _flarumUtilsString ) {
getPlainContent = _flarumUtilsString . getPlainContent ;
} , function ( _flarumMentionsAddPostMentionPreviews ) {
2016-03-18 09:33:14 +10:30
addPostMentionPreviews = _flarumMentionsAddPostMentionPreviews . default ;
2015-11-03 10:03:33 +10:30
} , function ( _flarumMentionsAddMentionedByList ) {
2016-03-18 09:33:14 +10:30
addMentionedByList = _flarumMentionsAddMentionedByList . default ;
2015-11-03 10:03:33 +10:30
} , function ( _flarumMentionsAddPostReplyAction ) {
2016-03-18 09:33:14 +10:30
addPostReplyAction = _flarumMentionsAddPostReplyAction . default ;
2016-04-16 00:44:33 +04:30
} , function ( _flarumMentionsAddPostQuoteButton ) {
addPostQuoteButton = _flarumMentionsAddPostQuoteButton . default ;
2015-11-03 10:03:33 +10:30
} , function ( _flarumMentionsAddComposerAutocomplete ) {
2016-03-18 09:33:14 +10:30
addComposerAutocomplete = _flarumMentionsAddComposerAutocomplete . default ;
2015-11-03 10:03:33 +10:30
} , function ( _flarumMentionsComponentsPostMentionedNotification ) {
2016-03-18 09:33:14 +10:30
PostMentionedNotification = _flarumMentionsComponentsPostMentionedNotification . default ;
2015-11-03 10:03:33 +10:30
} , function ( _flarumMentionsComponentsUserMentionedNotification ) {
2016-03-18 09:33:14 +10:30
UserMentionedNotification = _flarumMentionsComponentsUserMentionedNotification . default ;
2016-02-04 01:04:08 +03:30
} , function ( _flarumComponentsUserPage ) {
2016-03-18 09:33:14 +10:30
UserPage = _flarumComponentsUserPage . default ;
2016-02-04 01:04:08 +03:30
} , function ( _flarumComponentsLinkButton ) {
2016-03-18 09:33:14 +10:30
LinkButton = _flarumComponentsLinkButton . default ;
2016-02-04 01:04:08 +03:30
} , function ( _flarumMentionsComponentsMentionsUserPage ) {
2016-03-18 09:33:14 +10:30
MentionsUserPage = _flarumMentionsComponentsMentionsUserPage . default ;
2015-11-03 10:03:33 +10:30
} ] ,
execute : function ( ) {
app . initializers . add ( 'flarum-mentions' , function ( ) {
// For every mention of a post inside a post's content, set up a hover handler
// that shows a preview of the mentioned post.
addPostMentionPreviews ( ) ;
// In the footer of each post, show information about who has replied (i.e.
// who the post has been mentioned by).
addMentionedByList ( ) ;
// Add a 'reply' control to the footer of each post. When clicked, it will
// open up the composer and add a post mention to its contents.
addPostReplyAction ( ) ;
2016-04-16 00:44:33 +04:30
// Show a Quote button when Post text is selected
addPostQuoteButton ( ) ;
2015-11-03 10:03:33 +10:30
// After typing '@' in the composer, show a dropdown suggesting a bunch of
// posts or users that the user could mention.
addComposerAutocomplete ( ) ;
app . notificationComponents . postMentioned = PostMentionedNotification ;
app . notificationComponents . userMentioned = UserMentionedNotification ;
// Add notification preferences.
extend ( NotificationGrid . prototype , 'notificationTypes' , function ( items ) {
items . add ( 'postMentioned' , {
name : 'postMentioned' ,
icon : 'reply' ,
label : app . translator . trans ( 'flarum-mentions.forum.settings.notify_post_mentioned_label' )
} ) ;
items . add ( 'userMentioned' , {
name : 'userMentioned' ,
icon : 'at' ,
label : app . translator . trans ( 'flarum-mentions.forum.settings.notify_user_mentioned_label' )
} ) ;
} ) ;
2016-02-23 10:15:43 +09:00
// Add mentions tab in user profile
2016-02-04 01:04:08 +03:30
app . routes [ 'user.mentions' ] = { path : '/u/:username/mentions' , component : MentionsUserPage . component ( ) } ;
extend ( UserPage . prototype , 'navItems' , function ( items ) {
var user = this . user ;
items . add ( 'mentions' , LinkButton . component ( {
href : app . route ( 'user.mentions' , { username : user . username ( ) } ) ,
name : 'mentions' ,
children : [ app . translator . trans ( 'flarum-mentions.forum.user.mentions_link' ) ] ,
icon : 'at'
} ) , 80 ) ;
} ) ;
2015-11-03 10:03:33 +10:30
getPlainContent . removeSelectors . push ( 'a.PostMention' ) ;
} ) ;
}
} ;
2016-04-16 00:44:33 +04:30
} ) ; ;
'use strict' ;
System . register ( 'flarum/mentions/utils/reply' , [ 'flarum/utils/DiscussionControls' ] , function ( _export , _context ) {
2016-06-02 15:44:04 +04:30
"use strict" ;
2016-04-16 00:44:33 +04:30
var DiscussionControls ;
function insertMention ( post , component , quote ) {
var user = post . user ( ) ;
var mention = '@' + ( user ? user . username ( ) : post . number ( ) ) + '#' + post . id ( ) + ' ' ;
// If the composer is empty, then assume we're starting a new reply.
// In which case we don't want the user to have to confirm if they
// close the composer straight away.
if ( ! component . content ( ) ) {
component . props . originalContent = mention ;
}
var cursorPosition = component . editor . getSelectionRange ( ) [ 0 ] ;
var preceding = component . editor . value ( ) . slice ( 0 , cursorPosition ) ;
var precedingNewlines = preceding . length == 0 ? 0 : 3 - preceding . match ( /(\n{0,2})$/ ) [ 0 ] . length ;
component . editor . insertAtCursor ( Array ( precedingNewlines ) . join ( '\n' ) + ( // Insert up to two newlines, depending on preceding whitespace
quote ? '> ' + mention + quote . trim ( ) . replace ( /\n/g , '\n> ' ) + '\n\n' : mention ) ) ;
}
function reply ( post , quote ) {
var component = app . composer . component ;
if ( component && component . props . post && component . props . post . discussion ( ) === post . discussion ( ) ) {
insertMention ( post , component , quote ) ;
} else {
DiscussionControls . replyAction . call ( post . discussion ( ) ) . then ( function ( newComponent ) {
return insertMention ( post , newComponent , quote ) ;
} ) ;
}
}
_export ( 'default' , reply ) ;
return {
setters : [ function ( _flarumUtilsDiscussionControls ) {
DiscussionControls = _flarumUtilsDiscussionControls . default ;
} ] ,
execute : function ( ) { }
} ;
2016-06-02 15:44:04 +04:30
} ) ; ;
"use strict" ;
System . register ( "flarum/mentions/utils/selectedText" , [ ] , function ( _export , _context ) {
"use strict" ;
function selectedText ( body ) {
var selection = window . getSelection ( ) ;
if ( selection . rangeCount ) {
var range = selection . getRangeAt ( 0 ) ;
var parent = range . commonAncestorContainer ;
if ( body [ 0 ] === parent || $ . contains ( body [ 0 ] , parent ) ) {
var clone = $ ( "<div>" ) . append ( range . cloneContents ( ) ) ;
clone . find ( 'img.emoji' ) . replaceWith ( function ( ) {
return this . alt ;
} ) ;
return clone . text ( ) ;
}
}
return "" ;
}
_export ( "default" , selectedText ) ;
return {
setters : [ ] ,
execute : function ( ) { }
} ;
2015-10-11 13:02:57 +10:30
} ) ;