[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/webroot/rsrc/js/core/ -> behavior-phabricator-remarkup-assist.js (source)

   1  /**
   2   * @provides javelin-behavior-phabricator-remarkup-assist
   3   * @requires javelin-behavior
   4   *           javelin-stratcom
   5   *           javelin-dom
   6   *           phabricator-phtize
   7   *           phabricator-textareautils
   8   *           javelin-workflow
   9   *           javelin-vector
  10   */
  11  
  12  JX.behavior('phabricator-remarkup-assist', function(config) {
  13    var pht = JX.phtize(config.pht);
  14  
  15    var edit_mode = 'normal';
  16    var edit_root = null;
  17  
  18    function set_edit_mode(root, mode) {
  19      if (mode == edit_mode) {
  20        return;
  21      }
  22  
  23      // First, disable any active mode.
  24      if (edit_root) {
  25        if (edit_mode == 'fa-arrows-alt') {
  26          JX.DOM.alterClass(edit_root, 'remarkup-control-fullscreen-mode', false);
  27          JX.DOM.alterClass(document.body, 'remarkup-fullscreen-mode', false);
  28        }
  29        JX.DOM.find(edit_root, 'textarea').style.height = '';
  30      }
  31  
  32      edit_root = root;
  33      edit_mode = mode;
  34  
  35      // Now, apply the new mode.
  36      if (mode == 'fa-arrows-alt') {
  37        JX.DOM.alterClass(edit_root, 'remarkup-control-fullscreen-mode', true);
  38        JX.DOM.alterClass(document.body, 'remarkup-fullscreen-mode', true);
  39        resizearea();
  40      }
  41  
  42      JX.DOM.focus(JX.DOM.find(edit_root, 'textarea'));
  43    }
  44  
  45    function resizearea() {
  46      if (!edit_root) {
  47        return;
  48      }
  49      if (edit_mode != 'fa-arrows-alt') {
  50        return;
  51      }
  52  
  53      // In Firefox, a textarea with position "absolute" or "fixed", anchored
  54      // "top" and "bottom", and height "auto" renders as two lines high. Force
  55      // it to the correct height with Javascript.
  56  
  57      var area = JX.DOM.find(edit_root, 'textarea');
  58  
  59      var v = JX.Vector.getViewport();
  60      v.x = null;
  61      v.y -= 26;
  62  
  63      v.setDim(area);
  64    }
  65  
  66    JX.Stratcom.listen('resize', null, resizearea);
  67  
  68  
  69    JX.Stratcom.listen('keydown', null, function(e) {
  70      if (e.getSpecialKey() != 'esc') {
  71        return;
  72      }
  73  
  74      if (edit_mode != 'fa-arrows-alt') {
  75        return;
  76      }
  77  
  78      e.kill();
  79      set_edit_mode(edit_root, 'normal');
  80    });
  81  
  82    function update(area, l, m, r) {
  83      // Replace the selection with the entire assisted text.
  84      JX.TextAreaUtils.setSelectionText(area, l + m + r);
  85  
  86      // Now, select just the middle part. For instance, if the user clicked
  87      // "B" to create bold text, we insert '**bold**' but just select the word
  88      // "bold" so if they type stuff they'll be editing the bold text.
  89      var range = JX.TextAreaUtils.getSelectionRange(area);
  90      JX.TextAreaUtils.setSelectionRange(
  91        area,
  92        range.start + l.length,
  93        range.start + l.length + m.length);
  94    }
  95  
  96    function assist(area, action, root) {
  97      // If the user has some text selected, we'll try to use that (for example,
  98      // if they have a word selected and want to bold it). Otherwise we'll insert
  99      // generic text.
 100      var sel = JX.TextAreaUtils.getSelectionText(area);
 101      var r = JX.TextAreaUtils.getSelectionRange(area);
 102  
 103      switch (action) {
 104        case 'fa-bold':
 105          update(area, '**', sel || pht('bold text'), '**');
 106          break;
 107        case 'fa-italic':
 108          update(area, '//', sel || pht('italic text'), '//');
 109          break;
 110        case 'fa-link':
 111          var name = pht('name');
 112          if (/^https?:/i.test(sel)) {
 113            update(area, '[[ ' + sel + ' | ', name, ' ]]');
 114          } else {
 115            update(area, '[[ ', pht('URL'), ' | ' + (sel || name) + ' ]]');
 116          }
 117          break;
 118        case 'fa-text-width':
 119          update(area, '`', sel || pht('monospaced text'), '`');
 120          break;
 121        case 'fa-list-ul':
 122        case 'fa-list-ol':
 123          var ch = (action == 'fa-list-ol') ? '  # ' : '  - ';
 124          if (sel) {
 125            sel = sel.split('\n');
 126          } else {
 127            sel = [pht('List Item')];
 128          }
 129          sel = sel.join('\n' + ch);
 130          update(area, ((r.start === 0) ? '' : '\n\n') + ch, sel, '\n\n');
 131          break;
 132        case 'fa-code':
 133          sel = sel || 'foreach ($list as $item) {\n  work_miracles($item);\n}';
 134          var code_prefix = (r.start === 0) ? '' : '\n';
 135          update(area, code_prefix + '```\n', sel, '\n```');
 136          break;
 137        case 'fa-table':
 138          var table_prefix = (r.start === 0 ? '' : '\n\n');
 139          update(area, table_prefix + '| ', sel || pht('data'), ' |');
 140          break;
 141        case 'fa-meh-o':
 142          new JX.Workflow('/macro/meme/create/')
 143            .setHandler(function(response) {
 144              update(
 145                area,
 146                '',
 147                sel,
 148                (r.start === 0 ? '' : '\n\n') + response.text + '\n\n');
 149            })
 150            .start();
 151          break;
 152        case 'fa-cloud-upload':
 153          new JX.Workflow('/file/uploaddialog/').start();
 154          break;
 155        case 'fa-arrows-alt':
 156          if (edit_mode == 'fa-arrows-alt') {
 157            set_edit_mode(root, 'normal');
 158          } else {
 159            set_edit_mode(root, 'fa-arrows-alt');
 160          }
 161          break;
 162      }
 163    }
 164  
 165    JX.Stratcom.listen(
 166      ['click'],
 167      'remarkup-assist',
 168      function(e) {
 169        var data = e.getNodeData('remarkup-assist');
 170        if (!data.action) {
 171          return;
 172        }
 173  
 174        e.kill();
 175  
 176        var root = e.getNode('remarkup-assist-control');
 177        var area = JX.DOM.find(root, 'textarea');
 178  
 179        assist(area, data.action, root);
 180      });
 181  
 182  });


Generated: Sun Nov 30 09:20:46 2014 Cross-referenced by PHPXref 0.7.1