+import Sortable from 'sortablejs';
+
function LinkeditorAccessibility(linkeditor) {
this.linkeditor = linkeditor;
}
this.container = $("#linkeditor-panel-accessibility");
this.maskCheckEvents = false;
+ this.sortable = false;
+
$(document).on('click', '#linkeditor-panel-accessibility label span.uid', function () {
navigator.clipboard.writeText($(this).attr('fb-uid'));
let tippy = $(this).data('tippyinstance');
},
reorderSelection: function (way) {
- let selection = this.getCurrentOrderableSelection();
- let selectedOrder = parseInt($(selection).eq(0).attr('fb-order'));
- selection = this.orderLinksByPosition(selection, way);
- $(selection).each(function () {
- $(this).attr('fb-order', selectedOrder++);
+ return this.reorderLinks(this.getCurrentOrderableSelection(), way);
+ },
+
+ reorderLinks: function (links, way) {
+ let selectedOrder = parseInt($(links).eq(0).attr('fb-order'));
+ links = this.orderLinksByPosition(links, way);
+ let step = 1 / (links.length + 1);
+ $(links).each(function () {
+ let s = selectedOrder += step;
+ $(this).attr('fb-order', s);
});
this.normalizeLinksOrder();
},
+ reorderPageLinks: function (way) {
+ return this.reorderLinks(this.getOrderableLinksOnPage(), way);
+ },
+
+ reorderAllLinks: function (way) {
+ let $this = this;
+ let step = this.linkeditor.single ? 1 : 2;
+ for (let i = 0; i < FLUIDBOOK_DATA.settings.pages; i += step) {
+ let o = 0;
+ let links = this.orderLinksByPosition(this.getOrderableLinksOnPage(i), way);
+ $.each(links, function (k, v) {
+ LINKS[v.uid].order = o++;
+ if (i === $this.linkeditor.getCurrentPage()) {
+ $('.link[fb-uid="' + v.uid + '"]').attr('fb-order', o);
+ }
+ });
+ this.linkeditor.hasChanged();
+ }
+ this.normalizeLinksOrder(true);
+ },
+
moveSelectionOrder: function (way) {
let start;
let selection = this.getCurrentOrderableSelection();
+ console.log(selection);
let num = selection.length;
if (num <= 0) {
return;
}
let firstSelected = $(selection).get(0);
- let firstSelectedOrder = parseInt($(firstSelected).attr('fb-order'));
+ let firstSelectedOrder = parseFloat($(firstSelected).attr('fb-order'));
let max = this.getOrderableLinksOnPage().length + 1;
let step = 1 / (num + 1);
switch (way) {
case'start':
start = -num;
- step = -1;
break;
case'end':
start = max;
- step = 1;
break;
case'up':
start = firstSelectedOrder - 1 - step;
- step *= -1;
break;
case'down':
start = firstSelectedOrder + 1 + step;
this.normalizeLinksOrder();
},
- getOrderableLinksOnPage: function () {
- return this.filterOrderableLinks(this.linkeditor.links.getLinksOfCurrentPage());
+ getOrderableLinksOnPage: function (page) {
+ let links;
+ if (page === undefined) {
+ links = this.linkeditor.links.getLinksOfCurrentPage();
+ } else {
+ links = this.linkeditor.links.getLinksOfPage(page);
+ }
+
+ return this.filterOrderableLinks(links);
},
+
filterOrderableLinks: function (links) {
let res = [];
$.each(links, function () {
},
orderLinks: function (links) {
- return $(links).toArray().sort(function (a, b) {
- return parseInt($(a).attr('fb-order')) - parseInt($(b).attr('fb-order'));
+ let arr = links;
+ if (links instanceof jQuery) {
+ arr = $(links).toArray();
+ }
+ return arr.sort(function (a, b) {
+ return parseFloat($(a).attr('fb-order')) - parseFloat($(b).attr('fb-order'));
});
},
orderLinksByPosition: function (links, way) {
+ let $this = this;
let doublePage = !this.linkeditor.single && !this.linkeditor.utils.isSpecialPage(this.linkeditor.currentPage);
let pw = this.linkeditor.pw;
return $(links).toArray().sort(function (a, b) {
- let pa = 0;
- let pb = 0;
- let xa = parseFloat($(a).attr('fb-left'));
- let xb = parseFloat($(b).attr('fb-left'));
+ let ca = $this.getLinkDimensions(a);
+ let cb = $this.getLinkDimensions(b);
+
+ let pa = ca.page;
+ let pb = cb.page;
+ let xa = ca.x;
+ let xb = cb.x;
if (doublePage) {
if (xa >= pw) {
xa -= pw;
}
- let wa = parseFloat($(a).attr('fb-width'));
- let wb = parseFloat($(b).attr('fb-width'));
+ let wa = ca.width;
+ let wb = cb.width;
let xTolerance = Math.min(wa, wb) / 2;
- let ha = parseFloat($(a).attr('fb-height'));
- let hb = parseFloat($(b).attr('fb-height'));
+ let ha = ca.height;
+ let hb = cb.height;
let yTolerance = Math.min(ha, hb) / 2;
xa += wa / 2;
xb += wb / 2;
- let ya = parseFloat($(a).attr('fb-top')) + ha / 2;
- let yb = parseFloat($(b).attr('fb-top')) + hb / 2;
+ let ya = ca.y + ha / 2;
+ let yb = cb.y + hb / 2;
let xdiff = xa - xb;
let ydiff = ya - yb;
});
},
+ getLinkDimensions: function (link) {
+ if (link.left !== undefined) {
+ return {
+ x: parseFloat(link.left),
+ y: parseFloat(link.top),
+ width: parseFloat(link.width),
+ height: parseFloat(link.height),
+ page: parseInt(link.page),
+ }
+ } else {
+ return {
+ x: parseFloat($(link).attr('fb-left')),
+ y: parseFloat($(link).attr('fb-top')),
+ width: parseFloat($(link).attr('fb-width')),
+ height: parseFloat($(link).attr('fb-height')),
+ page: $(link).attr('fb-page'),
+ };
+ }
+ },
+
getCurrentOrderableSelection: function () {
return this.filterOrderableLinks(this.linkeditor.links.getCurrentSelection());
},
let links = [];
$('#linkeditor-links .link:not(.pendingCreate)').each(function () {
let level = $this.getLinkLevel($(this));
- links.push({link: $(this), interactive: level >= 5, order: parseInt($(this).attr('fb-order'),)});
+ links.push({link: $(this), interactive: level >= 5, order: parseFloat($(this).attr('fb-order'),)});
});
links.sort(function (a, b) {
return;
}
var $this = this;
- this.container.html('');
+ this.container.addClass('toolbar-top').addClass('toolbar-bottom');
+ this.container.html(this.getTopToolbar() + '<div class="linkeditor-panel-wrapper"></div>');
+ let wrapper = this.container.find('.linkeditor-panel-wrapper');
var accessibility = [];
this.normalizeLinksOrder(false);
$(this.orderLinks(this.linkeditor.links.getLinksOfCurrentPage())).each(function () {
l += dest;
if (interactive) {
l += '<span class="order">#' + $(this).attr('fb-order') + '</span>';
+ l += '<span class="drag">' + getSpriteIcon('linkeditor-drag-drop') + '</span>';
}
l += '</label>';
l += '</div>';
var seenLevels = {};
$.each(accessibility, function (k, v) {
+ let wrapperClass = 'order' + (v.interactive ? '-interactive' : '-noninteractive') + '-wrapper';
if (seenLevels[v.interactive] === undefined) {
seenLevels[v.interactive] = true;
- $this.container.append('<h3>' + (v.interactive ? TRANSLATIONS.interactive_links : TRANSLATIONS.noninteractive_links) + '</h3>');
+ wrapper.append('<h3>' + (v.interactive ? TRANSLATIONS.interactive_links : TRANSLATIONS.noninteractive_links) + '</h3><div class="' + wrapperClass + '"></div>');
}
- $this.container.append(v.html);
+ $this.container.find('.' + wrapperClass).append(v.html);
});
+ this.container.append(this.getBottomToolbar());
+
+ let sortableWrapper = $('.order-interactive-wrapper').get(0);
+ try {
+ this.sortable.destroy();
+ } catch (e) {
+
+ }
+ if ($('.order-interactive-wrapper').length > 0) {
+ this.sortable = Sortable.create(sortableWrapper, {
+ handle: '.drag', onSort: function (e) {
+ let i = 0;
+ $(sortableWrapper).find('div.layer').each(function () {
+ let uid = $(this).find('label.layer').data('uid');
+ let link = $('#linkeditor-links .link[fb-uid="' + uid + '"]');
+ $(link).attr('fb-order', i++);
+ });
+ $this.normalizeLinksOrder();
+ },
+ });
+ }
this.updateSelection();
this.linkeditor.initTooltips();
this.linkeditor.initIcons();
},
+ getTopToolbar: function () {
+ let res = '<div class="linkeditor-toolbar linkeditor-panel-toolbar linkeditor-panel-toolbar-top"><nav>';
+ res += '<a href="#" data-icon="order-horizontal" data-action="accessibility.reorderPageLinks" data-action-args="lines" data-tooltip="' + TRANSLATIONS.order_page_lines + '"></a>';
+ res += '<a href="#" data-icon="order-vertical" data-action="accessibility.reorderPageLinks" data-action-args="columns" data-tooltip="' + TRANSLATIONS.order_page_columns + '"></a>';
+ res += '<div class="separator"></div>';
+ res += '<a href="#" data-icon="order-horizontal-all" data-action="accessibility.reorderAllLinks" data-action-args="lines" data-tooltip="' + TRANSLATIONS.order_all_lines + '"></a>';
+ res += '<a href="#" data-icon="order-vertical-all" data-action="accessibility.reorderAllLinks" data-action-args="columns" data-tooltip="' + TRANSLATIONS.order_all_columns + '"></a>';
+ res += '</nav></div>';
+ return res;
+ },
+
+ getBottomToolbar: function () {
+ let res = '<div class="linkeditor-toolbar linkeditor-panel-toolbar linkeditor-panel-toolbar-bottom"><nav>';
+ res += '<a href="#" data-icon="order-horizontal" data-action="accessibility.reorderSelection" data-action-args="lines" data-tooltip="' + TRANSLATIONS.reorder_selection_lines + '"></a>';
+ res += '<a href="#" data-icon="order-vertical" data-action="accessibility.reorderSelection" data-action-args="columns" data-tooltip="' + TRANSLATIONS.reorder_selection_columns + '"></a>';
+ res += '<div class="separator"></div>';
+ res += '<a href="#" data-icon="move-start" data-action="accessibility.moveSelectionOrder" data-action-args="start" data-tooltip="' + TRANSLATIONS.move_order_start + '"></a>';
+ res += '<a href="#" data-icon="move-up" data-action="accessibility.moveSelectionOrder" data-action-args="up" data-tooltip="' + TRANSLATIONS.move_order_up + '"></a>';
+ res += '<a href="#" data-icon="move-down" data-action="accessibility.moveSelectionOrder" data-action-args="down" data-tooltip="' + TRANSLATIONS.move_order_down + '"></a>';
+ res += '<a href="#" data-icon="move-end" data-action="accessibility.moveSelectionOrder" data-action-args="end" data-tooltip="' + TRANSLATIONS.move_order_end + '"></a>';
+ res += '</nav></div>';
+ return res;
+ },
+
updateSelection() {
this.linkeditor.panels.updatePanelSelection(this);
+ let l=this.getCurrentOrderableSelection().length;
+ if(l<1){
+ $('[data-action="accessibility.moveSelectionOrder"]').addClass('disabled');
+ } else {
+ $('[data-action="accessibility.moveSelectionOrder"]').removeClass('disabled');
+ }
+ if (l < 2) {
+ $('[data-action="accessibility.reorderSelection"]').addClass('disabled');
+ } else {
+ $('[data-action="accessibility.reorderSelection"]').removeClass('disabled');
+ }
},
resize: function () {
import Noty from "noty";
import GrahamScan from "@lucio/graham-scan";
+
import LinkeditorLinks from './linkeditor.links';
import LinkeditorLoader from './linkeditor.loader';
import LinkeditorResize from './linkeditor.resize';
}
let change = false;
if (link.order === undefined) {
- console.log('link.order is undefined', link);
link.order = ++this.pageMaxOrderIndex;
} else {
this.pageMaxOrderIndex = Math.max(this.pageMaxOrderIndex, link.order);
}
- console.log(link.order);
if (link.uid === undefined) {
link.uid = this.linkeditor.utils.generateUID();
change = true;
if (change) {
LINKS[link.uid] = link;
}
-
link.origuid = link.uid;
let $this = this;
uid = $(this).attr('fb-uid');
l = this;
}
- console.log(uid, props);
for (let i = 0; i < props.length; i++) {
let prop = props[i];
LINKS[uid][prop] = $(l).attr('fb-' + prop);
.layer
position: relative
+ &.sortable-ghost
+ opacity: 0.4
+
+ &.sortable-drag
+ visibility: hidden
+
input
color: #fff
position: absolute
padding: 2px
font-family: "Courier New", Courier, monospace
+ &.drag
+ right: 5px
+ width: 16px
+ cursor: grab
+
&[data-locked="1"]
label
pointer-events: none
@include dark-theme
background-color: #444
- nav
+ > nav
position: absolute
left: 0
width: $sidebar-icons-width
.linkeditor-panel
display: none
+
&.open
display: block
.linkeditor-panel-side
margin-left: $sidebar-handle-width
margin-right: $sidebar-icons-width
+
+.linkeditor-panel-wrapper
+ position: relative
+ max-height: 100%
+ overflow: scroll
+
+.linkeditor-panel
+ position: relative
+ height: 100%
+
+ &.toolbar-top
+ .linkeditor-panel-wrapper
+ top: 40px
+ max-height: calc(100% - 40px)
+
+ &.toolbar-bottom
+ .linkeditor-panel-wrapper
+ bottom: 40px
+ max-height: calc(100% - 40px)
+
+ &.toolbar-bottom.toolbar-top
+ .linkeditor-panel-wrapper
+ max-height: calc(100% - 80px)
+
+.linkeditor-panel-toolbar
+ position: fixed
+ left: 0
+ width: 100%
+ height: 40px
+
+ .linkeditor-panel-toolbar-top
+ top: 0
+
+ .linkeditor-panel-toolbar-bottom
+ bottom: 0
-#linkeditor-toolbar
- background-color: #dbdddf
+.linkeditor-toolbar
+ background-color: $toolbar-background-color
@include dark-theme
- background-color: #444
+ background-color: $toolbar-background-color-dark
color: $toolbar-color
@include dark-theme
height: $toolbar-height
padding: 5px
-
nav
padding: 2px
display: inline-block
top: 1px
height: 18px
width: auto
+
+ &.linkeditor-panel-toolbar
+ position: absolute
+ left: 0
+ background-color: darken($toolbar-background-color, 5%)
+
+ nav
+ width: 100%
+
+ @include dark-theme
+ background-color: lighten($toolbar-background-color-dark, 5%)
+
+ &.linkeditor-panel-toolbar-top
+ top: 0
+
+ &.linkeditor-panel-toolbar-bottom
+ bottom: 0
$toolbar-color: #5d5d5d
$toolbar-color-dark: #bbb
+$toolbar-background-color: #dbdddf
+$toolbar-background-color-dark: #444
+
$toolbar-color-disabled: #bbb
$toolbar-color-disabled-dark: #666
'reorder_selection'=>__('Réordonner la sélection'),
'reorder_lines'=>__('Par lignes'),
'reorder_columns'=>__('Par colonnes'),
+ 'reorder_selection_lines'=>__('Réordonner la sélection par lignes'),
+ 'reorder_selection_columns'=>__('Réordonner la sélection par colonnes'),
+ 'move_order_start'=>__('Déplacer la sélection au début'),
+ 'move_order_up'=>__('Remonter la sélection'),
+ 'move_order_down'=>__('Descendre la sélection'),
+ 'move_order_end'=>__('Déplacer la sélection à la fin'),
'move_up'=>__('Avant'),
'move_down'=>__('Après'),
'move_beginning'=>__('Au début'),
'move_end'=>__('À la fin'),
+ 'order_all_lines'=>__('Réordonner les liens de toute la publication par lignes'),
+ 'order_all_columns'=>__('Réordonner les liens de toute la publication par colonnes'),
+ 'order_page_lines'=>__('Réordonner les liens de la page par lignes'),
+ 'order_page_columns'=>__('Réordonner les liens de la page par colonnes'),
'select_all'=>__('Tout sélectionner'),
'error_open_image_link'=>__('Impossible d\'ajouter des liens au contenu de ce lien'),
'empty'=>__('Vide'),
<div class="handle"></div>
</aside>
<div id="linkeditor-main">
- <div draggable="false" id="linkeditor-toolbar">
+ <div draggable="false" id="linkeditor-toolbar" class="linkeditor-toolbar">
<nav id="linkeditor-toolbar-left">
<a href="#" data-icon="save" data-action="save.save" data-tooltip="{{__('Sauvegarder')}} (Ctrl+S)"
data-key="ctrl+s"></a>
var DEPTH = @json($depths);
</script>
<script
- src="/packages/linkeditor{{$scriptVersion}}/js/linkeditor.js?v={{filemtime(public_path('packages/linkeditor'.$scriptVersion.'/js/linkeditor.js'))}}"></script>
+ src="/packages/linkeditor{{$scriptVersion}}/js/linkeditor.js?v={{filemtime(public_path('packages/linkeditor'.$scriptVersion.'/js/linkeditor.js'))}}"></script>
@endpush
@push('linkeditor_styles')
<script>window._skipAutoTriggers = true;</script>
</defs>
<path class="st0" d="M19.7,9.6H4c-.2,0-.5-.1-.6-.4,0-.2,0-.5.1-.7L11.5.7c.2-.2.6-.2.9,0l7.9,7.9c.2.2.2.4.1.7,0,.2-.3.4-.6.4ZM5.5,8.4h12.8l-6.4-6.4-6.4,6.4Z"/>
<path class="st0" d="M11.9,23.7c-.2,0-.3,0-.4-.2l-7.9-7.9c-.2-.2-.2-.4-.1-.7,0-.2.3-.4.6-.4h15.7c.2,0,.5.1.6.4,0,.2,0,.5-.1.7l-7.9,7.9c-.1.1-.3.2-.4.2ZM5.5,15.9l6.4,6.4,6.4-6.4H5.5Z"/>
+ </symbol><symbol id="linkeditor-move-start" viewBox="0 0 18 18">
+ <path fill="currentColor" d="M14.7,4.4c0,0,0-.1-.1-.2,0,0-.9-.9-1.9-1.9-2.1-2.1-1.9-1.9-2.2-1.9s-.2,0-.2,0c0,0-.5.4-2,1.9-1.1,1.1-1.9,1.9-1.9,2-.2.3,0,.7.3.9,0,0,.1,0,.2,0,.3,0,.1.1,2-1.7l1.7-1.7,1.6,1.6c1,1,1.7,1.7,1.7,1.7,0,0,.1,0,.2,0,.3,0,.5,0,.7-.3,0-.1,0-.3,0-.5M14.7,9.3c0,0,0-.1,0-.2,0,0-.9-.9-1.9-1.9-1.4-1.4-1.9-1.9-1.9-1.9-.1,0-.2,0-.4,0-.2,0-.1,0-2.2,2-2.1,2.1-2,2-2,2.2,0,.1,0,.2,0,.2.1.2.3.4.6.4.1,0,.2,0,.2,0,.1,0,.2-.1,1.4-1.4l1.3-1.3v2.4c0,2,0,2.5,0,2.6-.2,1.4-1.1,2.7-2.3,3.3-.4.2-.8.3-1.2.4-.2,0-.3,0-1.7,0-1,0-1.5,0-1.6,0-.2,0-.3.2-.4.4,0,.1,0,.3,0,.5,0,.1.2.2.3.3h0s1.5,0,1.5,0c1.7,0,1.7,0,2.2-.1.8-.2,1.6-.5,2.3-1.1.2-.2.7-.6.8-.8.5-.7.9-1.5,1.1-2.3.1-.5.1-.4.1-3.2v-2.5s1.3,1.3,1.3,1.3c1.4,1.4,1.4,1.4,1.6,1.4.2,0,.4,0,.5-.2.1-.1.2-.2.2-.4,0-.1,0-.2,0-.2"/>
+ </symbol><symbol id="linkeditor-move-end" viewBox="0 0 18 18">
+ <path fill="currentColor" d="M14.7,13.4c0-.1,0-.3,0-.5-.1-.3-.4-.4-.7-.3,0,0-.1,0-.2,0,0,0-.7.7-1.7,1.7l-1.6,1.6-1.7-1.7c-1.9-1.9-1.7-1.7-2-1.7-.1,0-.2,0-.2,0-.3.1-.5.5-.3.9,0,0,.9.9,1.9,2,1.5,1.5,1.9,1.9,2,1.9,0,0,.1,0,.2,0,.3,0,.1.2,2.2-1.9,1-1,1.9-1.9,1.9-1.9,0,0,0-.1.1-.2M14.7,8.5c0,0,0-.1,0-.2,0-.2,0-.3-.2-.4-.1-.2-.3-.2-.5-.2-.2,0-.2,0-1.6,1.4l-1.3,1.3v-2.5c0-2.8,0-2.6-.1-3.2-.2-.8-.6-1.7-1.1-2.3-.2-.2-.6-.7-.8-.8-.7-.5-1.5-.9-2.3-1.1-.5-.1-.5-.1-2.2-.1h-1.6c-.1.1-.2.2-.3.3,0,.1,0,.3,0,.5,0,.2.2.3.4.4,0,0,.6,0,1.6,0,1.4,0,1.5,0,1.7,0,.4,0,.8.2,1.2.4,1.3.6,2.2,1.9,2.3,3.3,0,.2,0,.7,0,2.6v2.4s-1.3-1.3-1.3-1.3c-1.3-1.2-1.3-1.3-1.4-1.4,0,0-.1,0-.2,0-.3,0-.5.1-.6.4,0,0,0,.1,0,.2,0,.3-.2.1,2,2.2,2,2,2,2,2.2,2,.1,0,.3,0,.4,0,0,0,.5-.5,1.9-1.9,1-1,1.9-1.9,1.9-1.9,0,0,0-.1,0-.2"/>
+ </symbol><symbol id="linkeditor-move-down" viewBox="0 0 18 18">
+ <path fill="currentColor" d="M3.3.5c-.2,0-.3.2-.4.4,0,.1,0,.3,0,.5,0,.1.2.3.3.3h0s1.5,0,1.5,0c.8,0,1.5,0,1.6,0,0,0,.1,0,.2,0,1.1.2,2.1.9,2.8,1.8.3.4.5.9.6,1.4,0,.4,0,.2,0,5.5v4.9l-1.3-1.3c-.9-.9-1.4-1.3-1.4-1.4-.3-.2-.7,0-.8.3,0,0,0,.1,0,.2,0,.3-.1.1,2,2.3,1.6,1.6,1.9,1.9,2,1.9,0,0,.1,0,.2,0,.3,0,.1.2,2.3-2,2.1-2.1,2-2,2-2.3s0-.2,0-.3c-.1-.3-.5-.4-.8-.3,0,0-.4.4-1.4,1.4l-1.3,1.3v-5c0-5.5,0-5-.1-5.6-.2-.8-.6-1.6-1.1-2.3-.2-.2-.6-.7-.8-.8-.7-.6-1.6-1-2.4-1.1-.4,0-.4,0-2,0-1.4,0-1.5,0-1.6,0"/>
+ </symbol><symbol id="linkeditor-move-up" viewBox="0 0 18 18">
+ <path fill="currentColor" d="M3.3,17.5c0,0,.2,0,1.6,0,1.6,0,1.6,0,2,0,.9-.2,1.7-.6,2.4-1.1.2-.2.7-.6.8-.8.5-.7.9-1.5,1.1-2.3.1-.5.1,0,.1-5.6V2.6s1.3,1.3,1.3,1.3c1,1,1.4,1.3,1.4,1.4.3.1.7,0,.8-.3,0,0,0-.1,0-.3,0-.3.2-.1-2-2.3-2.1-2.1-2-2-2.3-2s-.2,0-.2,0c0,0-.4.4-2,1.9-2.2,2.2-2,2-2,2.3,0,.1,0,.2,0,.2.1.3.5.4.8.3,0,0,.5-.5,1.4-1.4l1.3-1.3v4.9c0,5.3,0,5.1,0,5.5-.1.5-.3,1-.6,1.4-.6,1-1.6,1.6-2.8,1.8,0,0-.2,0-.2,0,0,0-.7,0-1.6,0h-1.5s0,0,0,0c-.1,0-.3.2-.3.3,0,.1,0,.3,0,.5,0,.2.2.3.4.4"/>
</symbol></svg></div>
<script>
function getSpriteIcon(icon, attrs, dimensions) {