Remove old, unused implementations of favorite, recent, and search-to-add preset toolbar items

This commit is contained in:
Quincy Morgan
2019-12-18 11:25:31 -05:00
parent 3f728c5f3e
commit e8d154a529
6 changed files with 1 additions and 1519 deletions
-217
View File
@@ -607,223 +607,6 @@ button.add-note svg.icon {
margin-left: 1px;
}
/* Add a feature search bar
------------------------------------------------------- */
.search-add {
width: 200%;
justify-content: center;
position: relative;
min-width: 150px;
max-width: 325px;
}
.search-add .search-wrap {
position: relative;
width: 100%;
}
[dir='ltr'] .search-add .search-wrap {
border-radius: 20px 4px 4px 20px;
}
[dir='rtl'] .search-add .search-wrap {
border-radius: 4px 20px 20px 4px;
}
.search-add .search-wrap.focused .tooltip {
display: none;
}
.search-add .search-wrap:last-child {
border-radius: 20px;
}
.search-add input[type='search'] {
position: relative;
width: 100%;
height: 100%;
border: none;
font-size: 14px;
text-indent: 25px;
padding: 5px 10px;
border-radius: inherit;
}
.search-add input[type='search'][disabled] {
opacity: 0.25;
cursor: not-allowed;
}
.search-add .search-icon {
color: #333;
display: block;
position: absolute;
left: 10px;
top: 10px;
pointer-events: none;
}
[dir='rtl'] .search-add .search-icon {
left: auto;
right: 10px;
}
.search-add .popover {
border: none;
border-radius: 6px;
position: absolute;
max-height: 600px;
top: 44px;
width: 200%;
max-width: 325px;
margin: auto;
left: auto;
right: auto;
z-index: 300;
}
.search-add .popover .popover-content {
overflow-y: auto;
height: 100%;
max-height: 60vh;
}
.search-add .popover,
.search-add .popover .popover-content {
/* ensure corners are rounded in Chrome */
-webkit-mask-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC);
}
.search-add .popover .popover-footer {
padding: 5px 10px 5px 10px;
background: #f6f6f6;
border-top: 1px solid #DCDCDC;
display: flex;
}
.search-add .popover .popover-footer .message {
color: #666666;
flex-grow: 1;
}
.search-add .popover .popover-footer button.filter {
height: 20px;
background: transparent;
color: #666;
}
.search-add .popover .popover-footer button.filter.active {
color: #7092ff;
}
.search-add .popover .popover-footer button.filter:hover {
color: #333;
}
.search-add .popover .popover-footer button.filter.active:hover {
color: #597be7;
}
.search-add .popover::-webkit-scrollbar {
/* don't overlap rounded corners */
background: transparent;
}
.search-add .popover .list {
height: 100%;
}
.search-add .list-item > .row {
display: flex;
position: relative;
padding: 2px;
}
.search-add .list-item:not(:last-of-type) .row,
.search-add .subsection.subitems .list-item .row,
.search-add .subsection > .tag-reference-body {
border-bottom: 1px solid #DCDCDC;
}
.search-add .list-item .label {
font-weight: bold;
font-size: 12px;
padding-left: 2px;
top: 0;
bottom: 0;
position: relative;
display: flex;
align-items: center;
line-height: 1.3em;
width: 100%;
}
.search-add .list-item .label .namepart:nth-child(2) {
font-weight: normal;
}
.search-add .list-item.disabled .preset-icon-container,
.search-add .list-item.disabled .label {
opacity: 0.55;
}
[dir='ltr'] .search-add .list-item .label .icon.inline {
margin-left: 0;
}
[dir='rtl'] .search-add .list-item .label .icon.inline {
margin-right: 0;
}
.search-add .list-item .row > *:not(button) {
pointer-events: none;
}
.search-add .list-item button.choose {
position: absolute;
border-radius: 0;
height: 100%;
width: 100%;
top: 0;
left: 0;
}
.search-add .list-item button.choose:hover,
.search-add .list-item button.choose:focus {
background: #fff;
}
.search-add .list-item.focused:not(.disabled) button.choose {
background: #e8ebff;
}
.search-add .list-item button.choose.disabled {
background-color: #ececec;
}
.search-add .subsection .list-item button.choose {
opacity: 0.85;
}
.search-add .subsection .tag-reference-body {
background: rgba(255, 255, 255, 0.85);
padding: 10px;
}
.search-add .list-item button.accessory {
position: relative;
flex: 0 0 auto;
color: #808080;
background: transparent;
padding-right: 3px;
padding-left: 3px;
}
.search-add .list-item button.accessory:hover {
color: #666;
}
.search-add .list-item button.tag-reference-open path {
fill: #000;
}
.search-add .subsection {
background-color: #CBCBCB;
}
[dir='ltr'] .search-add .subitems {
padding-left: 6px;
}
[dir='rtl'] .search-add .subitems {
padding-right: 6px;
}
/* Add a preset mode buttons
------------------------------------------------------- */
button.bar-button.add-preset {
border-radius: 4px;
}
[dir='ltr'] button.bar-button.add-preset {
margin-left: 1px;
}
[dir='rtl'] button.bar-button.add-preset {
margin-right: 1px;
}
[dir='ltr'] button.bar-button.add-preset.first-recent {
margin-left: 10px;
}
[dir='rtl'] button.bar-button.add-preset.first-recent {
margin-right: 10px;
}
button.bar-button.add-preset {
padding: 0;
}
button.add-preset.disabled .preset-icon-container {
opacity: 0.5;
}
/* Header for modals / panes
------------------------------------------------------- */
.header {
-295
View File
@@ -1,295 +0,0 @@
import _debounce from 'lodash-es/debounce';
import { drag as d3_drag } from 'd3-drag';
import { event as d3_event, select as d3_select } from 'd3-selection';
import { modeAddArea, modeAddLine, modeAddPoint, modeBrowse } from '../../modes';
import { t, textDirection } from '../../util/locale';
import { tooltip } from '../../util/tooltip';
import { uiPresetIcon } from '../preset_icon';
import { uiTooltipHtml } from '../tooltipHtml';
export function uiToolAddFavorite(context) {
var tool = {
id: 'add_favorite',
klass: 'modes',
label: t('toolbar.favorites')
};
function enabled() {
return osmEditable();
}
function osmEditable() {
return context.editable();
}
function toggleMode(d) {
if (!enabled(d)) return;
if (d.button === context.mode().button) {
context.enter(modeBrowse(context));
} else {
if (d.preset) {
context.presets().setMostRecent(d.preset, d.geometry);
}
context.enter(d);
}
}
tool.render = function(selection) {
context
.on('enter.editor.favorite', function(entered) {
selection.selectAll('button.add-button')
.classed('active', function(mode) { return entered.button === mode.button; });
context.container()
.classed('mode-' + entered.id, true);
});
context
.on('exit.editor.favorite', function(exited) {
context.container()
.classed('mode-' + exited.id, false);
});
var debouncedUpdate = _debounce(update, 500, { leading: true, trailing: true });
context.map()
.on('move.favorite', debouncedUpdate)
.on('drawn.favorite', debouncedUpdate);
context
.on('enter.favorite', update)
.presets()
.on('favoritePreset.favorite', update)
.on('recentsChange.favorite', update);
update();
function update() {
for (var i = 0; i <= 9; i++) {
context.keybinding().off(i.toString());
}
var items = context.presets().getFavorites();
var modes = items.map(function(d, index) {
var presetName = d.preset.name().split(' ')[0];
var markerClass = 'add-preset add-' + d.geometry + ' add-preset-' + presetName.replace(/\s+/g, '_')
+ '-' + d.geometry + ' add-' + d.source; // replace spaces with underscores to avoid css interpretation
if (d.preset.isFallback()) {
markerClass += ' add-generic-preset';
}
var supportedGeometry = d.preset.geometry.filter(function(geometry) {
return ['vertex', 'point', 'line', 'area'].indexOf(geometry) !== -1;
});
var vertexIndex = supportedGeometry.indexOf('vertex');
if (vertexIndex !== -1 && supportedGeometry.indexOf('point') !== -1) {
// both point and vertex allowed, just combine them
supportedGeometry.splice(vertexIndex, 1);
}
var tooltipTitleID = 'modes.add_preset.title';
if (supportedGeometry.length !== 1) {
if (d.preset.setTags({}, d.geometry).building) {
tooltipTitleID = 'modes.add_preset.building.title';
} else {
tooltipTitleID = 'modes.add_preset.' + context.presets().fallback(d.geometry).id + '.title';
}
}
var protoMode = Object.assign({}, d); // shallow copy
protoMode.button = markerClass;
protoMode.title = presetName;
protoMode.description = t(tooltipTitleID, { feature: '<strong>' + presetName + '</strong>' });
var keyCode;
// use number row order: 1 2 3 4 5 6 7 8 9 0
// use the same for RTL even though the layout is backward: #6107
if (index === 9) {
keyCode = 0;
} else if (index < 10) {
keyCode = index + 1;
}
if (keyCode !== undefined) {
protoMode.key = keyCode.toString();
}
var mode;
switch (d.geometry) {
case 'point':
case 'vertex':
mode = modeAddPoint(context, protoMode);
break;
case 'line':
mode = modeAddLine(context, protoMode);
break;
case 'area':
mode = modeAddArea(context, protoMode);
}
if (mode.key) {
context.keybinding().off(mode.key);
context.keybinding().on(mode.key, function() {
toggleMode(mode);
});
}
return mode;
});
var buttons = selection.selectAll('button.add-button')
.data(modes, function(d, index) { return d.button + index; });
// exit
buttons.exit()
.remove();
// enter
var buttonsEnter = buttons.enter()
.append('button')
.attr('tabindex', -1)
.attr('class', function(d) {
return d.button + ' add-button bar-button';
})
.on('click.mode-buttons', function(d) {
// When drawing, ignore accidental clicks on mode buttons - #4042
if (/^draw/.test(context.mode().id)) return;
toggleMode(d);
})
.call(tooltip()
.placement('bottom')
.html(true)
.title(function(d) { return uiTooltipHtml(d.description, d.key); })
.scrollContainer(d3_select('#bar'))
);
buttonsEnter
.each(function(d) {
d3_select(this)
.call(uiPresetIcon(context)
.geometry((d.geometry === 'point' && !d.preset.matchGeometry(d.geometry)) ? 'vertex' : d.geometry)
.preset(d.preset)
.sizeClass('small')
);
});
var dragOrigin, dragMoved, targetIndex;
buttonsEnter.call(d3_drag()
.on('start', function() {
dragOrigin = {
x: d3_event.x,
y: d3_event.y
};
targetIndex = null;
dragMoved = false;
})
.on('drag', function(d, index) {
dragMoved = true;
var x = d3_event.x - dragOrigin.x,
y = d3_event.y - dragOrigin.y;
if (!d3_select(this).classed('dragging') &&
// don't display drag until dragging beyond a distance threshold
Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)) <= 5) return;
d3_select(this)
.classed('dragging', true)
.classed('removing', y > 50);
targetIndex = null;
selection.selectAll('button.add-preset')
.style('transform', function(d2, index2) {
var node = d3_select(this).node();
if (index === index2) {
return 'translate(' + x + 'px, ' + y + 'px)';
} else if (y > 50) {
if (index2 > index) {
return 'translateX(' + (textDirection === 'rtl' ? '' : '-') + '100%)';
}
} else if (d.source === d2.source) {
if (index2 > index && (
(d3_event.x > node.offsetLeft && textDirection === 'ltr') ||
(d3_event.x < node.offsetLeft + node.offsetWidth && textDirection === 'rtl')
)) {
if (targetIndex === null || index2 > targetIndex) {
targetIndex = index2;
}
return 'translateX(' + (textDirection === 'rtl' ? '' : '-') + '100%)';
} else if (index2 < index && (
(d3_event.x < node.offsetLeft + node.offsetWidth && textDirection === 'ltr') ||
(d3_event.x > node.offsetLeft && textDirection === 'rtl')
)) {
if (targetIndex === null || index2 < targetIndex) {
targetIndex = index2;
}
return 'translateX(' + (textDirection === 'rtl' ? '-' : '') + '100%)';
}
}
return null;
});
})
.on('end', function(d, index) {
if (dragMoved && !d3_select(this).classed('dragging')) {
toggleMode(d);
return;
}
d3_select(this)
.classed('dragging', false)
.classed('removing', false);
selection.selectAll('button.add-preset')
.style('transform', null);
var y = d3_event.y - dragOrigin.y;
if (y > 50) {
// dragged out of the top bar, remove
if (d.isFavorite()) {
context.presets().removeFavorite(d.preset, d.geometry);
// also remove this as a recent so it doesn't still appear
context.presets().removeRecent(d.preset, d.geometry);
}
} else if (targetIndex !== null) {
// dragged to a new position, reorder
if (d.isFavorite()) {
context.presets().moveFavorite(index, targetIndex);
}
}
})
);
// update
buttons = buttons
.merge(buttonsEnter)
.classed('disabled', function(d) { return !enabled(d); });
}
};
tool.uninstall = function() {
context
.on('enter.editor.favorite', null)
.on('exit.editor.favorite', null)
.on('enter.favorite', null);
context.presets()
.on('favoritePreset.favorite', null)
.on('recentsChange.favorite', null);
context.map()
.on('move.favorite', null)
.on('drawn.favorite', null);
};
return tool;
}
-336
View File
@@ -1,336 +0,0 @@
import _debounce from 'lodash-es/debounce';
import { drag as d3_drag } from 'd3-drag';
import { event as d3_event, select as d3_select } from 'd3-selection';
import { modeAddArea, modeAddLine, modeAddPoint, modeBrowse } from '../../modes';
import { t, textDirection } from '../../util/locale';
import { tooltip } from '../../util/tooltip';
import { uiPresetIcon } from '../preset_icon';
import { uiTooltipHtml } from '../tooltipHtml';
export function uiToolAddRecent(context) {
var tool = {
id: 'add_recent',
klass: 'modes',
label: t('toolbar.recent')
};
function enabled() {
return osmEditable();
}
function osmEditable() {
return context.editable();
}
function toggleMode(d) {
if (!enabled(d)) return;
if (d.button === context.mode().button) {
context.enter(modeBrowse(context));
} else {
if (d.preset &&
// don't set a recent as most recent to avoid reordering buttons
!d.isRecent()) {
context.presets().setMostRecent(d.preset, d.geometry);
}
context.enter(d);
}
}
function recentsToDraw() {
var maxShown = 10;
var maxRecents = 5;
var favorites = context.presets().getFavorites().slice(0, maxShown);
function isAFavorite(recent) {
return favorites.some(function(favorite) {
return favorite.matches(recent.preset, recent.geometry);
});
}
var favoritesCount = favorites.length;
maxRecents = Math.min(maxRecents, maxShown - favoritesCount);
var items = [];
if (maxRecents > 0) {
var recents = context.presets().getRecents().filter(function(recent) {
return recent.geometry !== 'relation';
});
for (var i in recents) {
var recent = recents[i];
if (!isAFavorite(recent)) {
items.push(recent);
if (items.length === maxRecents) {
break;
}
}
}
}
return items;
}
tool.shouldShow = function() {
return recentsToDraw().length > 0;
};
tool.render = function(selection) {
context
.on('enter.editor.recent', function(entered) {
selection.selectAll('button.add-button')
.classed('active', function(mode) { return entered.button === mode.button; });
context.container()
.classed('mode-' + entered.id, true);
});
context
.on('exit.editor.recent', function(exited) {
context.container()
.classed('mode-' + exited.id, false);
});
var debouncedUpdate = _debounce(update, 500, { leading: true, trailing: true });
context.map()
.on('move.recent', debouncedUpdate)
.on('drawn.recent', debouncedUpdate);
context
.on('enter.recent', update)
.presets()
.on('favoritePreset.recent', update)
.on('recentsChange.recent', update);
update();
function update() {
var items = recentsToDraw();
var favoritesCount = context.presets().getFavorites().length;
var modes = items.map(function(d, index) {
var presetName = d.preset.name().split(' ')[0];
var markerClass = 'add-preset add-' + d.geometry + ' add-preset-' + presetName.replace(/\s+/g, '_')
+ '-' + d.geometry + ' add-' + d.source; // replace spaces with underscores to avoid css interpretation
if (d.preset.isFallback()) {
markerClass += ' add-generic-preset';
}
var supportedGeometry = d.preset.geometry.filter(function(geometry) {
return ['vertex', 'point', 'line', 'area'].indexOf(geometry) !== -1;
});
var vertexIndex = supportedGeometry.indexOf('vertex');
if (vertexIndex !== -1 && supportedGeometry.indexOf('point') !== -1) {
// both point and vertex allowed, just combine them
supportedGeometry.splice(vertexIndex, 1);
}
var tooltipTitleID = 'modes.add_preset.title';
if (supportedGeometry.length !== 1) {
if (d.preset.setTags({}, d.geometry).building) {
tooltipTitleID = 'modes.add_preset.building.title';
} else {
tooltipTitleID = 'modes.add_preset.' + context.presets().fallback(d.geometry).id + '.title';
}
}
var protoMode = Object.assign({}, d); // shallow copy
protoMode.button = markerClass;
protoMode.title = presetName;
protoMode.description = t(tooltipTitleID, { feature: '<strong>' + presetName + '</strong>' });
var totalIndex = favoritesCount + index;
var keyCode;
// use number row order: 1 2 3 4 5 6 7 8 9 0
// use the same for RTL even though the layout is backward: #6107
if (totalIndex === 9) {
keyCode = 0;
} else if (totalIndex < 10) {
keyCode = totalIndex + 1;
}
if (keyCode !== undefined) {
protoMode.key = keyCode.toString();
}
var mode;
switch (d.geometry) {
case 'point':
case 'vertex':
mode = modeAddPoint(context, protoMode);
break;
case 'line':
mode = modeAddLine(context, protoMode);
break;
case 'area':
mode = modeAddArea(context, protoMode);
}
if (mode.key) {
context.keybinding().off(mode.key);
context.keybinding().on(mode.key, function() {
toggleMode(mode);
});
}
return mode;
});
var buttons = selection.selectAll('button.add-button')
.data(modes, function(d, index) { return d.button + index; });
// exit
buttons.exit()
.remove();
// enter
var buttonsEnter = buttons.enter()
.append('button')
.attr('tabindex', -1)
.attr('class', function(d) {
return d.button + ' add-button bar-button';
})
.on('click.mode-buttons', function(d) {
// When drawing, ignore accidental clicks on mode buttons - #4042
if (/^draw/.test(context.mode().id)) return;
toggleMode(d);
})
.call(tooltip()
.placement('bottom')
.html(true)
.title(function(d) { return uiTooltipHtml(d.description, d.key); })
.scrollContainer(d3_select('#bar'))
);
buttonsEnter
.each(function(d) {
d3_select(this)
.call(uiPresetIcon(context)
.geometry((d.geometry === 'point' && !d.preset.matchGeometry(d.geometry)) ? 'vertex' : d.geometry)
.preset(d.preset)
.sizeClass('small')
);
});
var dragOrigin, dragMoved, targetIndex, targetData;
buttonsEnter.call(d3_drag()
.on('start', function() {
dragOrigin = {
x: d3_event.x,
y: d3_event.y
};
targetIndex = null;
targetData = null;
dragMoved = false;
})
.on('drag', function(d, index) {
dragMoved = true;
var x = d3_event.x - dragOrigin.x,
y = d3_event.y - dragOrigin.y;
if (!d3_select(this).classed('dragging') &&
// don't display drag until dragging beyond a distance threshold
Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)) <= 5) return;
d3_select(this)
.classed('dragging', true)
.classed('removing', y > 50);
targetIndex = null;
targetData = null;
selection.selectAll('button.add-preset')
.style('transform', function(d2, index2) {
var node = d3_select(this).node();
if (index === index2) {
return 'translate(' + x + 'px, ' + y + 'px)';
} else if (y > 50) {
if (index2 > index) {
return 'translateX(' + (textDirection === 'rtl' ? '' : '-') + '100%)';
}
} else if (d.source === d2.source) {
if (index2 > index && (
(d3_event.x > node.offsetLeft && textDirection === 'ltr') ||
(d3_event.x < node.offsetLeft + node.offsetWidth && textDirection === 'rtl')
)) {
if (targetIndex === null || index2 > targetIndex) {
targetIndex = index2;
targetData = d2;
}
return 'translateX(' + (textDirection === 'rtl' ? '' : '-') + '100%)';
} else if (index2 < index && (
(d3_event.x < node.offsetLeft + node.offsetWidth && textDirection === 'ltr') ||
(d3_event.x > node.offsetLeft && textDirection === 'rtl')
)) {
if (targetIndex === null || index2 < targetIndex) {
targetIndex = index2;
targetData = d2;
}
return 'translateX(' + (textDirection === 'rtl' ? '-' : '') + '100%)';
}
}
return null;
});
})
.on('end', function(d) {
if (dragMoved && !d3_select(this).classed('dragging')) {
toggleMode(d);
return;
}
d3_select(this)
.classed('dragging', false)
.classed('removing', false);
selection.selectAll('button.add-preset')
.style('transform', null);
var y = d3_event.y - dragOrigin.y;
if (y > 50) {
// dragged out of the top bar, remove
if (d.isRecent()) {
context.presets().removeRecent(d.preset, d.geometry);
}
} else if (targetIndex !== null) {
// dragged to a new position, reorder
if (d.isRecent()) {
var item = context.presets().recentMatching(d.preset, d.geometry);
var beforeItem = context.presets().recentMatching(targetData.preset, targetData.geometry);
context.presets().moveRecent(item, beforeItem);
}
}
})
);
// update
buttons = buttons
.merge(buttonsEnter)
.classed('disabled', function(d) { return !enabled(d); });
}
};
tool.uninstall = function() {
context
.on('enter.editor.recent', null)
.on('exit.editor.recent', null)
.on('enter.recent', null);
context.presets()
.on('favoritePreset.recent', null)
.on('recentsChange.recent', null);
context.map()
.on('move.recent', null)
.on('drawn.recent', null);
};
return tool;
}
-3
View File
@@ -1,8 +1,5 @@
export * from './add_favorite';
export * from './add_recent';
export * from './modes';
export * from './notes';
export * from './save';
export * from './search_add';
export * from './sidebar_toggle';
export * from './undo_redo';
-655
View File
@@ -1,655 +0,0 @@
import _debounce from 'lodash-es/debounce';
import { dispatch as d3_dispatch } from 'd3-dispatch';
import {
event as d3_event,
select as d3_select,
selectAll as d3_selectAll
} from 'd3-selection';
import { modeAddArea, modeAddLine, modeAddPoint } from '../../modes';
import { t, textDirection } from '../../util/locale';
import { svgIcon } from '../../svg/index';
import { tooltip } from '../../util/tooltip';
import { uiTagReference } from '../tag_reference';
import { uiTooltipHtml } from '../tooltipHtml';
import { uiPresetFavoriteButton } from '../preset_favorite_button';
import { uiPresetIcon } from '../preset_icon';
import { utilKeybinding, utilNoAuto, utilRebind } from '../../util';
export function uiToolSearchAdd(context) {
var tool = {
id: 'search_add',
label: t('inspector.search')
};
var dispatch = d3_dispatch('choose');
var presets;
var searchWrap = d3_select(null),
search = d3_select(null),
popover = d3_select(null),
popoverContent = d3_select(null),
list = d3_select(null),
footer = d3_select(null),
message = d3_select(null);
var allowedGeometry = ['area', 'line', 'point', 'vertex'];
var shownGeometry = [];
var key = t('modes.add_feature.key');
function updateShownGeometry(geom) {
shownGeometry = geom.sort();
presets = context.presets().matchAnyGeometry(shownGeometry);
}
function toggleShownGeometry(d) {
var geom = shownGeometry;
var index = geom.indexOf(d);
if (index === -1) {
geom.push(d);
if (d === 'point') geom.push('vertex');
} else {
geom.splice(index, 1);
if (d === 'point') geom.splice(geom.indexOf('vertex'), 1);
}
updateShownGeometry(geom);
}
function updateFilterButtonsStates() {
footer.selectAll('button.filter')
.classed('active', function(d) {
return shownGeometry.indexOf(d) !== -1;
});
}
tool.render = function(selection) {
updateShownGeometry(allowedGeometry.slice()); // shallow copy
searchWrap = selection
.append('div')
.attr('class', 'search-wrap')
.call(tooltip()
.placement('bottom')
.html(true)
.title(function() { return uiTooltipHtml(t('modes.add_feature.description'), key); })
.scrollContainer(d3_select('#bar'))
);
search = searchWrap
.append('input')
.attr('class', 'search-input')
.attr('placeholder', t('modes.add_feature.title'))
.attr('type', 'search')
.call(utilNoAuto)
.on('mousedown', function() {
search.attr('clicking', true);
})
.on('mouseup', function() {
search.attr('clicking', null);
})
.on('focus', function() {
searchWrap.classed('focused', true);
if (search.attr('clicking')) {
search.attr('focusing', true);
search.attr('clicking', null);
} else {
search.node().setSelectionRange(0, search.property('value').length);
}
popover.classed('hide', false);
})
.on('blur', function() {
searchWrap.classed('focused', false);
popover.classed('hide', true);
})
.on('click', function() {
if (search.attr('focusing')) {
search.node().setSelectionRange(0, search.property('value').length);
search.attr('focusing', null);
}
})
.on('keypress', keypress)
.on('keydown', keydown)
.on('input', updateResultsList);
searchWrap
.call(svgIcon('#iD-icon-search', 'search-icon pre-text'));
popover = searchWrap
.append('div')
.attr('class', 'popover fillL hide')
.on('mousedown', function() {
// don't blur the search input (and thus close results)
d3_event.preventDefault();
d3_event.stopPropagation();
});
popoverContent = popover
.append('div')
.attr('class', 'popover-content');
list = popoverContent.append('div')
.attr('class', 'list');
footer = popover
.append('div')
.attr('class', 'popover-footer');
message = footer.append('div')
.attr('class', 'message');
footer.append('div')
.attr('class', 'filter-wrap')
.selectAll('button.filter')
.data(['point', 'line', 'area'])
.enter()
.append('button')
.attr('class', 'filter active')
.attr('title', function(d) {
return t('modes.add_' + d + '.filter_tooltip');
})
.each(function(d) {
d3_select(this).call(svgIcon('#iD-icon-' + d));
})
.on('click', function(d) {
toggleShownGeometry(d);
if (shownGeometry.length === 0) {
updateShownGeometry(allowedGeometry.slice()); // shallow copy
toggleShownGeometry(d);
}
updateFilterButtonsStates();
updateResultsList();
});
context.features()
.on('change.search-add', updateForFeatureHiddenState);
context.keybinding().on(key, function() {
search.node().focus();
d3_event.preventDefault();
d3_event.stopPropagation();
});
var debouncedUpdate = _debounce(updateEnabledState, 500, { leading: true, trailing: true });
context.map()
.on('move.search-add', debouncedUpdate)
.on('drawn.search-add', debouncedUpdate);
updateEnabledState();
updateResultsList();
};
tool.uninstall = function() {
context.keybinding().off(key);
context.features()
.on('change.search-add', null);
context.map()
.on('move.search-add', null)
.on('drawn.search-add', null);
};
function osmEditable() {
return context.editable();
}
function updateEnabledState() {
var isEnabled = osmEditable();
searchWrap.classed('disabled', !isEnabled);
if (!isEnabled) {
search.node().blur();
}
search.attr('disabled', isEnabled ? null : true);
}
function keypress() {
if (d3_event.keyCode === utilKeybinding.keyCodes.enter) {
popover.selectAll('.list .list-item.focused button.choose')
.each(function(d) { d.choose.call(this); });
d3_event.preventDefault();
d3_event.stopPropagation();
}
}
function keydown() {
var nextFocus,
priorFocus,
parentSubsection;
if (d3_event.keyCode === utilKeybinding.keyCodes['↓'] ||
d3_event.keyCode === utilKeybinding.keyCodes.tab && !d3_event.shiftKey) {
d3_event.preventDefault();
d3_event.stopPropagation();
priorFocus = popover.selectAll('.list .list-item.focused');
if (priorFocus.empty()) {
nextFocus = popover.selectAll('.list > .list-item:first-child');
} else {
nextFocus = d3_select(priorFocus.nodes()[0].nextElementSibling);
if (!nextFocus.empty() && !nextFocus.classed('list-item')) {
nextFocus = nextFocus.selectAll('.list-item:first-child');
}
if (nextFocus.empty()) {
parentSubsection = priorFocus.nodes()[0].closest('.list .subsection');
if (parentSubsection && parentSubsection.nextElementSibling) {
nextFocus = d3_select(parentSubsection.nextElementSibling);
}
}
}
if (!nextFocus.empty()) {
focusListItem(nextFocus, true);
priorFocus.classed('focused', false);
}
} else if (d3_event.keyCode === utilKeybinding.keyCodes['↑'] ||
d3_event.keyCode === utilKeybinding.keyCodes.tab && d3_event.shiftKey) {
d3_event.preventDefault();
d3_event.stopPropagation();
priorFocus = popover.selectAll('.list .list-item.focused');
if (!priorFocus.empty()) {
nextFocus = d3_select(priorFocus.nodes()[0].previousElementSibling);
if (!nextFocus.empty() && !nextFocus.classed('list-item')) {
nextFocus = nextFocus.selectAll('.list-item:last-child');
}
if (nextFocus.empty()) {
parentSubsection = priorFocus.nodes()[0].closest('.list .subsection');
if (parentSubsection && parentSubsection.previousElementSibling) {
nextFocus = d3_select(parentSubsection.previousElementSibling);
}
}
if (!nextFocus.empty()) {
focusListItem(nextFocus, true);
priorFocus.classed('focused', false);
}
}
} else if (d3_event.keyCode === utilKeybinding.keyCodes.esc) {
search.node().blur();
d3_event.preventDefault();
d3_event.stopPropagation();
}
}
function updateResultsList() {
var value = search.property('value');
var results;
if (value.length) {
results = presets.search(value, shownGeometry).collection;
} else {
var recents = context.presets().getRecents();
recents = recents.filter(function(d) {
return shownGeometry.indexOf(d.geometry) !== -1;
});
results = recents.slice(0, 35);
}
list.call(drawList, results);
popover.selectAll('.list .list-item.focused')
.classed('focused', false);
focusListItem(popover.selectAll('.list > .list-item:first-child'), false);
popoverContent.node().scrollTop = 0;
var resultCount = results.length;
message.text(t('modes.add_feature.' + (resultCount === 1 ? 'result' : 'results'), { count: resultCount }));
}
function focusListItem(selection, scrollingToShow) {
if (!selection.empty()) {
selection.classed('focused', true);
if (scrollingToShow) {
// scroll to keep the focused item visible
scrollPopoverToShow(selection);
}
}
}
function scrollPopoverToShow(selection) {
if (selection.empty()) return;
var node = selection.nodes()[0];
var scrollableNode = popoverContent.node();
if (node.offsetTop < scrollableNode.scrollTop) {
scrollableNode.scrollTop = node.offsetTop;
} else if (node.offsetTop + node.offsetHeight > scrollableNode.scrollTop + scrollableNode.offsetHeight &&
node.offsetHeight < scrollableNode.offsetHeight) {
scrollableNode.scrollTop = node.offsetTop + node.offsetHeight - scrollableNode.offsetHeight;
}
}
function itemForPreset(preset) {
if (preset.members) {
return CategoryItem(preset);
}
if (preset.preset && preset.geometry) {
return AddablePresetItem(preset.preset, preset.geometry);
}
var supportedGeometry = preset.geometry.filter(function(geometry) {
return shownGeometry.indexOf(geometry) !== -1;
}).sort();
var vertexIndex = supportedGeometry.indexOf('vertex');
if (vertexIndex !== -1 && supportedGeometry.indexOf('point') !== -1) {
// both point and vertex allowed, just show point
supportedGeometry.splice(vertexIndex, 1);
}
if (supportedGeometry.length === 1) {
return AddablePresetItem(preset, supportedGeometry[0]);
}
return MultiGeometryPresetItem(preset, supportedGeometry);
}
function drawList(list, data) {
list.selectAll('.subsection.subitems').remove();
var dataItems = [];
for (var i = 0; i < data.length; i++) {
var preset = data[i];
if (i < data.length - 1) {
var nextPreset = data[i+1];
// group neighboring presets with the same name
if (preset.name && nextPreset.name && preset.name() === nextPreset.name()) {
var groupedPresets = [preset, nextPreset].sort(function(p1, p2) {
return (p1.geometry[0] < p2.geometry[0]) ? -1 : 1;
});
dataItems.push(MultiPresetItem(groupedPresets));
i++; // skip the next preset since we accounted for it
continue;
}
}
dataItems.push(itemForPreset(preset));
}
var items = list.selectAll('.list-item')
.data(dataItems, function(d) { return d.id(); });
items.order();
items.exit()
.remove();
drawItems(items.enter());
list.selectAll('.list-item.expanded')
.classed('expanded', false)
.selectAll('.label svg.icon use')
.attr('href', textDirection === 'rtl' ? '#iD-icon-backward' : '#iD-icon-forward');
updateForFeatureHiddenState();
}
function drawItems(selection) {
var item = selection
.append('div')
.attr('class', 'list-item')
.attr('id', function(d) {
return 'search-add-list-item-preset-' + d.id().replace(/[^a-zA-Z\d:]/g, '-');
})
.on('mouseover', function() {
list.selectAll('.list-item.focused')
.classed('focused', false);
d3_select(this)
.classed('focused', true);
})
.on('mouseout', function() {
d3_select(this)
.classed('focused', false);
});
var row = item.append('div')
.attr('class', 'row');
row.append('button')
.attr('class', 'choose')
.on('click', function(d) {
d.choose.call(this);
});
row.each(function(d) {
d3_select(this).call(
uiPresetIcon(context)
.geometry(d.geometry)
.preset(d.preset || d.presets[0])
.sizeClass('small')
);
});
var label = row.append('div')
.attr('class', 'label');
label.each(function(d) {
if (d.subitems) {
d3_select(this)
.call(svgIcon((textDirection === 'rtl' ? '#iD-icon-backward' : '#iD-icon-forward'), 'inline'));
}
});
label.each(function(d) {
// NOTE: split/join on en-dash, not a hypen (to avoid conflict with fr - nl names in Brussels etc)
d3_select(this)
.append('div')
.attr('class', 'label-inner')
.selectAll('.namepart')
.data(d.name().split(' '))
.enter()
.append('div')
.attr('class', 'namepart')
.text(function(d) { return d; });
});
row.each(function(d) {
if (d.geometry) {
var presetFavorite = uiPresetFavoriteButton(d.preset, d.geometry, context, 'accessory');
d3_select(this).call(presetFavorite.button);
}
});
item.each(function(d) {
if ((d.geometry && (!d.isSubitem || d.isInNameGroup)) || d.geometries) {
var reference = uiTagReference(d.preset.reference(d.geometry || d.geometries[0]), context);
var thisItem = d3_select(this);
thisItem.selectAll('.row').call(reference.button, 'accessory', 'info');
var subsection = thisItem
.append('div')
.attr('class', 'subsection reference');
subsection.call(reference.body);
}
});
}
function updateForFeatureHiddenState() {
var listItem = d3_selectAll('.search-add .popover .list-item');
// remove existing tooltips
listItem.selectAll('button.choose').call(tooltip().destroyAny);
listItem.each(function(item, index) {
if (!item.geometry) return;
var hiddenPresetFeaturesId = context.features().isHiddenPreset(item.preset, item.geometry);
var isHiddenPreset = !!hiddenPresetFeaturesId;
var button = d3_select(this).selectAll('button.choose');
d3_select(this).classed('disabled', isHiddenPreset);
button.classed('disabled', isHiddenPreset);
if (isHiddenPreset) {
var isAutoHidden = context.features().autoHidden(hiddenPresetFeaturesId);
var tooltipIdSuffix = isAutoHidden ? 'zoom' : 'manual';
var tooltipObj = { features: t('feature.' + hiddenPresetFeaturesId + '.description') };
button.call(tooltip('dark')
.html(true)
.title(t('inspector.hidden_preset.' + tooltipIdSuffix, tooltipObj))
.placement(index < 2 ? 'bottom' : 'top')
);
}
});
}
function chooseExpandable(item, itemSelection) {
var shouldExpand = !itemSelection.classed('expanded');
itemSelection.classed('expanded', shouldExpand);
var iconName = shouldExpand ?
'#iD-icon-down' : (textDirection === 'rtl' ? '#iD-icon-backward' : '#iD-icon-forward');
itemSelection.selectAll('.label svg.icon use')
.attr('href', iconName);
if (shouldExpand) {
var subitems = item.subitems();
var selector = '#' + itemSelection.node().id + ' + *';
item.subsection = d3_select(itemSelection.node().parentNode).insert('div', selector)
.attr('class', 'subsection subitems');
var subitemsEnter = item.subsection.selectAll('.list-item')
.data(subitems)
.enter();
drawItems(subitemsEnter);
updateForFeatureHiddenState();
scrollPopoverToShow(item.subsection);
} else {
item.subsection.remove();
}
}
function CategoryItem(preset) {
var item = {};
item.id = function() {
return preset.id;
};
item.name = function() {
return preset.name();
};
item.subsection = d3_select(null);
item.preset = preset;
item.choose = function() {
var selection = d3_select(this);
if (selection.classed('disabled')) return;
chooseExpandable(item, d3_select(selection.node().closest('.list-item')));
};
item.subitems = function() {
return preset.members.matchAnyGeometry(shownGeometry).collection.map(function(preset) {
return itemForPreset(preset);
});
};
return item;
}
function MultiPresetItem(presets) {
var item = {};
item.id = function() {
return presets.map(function(preset) { return preset.id; }).join();
};
item.name = function() {
return presets[0].name();
};
item.subsection = d3_select(null);
item.presets = presets;
item.choose = function() {
var selection = d3_select(this);
if (selection.classed('disabled')) return;
chooseExpandable(item, d3_select(selection.node().closest('.list-item')));
};
item.subitems = function() {
var items = [];
presets.forEach(function(preset) {
preset.geometry.filter(function(geometry) {
return shownGeometry.indexOf(geometry) !== -1;
}).forEach(function(geometry) {
items.push(AddablePresetItem(preset, geometry, true, true));
});
});
return items;
};
return item;
}
function MultiGeometryPresetItem(preset, geometries) {
var item = {};
item.id = function() {
return preset.id + geometries;
};
item.name = function() {
return preset.name();
};
item.subsection = d3_select(null);
item.preset = preset;
item.geometries = geometries;
item.choose = function() {
var selection = d3_select(this);
if (selection.classed('disabled')) return;
chooseExpandable(item, d3_select(selection.node().closest('.list-item')));
};
item.subitems = function() {
return geometries.map(function(geometry) {
return AddablePresetItem(preset, geometry, true);
});
};
return item;
}
function AddablePresetItem(preset, geometry, isSubitem, isInNameGroup) {
var item = {};
item.id = function() {
return preset.id + geometry + isSubitem;
};
item.name = function() {
if (isSubitem) {
if (preset.setTags({}, geometry).building) {
return t('presets.presets.building.name');
}
return t('modes.add_' + context.presets().fallback(geometry).id + '.title');
}
return preset.name();
};
item.isInNameGroup = isInNameGroup;
item.isSubitem = isSubitem;
item.preset = preset;
item.geometry = geometry;
item.choose = function() {
if (d3_select(this).classed('disabled')) return;
var markerClass = 'add-preset add-' + geometry +
' add-preset-' + preset.name().replace(/\s+/g, '_') + '-' + geometry;
var modeInfo = {
button: markerClass,
preset: preset,
geometry: geometry
};
var mode;
switch (geometry) {
case 'point':
case 'vertex':
mode = modeAddPoint(context, modeInfo);
break;
case 'line':
mode = modeAddLine(context, modeInfo);
break;
case 'area':
mode = modeAddArea(context, modeInfo);
}
search.node().blur();
context.presets().setMostRecent(preset, geometry);
context.enter(mode);
};
return item;
}
return utilRebind(tool, dispatch, 'on');
}
+1 -13
View File
@@ -5,16 +5,13 @@ import {
} from 'd3-selection';
import _debounce from 'lodash-es/debounce';
import { /*uiToolAddFavorite, uiToolAddRecent, uiToolSearchAdd, */ uiToolOldDrawModes, uiToolNotes, uiToolSave, uiToolSidebarToggle, uiToolUndoRedo } from './tools';
import { uiToolOldDrawModes, uiToolNotes, uiToolSave, uiToolSidebarToggle, uiToolUndoRedo } from './tools';
export function uiTopToolbar(context) {
var sidebarToggle = uiToolSidebarToggle(context),
modes = uiToolOldDrawModes(context),
//searchAdd = uiToolSearchAdd(context),
//addFavorite = uiToolAddFavorite(context),
//addRecent = uiToolAddRecent(context),
notes = uiToolNotes(context),
undoRedo = uiToolUndoRedo(context),
save = uiToolSave(context);
@@ -50,16 +47,7 @@ export function uiTopToolbar(context) {
sidebarToggle,
'spacer',
modes
// searchAdd
];
/*
if (context.presets().getFavorites().length > 0) {
tools.push(addFavorite);
}
if (addRecent.shouldShow()) {
tools.push(addRecent);
}*/
tools.push('spacer');