[ Index ] |
PHP Cross Reference of Phabricator |
[Summary view] [Print] [Text view]
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 });
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Sun Nov 30 09:20:46 2014 | Cross-referenced by PHPXref 0.7.1 |