This file is indexed.

/usr/lib/python2.7/dist-packages/notebook/static/notebook/js/clipboard.js is in python-notebook 5.2.2-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
// Copyright (c) Jupyter Development Team.
// Distributed under the terms of the Modified BSD License.

define([
    'jquery',
    'base/js/namespace',
    'base/js/utils',
    'base/js/i18n',
    'base/js/dialog'
], function($, Jupyter, utils, i18n, dialog) {

var jcbprefix = '<pre class="jupyter-nb-cells-json">';
var jcbsuffix = '</pre>';

function store_json(cells, clipboard) {
  // Firefox ignores application/json mime type, so put it in HTML as well.
  // We also copy a text version so you can paste cell sources into a text editor
  var j = JSON.stringify(cells);
  var t = cells.map(function(c) {return c.source;}).join('\n\n');
  clipboard.setData('text/plain', t);
  clipboard.setData('text/html', jcbprefix + j + jcbsuffix);
  clipboard.setData('application/json', j);
}

function load_json(clipboard) {
  var s = clipboard.getData('text/html');
  // System/browsers may add some more stuff before/after our content, so
  // find where our prefix and suffix are.
  var pix = s.indexOf(jcbprefix);
  var six = s.lastIndexOf(jcbsuffix);
  if (pix === -1 || six === -1) {
    return null;
  }
  return JSON.parse(s.slice(pix + jcbprefix.length, six));
}

function copy(event) {
  if ((Jupyter.notebook.mode !== 'command') ||
        // window.getSelection checks if text is selected, e.g. in output
        !window.getSelection().isCollapsed) {
    return;
  }
  var selecn = Jupyter.notebook.get_selected_cells().map(
    function(c) { return c.toJSON();});
  store_json(selecn, event.clipboardData);
  event.preventDefault();
}

function paste(event) {
  if (Jupyter.notebook.mode !== 'command') {
    return;
  }
  console.log(i18n.msg.sprintf(i18n.msg._('Clipboard types: %s'),event.clipboardData.types));
  cells = load_json(event.clipboardData);
  // console.log(cells);
  // Does this JSON look like cells?
  if (Array.isArray(cells) && (cells.length > 0) &&
      cells[0].cell_type && cells[0].source) {
    var first_inserted = null;
    for (var i=0; i < cells.length; i++) {
        var cell_data = cells[i];
        var new_cell = Jupyter.notebook.insert_cell_above(cell_data.cell_type);
        new_cell.fromJSON(cell_data);
        if (first_inserted === null) {
            first_inserted = new_cell;
        }
    }
    first_inserted.focus_cell();
  }
  event.preventDefault();
}

function notebookOnlyEvent(callback) {
    // Only call the callback to redirect the event if the notebook should be
    // handling the events, at the descretion of the keyboard manager.
    // If the focus is in a text widget or something (kbmanager disabled),
    // allow the default event.
    return function() {
        if (Jupyter.keyboard_manager.enabled) {
            callback.apply(this, arguments);
        }
    };
}

function needs_text_box_for_paste_event() {
  // I know this is bad, but I don't know a better way to check this
  return navigator.userAgent.indexOf('Firefox') !== -1;
}

function setup_paste_dialog() {
  // Firefox only fires a paste event if the cursor is in a text input. So, on
  // Ctrl-V, bring up a dialog with an invisible text box and catch the
  // second Ctrl-V
  var action = {
      icon: 'fa-clipboard', // a font-awesome class used on buttons, etc
      help    : i18n.msg._('Dialog for paste from system clipboard'),
      help_index : 'zz',
      handler : function () {
        var entry_box = $('<input type="text"/>');
        entry_box.css('opacity', 0);
        function paste_close_dlg(e) {
          paste(e);
          // There must be a better way to do this, but it's not any of:
          // .hide(), .remove() or .dialog('close')
          paste_dlg.find('.close').click();
          document.removeEventListener('paste', paste_close_dlg);
        }
        document.addEventListener('paste', paste_close_dlg);
        var cmdtrl = i18n.msg._('Ctrl-V');
        if (utils.platform === 'MacOS') {
            cmdtrl = i18n.msg._('Cmd-V');
        }
        var dialog_body = $("<div/>").append("<p>").append(i18n.msg.sprintf(i18n.msg._("Press %s again to paste"),cmdtrl))
            .append("<br/>")
            .append("<p><b>")
            .append(i18n.msg._("Why is this needed? "))
            .append("</b>")
            .append(i18n.msg._("We can't get paste events in this browser without a text box. "))
            .append(i18n.msg._("There's an invisible text box focused in this dialog."))
            .append($("<form/>").append(entry_box));

        var paste_dlg = dialog.modal({
            notebook: Jupyter.notebook,
            keyboard_manager: Jupyter.keyboard_manager,
            title : i18n.msg.sprintf(i18n.msg._("%s to paste"),cmdtrl),
            body : dialog_body,
            open: function() {
                entry_box.focus();
            },
            buttons : {
                "Cancel" : {
                    // click : function() { reject("Dialog cancelled"); },
                }
            }
        });
      }
  };
  var full_action_name = Jupyter.actions.register(action, 'paste-dialog', 'system-clipboard');
  Jupyter.keyboard_manager.command_shortcuts.add_shortcut('Cmdtrl-V', full_action_name);
}

// Set clipboard event listeners on the document.
return {setup_clipboard_events: function() {
  document.addEventListener('copy', notebookOnlyEvent(copy));
  if (needs_text_box_for_paste_event()) {
    setup_paste_dialog();
  } else {
    document.addEventListener('paste', notebookOnlyEvent(paste));
  }
}};
});