mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-03 21:43:21 +00:00 
			
		
		
		
	copy_and_paste: Extract analyze_selection function.
				
					
				
			This is the part where the whole selection is analyzed to get the `start_id` and `end_id` of the messages that are selected (the loop part of the copy handler). This is extracted and exported as well.
This commit is contained in:
		@@ -88,83 +88,15 @@ function copy_handler() {
 | 
			
		||||
    //
 | 
			
		||||
    // * Otherwise, we want to copy the bodies of all messages that
 | 
			
		||||
    //   were partially covered by the selection.
 | 
			
		||||
    //
 | 
			
		||||
    // Firefox and Chrome handle selection of multiple messages
 | 
			
		||||
    // differently. Firefox typically creates multiple ranges for the
 | 
			
		||||
    // selection, whereas Chrome typically creates just one.
 | 
			
		||||
    //
 | 
			
		||||
    // Our goal in the below loop is to compute and be prepared to
 | 
			
		||||
    // analyze the combined range of the selections, and copy their
 | 
			
		||||
    // full content.
 | 
			
		||||
 | 
			
		||||
    var selection = window.getSelection();
 | 
			
		||||
    var i;
 | 
			
		||||
    var range;
 | 
			
		||||
    var ranges = [];
 | 
			
		||||
    var startc;
 | 
			
		||||
    var endc;
 | 
			
		||||
    var initial_end_tr;
 | 
			
		||||
    var start_id;
 | 
			
		||||
    var end_id;
 | 
			
		||||
    var start_data;
 | 
			
		||||
    var end_data;
 | 
			
		||||
    // skip_same_td_check is true whenever we know for a fact that the
 | 
			
		||||
    // selection covers multiple messages (and thus we should no
 | 
			
		||||
    // longer consider letting the browser handle the copy event).
 | 
			
		||||
    var skip_same_td_check = false;
 | 
			
		||||
    var analysis = exports.analyze_selection(selection);
 | 
			
		||||
    var ranges = analysis.ranges;
 | 
			
		||||
    var start_id = analysis.start_id;
 | 
			
		||||
    var end_id = analysis.end_id;
 | 
			
		||||
    var skip_same_td_check = analysis.skip_same_td_check;
 | 
			
		||||
    var div = $('<div>');
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < selection.rangeCount; i += 1) {
 | 
			
		||||
        range = selection.getRangeAt(i);
 | 
			
		||||
        ranges.push(range);
 | 
			
		||||
 | 
			
		||||
        startc = $(range.startContainer);
 | 
			
		||||
        start_data = find_boundary_tr($(startc.parents('.selectable_row, .message_header')[0]), function (row) {
 | 
			
		||||
            return row.next();
 | 
			
		||||
        });
 | 
			
		||||
        if (start_data === undefined) {
 | 
			
		||||
            // Skip any selection sections that don't intersect a message.
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
        if (start_id === undefined) {
 | 
			
		||||
            // start_id is the Zulip message ID of the first message
 | 
			
		||||
            // touched by the selection.
 | 
			
		||||
            start_id = start_data[0];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        endc = $(range.endContainer);
 | 
			
		||||
        // If the selection ends in the bottom whitespace, we should
 | 
			
		||||
        // act as though the selection ends on the final message.
 | 
			
		||||
        // This handles the issue that Chrome seems to like selecting
 | 
			
		||||
        // the compose_close button when you go off the end of the
 | 
			
		||||
        // last message
 | 
			
		||||
        if (endc.attr('id') === "bottom_whitespace" || endc.attr('id') === "compose_close") {
 | 
			
		||||
            initial_end_tr = $(".message_row:last");
 | 
			
		||||
            // The selection goes off the end of the message feed, so
 | 
			
		||||
            // this is a multi-message selection.
 | 
			
		||||
            skip_same_td_check = true;
 | 
			
		||||
        } else {
 | 
			
		||||
            initial_end_tr = $(endc.parents('.selectable_row')[0]);
 | 
			
		||||
        }
 | 
			
		||||
        end_data = find_boundary_tr(initial_end_tr, function (row) {
 | 
			
		||||
            return row.prev();
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        if (end_data === undefined) {
 | 
			
		||||
            // Skip any selection sections that don't intersect a message.
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
        if (end_data[0] !== undefined) {
 | 
			
		||||
            end_id = end_data[0];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (start_data[1] || end_data[1]) {
 | 
			
		||||
            // If the find_boundary_tr call for either the first or
 | 
			
		||||
            // the last message covered by the selection
 | 
			
		||||
            skip_same_td_check = true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (start_id === undefined || end_id === undefined) {
 | 
			
		||||
        // In this case either the starting message or the ending
 | 
			
		||||
        // message is not defined, so this is definitely not a
 | 
			
		||||
@@ -236,6 +168,92 @@ function copy_handler() {
 | 
			
		||||
    }, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
exports.analyze_selection = function (selection) {
 | 
			
		||||
    // Here we analyze our selection to determine if part of a message
 | 
			
		||||
    // or multiple messages are selected.
 | 
			
		||||
    //
 | 
			
		||||
    // Firefox and Chrome handle selection of multiple messages
 | 
			
		||||
    // differently. Firefox typically creates multiple ranges for the
 | 
			
		||||
    // selection, whereas Chrome typically creates just one.
 | 
			
		||||
    //
 | 
			
		||||
    // Our goal in the below loop is to compute and be prepared to
 | 
			
		||||
    // analyze the combined range of the selections, and copy their
 | 
			
		||||
    // full content.
 | 
			
		||||
 | 
			
		||||
    var i;
 | 
			
		||||
    var range;
 | 
			
		||||
    var ranges = [];
 | 
			
		||||
    var startc;
 | 
			
		||||
    var endc;
 | 
			
		||||
    var initial_end_tr;
 | 
			
		||||
    var start_id;
 | 
			
		||||
    var end_id;
 | 
			
		||||
    var start_data;
 | 
			
		||||
    var end_data;
 | 
			
		||||
    // skip_same_td_check is true whenever we know for a fact that the
 | 
			
		||||
    // selection covers multiple messages (and thus we should no
 | 
			
		||||
    // longer consider letting the browser handle the copy event).
 | 
			
		||||
    var skip_same_td_check = false;
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < selection.rangeCount; i += 1) {
 | 
			
		||||
        range = selection.getRangeAt(i);
 | 
			
		||||
        ranges.push(range);
 | 
			
		||||
 | 
			
		||||
        startc = $(range.startContainer);
 | 
			
		||||
        start_data = find_boundary_tr($(startc.parents('.selectable_row, .message_header')[0]), function (row) {
 | 
			
		||||
            return row.next();
 | 
			
		||||
        });
 | 
			
		||||
        if (start_data === undefined) {
 | 
			
		||||
            // Skip any selection sections that don't intersect a message.
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
        if (start_id === undefined) {
 | 
			
		||||
            // start_id is the Zulip message ID of the first message
 | 
			
		||||
            // touched by the selection.
 | 
			
		||||
            start_id = start_data[0];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        endc = $(range.endContainer);
 | 
			
		||||
        // If the selection ends in the bottom whitespace, we should
 | 
			
		||||
        // act as though the selection ends on the final message.
 | 
			
		||||
        // This handles the issue that Chrome seems to like selecting
 | 
			
		||||
        // the compose_close button when you go off the end of the
 | 
			
		||||
        // last message
 | 
			
		||||
        if (endc.attr('id') === "bottom_whitespace" || endc.attr('id') === "compose_close") {
 | 
			
		||||
            initial_end_tr = $(".message_row:last");
 | 
			
		||||
            // The selection goes off the end of the message feed, so
 | 
			
		||||
            // this is a multi-message selection.
 | 
			
		||||
            skip_same_td_check = true;
 | 
			
		||||
        } else {
 | 
			
		||||
            initial_end_tr = $(endc.parents('.selectable_row')[0]);
 | 
			
		||||
        }
 | 
			
		||||
        end_data = find_boundary_tr(initial_end_tr, function (row) {
 | 
			
		||||
            return row.prev();
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        if (end_data === undefined) {
 | 
			
		||||
            // Skip any selection sections that don't intersect a message.
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
        if (end_data[0] !== undefined) {
 | 
			
		||||
            end_id = end_data[0];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (start_data[1] || end_data[1]) {
 | 
			
		||||
            // If the find_boundary_tr call for either the first or
 | 
			
		||||
            // the last message covered by the selection
 | 
			
		||||
            skip_same_td_check = true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
        ranges: ranges,
 | 
			
		||||
        start_id: start_id,
 | 
			
		||||
        end_id: end_id,
 | 
			
		||||
        skip_same_td_check: skip_same_td_check,
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
exports.paste_handler_converter = function (paste_html) {
 | 
			
		||||
    var converters = {
 | 
			
		||||
        converters: [
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user