Files
iD/modules/ui/help.js
Quincy Morgan 523a467836 2.x: Make toolbar horizontally scrollable when it overflows (re: #6755, re: 7545f67063b5e7007ef2d8367e3181e59c04a487)
Generalize tooltip into popover control
Use the same popover control for tooltip as the preset browser and tools list popovers
Smartly position the preset browser popover and menu bar tooltips to stay fully onscreen
Position most tooltips closer to their controls
Fix small gap that could appear between a tooltip and its arrow
Allow wider toolbar tooltips
2019-12-16 13:30:07 -05:00

464 lines
13 KiB
JavaScript

import {
event as d3_event,
select as d3_select
} from 'd3-selection';
import marked from 'marked';
import { svgIcon } from '../svg/icon';
import { uiCmd } from './cmd';
import { uiIntro } from './intro/intro';
import { uiShortcuts } from './shortcuts';
import { uiTooltipHtml } from './tooltipHtml';
import { t, textDirection } from '../util/locale';
import { tooltip } from '../util/tooltip';
import { icon } from './intro/helper';
export function uiHelp(context) {
var key = t('help.key');
var _pane = d3_select(null);
var docKeys = [
['help', [
'welcome',
'open_data_h',
'open_data',
'before_start_h',
'before_start',
'open_source_h',
'open_source',
'open_source_help'
]],
['overview', [
'navigation_h',
'navigation_drag',
'navigation_zoom',
'features_h',
'features',
'nodes_ways'
]],
['editing', [
'select_h',
'select_left_click',
'select_right_click',
'multiselect_h',
'multiselect_shift_click',
'multiselect_lasso',
'undo_redo_h',
'undo_redo',
'save_h',
'save',
'save_validation',
'upload_h',
'upload',
'backups_h',
'backups',
'keyboard_h',
'keyboard'
]],
['feature_editor', [
'intro',
'definitions',
'type_h',
'type',
'type_picker',
'fields_h',
'fields_all_fields',
'fields_example',
'fields_add_field',
'tags_h',
'tags_all_tags',
'tags_resources'
]],
['points', [
'intro',
'add_point_h',
'add_point',
'add_point_finish',
'move_point_h',
'move_point',
'delete_point_h',
'delete_point',
'delete_point_command'
]],
['lines', [
'intro',
'add_line_h',
'add_line',
'add_line_draw',
'add_line_finish',
'modify_line_h',
'modify_line_dragnode',
'modify_line_addnode',
'connect_line_h',
'connect_line',
'connect_line_display',
'connect_line_drag',
'connect_line_tag',
'disconnect_line_h',
'disconnect_line_command',
'move_line_h',
'move_line_command',
'move_line_connected',
'delete_line_h',
'delete_line',
'delete_line_command'
]],
['areas', [
'intro',
'point_or_area_h',
'point_or_area',
'add_area_h',
'add_area_command',
'add_area_draw',
'add_area_finish',
'square_area_h',
'square_area_command',
'modify_area_h',
'modify_area_dragnode',
'modify_area_addnode',
'delete_area_h',
'delete_area',
'delete_area_command'
]],
['relations', [
'intro',
'edit_relation_h',
'edit_relation',
'edit_relation_add',
'edit_relation_delete',
'maintain_relation_h',
'maintain_relation',
'relation_types_h',
'multipolygon_h',
'multipolygon',
'multipolygon_create',
'multipolygon_merge',
'turn_restriction_h',
'turn_restriction',
'turn_restriction_field',
'turn_restriction_editing',
'route_h',
'route',
'route_add',
'boundary_h',
'boundary',
'boundary_add'
]],
['notes', [
'intro',
'add_note_h',
'add_note',
'move_note',
'update_note_h',
'update_note',
'save_note_h',
'save_note'
]],
['imagery', [
'intro',
'sources_h',
'choosing',
'sources',
'offsets_h',
'offset',
'offset_change'
]],
['streetlevel', [
'intro',
'using_h',
'using',
'photos',
'viewer'
]],
['gps', [
'intro',
'survey',
'using_h',
'using',
'tracing',
'upload'
]],
['qa', [
'intro',
'tools_h',
'tools',
'issues_h',
'issues'
]]
];
var headings = {
'help.help.open_data_h': 3,
'help.help.before_start_h': 3,
'help.help.open_source_h': 3,
'help.overview.navigation_h': 3,
'help.overview.features_h': 3,
'help.editing.select_h': 3,
'help.editing.multiselect_h': 3,
'help.editing.undo_redo_h': 3,
'help.editing.save_h': 3,
'help.editing.upload_h': 3,
'help.editing.backups_h': 3,
'help.editing.keyboard_h': 3,
'help.feature_editor.type_h': 3,
'help.feature_editor.fields_h': 3,
'help.feature_editor.tags_h': 3,
'help.points.add_point_h': 3,
'help.points.move_point_h': 3,
'help.points.delete_point_h': 3,
'help.lines.add_line_h': 3,
'help.lines.modify_line_h': 3,
'help.lines.connect_line_h': 3,
'help.lines.disconnect_line_h': 3,
'help.lines.move_line_h': 3,
'help.lines.delete_line_h': 3,
'help.areas.point_or_area_h': 3,
'help.areas.add_area_h': 3,
'help.areas.square_area_h': 3,
'help.areas.modify_area_h': 3,
'help.areas.delete_area_h': 3,
'help.relations.edit_relation_h': 3,
'help.relations.maintain_relation_h': 3,
'help.relations.relation_types_h': 2,
'help.relations.multipolygon_h': 3,
'help.relations.turn_restriction_h': 3,
'help.relations.route_h': 3,
'help.relations.boundary_h': 3,
'help.notes.add_note_h': 3,
'help.notes.update_note_h': 3,
'help.notes.save_note_h': 3,
'help.imagery.sources_h': 3,
'help.imagery.offsets_h': 3,
'help.streetlevel.using_h': 3,
'help.gps.using_h': 3,
'help.qa.tools_h': 3,
'help.qa.issues_h': 3
};
var replacements = {
point: icon('#iD-icon-point', 'pre-text'),
line: icon('#iD-icon-line', 'pre-text'),
area: icon('#iD-icon-area', 'pre-text'),
note: icon('#iD-icon-note', 'pre-text add-note'),
plus: icon('#iD-icon-plus', 'pre-text'),
minus: icon('#iD-icon-minus', 'pre-text'),
orthogonalize: icon('#iD-operation-orthogonalize', 'pre-text'),
disconnect: icon('#iD-operation-disconnect', 'pre-text'),
layers: icon('#iD-icon-layers', 'pre-text'),
data: icon('#iD-icon-data', 'pre-text'),
inspect: icon('#iD-icon-inspect', 'pre-text'),
move: icon('#iD-operation-move', 'pre-text'),
merge: icon('#iD-operation-merge', 'pre-text'),
delete: icon('#iD-operation-delete', 'pre-text'),
close: icon('#iD-icon-close', 'pre-text'),
undo: icon(textDirection === 'rtl' ? '#iD-icon-redo' : '#iD-icon-undo', 'pre-text'),
redo: icon(textDirection === 'rtl' ? '#iD-icon-undo' : '#iD-icon-redo', 'pre-text'),
save: icon('#iD-icon-save', 'pre-text'),
leftclick: icon('#iD-walkthrough-mouse', 'pre-text mouseclick', 'left'),
rightclick: icon('#iD-walkthrough-mouse', 'pre-text mouseclick', 'right'),
shift: uiCmd.display('⇧'),
alt: uiCmd.display('⌥'),
return: uiCmd.display('↵'),
version: context.version
};
// For each section, squash all the texts into a single markdown document
var docs = docKeys.map(function(key) {
var helpkey = 'help.' + key[0];
var text = key[1].reduce(function(all, part) {
var subkey = helpkey + '.' + part;
var depth = headings[subkey]; // is this subkey a heading?
var hhh = depth ? Array(depth + 1).join('#') + ' ' : ''; // if so, prepend with some ##'s
return all + hhh + t(subkey, replacements) + '\n\n';
}, '');
return {
title: t(helpkey + '.title'),
html: marked(text.trim())
};
});
var paneTooltip = tooltip()
.placement((textDirection === 'rtl') ? 'right' : 'left')
.html(true)
.title(uiTooltipHtml(t('help.title'), key));
function hidePane() {
context.ui().togglePanes();
}
uiHelp.togglePane = function() {
if (d3_event) d3_event.preventDefault();
paneTooltip.hide();
context.ui().togglePanes(!_pane.classed('shown') ? _pane : undefined);
};
uiHelp.renderToggleButton = function(selection) {
selection.append('button')
.on('click', uiHelp.togglePane)
.call(svgIcon('#iD-icon-help', 'light'))
.call(paneTooltip);
};
uiHelp.renderPane = function(selection) {
function clickHelp(d, i) {
var rtl = (textDirection === 'rtl');
content.property('scrollTop', 0);
doctitle.html(d.title);
body.html(d.html);
body.selectAll('a')
.attr('target', '_blank');
menuItems.classed('selected', function(m) {
return m.title === d.title;
});
nav.html('');
if (rtl) {
nav.call(drawNext).call(drawPrevious);
} else {
nav.call(drawPrevious).call(drawNext);
}
function drawNext(selection) {
if (i < docs.length - 1) {
var nextLink = selection
.append('a')
.attr('class', 'next')
.on('click', function() {
clickHelp(docs[i + 1], i + 1);
});
nextLink
.append('span')
.text(docs[i + 1].title)
.call(svgIcon((rtl ? '#iD-icon-backward' : '#iD-icon-forward'), 'inline'));
}
}
function drawPrevious(selection) {
if (i > 0) {
var prevLink = selection
.append('a')
.attr('class', 'previous')
.on('click', function() {
clickHelp(docs[i - 1], i - 1);
});
prevLink
.call(svgIcon((rtl ? '#iD-icon-forward' : '#iD-icon-backward'), 'inline'))
.append('span')
.text(docs[i - 1].title);
}
}
}
function clickWalkthrough() {
if (context.inIntro()) return;
context.container().call(uiIntro(context));
context.ui().togglePanes();
}
function clickShortcuts() {
context.container().call(uiShortcuts(context), true);
}
_pane = selection.append('div')
.attr('class', 'help-wrap map-pane fillL hide')
.attr('pane', 'help');
var heading = _pane
.append('div')
.attr('class', 'pane-heading');
var doctitle = heading
.append('h2')
.text(t('help.title'));
heading
.append('button')
.on('click', hidePane)
.call(svgIcon('#iD-icon-close'));
var content = _pane
.append('div')
.attr('class', 'pane-content');
var toc = content
.append('ul')
.attr('class', 'toc');
var menuItems = toc.selectAll('li')
.data(docs)
.enter()
.append('li')
.append('a')
.html(function(d) { return d.title; })
.on('click', clickHelp);
var shortcuts = toc
.append('li')
.attr('class', 'shortcuts')
.call(tooltip()
.html(true)
.title(uiTooltipHtml(t('shortcuts.tooltip'), '?'))
.placement('top')
)
.append('a')
.on('click', clickShortcuts);
shortcuts
.append('div')
.text(t('shortcuts.title'));
var walkthrough = toc
.append('li')
.attr('class', 'walkthrough')
.append('a')
.on('click', clickWalkthrough);
walkthrough
.append('svg')
.attr('class', 'logo logo-walkthrough')
.append('use')
.attr('xlink:href', '#iD-logo-walkthrough');
walkthrough
.append('div')
.text(t('splash.walkthrough'));
var helpContent = content
.append('div')
.attr('class', 'left-content');
var body = helpContent
.append('div')
.attr('class', 'body');
var nav = helpContent
.append('div')
.attr('class', 'nav');
clickHelp(docs[0], 0);
context.keybinding()
.on(key, uiHelp.togglePane);
};
return uiHelp;
}