@@ -129,6 +129,23 @@ div {
129129 " images" : [{ " url" : data .Values .url }]
130130 });
131131 },
132+ ' Action_SetUsers ' : function (data ) {
133+ // response to UI_RequestUsers; "c" is echoed back by the host so the editor can
134+ // route the list to the request that asked for it. Each user needs both "email"
135+ // and "name" or Common.UI.ExternalUsers drops it from the list; "hasAccess"
136+ // sorts users who can already open the file above a separator, "image" is the
137+ // optional avatar. isPaginated must be present to keep the editor in
138+ // server-side-search mode (undefined switches it to "fetch once, filter locally").
139+ data && data .Values && docEditor .setUsers ({
140+ " c" : data .Values .c ,
141+ " users" : data .Values .users ,
142+ " isPaginated" : data .Values .isPaginated
143+ });
144+ },
145+ ' Action_SetActionLink ' : function (data ) {
146+ // response to UI_MakeActionLink; setActionLink takes the url as a bare string
147+ data && data .Values && docEditor .setActionLink (data .Values .url );
148+ },
132149 ' Host_PostmessageReady ' : function (data ) {
133150 innerAlert (' Host_PostmessageReady' );
134151 }
@@ -250,6 +267,40 @@ div {
250267 _postMessage (' UI_InsertGraphic' , {});
251268 };
252269
270+ var onRequestUsers = function (event ) {
271+ // see Common.Gateway.requestUsers: "c" is the operation type (mention/protect/info),
272+ // "id" carries the user ids to resolve for c==="info", and from/count/search describe
273+ // the mention autocomplete query. Forwarding search/from/count lets the host search
274+ // server-side; it must then answer with isPaginated set, otherwise
275+ // Common.UI.ExternalUsers caches the first response and never asks again.
276+ _postMessage (' UI_RequestUsers' , {
277+ " c" : event .data .c ,
278+ " id" : event .data .id ,
279+ " from" : event .data .from ,
280+ " count" : event .data .count ,
281+ " search" : event .data .search
282+ });
283+ };
284+
285+ var onRequestSendNotify = function (event ) {
286+ // event.data is Comments.js' pickEMail payload: the emails are parsed out of the
287+ // comment text, so they are exactly the ones the host handed over in Action_SetUsers
288+ _postMessage (' UI_SendNotify' , {
289+ " actionLink" : event .data .actionLink ,
290+ " actionId" : event .data .actionId ,
291+ " message" : event .data .message ,
292+ " emails" : event .data .emails
293+ });
294+ };
295+
296+ var onMakeActionLink = function (event ) {
297+ // event.data is {action: {type: "bookmark"|"comment", data: <name|comment id>}}; the host
298+ // turns it into a document url carrying that anchor, and answers Action_SetActionLink
299+ _postMessage (' UI_MakeActionLink' , {
300+ " config" : event .data
301+ });
302+ };
303+
253304 var onError = function (event ) {
254305 if (event )
255306 innerAlert (event .data );
@@ -405,10 +456,30 @@ div {
405456 " onRequestRename" : fileInfo .SupportsRename && fileInfo .UserCanRename ? onRequestRename : undefined ,
406457 " onRequestSharingSettings" : fileInfo .FileSharingPostMessage || fileInfo .FileSharingUrl ? onRequestSharingSettings : undefined ,
407458 " onRequestHistory" : fileInfo .FileVersionUrl || fileInfo .FileVersionPostMessage ? onRequestHistory : undefined ,
408- " onRequestInsertImage" : fileInfo .EnableInsertRemoteImage ? onRequestInsertImage : undefined
459+ " onRequestInsertImage" : fileInfo .EnableInsertRemoteImage ? onRequestInsertImage : undefined ,
460+ // mentions: the @/+ button only renders when onRequestSendNotify is set, and on
461+ // editors < 5.5 onRequestSendNotify requires onRequestUsers - register both or
462+ // neither. Also gated on comment rights: a view-only user must not be offered
463+ // mention prompts.
464+ " onRequestUsers" : permissionsComment && fileInfo .UserMentionPostMessage ? onRequestUsers : undefined ,
465+ " onRequestSendNotify" : permissionsComment && fileInfo .UserMentionPostMessage ? onRequestSendNotify : undefined ,
466+ // "copy link to this comment/bookmark". Not gated on comment rights: bookmark
467+ // links are useful to a read-only reader too.
468+ " onMakeActionLink" : fileInfo .UserMentionPostMessage ? onMakeActionLink : undefined
409469 }
410470 });
411471
472+ // Deep link into a comment/bookmark: the other half of onMakeActionLink and of the
473+ // mention notifications. Set after the merges rather than inside them, so an absent
474+ // param doesn't clobber an actionLink the host supplied via docs_api_config.
475+ if (queryParams .actionlink ) {
476+ try {
477+ config .editorConfig .actionLink = JSON .parse (queryParams .actionlink );
478+ } catch (e) {
479+ innerAlert (" Ignoring malformed actionlink parameter" );
480+ }
481+ }
482+
412483 postMessageOrigin = fileInfo .PostMessageOrigin || " *" ;
413484 if (postMessageOrigin && (typeof postMessageOrigin === ' string' ) && postMessageOrigin .charAt (postMessageOrigin .length - 1 )== ' /' )
414485 postMessageOrigin = postMessageOrigin .substring (0 , postMessageOrigin .length - 1 );
0 commit comments