Files
phabricator/webroot/rsrc/js/core/TextAreaUtils.js
epriestley af8cc2a5fc Don't select {F...} text after adding it to textareas
Summary:
Fixes T10039. We add text to textareas in two cases:

  - Users clicking assitance buttons in Remarkup text areas.
  - Drag-and-drop file uploads.

In case (1), it makes sense to highlight the text (it shows the user what we inserted, and lets them undo the action easily if it isn't what they wanted).

In case (2), it does not. Users almost never want to delete or edit a file reference. It is slightly nice to have the reference as a visual callout, but I don't think this is a big deal.

Change the behavior so that we highlight only for remarkup buttons, not for drag-and-drop files.

Test Plan:
  - Clicked an "isnert quote" button on remarkup assist area, got highlighted example text.
  - Dragged and dropped a file, got text inserted with no highlight.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T10039

Differential Revision: https://secure.phabricator.com/D14851
2015-12-22 08:21:06 -08:00

115 lines
3.0 KiB
JavaScript

/**
* @requires javelin-install
* javelin-dom
* javelin-vector
* @provides phabricator-textareautils
* @javelin
*/
JX.install('TextAreaUtils', {
statics : {
getSelectionRange : function(area) {
var v = area.value;
// NOTE: This works well in Safari, Firefox and Chrome. We'll probably get
// less-good behavior on IE.
var s = v.length;
var e = v.length;
if ('selectionStart' in area) {
s = area.selectionStart;
e = area.selectionEnd;
}
return {start: s, end: e};
},
getSelectionText : function(area) {
var v = area.value;
var r = JX.TextAreaUtils.getSelectionRange(area);
return v.substring(r.start, r.end);
},
setSelectionRange : function(area, start, end) {
if ('setSelectionRange' in area) {
area.focus();
area.setSelectionRange(start, end);
}
},
setSelectionText : function(area, text, select) {
var v = area.value;
var r = JX.TextAreaUtils.getSelectionRange(area);
v = v.substring(0, r.start) + text + v.substring(r.end, v.length);
area.value = v;
var start = r.start;
var end = r.start + text.length;
if (!select) {
start = end;
}
JX.TextAreaUtils.setSelectionRange(area, start, end);
},
/**
* Get the document pixel positions of the beginning and end of a character
* range in a textarea.
*/
getPixelDimensions: function(area, start, end) {
var v = area.value;
// We're using zero-width spaces to make sure the spans get some
// height even if there's no text in the metrics tag.
var head = v.substring(0, start);
var before = JX.$N('span', {}, '\u200b');
var body = v.substring(start, end);
var after = JX.$N('span', {}, '\u200b');
// Create a similar shadow element which we can measure.
var metrics = JX.$N(
'var',
{
className: area.className,
},
[head, before, body, after]);
// If the textarea has a scrollbar, force a scrollbar on the shadow
// element too.
if (area.scrollHeight > area.clientHeight) {
metrics.style.overflowY = 'scroll';
}
area.parentNode.appendChild(metrics);
// Adjust the positions we read out of the document to account for the
// current scroll position of the textarea.
var metrics_pos = JX.Vector.getPos(metrics);
metrics_pos.x += area.scrollLeft;
metrics_pos.y += area.scrollTop;
var area_pos = JX.Vector.getPos(area);
var before_pos = JX.Vector.getPos(before);
var after_pos = JX.Vector.getPos(after);
JX.DOM.remove(metrics);
return {
start: {
x: area_pos.x + (before_pos.x - metrics_pos.x),
y: area_pos.y + (before_pos.y - metrics_pos.y)
},
end: {
x: area_pos.x + (after_pos.x - metrics_pos.x),
y: area_pos.y + (after_pos.y - metrics_pos.y)
}
};
}
}
});