mirror of
https://github.com/cryptpad/cryptpad.git
synced 2026-09-14 11:05:41 +05:00
Merge branch 'documents-toolbar' into staging
This commit is contained in:
commit
fcdce45083
@ -1038,6 +1038,13 @@
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
.cp-dropdown-container {
|
||||
button {
|
||||
.cp-icon {
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cp-app-drive-button {
|
||||
|
||||
@ -48,6 +48,16 @@
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
|
||||
// If a menu is displayed "left", pour the submenus on the left too
|
||||
.cp-dropdown-left {
|
||||
.cp-dropdown-submenu {
|
||||
.cp-dropdown-content {
|
||||
left: unset;
|
||||
right: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.fa {
|
||||
font-family: FontAwesome;
|
||||
}
|
||||
@ -61,6 +71,16 @@
|
||||
}
|
||||
}
|
||||
|
||||
.cp-dropdown-left {
|
||||
.cp-dropdown-content {
|
||||
right: 0;
|
||||
margin-right: 5px;
|
||||
&.cp-dropdown-submenu {
|
||||
left: unset;
|
||||
right: 250px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.cp-dropdown-content {
|
||||
list-style-type: none;
|
||||
display: none;
|
||||
@ -76,9 +96,8 @@
|
||||
font: @dropdown_font;
|
||||
line-height: 1em;
|
||||
|
||||
&.cp-dropdown-left {
|
||||
right: 0;
|
||||
margin-right: 5px;
|
||||
&.cp-dropdown-submenu {
|
||||
left: 250px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
@ -140,9 +159,13 @@
|
||||
}
|
||||
li[role="menuitem"] {
|
||||
border-radius: @variables_radius;
|
||||
&:hover, &:focus {
|
||||
white-space: nowrap;
|
||||
&:hover {
|
||||
background-color: @cp_dropdown-bg-hover !important;
|
||||
color: @cp_dropdown-fg;
|
||||
//color: @cp_dropdown-fg;
|
||||
}
|
||||
&:focus-visible {
|
||||
outline-color: @cp_dropdown-fg;
|
||||
}
|
||||
}
|
||||
&> span {
|
||||
|
||||
@ -366,7 +366,7 @@
|
||||
.cp-toolbar {
|
||||
* {
|
||||
outline-style: none;
|
||||
&:focus {
|
||||
&:focus-visible {
|
||||
outline: @cryptpad_color_brand solid 2px;
|
||||
}
|
||||
}
|
||||
@ -523,11 +523,6 @@
|
||||
&::before {
|
||||
padding-top: 1px;
|
||||
}
|
||||
// .cp-dropdown-button-title {
|
||||
// transform: scale(0.5);
|
||||
// bottom: -5px;
|
||||
// right: -5px;
|
||||
// }
|
||||
}
|
||||
}
|
||||
.cp-toolbar-user-dropdown {
|
||||
@ -960,6 +955,11 @@
|
||||
&:empty {
|
||||
height: 0;
|
||||
}
|
||||
|
||||
& > div:empty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.cp-toolbar-users {
|
||||
pre {
|
||||
/* needed for ckeditor */
|
||||
@ -1053,7 +1053,7 @@
|
||||
|
||||
&.cp-toolbar-small {
|
||||
button {
|
||||
.cp-toolbar-name, .cp-button-name {
|
||||
.cp-toolbar-name, .cp-button-name, .cp-dropdown-button-title {
|
||||
display: none;
|
||||
}
|
||||
i, span {
|
||||
@ -1127,27 +1127,29 @@
|
||||
order: 8;
|
||||
}
|
||||
.cp-toolbar-file {
|
||||
button {
|
||||
&.fa-plus { order: 0; }
|
||||
&.fa-history { order: 5; }
|
||||
&.fa-hashtag { order: 10; }
|
||||
&.fa-bookmark { order: 15; }
|
||||
&.fa-upload { order: 20; }
|
||||
&.fa-files-o { order: 25; }
|
||||
&.fa-download { order: 30; }
|
||||
&.fa-print { order: 35; }
|
||||
&.fa-trash { order: 40; }
|
||||
&.cp-toolbar-icon-pad-settings { order: 75; }
|
||||
&.fa-info-circle { order: 100; }
|
||||
li, button {
|
||||
.fa-plus { order: 0; }
|
||||
.fa-history { order: 5; }
|
||||
.fa-hashtag { order: 10; }
|
||||
.fa-bookmark { order: 15; }
|
||||
.fa-upload { order: 20; }
|
||||
.fa-files-o { order: 25; }
|
||||
.fa-download { order: 30; }
|
||||
.fa-print { order: 35; }
|
||||
.fa-trash { order: 40; }
|
||||
.cp-toolbar-icon-pad-settings { order: 75; }
|
||||
.fa-info-circle { order: 100; }
|
||||
|
||||
&.cp-toolbar-icon-help { order: 150; }
|
||||
.fa-question { order: 150; }
|
||||
|
||||
span { order: 1000; } // text always after icon
|
||||
}
|
||||
}
|
||||
|
||||
.cp-toolbar-drawer-content:empty ~ .cp-toolbar-drawer-button {
|
||||
.cp-toolbar-drawer-contentsss:empty ~ .cp-toolbar-drawer-button {
|
||||
display: none;
|
||||
}
|
||||
.cp-toolbar-drawer-content {
|
||||
.cp-toolbar-drawer-contentsss {
|
||||
box-shadow: 0px 1px 5px 0px @cp_shadow-color;
|
||||
border-radius: @variables_radius;
|
||||
overflow-y: auto;
|
||||
|
||||
@ -18,6 +18,7 @@ define([
|
||||
'/common/TypingTests.js',
|
||||
'/customize/messages.js',
|
||||
'cm/lib/codemirror',
|
||||
'/common/common-ui-elements.js',
|
||||
|
||||
|
||||
'css!cm/lib/codemirror.css',
|
||||
@ -64,7 +65,8 @@ define([
|
||||
Visible,
|
||||
TypingTest,
|
||||
Messages,
|
||||
CMeditor)
|
||||
CMeditor,
|
||||
UIElements)
|
||||
{
|
||||
window.CodeMirror = CMeditor;
|
||||
|
||||
@ -82,19 +84,15 @@ define([
|
||||
]);
|
||||
|
||||
var mkThemeButton = function (framework) {
|
||||
var $theme = $(h('button.cp-toolbar-appmenu', [
|
||||
h('i.cptools.cptools-palette'),
|
||||
h('span.cp-button-name', Messages.toolbar_theme)
|
||||
]));
|
||||
var $content = $(h('div.cp-toolbar-drawer-content', {
|
||||
tabindex: 1
|
||||
})).hide();
|
||||
|
||||
// set up all the necessary events
|
||||
UI.createDrawer($theme, $content);
|
||||
|
||||
framework._.toolbar.$theme = $content;
|
||||
framework._.toolbar.$bottomL.append($theme);
|
||||
const $drawer = UIElements.createDropdown({
|
||||
text: Messages.toolbar_theme,
|
||||
options: [],
|
||||
common: framework._.sfCommon,
|
||||
iconCls: 'cptools cptools-palette'
|
||||
});
|
||||
framework._.toolbar.$theme = $drawer.find('ul.cp-dropdown-content');
|
||||
framework._.toolbar.$bottomL.append($drawer);
|
||||
$drawer.addClass('cp-toolbar-appmenu');
|
||||
};
|
||||
|
||||
var mkCbaButton = function (framework, markers) {
|
||||
@ -103,10 +101,12 @@ define([
|
||||
name: 'authormarks',
|
||||
icon: 'fa-paint-brush',
|
||||
}).hide();
|
||||
framework._.toolbar.$theme.append($showAuthorColorsButton);
|
||||
markers.setButton($showAuthorColorsButton);
|
||||
var $showAuthorColors = UIElements.getEntryFromButton($showAuthorColorsButton).hide();
|
||||
$showAuthorColors.find('span').addClass('cp-toolbar-name cp-toolbar-drawer-element');
|
||||
framework._.toolbar.$theme.append($showAuthorColors);
|
||||
markers.setButton($showAuthorColors);
|
||||
};
|
||||
var mkPrintButton = function (framework, $content, $print) {
|
||||
var mkPrintButton = function (framework, $content) {
|
||||
var $printButton = framework._.sfCommon.createButton('print', true);
|
||||
$printButton.click(function () {
|
||||
$print.html($content.html());
|
||||
@ -114,7 +114,8 @@ define([
|
||||
window.print();
|
||||
framework.feedback('PRINT_CODE');
|
||||
});
|
||||
framework._.toolbar.$drawer.append($printButton);
|
||||
var $print = UIElements.getEntryFromButton($printButton);
|
||||
framework._.toolbar.$drawer.append($print);
|
||||
};
|
||||
var mkMarkdownTb = function (editor, framework) {
|
||||
var $codeMirrorContainer = $('#cp-app-code-container');
|
||||
@ -137,7 +138,8 @@ define([
|
||||
var helpMenu = framework._.sfCommon.createHelpMenu(['text', 'code']);
|
||||
$codeMirrorContainer.prepend(helpMenu.menu);
|
||||
|
||||
framework._.toolbar.$drawer.append(helpMenu.button);
|
||||
var $helpMenuButton = UIElements.getEntryFromButton(helpMenu.button);
|
||||
framework._.toolbar.$drawer.append($helpMenuButton);
|
||||
};
|
||||
|
||||
var previews = {};
|
||||
@ -393,7 +395,8 @@ define([
|
||||
setButton(!markers.getState());
|
||||
UI.alert(content);
|
||||
});
|
||||
framework._.toolbar.$theme.append($cbaButton);
|
||||
var $cba = UIElements.getEntryFromButton($cbaButton);
|
||||
framework._.toolbar.$theme.prepend($cba);
|
||||
};
|
||||
|
||||
var mkFilePicker = function (framework, editor, evModeChange) {
|
||||
|
||||
@ -25,7 +25,7 @@ define([
|
||||
|
||||
var debug = function () {};
|
||||
|
||||
var MARK_OPACITY = 0.5;
|
||||
var MARK_OPACITY = 0.2;
|
||||
var DEFAULT = {
|
||||
authors: {},
|
||||
marks: [[-1, 0, 0, Number.MAX_SAFE_INTEGER, Number.MAX_SAFE_INTEGER]]
|
||||
@ -624,11 +624,9 @@ define([
|
||||
if (Env.opacity) {
|
||||
Env.opacity = 0;
|
||||
$button.find('.cp-toolbar-drawer-element').text(Messages.cba_show);
|
||||
$button.removeClass("cp-toolbar-button-active");
|
||||
} else {
|
||||
Env.opacity = MARK_OPACITY;
|
||||
$button.find('.cp-toolbar-drawer-element').text(Messages.cba_hide);
|
||||
$button.addClass("cp-toolbar-button-active");
|
||||
}
|
||||
};
|
||||
toggle();
|
||||
|
||||
@ -1466,44 +1466,6 @@ define([
|
||||
};
|
||||
};
|
||||
|
||||
/* Given two jquery objects (a 'button' and a 'drawer')
|
||||
add handlers to make it such that clicking the button
|
||||
displays the drawer contents, and blurring the button
|
||||
hides the drawer content. Used for toolbar buttons at the moment.
|
||||
*/
|
||||
UI.createDrawer = function ($button, $content) {
|
||||
$button.click(function () {
|
||||
var topPos = $button[0].getBoundingClientRect().bottom;
|
||||
$content.toggle();
|
||||
$button.removeClass('cp-toolbar-button-active');
|
||||
if ($content.is(':visible')) {
|
||||
$button.addClass('cp-toolbar-button-active');
|
||||
$content.focus();
|
||||
var wh = $(window).height();
|
||||
$content.css('max-height', Math.floor(wh - topPos - 1)+'px');
|
||||
}
|
||||
});
|
||||
var onBlur = function (e) {
|
||||
if (e.relatedTarget) {
|
||||
var $relatedTarget = $(e.relatedTarget);
|
||||
|
||||
if ($relatedTarget.is('.cp-toolbar-drawer-button')) { return; }
|
||||
if ($relatedTarget.parents('.cp-toolbar-drawer-content').length) {
|
||||
$relatedTarget.blur(onBlur);
|
||||
return;
|
||||
}
|
||||
}
|
||||
$button.removeClass('cp-toolbar-button-active');
|
||||
$content.hide();
|
||||
};
|
||||
$content.blur(onBlur).appendTo($button);
|
||||
$('body').keydown(function (e) {
|
||||
if (e.which === 27) {
|
||||
$content.blur();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/* QR code generation is synchronous once the library is loaded
|
||||
so this could be syncronous if we load the library separately. */
|
||||
UI.createQRCode = function (data, _cb) {
|
||||
|
||||
@ -577,12 +577,38 @@ define([
|
||||
});
|
||||
};
|
||||
|
||||
UIElements.getEntryFromButton = function ($button) {
|
||||
if (!$button || !$button.length) { return; }
|
||||
let $icon = $button.find('> i');
|
||||
|
||||
let attributes = {};
|
||||
let btnClass = $button.attr('class');
|
||||
let btnId = $button.attr('id');
|
||||
if (btnClass) { attributes['class'] = btnClass; }
|
||||
if (btnId) { attributes['id'] = btnId; }
|
||||
|
||||
return UIElements.createDropdownEntry({
|
||||
tag: 'a',
|
||||
attributes: attributes,
|
||||
content: [
|
||||
h('i',{ 'class': $icon.attr('class') }),
|
||||
h('span', $button.text())
|
||||
],
|
||||
action: function () {
|
||||
$button.click();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
UIElements.createButton = function (common, type, rightside, data, callback) {
|
||||
var AppConfig = common.getAppConfig();
|
||||
var button;
|
||||
var sframeChan = common.getSframeChannel();
|
||||
var appType = (common.getMetadataMgr().getMetadata().type || 'pad').toUpperCase();
|
||||
data = data || {};
|
||||
if (!callback && data.callback) { callback = data.callback; }
|
||||
switch (type) {
|
||||
case 'export':
|
||||
button = $('<button>', {
|
||||
@ -858,12 +884,12 @@ define([
|
||||
h('i.fa.fa-file-image-o'),
|
||||
h('span.cp-toolbar-name.cp-toolbar-drawer-element', Messages.toolbar_savetodrive)
|
||||
])).click(common.prepareFeedback(type));
|
||||
if (callback) { button.click(callback); }
|
||||
break;
|
||||
case 'storeindrive':
|
||||
button = $(h('button.cp-toolbar-storeindrive', {
|
||||
button = $(h('button.cp-toolbar-storeindrive.fa.fa-hdd-o', {
|
||||
style: 'display:none;'
|
||||
}, [
|
||||
h('i.fa.fa-hdd-o'),
|
||||
h('span.cp-toolbar-name.cp-toolbar-drawer-element', Messages.toolbar_storeInDrive)
|
||||
])).click(common.prepareFeedback(type)).click(function () {
|
||||
$(button).hide();
|
||||
@ -994,7 +1020,7 @@ define([
|
||||
h('span.cp-toolbar-name'+drawerCls, data.text)
|
||||
]));
|
||||
var feedbackHandler = common.prepareFeedback(data.name || 'DEFAULT');
|
||||
button[0].addEventListener('click', function () {
|
||||
Util.onClickEnter(button, function () {
|
||||
feedbackHandler();
|
||||
if (typeof(callback) !== 'function') { return; }
|
||||
callback();
|
||||
@ -1454,6 +1480,94 @@ define([
|
||||
};
|
||||
};
|
||||
|
||||
UIElements.createDropdownEntry = function (config) {
|
||||
var hide = function () {};
|
||||
var allowedTags = ['a', 'li', 'p', 'hr', 'div'];
|
||||
var isElement = function (o) {
|
||||
return /HTML/.test(Object.prototype.toString.call(o)) &&
|
||||
typeof(o.tagName) === 'string';
|
||||
};
|
||||
var isValidOption = function (o) {
|
||||
if (typeof o !== "object") { return false; }
|
||||
if (isElement(o)) { return true; }
|
||||
if (!o.tag || allowedTags.indexOf(o.tag) === -1) { return false; }
|
||||
return true;
|
||||
};
|
||||
|
||||
var entry;
|
||||
if (!isValidOption(config)) { return; }
|
||||
|
||||
if (isElement(config)) {
|
||||
entry = $(config);
|
||||
} else {
|
||||
var $el = $(h(config.tag, (config.attributes || {})));
|
||||
|
||||
if (typeof(config.content) === 'string' || (config.content instanceof Element)) {
|
||||
config.content = [config.content];
|
||||
}
|
||||
|
||||
if (Array.isArray(config.content)) {
|
||||
config.content.forEach(function (item) {
|
||||
if (item instanceof Element) {
|
||||
return void $el.append(item);
|
||||
}
|
||||
if (typeof(item) === 'string') {
|
||||
$el[0].appendChild(document.createTextNode(item));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Everything is added as an "li" tag
|
||||
// Links and items with action are focusable
|
||||
// Add correct "role" attribute
|
||||
entry = $(h('li'));
|
||||
if (config.tag === 'a') {
|
||||
$el.attr('tabindex', '-1');
|
||||
entry.attr('role', 'menuitem');
|
||||
entry.attr('tabindex', '0');
|
||||
} else if (config.tag === 'li') {
|
||||
entry = $el;
|
||||
entry.attr('role', 'menuitem');
|
||||
entry.attr('tabindex', '0');
|
||||
} else if (config.tag === 'hr') {
|
||||
entry.attr('role', 'separator');
|
||||
} else {
|
||||
entry.attr('role', 'none');
|
||||
}
|
||||
entry.append($el);
|
||||
|
||||
// Action can be triggered with a click or keyboard event
|
||||
if (config.tag === 'a' || config.tag === 'li') {
|
||||
entry.on('mouseenter', (e) => {
|
||||
e.stopPropagation();
|
||||
entry.focus();
|
||||
});
|
||||
|
||||
Util.onClickEnter(entry, function(e) {
|
||||
if (config.isSelect) { return; }
|
||||
e.stopPropagation();
|
||||
if (typeof(config.action) === "function") {
|
||||
var close = config.action(e);
|
||||
if (close) { hide(); }
|
||||
} else {
|
||||
// Click on <a> with an href
|
||||
if (e.type === 'keydown'){ $el.get(0).click(); }
|
||||
}
|
||||
}, {space: true});
|
||||
}
|
||||
}
|
||||
|
||||
hide = function () {
|
||||
window.setTimeout(function () {
|
||||
entry.closest('.cp-dropdown-menu-container').find('.cp-dropdown-submenu').hide();
|
||||
entry.parents('.cp-dropdown-content').hide();
|
||||
|
||||
}, 0);
|
||||
};
|
||||
|
||||
return entry;
|
||||
};
|
||||
|
||||
// Create a button with a dropdown menu
|
||||
// input is a config object with parameters:
|
||||
// - container (optional): the dropdown container (span)
|
||||
@ -1465,18 +1579,6 @@ define([
|
||||
if (typeof config !== "object" || !Array.isArray(config.options)) { return; }
|
||||
if (config.feedback && !config.common) { return void console.error("feedback in a dropdown requires sframe-common"); }
|
||||
|
||||
var isElement = function (o) {
|
||||
return /HTML/.test(Object.prototype.toString.call(o)) &&
|
||||
typeof(o.tagName) === 'string';
|
||||
};
|
||||
var allowedTags = ['a', 'li', 'p', 'hr', 'div'];
|
||||
var isValidOption = function (o) {
|
||||
if (typeof o !== "object") { return false; }
|
||||
if (isElement(o)) { return true; }
|
||||
if (!o.tag || allowedTags.indexOf(o.tag) === -1) { return false; }
|
||||
return true;
|
||||
};
|
||||
|
||||
// Container
|
||||
var $container = $(config.container);
|
||||
var containerConfig = {
|
||||
@ -1490,47 +1592,45 @@ define([
|
||||
$container = $('<span>', containerConfig);
|
||||
}
|
||||
|
||||
|
||||
// Button
|
||||
var $button;
|
||||
|
||||
if (config.buttonContent) {
|
||||
$button = $(h('button', {
|
||||
class: config.buttonCls || '',
|
||||
'aria-haspopup': 'menu',
|
||||
'aria-expanded': 'false',
|
||||
'title': config.buttonTitle || '',
|
||||
'aria-label': config.buttonTitle || '',
|
||||
}, [
|
||||
h('span.cp-dropdown-button-title', config.buttonContent),
|
||||
]));
|
||||
} else {
|
||||
$button = $('<button>', {
|
||||
'class': config.buttonCls || '',
|
||||
'aria-haspopup': 'menu',
|
||||
'aria-expanded': 'false',
|
||||
'title': config.buttonTitle || '',
|
||||
'aria-label': config.buttonTitle || '',
|
||||
}).append($('<span>', {'class': 'cp-dropdown-button-title'}).text(config.text || ""));
|
||||
}
|
||||
|
||||
let icon = config.iconCls ? h('i', {class:config.iconCls}) : undefined;
|
||||
var $button = $(h('button', {
|
||||
class: config.buttonCls || '',
|
||||
'aria-haspopup': 'menu',
|
||||
'aria-expanded': 'false',
|
||||
'title': config.buttonTitle || '',
|
||||
'aria-label': config.buttonTitle || '',
|
||||
}, config.buttonContent || [
|
||||
icon,
|
||||
h('span.cp-dropdown-button-title', config.text),
|
||||
]));
|
||||
|
||||
if (config.caretDown) {
|
||||
$('<span>', {
|
||||
'class': 'fa fa-caret-down',
|
||||
}).prependTo($button);
|
||||
$button.append(h('i.fa.fa-caret-down'));
|
||||
}
|
||||
if (config.angleDown) {
|
||||
$('<span>', {
|
||||
'class': 'fa fa-angle-down',
|
||||
}).prependTo($button);
|
||||
$button.append(h('i.fa.fa-angle-down'));
|
||||
}
|
||||
|
||||
// Menu
|
||||
var $innerblock = $('<ul>', {'class': 'cp-dropdown-content', 'role': 'menu'});
|
||||
if (config.left) { $innerblock.addClass('cp-dropdown-left'); }
|
||||
var $innerblock = $('<ul>', {
|
||||
'class': 'cp-dropdown-content',
|
||||
'role': 'menu',
|
||||
'tabindex': '-1'
|
||||
});
|
||||
var $outerblock = $(h('div.cp-dropdown-menu-container', $innerblock[0]));
|
||||
let $parentMenu = config.isSubmenuOf;
|
||||
$container.$menu = $innerblock;
|
||||
if (config.left) { $outerblock.addClass('cp-dropdown-left'); }
|
||||
if (config.isSubmenuOf && config.isSubmenuOf.length) {
|
||||
$innerblock.addClass('cp-dropdown-submenu');
|
||||
}
|
||||
|
||||
var hide = function () {
|
||||
window.setTimeout(function () { $innerblock.hide(); }, 0);
|
||||
window.setTimeout(function () {
|
||||
$innerblock.hide();
|
||||
}, 0);
|
||||
};
|
||||
|
||||
// When the menu is collapsed, update aria-expanded
|
||||
@ -1539,81 +1639,35 @@ define([
|
||||
if (mutation.attributeName !== 'style') { return; }
|
||||
if ($innerblock[0].style.display === 'none') {
|
||||
$button.attr('aria-expanded', 'false');
|
||||
if (config.$parentButton) {
|
||||
config.$parentButton.find('a')
|
||||
.toggleClass('cp-dropdown-element-active', false);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
observer.observe($innerblock[0], { attributes: true });
|
||||
|
||||
// Add the dropdown content
|
||||
var setOptions = function (options) {
|
||||
var setOptions = $container.setOptions = function (options) {
|
||||
$innerblock.empty();
|
||||
options.forEach(function (o) {
|
||||
if (!isValidOption(o)) { return; }
|
||||
if (isElement(o)) { return void $innerblock.append(o); }
|
||||
var $el = $(h(o.tag, (o.attributes || {})));
|
||||
if (typeof(o.content) === 'string' || (o.content instanceof Element)) {
|
||||
o.content = [o.content];
|
||||
}
|
||||
if (Array.isArray(o.content)) {
|
||||
o.content.forEach(function (item) {
|
||||
if (item instanceof Element) {
|
||||
return void $el.append(item);
|
||||
}
|
||||
if (typeof(item) === 'string') {
|
||||
$el[0].appendChild(document.createTextNode(item));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Everything is added as an "li" tag
|
||||
// Links and items with action are focusable
|
||||
// Add correct "role" attribute
|
||||
var $li = $(h('li'));
|
||||
if (o.tag === 'a') {
|
||||
$el.attr('tabindex', '-1');
|
||||
$li.attr('role', 'menuitem');
|
||||
$li.attr('tabindex', '0');
|
||||
} else if (o.tag === 'li') {
|
||||
$li = $el;
|
||||
$li.attr('role', 'menuitem');
|
||||
$li.attr('tabindex', '0');
|
||||
} else if (o.tag === 'hr') {
|
||||
$li.attr('role', 'separator');
|
||||
} else {
|
||||
$li.attr('role', 'none');
|
||||
}
|
||||
$li.append($el);
|
||||
$li.appendTo($innerblock);
|
||||
|
||||
// Action can be triggered with a click or keyboard event
|
||||
if (o.tag !== 'a' && o.tag !== 'li') { return; }
|
||||
|
||||
$li.on('mouseenter', (e) => {
|
||||
e.stopPropagation();
|
||||
$li.focus();
|
||||
});
|
||||
var onAction = function (e) {
|
||||
if (config.isSelect) { return; }
|
||||
if (e.type === 'click' || (e.type === 'keydown' && e.keyCode === 13) || (e.type === 'keydown' && e.keyCode === 32)) {
|
||||
e.stopPropagation();
|
||||
if (typeof(o.action) === "function") {
|
||||
var close = o.action(e);
|
||||
if (close) { hide(); }
|
||||
} else {
|
||||
// Click on <a> with an href
|
||||
if (e.type === 'keydown'){ $el.get(0).click(); }
|
||||
}
|
||||
}
|
||||
};
|
||||
$li.on('click keydown', onAction);
|
||||
if (!o) { return; }
|
||||
o.isSelect = config.isSelect;
|
||||
let $entry = UIElements.createDropdownEntry(o);
|
||||
if (!$entry) { return void console.error('Error adding dropdown entry', o); }
|
||||
$entry.appendTo($innerblock);
|
||||
});
|
||||
};
|
||||
setOptions(config.options);
|
||||
$container.setOptions = function (options) {
|
||||
$innerblock.empty();
|
||||
setOptions(options);
|
||||
|
||||
$container.addOption = function (config) {
|
||||
let $entry = UIElements.createDropdownEntry(config);
|
||||
$entry.appendTo($innerblock);
|
||||
};
|
||||
|
||||
$container.append($button).append($innerblock);
|
||||
$container.append($button).append($outerblock);
|
||||
if ($parentMenu) { $parentMenu.after($innerblock); }
|
||||
|
||||
var value = config.initialValue || '';
|
||||
|
||||
@ -1640,15 +1694,40 @@ define([
|
||||
var topPos = button.bottom;
|
||||
$button.attr('aria-expanded', 'true');
|
||||
$innerblock.css('bottom', '');
|
||||
$innerblock.show();
|
||||
if ($parentMenu) {
|
||||
// keep parent open when recursive
|
||||
$parentMenu.show();
|
||||
if (config.$parentButton) {
|
||||
config.$parentButton.find('a')
|
||||
.toggleClass('cp-dropdown-element-active', true);
|
||||
}
|
||||
}
|
||||
|
||||
if (config.noscroll) {
|
||||
var h = $innerblock.outerHeight();
|
||||
if ((topPos + h) > wh) {
|
||||
$innerblock.css('bottom', button.height+'px');
|
||||
}
|
||||
} else if ($parentMenu) {
|
||||
let max = $parentMenu.css('max-height');
|
||||
let css = {
|
||||
'max-height': max
|
||||
};
|
||||
if (config.$parentButton) {
|
||||
let pos = config.$parentButton.position();
|
||||
let diff = pos.top;
|
||||
css['margin-top'] = diff+'px';
|
||||
css['max-height'] = (parseFloat(max)-diff)+'px';
|
||||
}
|
||||
$innerblock.css(css);
|
||||
if ($innerblock.height() < 50) {
|
||||
$innerblock.css('max-height', max);
|
||||
$innerblock.css('margin-top', '');
|
||||
}
|
||||
} else {
|
||||
$innerblock.css('max-height', Math.floor(wh - topPos - 1)+'px');
|
||||
}
|
||||
$innerblock.show();
|
||||
$innerblock.find('.cp-dropdown-element-active').removeClass('cp-dropdown-element-active');
|
||||
setTimeout(() => {
|
||||
if (config.isSelect && value) {
|
||||
@ -1671,12 +1750,6 @@ define([
|
||||
var state = $innerblock.is(':visible');
|
||||
$('.cp-dropdown-content').hide();
|
||||
|
||||
var $c = $container.closest('.cp-toolbar-drawer-content');
|
||||
$c.removeClass('cp-dropdown-visible');
|
||||
if (!state) {
|
||||
$c.addClass('cp-dropdown-visible');
|
||||
}
|
||||
|
||||
try {
|
||||
$('iframe').each(function (idx, ifrw) {
|
||||
$(ifrw).contents().find('.cp-dropdown-content').hide();
|
||||
@ -1693,7 +1766,7 @@ define([
|
||||
|
||||
if (config.isSelect) {
|
||||
$container.onChange = Util.mkEvent();
|
||||
$container.on('click', 'li', function () {
|
||||
$innerblock.on('click', 'li', function () {
|
||||
var $val = $(this).find('a');
|
||||
value = $val.data('value');
|
||||
var textValue = $val.text() || value;
|
||||
@ -1756,7 +1829,10 @@ define([
|
||||
var next = (idx + 1) % $all.length;
|
||||
return $($all.get(next));
|
||||
};
|
||||
$container.keydown(function (e) {
|
||||
|
||||
let $listener = $container;
|
||||
if ($parentMenu) { $listener = $innerblock; }
|
||||
$listener.keydown(function (e) {
|
||||
e.stopPropagation(); // don't propagate event to window if the dropdown is focused
|
||||
|
||||
var visible = $innerblock.is(':visible');
|
||||
@ -1765,6 +1841,7 @@ define([
|
||||
$container.click();
|
||||
visible = true;
|
||||
}
|
||||
|
||||
if (!visible) { return; }
|
||||
if (e.which === 38) { // Up
|
||||
e.preventDefault();
|
||||
@ -1807,19 +1884,34 @@ define([
|
||||
if (e.which === 27) { // Esc
|
||||
e.preventDefault();
|
||||
$value.mouseleave();
|
||||
if ($container.find('.cp-dropdown-submenu:visible').length) {
|
||||
let $submenu = $container.find('.cp-dropdown-submenu:visible');
|
||||
if ($submenu[0] !== $innerblock[0]) {
|
||||
$submenu.hide();
|
||||
return;
|
||||
}
|
||||
}
|
||||
hide();
|
||||
$button.focus();
|
||||
if ($parentMenu) { $button.closest('li').focus(); }
|
||||
else { $button.focus(); }
|
||||
}
|
||||
if (e.which === 9) { // Tab
|
||||
hide();
|
||||
if (e.shiftKey) {
|
||||
$button.focus();
|
||||
hide();
|
||||
if ($parentMenu) { $button.closest('li').focus(); }
|
||||
else { $button.focus(); }
|
||||
} else {
|
||||
// Hide parent only if we're not going to focus visible submenu
|
||||
if ($parentMenu ||
|
||||
!$container.find('.cp-dropdown-submenu:visible').length) {
|
||||
hide();
|
||||
}
|
||||
if ($parentMenu) { $parentMenu.hide(); }
|
||||
$innerblock.find('[role="menuitem"]').last().focus();
|
||||
}
|
||||
}
|
||||
});
|
||||
$container.keypress(function (e) {
|
||||
$listener.keypress(function (e) {
|
||||
e.stopPropagation(); // Don't propagate to window
|
||||
window.clearTimeout(to);
|
||||
var c = String.fromCharCode(e.which);
|
||||
@ -1840,6 +1932,8 @@ define([
|
||||
}, 1000);
|
||||
});
|
||||
|
||||
$container.close = hide;
|
||||
|
||||
|
||||
return $container;
|
||||
};
|
||||
@ -2237,7 +2331,7 @@ define([
|
||||
};
|
||||
});
|
||||
var dropdownConfigUser = {
|
||||
buttonContent: $userButton[0],
|
||||
text: $userButton[0],
|
||||
options: options, // Entries displayed in the menu
|
||||
left: true, // Open to the left of the button
|
||||
container: config.$initBlock, // optional
|
||||
|
||||
@ -117,7 +117,7 @@
|
||||
// "enter" on a button triggers a click, disable it
|
||||
if (e.type === 'keydown') { e.preventDefault(); }
|
||||
|
||||
handler();
|
||||
handler(e);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@ -2724,12 +2724,14 @@ Uncaught TypeError: Cannot read property 'calculatedType' of null
|
||||
});
|
||||
};
|
||||
|
||||
common.createButton('', true, {
|
||||
var $historyButton = common.createButton('', true, {
|
||||
name: 'history',
|
||||
icon: 'fa-history',
|
||||
text: Messages.historyText,
|
||||
tippy: Messages.historyButton
|
||||
}).click(function () {
|
||||
});
|
||||
|
||||
$historyButton.click(function () {
|
||||
ooChannel.historyLastHash = ooChannel.lastHash;
|
||||
ooChannel.currentIndex = ooChannel.cpIndex;
|
||||
Feedback.send('OO_HISTORY');
|
||||
@ -2747,19 +2749,24 @@ Uncaught TypeError: Cannot read property 'calculatedType' of null
|
||||
$toolbar: $('.cp-toolbar-container')
|
||||
};
|
||||
History.create(common, histConfig);
|
||||
}).appendTo(toolbar.$drawer);
|
||||
});
|
||||
|
||||
var $historyDropdown = UIElements.getEntryFromButton($historyButton);
|
||||
$historyDropdown.appendTo(toolbar.$drawer);
|
||||
|
||||
// Snapshots
|
||||
var $snapshot = common.createButton('snapshots', true, {
|
||||
var $snapshotButton = common.createButton('snapshots', true, {
|
||||
remove: deleteSnapshot,
|
||||
make: makeSnapshot,
|
||||
load: loadSnapshot
|
||||
});
|
||||
var $snapshot = UIElements.getEntryFromButton($snapshotButton);
|
||||
toolbar.$drawer.append($snapshot);
|
||||
|
||||
// Import template
|
||||
var $template = common.createButton('importtemplate', true, {}, openTemplatePicker);
|
||||
if ($template && typeof($template.appendTo) === 'function') {
|
||||
var $importTemplateButton = common.createButton('importtemplate', true, {}, openTemplatePicker);
|
||||
if ($importTemplateButton && $importTemplateButton.length) {
|
||||
let $template = UIElements.getEntryFromButton($importTemplateButton);
|
||||
$template.appendTo(toolbar.$drawer);
|
||||
}
|
||||
|
||||
@ -2782,8 +2789,9 @@ Uncaught TypeError: Cannot read property 'calculatedType' of null
|
||||
APP.FM.handleFile(blob, data);
|
||||
}
|
||||
};
|
||||
var $templateButton = common.createButton('template', true, templateObj);
|
||||
toolbar.$drawer.append($templateButton);
|
||||
let $templateButton = common.createButton('template', true, templateObj);
|
||||
let $template = UIElements.getEntryFromButton($templateButton);
|
||||
toolbar.$drawer.append($template);
|
||||
}
|
||||
})();
|
||||
}
|
||||
@ -2807,7 +2815,8 @@ Uncaught TypeError: Cannot read property 'calculatedType' of null
|
||||
}).attr('title', 'Restore last checkpoint').appendTo(toolbar.$bottomM);
|
||||
}
|
||||
|
||||
var $exportXLSX = common.createButton('export', true, {}, exportXLSXFile);
|
||||
var $exportXLSXButton = common.createButton('export', true, {}, exportXLSXFile);
|
||||
var $exportXLSX = UIElements.getEntryFromButton($exportXLSXButton);
|
||||
$exportXLSX.appendTo(toolbar.$drawer);
|
||||
|
||||
var type = privateData.ooType;
|
||||
@ -2835,35 +2844,44 @@ Uncaught TypeError: Cannot read property 'calculatedType' of null
|
||||
|
||||
if (common.isLoggedIn()) {
|
||||
window.CryptPad_deleteLastCp = deleteLastCp;
|
||||
var $importXLSX = common.createButton('import', true, {
|
||||
var $importXLSXButton = common.createButton('import', true, {
|
||||
accept: accept,
|
||||
binary : ["ods", "xlsx", "odt", "docx", "odp", "pptx"],
|
||||
binary: ["ods", "xlsx", "odt", "docx", "odp", "pptx"],
|
||||
first: first,
|
||||
}, importXLSXFile);
|
||||
var $importXLSX = UIElements.getEntryFromButton($importXLSXButton);
|
||||
// tag button
|
||||
var $hashtagButton = common.createButton('hashtag', true);
|
||||
var $hashtag = UIElements.getEntryFromButton($hashtagButton);
|
||||
$importXLSX.appendTo(toolbar.$drawer);
|
||||
common.createButton('hashtag', true).appendTo(toolbar.$drawer);
|
||||
$hashtag.appendTo(toolbar.$drawer);
|
||||
}
|
||||
|
||||
var $store = common.createButton('storeindrive', true);
|
||||
toolbar.$drawer.append($store);
|
||||
|
||||
var $forget = common.createButton('forget', true, {}, function (err) {
|
||||
// Move to trash button
|
||||
var $forgetButton = common.createButton('forget', true, {}, function (err) {
|
||||
if (err) { return; }
|
||||
setEditable(false);
|
||||
});
|
||||
var $forget = UIElements.getEntryFromButton($forgetButton);
|
||||
toolbar.$drawer.append($forget);
|
||||
|
||||
if (!privateData.isEmbed) {
|
||||
var helpMenu = APP.helpMenu = common.createHelpMenu(['beta', 'oo']);
|
||||
$('#cp-app-oo-editor').prepend(common.getBurnAfterReadingWarning());
|
||||
$('#cp-app-oo-editor').prepend(helpMenu.menu);
|
||||
toolbar.$drawer.append(helpMenu.button);
|
||||
var $helpMenuButton = UIElements.getEntryFromButton(helpMenu.button);
|
||||
toolbar.$drawer.append($helpMenuButton);
|
||||
}
|
||||
|
||||
var $properties = common.createButton('properties', true);
|
||||
var $propertiesButton = common.createButton('properties', true);
|
||||
var $properties = UIElements.getEntryFromButton($propertiesButton);
|
||||
toolbar.$drawer.append($properties);
|
||||
|
||||
var $copy = common.createButton('copy', true);
|
||||
|
||||
var $copyButton = common.createButton('copy', true);
|
||||
var $copy = UIElements.getEntryFromButton($copyButton);
|
||||
toolbar.$drawer.append($copy);
|
||||
};
|
||||
|
||||
|
||||
@ -710,7 +710,7 @@ define([
|
||||
|
||||
var setFileExporter = function (extension, fe, async) {
|
||||
fileExporter = fe;
|
||||
var $export = common.createButton('export', true, {}, function () {
|
||||
var $exportButton = common.createButton('export', true, {}, function () {
|
||||
var ext = (typeof(extension) === 'function') ? extension() : extension;
|
||||
var suggestion = title.suggestTitle('cryptpad-document');
|
||||
ext = ext || '.txt';
|
||||
@ -774,6 +774,7 @@ define([
|
||||
});
|
||||
$select.find('button').addClass('btn');
|
||||
});
|
||||
var $export = UIElements.getEntryFromButton($exportButton);
|
||||
toolbar.$drawer.append($export);
|
||||
};
|
||||
|
||||
@ -803,9 +804,9 @@ define([
|
||||
onLocal();
|
||||
});
|
||||
};
|
||||
toolbar.$drawer.append(
|
||||
common.createButton('import', true, options, fileImporter)
|
||||
);
|
||||
var $importButton = common.createButton('import', true, options, fileImporter);
|
||||
var $import = UIElements.getEntryFromButton($importButton);
|
||||
toolbar.$drawer.append($import);
|
||||
};
|
||||
|
||||
var feedback = function (action, force) {
|
||||
@ -998,21 +999,26 @@ define([
|
||||
},
|
||||
$toolbar: $(toolbarContainer)
|
||||
};
|
||||
var $hist = common.createButton('history', true, {histConfig: histConfig});
|
||||
var $histButton = common.createButton('history', true, {histConfig: histConfig});
|
||||
var $hist = UIElements.getEntryFromButton($histButton);
|
||||
toolbar.$drawer.append($hist);
|
||||
|
||||
var $snapshot = common.createButton('snapshots', true, {
|
||||
var $snapshotButton = common.createButton('snapshots', true, {
|
||||
remove: deleteSnapshot,
|
||||
make: makeSnapshot,
|
||||
load: loadSnapshot
|
||||
});
|
||||
var $snapshot = UIElements.getEntryFromButton($snapshotButton);
|
||||
toolbar.$drawer.append($snapshot);
|
||||
|
||||
var $copy = common.createButton('copy', true);
|
||||
|
||||
var $copyButton = common.createButton('copy', true);
|
||||
var $copy = UIElements.getEntryFromButton($copyButton);
|
||||
toolbar.$drawer.append($copy);
|
||||
|
||||
var $store = common.createButton('storeindrive', true);
|
||||
toolbar.$drawer.append($store);
|
||||
var $storeButton = UIElements.getEntryFromButton($store);
|
||||
toolbar.$drawer.append($storeButton);
|
||||
|
||||
if (!cpNfInner.metadataMgr.getPrivateData().isTemplate) {
|
||||
var templateObj = {
|
||||
@ -1020,26 +1026,34 @@ define([
|
||||
getTitle: function () { return cpNfInner.metadataMgr.getMetadata().title; }
|
||||
};
|
||||
var $templateButton = common.createButton('template', true, templateObj);
|
||||
toolbar.$drawer.append($templateButton);
|
||||
var $template = UIElements.getEntryFromButton($templateButton);
|
||||
toolbar.$drawer.append($template);
|
||||
|
||||
}
|
||||
|
||||
var $importTemplateButton = common.createButton('importtemplate', true);
|
||||
if (!readOnly) {
|
||||
toolbar.$drawer.append($importTemplateButton);
|
||||
var $importTemplate = UIElements.getEntryFromButton($importTemplateButton);
|
||||
toolbar.$drawer.append($importTemplate);
|
||||
}
|
||||
|
||||
/* add a forget button */
|
||||
toolbar.$drawer.append(common.createButton('forget', true, {}, function (err) {
|
||||
/* add a forget button = trash button */
|
||||
var $forgetButton = common.createButton('forget', true, {}, function (err) {
|
||||
if (err) { return; }
|
||||
stateChange(STATE.FORGOTTEN);
|
||||
}));
|
||||
});
|
||||
var $forget = UIElements.getEntryFromButton($forgetButton);
|
||||
toolbar.$drawer.append($forget);
|
||||
|
||||
|
||||
if (common.isLoggedIn()) {
|
||||
var $tags = common.createButton('hashtag', true);
|
||||
var $tagsButton = common.createButton('hashtag', true);
|
||||
var $tags = UIElements.getEntryFromButton($tagsButton);
|
||||
toolbar.$drawer.append($tags);
|
||||
}
|
||||
|
||||
var $properties = common.createButton('properties', true);
|
||||
var $propertiesButton = common.createButton('properties', true);
|
||||
var $properties = UIElements.getEntryFromButton($propertiesButton);
|
||||
toolbar.$drawer.append($properties);
|
||||
|
||||
createFilePicker();
|
||||
|
||||
@ -13,7 +13,8 @@ define([
|
||||
'/common/common-util.js',
|
||||
'/common/text-cursor.js',
|
||||
'/components/chainpad/chainpad.dist.js',
|
||||
], function ($, Modes, Themes, Messages, UIElements, MT, Hash, Util, TextCursor, ChainPad) {
|
||||
'/common/hyperscript.js',
|
||||
], function ($, Modes, Themes, Messages, UIElements, MT, Hash, Util, TextCursor, ChainPad, h) {
|
||||
var module = {};
|
||||
|
||||
var cursorToPos = module.cursorToPos = function(cursor, oldText) {
|
||||
@ -274,6 +275,7 @@ define([
|
||||
module.handleImagePaste(editor);
|
||||
|
||||
var setMode = exp.setMode = function (mode, cb) {
|
||||
if (!mode) { return; }
|
||||
exp.highlightMode = mode;
|
||||
if (mode === 'markdown') { mode = 'gfm'; }
|
||||
if (/text\/x/.test(mode)) {
|
||||
@ -293,9 +295,11 @@ define([
|
||||
editor.setOption('mode', mode);
|
||||
}
|
||||
if (exp.$language) {
|
||||
var name = exp.$language.find('a[data-value="' + mode + '"]').text() || undefined;
|
||||
var name = exp.$language.$menu.find('a[data-value="' + mode + '"]').text() || undefined;
|
||||
name = name ? Messages.languageButton + ' ('+name+')' : Messages.languageButton;
|
||||
exp.$language.setValue(mode, name);
|
||||
exp.$language.find('span.cp-language-text').text(name);
|
||||
exp.$language.find('span.cp-language-text').prepend('<i class="fa fa-chevron-right"></i>');
|
||||
}
|
||||
|
||||
if (mode === "orgmode") {
|
||||
@ -340,6 +344,8 @@ define([
|
||||
var name = theme || undefined;
|
||||
name = name ? Messages.themeButton + ' ('+theme+')' : Messages.themeButton;
|
||||
$select.setValue(theme, name);
|
||||
$select.find('span.cp-theme-text').text(name);
|
||||
$select.find('span.cp-theme-text').prepend('<i class="fa fa-chevron-right"></i>');
|
||||
}
|
||||
};
|
||||
}());
|
||||
@ -364,31 +370,45 @@ define([
|
||||
text: Messages.languageButton, // Button initial text
|
||||
options: options, // Entries displayed in the menu
|
||||
isSelect: true,
|
||||
isSubmenuOf: $drawer,
|
||||
feedback: 'CODE_LANGUAGE',
|
||||
common: Common
|
||||
};
|
||||
var $block = exp.$language = UIElements.createDropdown(dropdownConfig);
|
||||
$block.find('button').attr('title', Messages.languageButtonTitle);
|
||||
$block.find('button').attr('title', Messages.languageButtonTitle).hide();
|
||||
$block.prepend(h('span.cp-language-text', Messages.languageButton));
|
||||
|
||||
var isHovering = false;
|
||||
var $aLanguages = $block.find('li');
|
||||
var $aLanguages = $block.$menu.find('li');
|
||||
$aLanguages.mouseenter(function () {
|
||||
isHovering = true;
|
||||
setMode($(this).find('a').attr('data-value'));
|
||||
});
|
||||
$aLanguages.mouseleave(function () {
|
||||
if (isHovering) {
|
||||
setMode($block.find(".cp-dropdown-element-active").attr('data-value'));
|
||||
setMode($block.$menu.find(".cp-dropdown-element-active").attr('data-value'));
|
||||
}
|
||||
});
|
||||
$aLanguages.click(function () {
|
||||
//$aLanguages.click(function () {
|
||||
$block.onChange.reg(() => {
|
||||
isHovering = false;
|
||||
var mode = $(this).find('a').attr('data-value');
|
||||
var mode = $block.getValue();
|
||||
setMode(mode, onModeChanged);
|
||||
$block.close();
|
||||
onLocal();
|
||||
});
|
||||
|
||||
if ($drawer) { $drawer.append($block); }
|
||||
if ($drawer) {
|
||||
var $blockButton = UIElements.createDropdownEntry({
|
||||
tag: 'a',
|
||||
content: $block[0],
|
||||
action: function () {
|
||||
$block.find('button').click();
|
||||
},
|
||||
});
|
||||
dropdownConfig.$parentButton = $blockButton;
|
||||
$drawer.append($blockButton);
|
||||
}
|
||||
if (exp.highlightMode) { exp.setMode(exp.highlightMode); }
|
||||
if (cb) { cb(); }
|
||||
};
|
||||
@ -416,24 +436,27 @@ define([
|
||||
text: Messages.code_editorTheme, // Button initial text
|
||||
options: options, // Entries displayed in the menu
|
||||
isSelect: true,
|
||||
isSubmenuOf: $drawer,
|
||||
initialValue: lastTheme,
|
||||
feedback: 'CODE_THEME',
|
||||
common: Common
|
||||
};
|
||||
var $block = exp.$theme = UIElements.createDropdown(dropdownConfig);
|
||||
$block.find('button').attr('title', Messages.themeButtonTitle).click(function () {
|
||||
/*$block.find('button').attr('title', Messages.themeButtonTitle).click(function () {
|
||||
var state = $block.find('.cp-dropdown-content').is(':visible');
|
||||
var $c = $block.closest('.cp-toolbar-drawer-content');
|
||||
$c.removeClass('cp-dropdown-visible');
|
||||
if (!state) {
|
||||
$c.addClass('cp-dropdown-visible');
|
||||
}
|
||||
});
|
||||
});*/
|
||||
$block.find('button').hide();
|
||||
$block.prepend(h('span.cp-theme-text', Messages.languageButton));
|
||||
|
||||
setTheme(lastTheme, $block);
|
||||
|
||||
var isHovering = false;
|
||||
var $aThemes = $block.find('li');
|
||||
var $aThemes = $block.$menu.find('li');
|
||||
$aThemes.mouseenter(function () {
|
||||
isHovering = true;
|
||||
var theme = $(this).find('a').attr('data-value');
|
||||
@ -445,14 +468,24 @@ define([
|
||||
Common.setAttribute(themeKey, lastTheme);
|
||||
}
|
||||
});
|
||||
$aThemes.click(function () {
|
||||
$block.onChange.reg(() => {
|
||||
isHovering = false;
|
||||
var theme = $(this).find('a').attr('data-value');
|
||||
var theme = $block.getValue();
|
||||
setTheme(theme, $block);
|
||||
Common.setAttribute(themeKey, theme);
|
||||
});
|
||||
|
||||
if ($drawer) { $drawer.append($block); }
|
||||
if ($drawer) {
|
||||
const $blockButton = UIElements.createDropdownEntry({
|
||||
tag: 'a',
|
||||
content: $block[0],
|
||||
action: function () {
|
||||
$block.find('button').click();
|
||||
},
|
||||
});
|
||||
dropdownConfig.$parentButton = $blockButton;
|
||||
$drawer.append($blockButton);
|
||||
}
|
||||
if (cb) { cb(); }
|
||||
};
|
||||
Common.getAttribute(themeKey, todo);
|
||||
|
||||
@ -64,7 +64,7 @@ MessengerUI, Messages, Pages, PadTypes) {
|
||||
return 'cp-toolbar-uid-' + String(Math.random()).substring(2);
|
||||
};
|
||||
|
||||
var observeChildren = function ($content) {
|
||||
var observeChildren = function ($content, isDrawer) {
|
||||
var reorderDOM = Util.throttle(function ($content, observer) {
|
||||
if (!$content.length) { return; }
|
||||
|
||||
@ -73,7 +73,15 @@ MessengerUI, Messages, Pages, PadTypes) {
|
||||
$content[0].childNodes.forEach((node) => {
|
||||
try {
|
||||
if (!node.attributes) { return; }
|
||||
var order = getComputedStyle(node).getPropertyValue("order");
|
||||
let nodeWithOrder;
|
||||
if (isDrawer) { // HACK: the order is set on their inner "a" tag
|
||||
let $n = $(node);
|
||||
if (!$n.attr('class') &&
|
||||
($n.find('.fa').length || $n.find('.cptools').length)) {
|
||||
nodeWithOrder = $n.find('.fa')[0] || $n.find('.cptools')[0];
|
||||
}
|
||||
}
|
||||
var order = getComputedStyle(nodeWithOrder || node).getPropertyValue("order");
|
||||
var a = map[order] = map[order] || [];
|
||||
a.push(node);
|
||||
} catch (e) { console.error(e, node); }
|
||||
@ -102,6 +110,7 @@ MessengerUI, Messages, Pages, PadTypes) {
|
||||
});
|
||||
});
|
||||
observer.start = function () {
|
||||
if (!$content.length) { return; }
|
||||
observer.observe($content[0], {
|
||||
childList: true
|
||||
});
|
||||
@ -146,13 +155,16 @@ MessengerUI, Messages, Pages, PadTypes) {
|
||||
|
||||
var $file = $toolbar.find('.'+BOTTOM_LEFT_CLS);
|
||||
|
||||
if (!config.hideDrawer) {
|
||||
var $drawer = $(h('button.' + FILE_CLS, [
|
||||
h('i.fa.fa-file-o'),
|
||||
h('span.cp-button-name', Messages.toolbar_file)
|
||||
])).appendTo($file).hide();
|
||||
var $drawerContent = $(h('div.'+ DRAWER_CLS, {tabindex: 1})).hide();
|
||||
UI.createDrawer($drawer, $drawerContent);
|
||||
if (config.addFileMenu) {
|
||||
var $drawer = UIElements.createDropdown({
|
||||
text: Messages.toolbar_file,
|
||||
options: [],
|
||||
common: Common,
|
||||
iconCls: 'fa fa-file-o'
|
||||
}).hide();
|
||||
$drawer.addClass(FILE_CLS).appendTo($file);
|
||||
$drawer.find('.cp-dropdown-content').addClass(DRAWER_CLS);
|
||||
$drawer.find('span').addClass('cp-button-name');
|
||||
}
|
||||
|
||||
// The 'notitle' class removes the line added for the title with a small screen
|
||||
@ -283,7 +295,7 @@ MessengerUI, Messages, Pages, PadTypes) {
|
||||
var fa_editusers = '<span class="fa fa-users"></span>';
|
||||
var fa_viewusers = numberOfViewUsers === '' ? '' : '<span class="fa fa-eye"></span>';
|
||||
var $spansmall = $('<span>').html(fa_editusers + ' ' + numberOfEditUsers + ' ' + fa_viewusers + ' ' + numberOfViewUsers);
|
||||
$userButtons.find('.cp-dropdown-button-title').html('').append($spansmall);
|
||||
$userButtons.find('.cp-toolbar-userlist-button').html('').append($spansmall);
|
||||
|
||||
if (!online || toolbar.isDeleted) { return; }
|
||||
|
||||
@ -462,7 +474,7 @@ MessengerUI, Messages, Pages, PadTypes) {
|
||||
var $container = $('<span>', {id: 'cp-toolbar-userlist-drawer-open', title: Messages.userListButton});
|
||||
|
||||
var $button = $('<button>').appendTo($container);
|
||||
$('<span>',{'class': 'cp-dropdown-button-title'}).appendTo($button);
|
||||
$('<span>',{'class': 'cp-toolbar-userlist-button'}).appendTo($button);
|
||||
|
||||
toolbar.$bottomR.prepend($container);
|
||||
|
||||
@ -998,8 +1010,9 @@ MessengerUI, Messages, Pages, PadTypes) {
|
||||
|
||||
var createNewPad = function (toolbar) {
|
||||
var $button = Common.createButton('newpad', true);
|
||||
toolbar.$drawer.append($button);
|
||||
return $button;
|
||||
var $newPad = UIElements.getEntryFromButton($button);
|
||||
toolbar.$drawer.append($newPad);
|
||||
return $newPad;
|
||||
};
|
||||
|
||||
var createUserAdmin = function (toolbar, config) {
|
||||
@ -1353,6 +1366,10 @@ MessengerUI, Messages, Pages, PadTypes) {
|
||||
toolbar.connected = false;
|
||||
toolbar.firstConnection = true;
|
||||
|
||||
if (Array.isArray(cfg.displayed) && cfg.displayed.includes('pad')) {
|
||||
cfg.addFileMenu = true;
|
||||
}
|
||||
|
||||
var $toolbar = toolbar.$toolbar = createRealtimeToolbar(config);
|
||||
toolbar.$bottom = $toolbar.find('.'+Bar.constants.bottom);
|
||||
toolbar.$bottomL = $toolbar.find('.'+Bar.constants.bottomL);
|
||||
@ -1366,7 +1383,7 @@ MessengerUI, Messages, Pages, PadTypes) {
|
||||
toolbar.$history = $toolbar.find('.'+Bar.constants.history);
|
||||
toolbar.$user = $toolbar.find('.'+Bar.constants.userAdmin);
|
||||
|
||||
observeChildren(toolbar.$drawer);
|
||||
observeChildren(toolbar.$drawer, true);
|
||||
observeChildren(toolbar.$bottomL);
|
||||
observeChildren(toolbar.$bottomM);
|
||||
observeChildren(toolbar.$bottomR);
|
||||
|
||||
@ -4645,8 +4645,9 @@ define([
|
||||
var $toolbarContainer = $('#cp-toolbar');
|
||||
|
||||
var helpMenu = framework._.sfCommon.createHelpMenu(['text', 'pad']);
|
||||
var $helpMenuButton = UIElements.getEntryFromButton(helpMenu.button);
|
||||
$toolbarContainer.after(helpMenu.menu);
|
||||
framework._.toolbar.$drawer.append(helpMenu.button);
|
||||
framework._.toolbar.$drawer.append($helpMenuButton);
|
||||
if (!APP.isEditor && !priv.form_auditorKey) {
|
||||
$(helpMenu.menu).hide();
|
||||
}
|
||||
|
||||
@ -1118,11 +1118,13 @@ define([
|
||||
var $toolbarContainer = $('#cp-app-kanban-container');
|
||||
|
||||
var helpMenu = framework._.sfCommon.createHelpMenu(['kanban']);
|
||||
$toolbarContainer.prepend(helpMenu.menu);
|
||||
|
||||
framework._.toolbar.$drawer.append(helpMenu.button);
|
||||
var $helpMenuButton = UIElements.getEntryFromButton(helpMenu.button);
|
||||
$toolbarContainer.prepend(helpMenu.menu);
|
||||
framework._.toolbar.$drawer.append($helpMenuButton);
|
||||
};
|
||||
|
||||
|
||||
// Start of the main loop
|
||||
var andThen2 = function (framework) {
|
||||
|
||||
|
||||
@ -345,15 +345,19 @@ define([
|
||||
}, function () {
|
||||
UI.alert(getSettings());
|
||||
});
|
||||
framework._.toolbar.$drawer.append($settingsButton);
|
||||
|
||||
var $settings = UIElements.getEntryFromButton($settingsButton);
|
||||
framework._.toolbar.$drawer.append($settings);
|
||||
|
||||
};
|
||||
|
||||
var mkHelpMenu = function(framework) {
|
||||
var $toolbarContainer = $('.cke_toolbox_main');
|
||||
var helpMenu = framework._.sfCommon.createHelpMenu(['text', 'pad']);
|
||||
$toolbarContainer.before(helpMenu.menu);
|
||||
var $helpMenuButton = UIElements.getEntryFromButton(helpMenu.button);
|
||||
|
||||
framework._.toolbar.$drawer.append(helpMenu.button);
|
||||
$toolbarContainer.before(helpMenu.menu);
|
||||
framework._.toolbar.$drawer.append($helpMenuButton);
|
||||
};
|
||||
|
||||
var mkDiffOptions = function(cursor, readOnly) {
|
||||
@ -632,7 +636,8 @@ define([
|
||||
editor.execCommand('print');
|
||||
framework.feedback('PRINT_PAD');
|
||||
});
|
||||
framework._.toolbar.$drawer.append($printButton);
|
||||
var $print = UIElements.getEntryFromButton($printButton);
|
||||
framework._.toolbar.$drawer.append($print);
|
||||
};
|
||||
|
||||
var andThen2 = function(editor, Ckeditor, framework) {
|
||||
|
||||
@ -16,6 +16,7 @@ define([
|
||||
'/common/hyperscript.js',
|
||||
'/customize/messages.js',
|
||||
'cm/lib/codemirror',
|
||||
'/common/common-ui-elements.js',
|
||||
|
||||
'css!/components/bootstrap/dist/css/bootstrap.min.css',
|
||||
'css!/components/components-font-awesome/css/font-awesome.min.css',
|
||||
@ -61,7 +62,8 @@ define([
|
||||
UI,
|
||||
h,
|
||||
Messages,
|
||||
CMeditor)
|
||||
CMeditor,
|
||||
UIElements)
|
||||
{
|
||||
window.CodeMirror = CMeditor;
|
||||
|
||||
@ -106,19 +108,15 @@ define([
|
||||
};
|
||||
|
||||
var mkThemeButton = function (framework) {
|
||||
var $theme = $(h('button.cp-toolbar-appmenu', [
|
||||
h('i.cptools.cptools-palette'),
|
||||
h('span.cp-button-name', Messages.toolbar_theme)
|
||||
]));
|
||||
var $content = $(h('div.cp-toolbar-drawer-content', {
|
||||
tabindex: 1
|
||||
})).hide();
|
||||
|
||||
// set up all the necessary events
|
||||
UI.createDrawer($theme, $content);
|
||||
|
||||
framework._.toolbar.$theme = $content;
|
||||
framework._.toolbar.$bottomL.append($theme);
|
||||
const $drawer = UIElements.createDropdown({
|
||||
text: Messages.toolbar_theme,
|
||||
options: [],
|
||||
common: framework._.sfCommon,
|
||||
iconCls: 'cptools cptools-palette'
|
||||
});
|
||||
framework._.toolbar.$theme = $drawer.find('ul.cp-dropdown-content');
|
||||
framework._.toolbar.$bottomL.append($drawer);
|
||||
$drawer.addClass('cp-toolbar-appmenu');
|
||||
};
|
||||
|
||||
var mkPrintButton = function (framework, editor, $content, $print) {
|
||||
@ -130,7 +128,8 @@ define([
|
||||
window.print();
|
||||
framework.feedback('PRINT_SLIDES');
|
||||
});
|
||||
framework._.toolbar.$drawer.append($printButton);
|
||||
var $printEntry = UIElements.getEntryFromButton($printButton);
|
||||
framework._.toolbar.$drawer.append($printEntry);
|
||||
};
|
||||
|
||||
// Flag to check if a file from the filepicker is a mediatag for the slides or a background image
|
||||
@ -325,12 +324,13 @@ define([
|
||||
title: Messages.slideOptionsTitle,
|
||||
hiddenReadOnly: true,
|
||||
text: Messages.slideOptionsText,
|
||||
name: 'options'
|
||||
name: 'options',
|
||||
callback: function () {
|
||||
$('body').append(createPrintDialog());
|
||||
}
|
||||
});
|
||||
$optionsButton.click(function () {
|
||||
$('body').append(createPrintDialog());
|
||||
});
|
||||
framework._.toolbar.$theme.append($optionsButton);
|
||||
var $options = UIElements.getEntryFromButton($optionsButton);
|
||||
framework._.toolbar.$theme.append($options);
|
||||
|
||||
metadataMgr.onChange(function () {
|
||||
var md = metadataMgr.getMetadata();
|
||||
@ -385,6 +385,7 @@ define([
|
||||
$backgroundPicker.val(backColor);
|
||||
$backgroundPicker.click();
|
||||
});
|
||||
var $backButton = UIElements.getEntryFromButton($back);
|
||||
|
||||
var $foregroundPicker = $('<input>', { type: 'color', value: textColor })
|
||||
.css({ display: 'none', })
|
||||
@ -400,13 +401,15 @@ define([
|
||||
$foregroundPicker.val(textColor);
|
||||
$foregroundPicker.click();
|
||||
});
|
||||
|
||||
var $textButton = UIElements.getEntryFromButton($text);
|
||||
var $testColor = $('<input>', { type: 'color', value: '!' });
|
||||
if ($testColor.attr('type') !== "color" || $testColor.val() === '!') { return; }
|
||||
|
||||
$check.append($backgroundPicker);
|
||||
$check.append($foregroundPicker);
|
||||
|
||||
framework._.toolbar.$theme.append($text).append($back);
|
||||
framework._.toolbar.$theme.append($textButton).append($backButton);
|
||||
|
||||
metadataMgr.onChange(function () {
|
||||
var md = metadataMgr.getMetadata();
|
||||
@ -436,9 +439,9 @@ define([
|
||||
var mkHelpMenu = function (framework) {
|
||||
var $codeMirrorContainer = $('#cp-app-slide-editor-container');
|
||||
var helpMenu = framework._.sfCommon.createHelpMenu(['text', 'slide']);
|
||||
var $helpMenuButton = UIElements.getEntryFromButton(helpMenu.button);
|
||||
$codeMirrorContainer.prepend(helpMenu.menu);
|
||||
|
||||
framework._.toolbar.$drawer.append(helpMenu.button);
|
||||
framework._.toolbar.$drawer.append($helpMenuButton);
|
||||
};
|
||||
|
||||
var activateLinks = function ($content, framework) {
|
||||
|
||||
@ -17,6 +17,7 @@ define([
|
||||
'/whiteboard/colors.js',
|
||||
'/customize/application_config.js',
|
||||
'/components/chainpad/chainpad.dist.js',
|
||||
'/common/common-ui-elements.js',
|
||||
|
||||
'/lib/fabric.min.js',
|
||||
'less!/whiteboard/app-whiteboard.less'
|
||||
@ -34,7 +35,8 @@ define([
|
||||
Messages,
|
||||
Colors,
|
||||
AppConfig,
|
||||
ChainPad)
|
||||
ChainPad,
|
||||
UIElements)
|
||||
{
|
||||
|
||||
var APP = window.APP = {
|
||||
@ -295,8 +297,10 @@ define([
|
||||
var mkHelpMenu = function (framework) {
|
||||
var $appContainer = $('#cp-app-whiteboard-container');
|
||||
var helpMenu = framework._.sfCommon.createHelpMenu(['whiteboard']);
|
||||
|
||||
var $helpMenuButton = UIElements.getEntryFromButton(helpMenu.button);
|
||||
$appContainer.prepend(helpMenu.menu);
|
||||
framework._.toolbar.$drawer.append(helpMenu.button);
|
||||
framework._.toolbar.$drawer.append($helpMenuButton);
|
||||
};
|
||||
|
||||
// Start of the main loop
|
||||
@ -431,13 +435,19 @@ define([
|
||||
});
|
||||
|
||||
// Export to drive as PNG
|
||||
framework._.sfCommon.createButton('savetodrive', true, {}).click(function () {
|
||||
var defaultName = framework._.title.getTitle();
|
||||
UI.prompt(Messages.exportPrompt, defaultName + '.png', function (name) {
|
||||
if (name === null || !name.trim()) { return; }
|
||||
APP.upload(name);
|
||||
});
|
||||
}).appendTo($drawer);
|
||||
var $saveToDriveButton = framework._.sfCommon.createButton('savetodrive', true, {
|
||||
callback: function () {
|
||||
var defaultName = framework._.title.getTitle()
|
||||
|| framework._.title.defaultTitle;
|
||||
UI.prompt(Messages.exportPrompt, defaultName + '.png', function (name) {
|
||||
if (name === null || !name.trim()) { return; }
|
||||
APP.upload(name);
|
||||
});
|
||||
}
|
||||
});
|
||||
var $saveToDrive = UIElements.getEntryFromButton($saveToDriveButton);
|
||||
$saveToDrive.appendTo($drawer);
|
||||
|
||||
} else {
|
||||
framework._.sfCommon.createButton('', true, {
|
||||
title: Messages.canvas_imageEmbed,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user