"dependencies": {
"command-line-args": "^5.2.1",
"jquery.scrollto": "^2.1.3",
+ "keymaster": "^1.6.2",
"lz4js": "^0.2.0",
"pako": "^2.0.4",
"pdfjs-dist": "^2.14.305",
"pipwerks-scorm-api-wrapper": "^0.1.2",
"plyr": "^3.7.2",
- "puppeteer": "^17.0.0"
+ "puppeteer": "^17.0.0",
+ "tippy.js": "^6.3.7"
},
"devDependencies": {
"axios": "^0.19",
"node": ">= 8"
}
},
+ "node_modules/@popperjs/core": {
+ "version": "2.11.6",
+ "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz",
+ "integrity": "sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/popperjs"
+ }
+ },
"node_modules/@types/glob": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz",
"graceful-fs": "^4.1.6"
}
},
+ "node_modules/keymaster": {
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/keymaster/-/keymaster-1.6.2.tgz",
+ "integrity": "sha512-OvA/AALN8IDKKkTk2Z+bDrzs/SQao4lo/QPbwSdDvm+frxfiYiYCSn1aHFUypJY3SruAO1y/c771agBmTXqUtg=="
+ },
"node_modules/killable": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz",
"integrity": "sha512-qsdtZH+vMoCARQtyod4imc2nIJwg9Cc7lPRrw9CzF8ZKR0khdr8+2nX80PBhET3tcyTtJDxAffGh2rXH4tyU8A==",
"dev": true
},
+ "node_modules/tippy.js": {
+ "version": "6.3.7",
+ "resolved": "https://registry.npmjs.org/tippy.js/-/tippy.js-6.3.7.tgz",
+ "integrity": "sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==",
+ "dependencies": {
+ "@popperjs/core": "^2.9.0"
+ }
+ },
"node_modules/to-arraybuffer": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz",
"fastq": "^1.6.0"
}
},
+ "@popperjs/core": {
+ "version": "2.11.6",
+ "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz",
+ "integrity": "sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw=="
+ },
"@types/glob": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz",
"graceful-fs": "^4.1.6"
}
},
+ "keymaster": {
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/keymaster/-/keymaster-1.6.2.tgz",
+ "integrity": "sha512-OvA/AALN8IDKKkTk2Z+bDrzs/SQao4lo/QPbwSdDvm+frxfiYiYCSn1aHFUypJY3SruAO1y/c771agBmTXqUtg=="
+ },
"killable": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz",
"integrity": "sha512-qsdtZH+vMoCARQtyod4imc2nIJwg9Cc7lPRrw9CzF8ZKR0khdr8+2nX80PBhET3tcyTtJDxAffGh2rXH4tyU8A==",
"dev": true
},
+ "tippy.js": {
+ "version": "6.3.7",
+ "resolved": "https://registry.npmjs.org/tippy.js/-/tippy.js-6.3.7.tgz",
+ "integrity": "sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==",
+ "requires": {
+ "@popperjs/core": "^2.9.0"
+ }
+ },
"to-arraybuffer": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz",
+++ /dev/null
-* {
- margin: 0;
- padding: 0;
- box-sizing: border-box;
-}
-body {
- background-color: #ebecee;
-}
-@media (prefers-color-scheme: dark) {
- body {
- background-color: #333;
- }
-}
-img,
-.division,
-.info {
- user-select: none;
- user-drag: none;
-}
-body,
-#linkeditor,
-html {
- height: 100%;
- width: 100%;
- overflow: hidden;
-}
-#linkeditor {
- white-space: nowrap;
- font-size: 0;
- overflow: hidden;
-}
-#linkeditor aside,
-#linkeditor #linkeditor-main {
- display: inline-block;
- height: 100%;
- vertical-align: top;
- text-align: left;
-}
-#linkeditor aside {
- width: 40px;
- background-color: #EBECEE;
-}
-@media (prefers-color-scheme: dark) {
- #linkeditor aside {
- background-color: #333;
- }
-}
-#linkeditor #linkeditor-main {
- width: calc(100% - 40px - 40px);
-}
-#linkeditor #linkeditor-main.grab {
- cursor: grab;
-}
-#linkeditor #linkeditor-main.grabbing {
- cursor: grabbing;
-}
-#linkeditor #linkeditor-main #linkeditor-toolbar {
- background-color: #dbdddf;
- color: #5d5d5d;
- height: 40px;
- padding: 5px;
-}
-@media (prefers-color-scheme: dark) {
- #linkeditor #linkeditor-main #linkeditor-toolbar {
- background-color: #444;
- }
-}
-@media (prefers-color-scheme: dark) {
- #linkeditor #linkeditor-main #linkeditor-toolbar {
- color: #bbb;
- }
-}
-#linkeditor #linkeditor-main #linkeditor-toolbar nav {
- padding: 2px;
- display: inline-block;
- height: 26px;
- vertical-align: top;
- width: 33%;
-}
-#linkeditor #linkeditor-main #linkeditor-toolbar nav#linkeditor-toolbar-center {
- text-align: center;
-}
-#linkeditor #linkeditor-main #linkeditor-toolbar div {
- display: inline-block;
- font-size: 16px;
-}
-#linkeditor #linkeditor-main #linkeditor-toolbar .separator {
- width: 0;
- height: 26px;
- margin: 0 2px;
- border-left: 1px solid #5d5d5d;
-}
-#linkeditor #linkeditor-main #linkeditor-toolbar #linkeditor-page-field {
- padding: 2px 10px;
- background-color: #fff;
- border: 1px solid #ccc;
- border-radius: 5px;
- cursor: text;
- font-size: 13px;
- position: relative;
- top: -9px;
- user-select: none;
- margin: 0 8px;
- font-weight: 600;
-}
-@media (prefers-color-scheme: dark) {
- #linkeditor #linkeditor-main #linkeditor-toolbar #linkeditor-page-field {
- background-color: #000;
- border-color: #333;
- }
-}
-#linkeditor #linkeditor-main #linkeditor-toolbar #linkeditor-page-field input {
- vertical-align: top;
- text-align: right;
- border: 0;
- background-color: transparent;
- width: 20px;
- color: #5d5d5d;
- font-size: 13px;
- appearance: textfield;
- font-weight: 600;
- position: relative;
-}
-@media (prefers-color-scheme: dark) {
- #linkeditor #linkeditor-main #linkeditor-toolbar #linkeditor-page-field input {
- color: #bbb;
- }
-}
-#linkeditor #linkeditor-main #linkeditor-toolbar #linkeditor-page-field input::-webkit-outer-spin-button,
-#linkeditor #linkeditor-main #linkeditor-toolbar #linkeditor-page-field input::-webkit-inner-spin-button {
- -webkit-appearance: none;
- margin: 0;
-}
-#linkeditor #linkeditor-main #linkeditor-toolbar #linkeditor-page-field input:hover,
-#linkeditor #linkeditor-main #linkeditor-toolbar #linkeditor-page-field input:focus {
- outline: 0;
- border: 0;
-}
-#linkeditor #linkeditor-main #linkeditor-toolbar [data-icon] {
- display: inline-block;
- vertical-align: top;
- height: 26px;
- min-width: 26px;
- padding: 3px;
- border-radius: 5px;
- margin: 0 3px;
- text-align: center;
- color: #5d5d5d;
-}
-@media (prefers-color-scheme: dark) {
- #linkeditor #linkeditor-main #linkeditor-toolbar [data-icon] {
- color: #bbb;
- }
-}
-#linkeditor #linkeditor-main #linkeditor-toolbar [data-icon]:hover,
-#linkeditor #linkeditor-main #linkeditor-toolbar [data-icon].hover {
- background-color: #fff;
-}
-@media (prefers-color-scheme: dark) {
- #linkeditor #linkeditor-main #linkeditor-toolbar [data-icon]:hover,
- #linkeditor #linkeditor-main #linkeditor-toolbar [data-icon].hover {
- background-color: #000;
- }
-}
-#linkeditor #linkeditor-main #linkeditor-toolbar [data-icon].arrow {
- padding: 1px;
-}
-#linkeditor #linkeditor-main #linkeditor-toolbar [data-icon].arrow svg {
- height: 16px;
-}
-#linkeditor #linkeditor-main #linkeditor-toolbar [data-icon] svg {
- position: relative;
- top: 1px;
- height: 18px;
- width: auto;
-}
-#linkeditor #linkeditor-main #linkeditor-editor {
- position: relative;
- height: calc( 100% - 40px);
- width: 100%;
- overflow: hidden;
-}
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-links {
- position: relative;
- z-index: 500;
-}
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-links .link {
- position: absolute;
- outline: 1px solid currentColor;
- cursor: cell;
-}
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-links .link.selected .corners {
- visibility: visible;
-}
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-links .link .corners {
- visibility: hidden;
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
-}
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-links .link .corners > div {
- position: absolute;
- outline: 1px solid currentColor;
- background-color: #fff;
- width: 8px;
- height: 8px;
-}
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-links .link .corners > div.nw {
- cursor: nw-resize;
-}
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-links .link .corners > div.n {
- cursor: n-resize;
-}
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-links .link .corners > div.ne {
- cursor: ne-resize;
-}
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-links .link .corners > div.e {
- cursor: e-resize;
-}
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-links .link .corners > div.se {
- cursor: se-resize;
-}
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-links .link .corners > div.s {
- cursor: s-resize;
-}
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-links .link .corners > div.sw {
- cursor: sw-resize;
-}
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-links .link .corners > div.w {
- cursor: w-resize;
-}
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-links .link .corners > div.n,
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-links .link .corners > div.nw,
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-links .link .corners > div.ne {
- top: -4px;
-}
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-links .link .corners > div.e,
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-links .link .corners > div.w {
- top: calc(50% - 4px);
-}
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-links .link .corners > div.sw,
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-links .link .corners > div.s,
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-links .link .corners > div.se {
- bottom: -4px;
-}
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-links .link .corners > div.nw,
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-links .link .corners > div.w,
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-links .link .corners > div.sw {
- left: -4px;
-}
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-links .link .corners > div.ne,
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-links .link .corners > div.e,
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-links .link .corners > div.se {
- right: -4px;
-}
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-links .link .corners > div.n,
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-links .link .corners > div.s {
- left: calc(50% - 4px);
-}
-#linkeditor #linkeditor-main #linkeditor-editor .ruler {
- position: absolute;
- top: 0;
- left: 0;
- z-index: 600;
- border-width: 0;
- border-color: #0f0;
- border-style: solid;
-}
-#linkeditor #linkeditor-main #linkeditor-editor .ruler:after {
- position: absolute;
- content: "";
- display: block;
- height: 100%;
- width: 100%;
-}
-#linkeditor #linkeditor-main #linkeditor-editor .ruler.pending-delete {
- border-color: #f00 !important;
- z-index: 1100;
-}
-#linkeditor #linkeditor-main #linkeditor-editor .ruler:hover {
- border-color: #0ff;
-}
-#linkeditor #linkeditor-main #linkeditor-editor .ruler[data-axis="x"] {
- width: 0px;
- height: calc( 100% - 16px);
- border-left-width: 1px;
- cursor: col-resize;
- top: 16px;
-}
-#linkeditor #linkeditor-main #linkeditor-editor .ruler[data-axis="x"]:after {
- left: -2px;
- width: 4px;
-}
-#linkeditor #linkeditor-main #linkeditor-editor .ruler[data-axis="y"] {
- border-bottom-width: 1px;
- height: 0px;
- width: calc( 100% - 16px);
- left: 16px;
-}
-#linkeditor #linkeditor-main #linkeditor-editor .ruler[data-axis="y"]:after {
- top: -2px;
- height: 4px;
- cursor: row-resize;
-}
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-rulers {
- color: #333;
- position: absolute;
- top: 0px;
- left: 0px;
- width: 100%;
- height: 100%;
-}
-@media (prefers-color-scheme: dark) {
- #linkeditor #linkeditor-main #linkeditor-editor #linkeditor-rulers {
- color: #eee;
- }
-}
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-rulers #linkeditor-ruler-corner {
- position: absolute;
- top: 0px;
- left: 0px;
- width: 16px;
- height: 16px;
- z-index: 5;
- background-color: #aaa;
-}
-@media (prefers-color-scheme: dark) {
- #linkeditor #linkeditor-main #linkeditor-editor #linkeditor-rulers #linkeditor-ruler-corner {
- background-color: #666;
- }
-}
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-rulers .ruler-bar {
- overflow: hidden;
- position: absolute;
- left: 0;
- top: 0;
- z-index: 1000;
-}
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-rulers .ruler-bar .info {
- position: absolute;
- top: 0;
- left: 0;
- z-index: 3;
- font-size: 12px;
- line-height: 8px;
- display: none;
-}
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-rulers .ruler-bar .info span {
- display: block;
- position: absolute;
- top: 0;
- left: 0;
- background-color: #fff;
- color: #000;
- padding: 3px;
-}
-@media (prefers-color-scheme: dark) {
- #linkeditor #linkeditor-main #linkeditor-editor #linkeditor-rulers .ruler-bar .info span {
- background-color: #000;
- color: #fff;
- }
-}
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-rulers .ruler-bar .division {
- pointer-events: none;
- position: absolute;
- background: #fff;
-}
-@media (prefers-color-scheme: dark) {
- #linkeditor #linkeditor-main #linkeditor-editor #linkeditor-rulers .ruler-bar .division {
- background-color: #000;
- }
-}
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-rulers .ruler-bar .division .value {
- position: absolute;
- font-size: 12px;
-}
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-rulers .ruler-bar .division .subdivision {
- position: absolute;
-}
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-rulers #linkeditor-ruler-x {
- height: 16px;
- width: 100%;
-}
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-rulers #linkeditor-ruler-x .info {
- height: 16px;
- border-left: 1px dotted #333;
-}
-@media (prefers-color-scheme: dark) {
- #linkeditor #linkeditor-main #linkeditor-editor #linkeditor-rulers #linkeditor-ruler-x .info {
- border-color: #eee;
- }
-}
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-rulers #linkeditor-ruler-x .division,
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-rulers #linkeditor-ruler-x .subdivision {
- width: 0px;
- border-left: 1px solid #333;
-}
-@media (prefers-color-scheme: dark) {
- #linkeditor #linkeditor-main #linkeditor-editor #linkeditor-rulers #linkeditor-ruler-x .division,
- #linkeditor #linkeditor-main #linkeditor-editor #linkeditor-rulers #linkeditor-ruler-x .subdivision {
- border-color: #eee;
- }
-}
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-rulers #linkeditor-ruler-x .division {
- height: 16px;
-}
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-rulers #linkeditor-ruler-x .division .value {
- bottom: 0px;
- left: 3px;
-}
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-rulers #linkeditor-ruler-x .subdivision {
- bottom: 0;
- height: 2px;
-}
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-rulers #linkeditor-ruler-x .subdivision.middle {
- height: 5px;
-}
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-rulers #linkeditor-ruler-y {
- width: 16px;
- height: 100%;
-}
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-rulers #linkeditor-ruler-y .info {
- width: 16px;
- border-bottom: 1px dotted #333;
-}
-@media (prefers-color-scheme: dark) {
- #linkeditor #linkeditor-main #linkeditor-editor #linkeditor-rulers #linkeditor-ruler-y .info {
- border-color: #eee;
- }
-}
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-rulers #linkeditor-ruler-y .info span {
- transform-origin: 0 0;
- transform: rotate(270deg);
-}
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-rulers #linkeditor-ruler-y .division,
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-rulers #linkeditor-ruler-y .subdivision {
- height: 0px;
- border-bottom: 1px solid #333;
-}
-@media (prefers-color-scheme: dark) {
- #linkeditor #linkeditor-main #linkeditor-editor #linkeditor-rulers #linkeditor-ruler-y .division,
- #linkeditor #linkeditor-main #linkeditor-editor #linkeditor-rulers #linkeditor-ruler-y .subdivision {
- border-color: #eee;
- }
-}
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-rulers #linkeditor-ruler-y .division {
- width: 16px;
-}
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-rulers #linkeditor-ruler-y .division .value {
- text-align: center;
- max-width: 16px;
- word-wrap: break-word;
- white-space: normal;
- line-height: 10px;
- letter-spacing: 30px;
- top: 3px;
- left: 3px;
-}
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-rulers #linkeditor-ruler-y .division .subdivision {
- right: 0;
- width: 2px;
-}
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-rulers #linkeditor-ruler-y .division .subdivision.middle {
- width: 5px;
-}
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-zoom {
- width: 100%;
- height: 100%;
- max-width: 100%;
- max-height: 100%;
- min-height: 100%;
- min-width: 100%;
- transform-origin: 0 0;
- overflow: hidden;
-}
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-canvas {
- background-color: #505050;
- position: relative;
- z-index: 1;
- top: 16px;
- left: 16px;
- height: calc( 100% - 16px);
- max-height: calc( 100% - 16px);
- width: calc( 100% - 16px);
- max-width: calc( 100% - 16px);
- overflow: auto;
-}
-@media (prefers-color-scheme: dark) {
- #linkeditor #linkeditor-main #linkeditor-editor #linkeditor-canvas {
- background-color: #222;
- }
-}
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-canvas::-webkit-scrollbar {
- width: 6px;
- height: 6px;
-}
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-canvas::-webkit-scrollbar-track {
- background: transparent;
-}
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-canvas::-webkit-scrollbar-track:hover {
- background-color: #000;
-}
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-canvas::-webkit-scrollbar-thumb {
- background-color: #aaa;
- border: 1px solid #333;
- border-radius: 20px;
-}
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-canvas #linkeditor-fluidbook {
- transform-origin: 0 0;
- position: absolute;
- top: 0;
- left: 0;
-}
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-canvas #linkeditor-fluidbook .linkeditor-page {
- position: absolute;
- top: 0px;
- left: 0px;
- background-color: rgba(255, 255, 255, 0.2);
-}
-@media (prefers-color-scheme: dark) {
- #linkeditor #linkeditor-main #linkeditor-editor #linkeditor-canvas #linkeditor-fluidbook .linkeditor-page {
- background-color: rgba(0, 0, 0, 0.2);
- }
-}
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-canvas #linkeditor-fluidbook .linkeditor-page .contents {
- background-color: #fff;
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
-}
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-canvas #linkeditor-fluidbook .linkeditor-page .contents img {
- display: block;
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: auto;
- z-index: 1;
-}
-#linkeditor #linkeditor-main #linkeditor-editor #linkeditor-canvas #linkeditor-fluidbook .linkeditor-page .contents img.texts {
- z-index: 2;
-}
-.simple #linkeditor #linkeditor-main #linkeditor-editor #linkeditor-canvas #linkeditor-fluidbook .linkeditor-page#linkeditor-page-right {
- display: none;
-}
-#linkeditor-preload {
- display: none;
-}
-/*# sourceMappingURL=linkeditor.css.map */
\ No newline at end of file
+++ /dev/null
-{"version":3,"sources":["linkeditor.less"],"names":[],"mappings":"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","file":"linkeditor.css"}
\ No newline at end of file
+++ /dev/null
-* {
- margin: 0;
- padding: 0;
- box-sizing: border-box;
-}
-
-@font-size: 16px;
-
-body {
- background-color: #ebecee;
- @media (prefers-color-scheme: dark) {
- background-color: #333;
- }
-}
-
-img, .division, .info {
- user-select: none;
- user-drag: none;
-}
-
-body, #linkeditor, html {
- height: 100%;
- width: 100%;
- overflow: hidden;
-}
-
-#linkeditor {
- @sidebar-width: 40px;
- @rulers-size: 16px;
- white-space: nowrap;
- font-size: 0;
- overflow: hidden;
-
- aside, #linkeditor-main {
- display: inline-block;
- height: 100%;
- vertical-align: top;
- text-align: left;
- }
-
- aside {
- width: @sidebar-width;
- background-color: #EBECEE;
- @media (prefers-color-scheme: dark) {
- background-color: #333;
- }
- }
-
- #linkeditor-main {
- @toolbar-height: 40px;
-
- width: ~"calc(100% - @{sidebar-width} - @{sidebar-width})";
-
- &.grab {
- cursor: grab;
- }
-
- &.grabbing {
- cursor: grabbing;
- }
-
- #linkeditor-toolbar {
-
- @toolbar-color: #5d5d5d;
- @toolbar-color-dark: #bbb;
- background-color: #dbdddf;
-
- @media (prefers-color-scheme: dark) {
- background-color: #444;
- }
- color: @toolbar-color;
- @media (prefers-color-scheme: dark) {
- color: @toolbar-color-dark;
- }
- height: @toolbar-height;
- padding: 5px;
-
- nav {
- padding: 2px;
- display: inline-block;
- height: 26px;
- vertical-align: top;
- width: 33%;
-
- &#linkeditor-toolbar-center {
- text-align: center;
- }
-
- &#linkeditor-toolbar-right {
-
- }
- }
-
- div {
- display: inline-block;
- font-size: @font-size;
- }
-
- .separator {
- width: 0;
- height: 26px;
- margin: 0 2px;
- border-left: 1px solid @toolbar-color;
- }
-
- #linkeditor-page-field {
- padding: 2px 10px;
- background-color: #fff;
- @media (prefers-color-scheme: dark) {
- background-color: #000;
- border-color: #333;
- }
- border: 1px solid #ccc;
- border-radius: 5px;
- cursor: text;
- font-size: 13px;
- position: relative;
- top: -9px;
- user-select: none;
- margin: 0 8px;
- font-weight: 600;
-
-
- input {
- vertical-align: top;
- text-align: right;
- border: 0;
- background-color: transparent;
- width: 20px;
- color: @toolbar-color;
- @media (prefers-color-scheme: dark) {
- color: @toolbar-color-dark;
- }
- font-size: 13px;
- appearance: textfield;
-
- &::-webkit-outer-spin-button, &::-webkit-inner-spin-button {
- -webkit-appearance: none;
- margin: 0;
- }
-
- font-weight: 600;
- position: relative;
-
-
- &:hover, &:focus {
- outline: 0;
- border: 0;
- }
- }
- }
-
- [data-icon] {
- display: inline-block;
- vertical-align: top;
- height: 26px;
- min-width: 26px;
- padding: 3px;
- border-radius: 5px;
- margin: 0 3px;
- text-align: center;
- color: @toolbar-color;
- @media (prefers-color-scheme: dark) {
- color: @toolbar-color-dark;
- }
-
- &:hover, &.hover {
- background-color: #fff;
- @media (prefers-color-scheme: dark) {
- background-color: #000;
- }
- }
-
- &.arrow {
- padding: 1px;
-
- svg {
- height: 16px;
- }
- }
-
- svg {
- position: relative;
- top: 1px;
- height: 18px;
- width: auto;
- }
- }
- }
-
- #linkeditor-editor {
- position: relative;
- height: ~"calc( 100% - @{toolbar-height})";
- width: 100%;
- overflow: hidden;
-
- @ruler-margin: 2px;
-
- #linkeditor-links {
- .link {
- position: absolute;
- outline: 1px solid currentColor;
- cursor: cell;
-
- &.selected {
- .corners {
- visibility: visible;
- }
- }
-
- .corners {
- visibility: hidden;
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
-
- > div {
- position: absolute;
- outline: 1px solid currentColor;
- background-color: #fff;
- width: 8px;
- height: 8px;
-
- &.nw {
- cursor: nw-resize;
- }
-
- &.n {
- cursor: n-resize;
- }
-
- &.ne {
- cursor: ne-resize;
- }
-
- &.e {
- cursor: e-resize;
- }
-
- &.se {
- cursor: se-resize;
- }
-
- &.s {
- cursor: s-resize;
- }
-
- &.sw {
- cursor: sw-resize;
- }
-
- &.w {
- cursor: w-resize;
- }
-
- &.n, &.nw, &.ne {
- top: -4px;
- }
-
- &.e, &.w {
- top: calc(50% - 4px);
- }
-
- &.sw, &.s, &.se {
- bottom: -4px;
- }
-
- &.nw, &.w, &.sw {
- left: -4px;
- }
-
- &.ne, &.e, &.se {
- right: -4px;
- }
-
- &.n, &.s {
- left: calc(50% - 4px);
- }
- }
- }
- }
-
- position: relative;
- z-index: 500;
- }
-
- .ruler {
- position: absolute;
- top: 0;
- left: 0;
- z-index: 600;
- border-width: 0;
- border-color: #0f0;
- border-style: solid;
-
- &:after {
- position: absolute;
- content: "";
- display: block;
- height: 100%;
- width: 100%;
- }
-
- &.pending-delete {
- border-color: #f00 !important;
- z-index: 1100;
- }
-
- &:hover {
- border-color: #0ff;
- }
-
- &[data-axis="x"] {
- width: 0px;
- height: ~"calc( 100% - @{rulers-size})";
- border-left-width: 1px;
- cursor: col-resize;
- top: @rulers-size;
-
- &:after {
- left: @ruler-margin*-1;
- width: @ruler-margin*2;
- }
- }
-
- &[data-axis="y"] {
- border-bottom-width: 1px;
- height: 0px;
- width: ~"calc( 100% - @{rulers-size})";
- left: @rulers-size;
-
- &:after {
- top: @ruler-margin*-1;
- height: @ruler-margin*2;
- cursor: row-resize;
- }
- }
- }
-
-
- #linkeditor-rulers {
- @rulers-color: #333;
- @rulers-color-dark: #eee;
-
- @media (prefers-color-scheme: dark) {
- color: @rulers-color-dark;
- }
-
- color: @rulers-color;
- position: absolute;
- top: 0px;
- left: 0px;
- width: 100%;
- height: 100%;
-
- #linkeditor-ruler-corner {
- position: absolute;
- top: 0px;
- left: 0px;
- width: @rulers-size;
- height: @rulers-size;
- z-index: 5;
- background-color: #aaa;
- @media (prefers-color-scheme: dark) {
- background-color: #666;
- }
-
- }
-
- .ruler-bar {
- overflow: hidden;
- position: absolute;
- left: 0;
- top: 0;
- z-index: 1000;
-
- .info {
- position: absolute;
- top: 0;
- left: 0;
- z-index: 3;
- font-size: 12px;
- line-height: 8px;
- display: none;
-
- span {
- display: block;
- position: absolute;
- top: 0;
- left: 0;
- background-color: #fff;
- color: #000;
- @media (prefers-color-scheme: dark) {
- background-color: #000;
- color: #fff;
- }
- padding: 3px;
- }
- }
-
- .division {
- pointer-events: none;
- position: absolute;
- background: #fff;
- @media (prefers-color-scheme: dark) {
- background-color: #000;
- }
-
- .value {
- position: absolute;
- font-size: 12px;
- }
-
- .subdivision {
- position: absolute;
- }
- }
- }
-
- #linkeditor-ruler-x {
- height: @rulers-size;
- width: 100%;
-
- .info {
- height: @rulers-size;
- border-left: 1px dotted @rulers-color;
- @media (prefers-color-scheme: dark) {
- border-color: @rulers-color-dark;
- }
- }
-
- .division, .subdivision {
- width: 0px;
- border-left: 1px solid @rulers-color;
- @media (prefers-color-scheme: dark) {
- border-color: @rulers-color-dark;
- }
- }
-
- .division {
- height: @rulers-size;
-
- .value {
- bottom: 0px;
- left: 3px;
- }
- }
-
- .subdivision {
- bottom: 0;
- height: 2px;
-
- &.middle {
- height: 5px;
- }
- }
- }
-
- #linkeditor-ruler-y {
- width: @rulers-size;
- height: 100%;
-
- .info {
- width: @rulers-size;
- border-bottom: 1px dotted @rulers-color;
- @media (prefers-color-scheme: dark) {
- border-color: @rulers-color-dark;
- }
-
- span {
- transform-origin: 0 0;
- transform: rotate(270deg);
- }
- }
-
- .division, .subdivision {
- height: 0px;
- border-bottom: 1px solid @rulers-color;
- @media (prefers-color-scheme: dark) {
- border-color: @rulers-color-dark;
- }
- }
-
- .division {
- width: @rulers-size;
-
- .value {
- text-align: center;
- max-width: @rulers-size;
- word-wrap: break-word;
- white-space: normal;
- line-height: 10px;
- letter-spacing: 30px;
- top: 3px;
- left: 3px;
- }
-
- .subdivision {
- right: 0;
- width: 2px;
-
- &.middle {
- width: 5px;
- }
- }
- }
- }
- }
-
- #linkeditor-zoom {
- width: 100%;
- height: 100%;
- max-width: 100%;
- max-height: 100%;
- min-height: 100%;
- min-width: 100%;
- transform-origin: 0 0;
- overflow: hidden;
- }
-
- #linkeditor-canvas {
- background-color: #505050;
- @media (prefers-color-scheme: dark) {
- background-color: #222;
- }
-
- position: relative;
- z-index: 1;
- top: @rulers-size;
- left: @rulers-size;
- height: ~"calc( 100% - @{rulers-size})";
- max-height: ~"calc( 100% - @{rulers-size})";
- width: ~"calc( 100% - @{rulers-size})";
- max-width: ~"calc( 100% - @{rulers-size})";
- overflow: auto;
-
- &::-webkit-scrollbar {
- width: 6px;
- height: 6px;
- }
-
- &::-webkit-scrollbar-track {
- background: transparent;
-
- &:hover {
- background-color: #000;
- }
- }
-
- &::-webkit-scrollbar-thumb {
- background-color: #aaa;
- border: 1px solid #333;
- border-radius: 20px;
- }
-
-
- #linkeditor-fluidbook {
- transform-origin: 0 0;
- position: absolute;
- top: 0;
- left: 0;
-
- .linkeditor-page {
- position: absolute;
- top: 0px;
- left: 0px;
- background-color: rgba(255, 255, 255, 0.2);
- @media (prefers-color-scheme: dark) {
- background-color: rgba(0, 0, 0, 0.2);
- }
-
-
- .contents {
- background-color: #fff;
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
-
- img {
- display: block;
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: auto;
- z-index: 1;
-
- &.texts {
- z-index: 2;
- }
- }
- }
-
-
- &#linkeditor-page-right {
- .simple & {
- display: none;
- }
- }
- }
- }
- }
- }
- }
-
-
-}
-
-#linkeditor-preload {
- display: none;
-}
+++ /dev/null
-var single = ['mobilefirst', 'portrait'].indexOf(FLUIDBOOK_DATA.settings.mobileNavigationType) >= 0;
-var pw = FLUIDBOOK_DATA.settings.width;
-var ph = FLUIDBOOK_DATA.settings.height;
-var fw = pw * (single ? 1 : 2);
-var fh = ph;
-var fs = 1;
-var mx = 0, my = 0;
-var zoom = 1;
-var zoomdragging = false;
-var dividers = [1, 2, 5, 10, 20, 50, 100, 200];
-var fluidbookRect, canvasRect, editorRect;
-var currentPage;
-var movingRuler = null;
-var rasterizePages = splitPages(FLUIDBOOK_DATA.settings.rasterizePages);
-var vectorPages = splitPages(FLUIDBOOK_DATA.settings.vectorPages);
-var unsavedChanges = false;
-var automaticSaveTimeout;
-var runningAutomaticSaveTimeout = false;
-var dimensionProperties = ['left', 'top', 'width', 'height'];
-var rulersMagnetValuesX = [];
-var rulersMagnetValuesY = [];
-var currentSelection = [];
-
-$(function () {
- init();
-});
-
-
-function init() {
- $(window).on('hashchange', function () {
- changePage();
- });
- $(window).on('resize', function () {
- resize();
- });
- $(window).on('beforeunload', function () {
- if (unsavedChanges) {
- return TRANSLATIONS.warning_unsaved_changes;
- }
- })
- // Disable scroll by spacebar
- $(window).on('keydown', function (e) {
- if (e.keyCode == 32) {
- $("#linkeditor-main").addClass('grab');
- return false;
- }
- moveRuler();
- });
- $(window).on('keyup', function (e) {
- if (e.keyCode == 32) {
- resetZoomDrag();
- }
- moveRuler();
- });
-
- $("#linkeditor-canvas").on('scroll', function () {
- updateRulers();
- });
- $("#linkeditor-main").on('mousedown', function (e) {
- if ($(this).hasClass('grab') && zoom > 1) {
- zoomdragging = {
- x: e.pageX,
- y: e.pageY,
- scrollX: $("#linkeditor-canvas").scrollLeft(),
- scrollY: $("#linkeditor-canvas").scrollTop()
- };
- $(this).addClass('grabbing');
- } else {
- resetZoomDrag();
- }
- deselectAllLinks();
- });
-
- $(document).on('mousedown', '.link', function (e) {
- if (!e.ctrlKey) {
- deselectAllLinks();
- }
- selectLink($(this));
- });
-
- $("#linkeditor-ruler-x").on('mousedown', function (e) {
- addRuler('y');
- });
-
- $("#linkeditor-ruler-y").on('mousedown', function (e) {
- addRuler('x');
- });
-
- $(document).on('mousedown', ".ruler", function (e) {
- movingRuler = $(this);
-
- });
-
- $(window).on('mousemove', function (e) {
- if (!$("#linkeditor-main").hasClass('grab') || zoom === 1) {
- resetZoomDrag();
- }
- if (zoomdragging !== false) {
- moveZoomDrag(e);
- }
- updateMousePosition(e);
- });
- $(window).on('mouseup', function (e) {
- if (zoomdragging !== false) {
- moveZoomDrag(e);
- }
- stopMoveRuler();
- resetZoomDrag();
- });
- $("#linkeditor-main").on('wheel', function (e) {
- var delta = e.originalEvent.deltaY;
- if (delta == 0) {
- return true;
- }
- e.stopPropagation();
- e.stopImmediatePropagation();
- e.preventDefault();
- if (delta < 0) {
- if (setZoom(zoom + 0.25)) {
- moveZoom(e);
- }
- } else {
- setZoom(zoom - 0.25);
- }
- return false;
- });
-
- if (single) {
- $("#linkeditor").addClass('single');
- } else {
- $("#linkeditor").addClass('double');
- }
- $('.linkeditor-page').css({
- width: pw, height: ph
- });
- $("#linkeditor-page-right").css({left: pw})
- $('#linkeditor-fluidbook').css({
- width: fw, height: ph
- });
- initToolbar();
- resize();
- changePage();
-}
-
-function selectLink(l) {
- if ($(l).find('.corners').length === 0) {
- $(l).append('<div class="corners"><div class="nw"></div><div class="n"></div><div class="ne"></div><div class="e"></div><div class="se"></div><div class="s"></div><div class="sw"></div><div class="w"></div></div>')
- }
- $(l).addClass('selected');
- currentSelection.push(l);
-}
-
-function deselectAllLinks() {
- currentSelection = [];
- $(".link.selected").removeClass('selected');
-}
-
-function initToolbar() {
- $("#linkeditor-page-field input").on('change', function () {
- changePage($(this).val());
- $(this).blur();
- return false;
- });
-
- $("#linkeditor-toolbar [data-icon]").each(function () {
- $(this).append(getSpriteIcon('linkeditor-' + $(this).data('icon')));
- });
-
- $("[data-key]").each(function () {
- var e = $(this);
- key($(this).data('key'), function () {
- $(e).addClass('hover');
- runAction($(e).data('action'));
- setTimeout(function () {
- $(e).removeClass('hover')
- }, 150);
- return false;
- });
- });
-
- $('[data-action]').click(function () {
- runAction($(this).data('action'));
- return false;
- });
-
- $('[data-tooltip]').each(function () {
- tippy($(this).get(0), {content: $(this).data('tooltip')});
- });
-}
-
-function runAction(act) {
- window[act]();
-}
-
-function saveLinks(message) {
- if (message === undefined) {
- message = TRANSLATIONS.manual_save_message;
- }
- $.ajax({
- url: '/fluidbook-publication/' + FLUIDBOOK_DATA.id + '/save/links', method: 'post', data: {
- _method: 'put', 'message': message, rulers: window.RULERS, links: window.LINKS,
- }, success: function (data) {
- new Noty({
- type: "success", text: TRANSLATIONS.success_save,
- }).show();
- clearTimeout(automaticSaveTimeout);
- unsavedChanges = false;
- runningAutomaticSaveTimeout = false;
- }, error: function (jqXHR, status, error) {
- hasChanged();
- new Noty({
- type: "error", text: TRANSLATIONS.error_save + ' : ' + error,
- }).show();
- },
- });
-}
-
-function automaticSaveLinks() {
- saveLinks(TRANSLATIONS.automatic_save_message);
-}
-
-function firstPage() {
- changePage(1);
-}
-
-function nextPage() {
- changePage(currentPage + (single ? 1 : 2));
-}
-
-function previousPage() {
- changePage(currentPage - (single ? 1 : 2));
-}
-
-function lastPage() {
- changePage(FLUIDBOOK_DATA.settings.pages);
-}
-
-function focusPageField() {
- var i = $("#linkeditor-page-field input").get(0);
- i.focus();
- i.select();
-}
-
-function zoomReset() {
- setZoom(1);
- resetZoomDrag();
-}
-
-function generateUID() {
- var length = 12;
- var result = '';
- var characters = 'abcdefghijklmnopqrstuvwxyz0123456789';
- var charactersLength = characters.length;
- for (var i = 0; i < length; i++) {
- result += characters.charAt(Math.floor(Math.random() * charactersLength));
- }
- return result;
-}
-
-function addRuler(axis, pos, uid) {
- if (undefined === uid) {
- uid = generateUID();
- RULERS[uid] = {page: currentPage, type: axis, uid: uid};
- hasChanged();
- }
- var ruler = $('<div class="ruler" data-uid="' + uid + '" fb-ref="editor" data-axis="' + axis + '"></div>');
- if (pos === undefined) {
- movingRuler = ruler;
- } else {
- var dim = axis == 'x' ? 'left' : 'top';
- $(ruler).attr('fb-' + dim, pos);
- }
- $("#linkeditor-editor").append(ruler);
- moveRuler();
-}
-
-function deleteRuler(ruler) {
- if (ruler === undefined) {
- ruler = movingRuler;
- }
- var uid = $(ruler).data('uid');
- delete RULERS[uid];
- $(ruler).remove();
- movingRuler = null;
- hasChanged();
-}
-
-function hasChanged() {
- unsavedChanges = true;
- if (runningAutomaticSaveTimeout === false) {
- runningAutomaticSaveTimeout = true;
- automaticSaveTimeout = setTimeout(function () {
- automaticSaveLinks();
- }, 1000 * 5 * 60);
- }
-}
-
-function moveRuler() {
- if (movingRuler === null || movingRuler === undefined) {
- return;
- }
- var magnet = !key.ctrl;
- var editorMouse = globalToEditor(mx, my);
- var fbMouse = globalToFluidbook(mx, my, false);
- var css = {};
- var attrs = {};
- var v, fbv;
- if ($(movingRuler).data('axis') === 'x') {
- v = editorMouse.x;
- fbv = attrs['fb-left'] = magnet ? magnetize(fbMouse.x, rulersMagnetValuesX) : fbMouse.x;
- } else {
- v = editorMouse.y;
- fbv = attrs['fb-top'] = magnet ? magnetize(fbMouse.y, rulersMagnetValuesY) : fbMouse.y;
- }
- if (v < 16) {
- $(movingRuler).addClass('pending-delete');
- } else {
- $(movingRuler).removeClass('pending-delete');
- }
- $(movingRuler).css(css).attr(attrs);
- RULERS[$(movingRuler).data('uid')].pos = fbv;
- updateFBElements();
-}
-
-function magnetize(value, values) {
- var sensibility = 8 / (zoom * fs);
- var min = 100000;
- var magnetValue;
- if (values.length === 0) {
- return value;
- }
-
- for (var i in values) {
- var v = values[i];
- var diff = Math.abs(v - value);
- if (diff < min) {
- min = diff;
- magnetValue = v;
- }
- }
-
- if (min > sensibility) {
- return value;
- }
- return magnetValue;
-}
-
-function getLinksOfPage(p) {
- let pages = [];
- if (!single) {
- if (p % 2 === 1) {
- p--;
- }
- pages.push(p);
- pages.push(p + 1);
- } else {
- pages.push(p);
- }
- let res = {};
- $.each(LINKS, function (uid, link) {
- if (pages.indexOf(parseInt(link.page)) >= 0) {
- res[uid] = link;
- }
- });
- return res;
-}
-
-function updateFBElements() {
- $('[fb-ref]').each(function () {
- var e = $(this);
- var rect = $(this).attr('fb-ref');
- var css = {};
- $.each(dimensionProperties, function (k, dim) {
- if ($(e).is('[fb-' + dim + ']')) {
- var v = parseFloat($(e).attr('fb-' + dim));
- if (dim === 'width' || dim === 'height') {
- css[dim] = v * (fs * zoom);
- } else {
- css[dim] = fluidbookTo(v, dim, rect);
- }
- }
- });
- $(e).css(css);
- });
-}
-
-function fluidbookTo(dim, name, rect) {
- switch (rect) {
- case 'editor':
- rect = editorRect;
- break;
- case 'canvas':
- rect = canvasRect;
- break;
- }
- return fluidbookToGlobal(dim, name) - rect[name];
-}
-
-function stopMoveRuler() {
- moveRuler();
- if ($(movingRuler).hasClass('pending-delete')) {
- deleteRuler($(movingRuler));
- }
- movingRuler = null;
-}
-
-function updateMousePosition(e) {
- mx = e.pageX;
- my = e.pageY;
- updateMousePositionRulers();
- moveRuler();
-}
-
-function updateMousePositionRulers() {
- var rulersRect = $("#linkeditor-rulers").get(0).getBoundingClientRect();
- var rx = mx - rulersRect.x;
- var ry = my - rulersRect.y;
- $("#linkeditor-ruler-x .info").css('left', rx);
- $("#linkeditor-ruler-y .info").css('top', ry);
-
- var rrect = $("#linkeditor-rulers").get(0).getBoundingClientRect();
-
- if (mx - rrect.x < 0 || my - rrect.y < 0 || mx - rrect.x > rrect.width || my - rrect.y > rrect.height) {
- $("#linkeditor-rulers .info").hide();
- return;
- }
-
- var fb = globalToFluidbook(mx, my, true);
- $("#linkeditor-ruler-y .info span").text(fb.y.toFixed(2));
- $("#linkeditor-ruler-x .info span").text(fb.x.toFixed(2));
- $("#linkeditor-rulers .info").css('display', 'inline-block');
-}
-
-function resetZoomDrag() {
- $("#linkeditor-main").removeClass('grab').removeClass('grabbing');
- if (zoom === 1) {
- $("#linkeditor-canvas").scrollTo({left: 0, top: 0});
- }
- zoomdragging = false;
-}
-
-function moveZoomDrag(e) {
- var deltaX = e.pageX - zoomdragging.x;
- var deltaY = e.pageY - zoomdragging.y;
- $("#linkeditor-canvas").scrollTo({
- top: zoomdragging.scrollY - deltaY, left: zoomdragging.scrollX - deltaX
- });
- updateRulers();
-}
-
-function moveZoom(e) {
- var rect = $("#linkeditor-zoom").get(0).getBoundingClientRect();
- var lx = (e.originalEvent.pageX - rect.x) / rect.width;
- var ly = (e.originalEvent.pageY - rect.y) / rect.height;
- $("#linkeditor-canvas").scrollTo({left: pct(lx), top: pct(ly)});
- updateRulers();
-}
-
-function pct(v) {
- return (v * 100) + '%';
-}
-
-function setZoom(z) {
- z = Math.max(1, Math.min(6, z));
- if (z === zoom) {
- return false;
- }
- zoom = z;
- $("#linkeditor-canvas").attr('data-z', zoom);
- $("#linkeditor-zoom").css({transform: 'scale(' + zoom + ')', overflow: 'visible'});
-
- setTimeout(function () {
- $("#linkeditor-zoom").css({overflow: 'hidden'});
- if (zoom === 1) {
- resetZoomDrag();
- }
- updateRulers();
-
- }, 10);
-
- return true;
-}
-
-function changePage(page) {
- if (page === undefined) {
- var h = window.location.hash;
- if (h.length === 0) {
- page = 0;
- } else {
- page = window.location.hash.substring(1);
- }
- }
- page = parseInt(page);
- if (page % 2 === 1 && !single) {
- page--;
- }
- var normPage = Math.max(0, Math.min(page, FLUIDBOOK_DATA.settings.pages));
- if (normPage === currentPage) {
- return;
- }
- currentPage = normPage;
-
- window.location.hash = '#' + currentPage;
- clearLinksAndRulers();
- loadPage(currentPage, 'left');
- if (!single) {
- loadPage(currentPage + 1, 'right');
- }
- $("#linkeditor-page-field input").val(currentPage);
- updateRulersMagnetValues();
- resize();
- preloadPages();
-}
-
-function updateRulersMagnetValues() {
- rulersMagnetValuesX = [0, pw, pw * 2];
- rulersMagnetValuesY = [0, ph];
- $.each(getLinksOfPage(currentPage), function (uid, link) {
- const left = parseFloat(link.left);
- const top = parseFloat(link.top);
- const width = parseFloat(link.width);
- const height = parseFloat(link.height);
- rulersMagnetValuesX.push(left, left + width);
- rulersMagnetValuesY.push(top, top + height);
- });
-}
-
-// Convert global coordinates to fluidbook ones
-function globalToFluidbook(x, y, onePage) {
- var res = _globalTo(x, y, fluidbookRect, 1 / (fs * zoom));
- if (onePage) {
- res.xside = 'left';
- if (!single && res.x >= pw) {
- res.xside = 'right';
- res.x -= pw;
- }
- }
- return res;
-}
-
-function fluidbookToGlobal(dim, name) {
- return fluidbookRect[name] + (dim * fs * zoom);
-}
-
-function globalToCanvas(x, y) {
- return _globalTo(x, y, canvasRect, 1);
-}
-
-function globalToEditor(x, y) {
- return _globalTo(x, y, editorRect, 1);
-}
-
-function _globalTo(x, y, rect, multi) {
- return {x: multi * (x - rect.x), y: multi * (y - rect.y)};
-}
-
-function loadPage(p, side) {
- var container = $("#linkeditor-page-" + side);
- $(container).attr('data-page', p);
-
- if (p === 0 || p > FLUIDBOOK_DATA.settings.pages) {
- $(container).html('');
- } else {
- _loadPage(p, container);
- }
-
- loadLinks(p, side);
- loadRulers(p, side);
-}
-
-function preloadPages() {
- let j = 1;
- for (let i = Math.max(1, currentPage - 4); i <= Math.min(currentPage + 16, FLUIDBOOK_DATA.settings.pages); i++) {
- if ($('.preload[data-page="' + i + '"]').length >= 1) {
- continue;
- }
- setTimeout(function () {
- var c = $('<div class="preload" data-page="i"></div>');
- $("#linkeditor-preload").append(c);
- _loadPage(i, c);
- }, j * 500);
- j++;
- }
-}
-
-function _loadPage(p, container) {
- var imageFormat = FLUIDBOOK_DATA.settings.imageFormat;
- var c = '<div class="contents">';
- if (rasterizePages.indexOf(p) >= 0) {
- c += '<img draggable="false" src="raster_' + p + '.' + imageFormat + '" />';
- } else if (vectorPages.indexOf(p) >= 0) {
- c += '<img draggable="false" src="vector_' + p + '.svg" />';
- } else {
- c += '<img draggable="false" class="images" src="images_' + p + '.' + imageFormat + '" />';
- c += '<img draggable="false" class="texts" src="texts_' + p + '.svg" />';
- }
- c += '</div>';
- $(container).html(c);
-}
-
-function loadLinks(page, side) {
- $.each(LINKS, function (uid, link) {
- if (link.page != page) {
- return;
- }
- if (side === 'right') {
- link.left = parseInt(link.left) + pw;
- }
- addLink(link, side);
- });
-}
-
-function addLink(link) {
- if (link.uid === undefined) {
- link.uid = generateUID();
- LINKS[link.uid] = link;
- updateRulersMagnetValues();
- hasChanged();
- }
-
- var attrs = {};
- $.each(link, function (k, v) {
- if (dimensionProperties.indexOf(k) >= 0) {
- attrs['fb-' + k] = v;
- } else {
- attrs['data-' + k] = v;
- }
- });
-
- var e = $('<div class="link" fb-ref="editor"></div>');
- $(e).attr(attrs);
- $("#linkeditor-links").append(e);
-}
-
-function clearLinksAndRulers() {
- $('#linkeditor-editor .ruler').remove();
-}
-
-function loadRulers(page, side) {
- $.each(RULERS, function (uid, ruler) {
- if (ruler.page != page) {
- return;
- }
- addRuler(ruler.type, ruler.pos, ruler.uid);
- });
-}
-
-
-function resize() {
- resizeCanvas();
- updateRulers();
-}
-
-function updateRulers() {
- // Update rects
- fluidbookRect = $("#linkeditor-fluidbook").get(0).getBoundingClientRect();
-
- $("#linkeditor-ruler-y,#linkeditor-ruler-x").html('');
- // Measure of visible fluidbook px at current zoom
-
- var factor = fs / zoom;
- var visible_w = (canvasRect.width / fs) / zoom;
- var visible_h = (canvasRect.height / fs) / zoom;
-
- // Find the best divider to have around 10 main divisions
- var divider = 0;
- for (var i in dividers) {
- divider = dividers[i];
- var v = visible_h / divider;
- if (v <= 10) {
- break;
- }
- }
-
- var divisionSize = divider * fs * zoom;
- // Draw vertical ruler
- var margin = 100;
- var nbDivisions = Math.floor(visible_h / divider);
- var y0 = 16 + fluidbookRect.y - canvasRect.y;
-
- var yruler = '<div class="info"><span>1234.12</span></div>';
- for (var y = -margin; y <= nbDivisions + (margin * 2) + 1; y++) {
- // Draw subdivision
- var v = divider * y;
- var ystart = y0 + (y * divisionSize);
- if (ystart + divisionSize < 0 || ystart > canvasRect.height) {
- continue;
- }
- yruler += '<div class="division" style="top:' + ystart + 'px;height:' + divisionSize + 'px;"><div class="value">' + Math.abs(v) + '</div>';
- for (var i = 1; i <= 9; i++) {
- yruler += '<div class="subdivision ' + (i === 5 ? ' middle' : '') + '" style="top:' + ((i * divisionSize) / 10) + 'px;"></div>';
- }
- yruler += '</div>';
- }
- $("#linkeditor-ruler-y").html(yruler);
-
- // Draw horizontal ruler
- nbDivisions = Math.floor(visible_w / divider);
- var x0 = 16 + fluidbookRect.x - canvasRect.x;
- var xruler = '<div class="info"><span></span></div>';
-
- for (var x = -margin; x <= nbDivisions + (margin * 2) + 1; x++) {
- // Draw subdivision
- var v = divider * x;
- var xstart = x0 + (x * divisionSize);
- if (xstart + divisionSize < 0 || xstart > canvasRect.width) {
- continue;
- }
- xruler += '<div class="division" style="left:' + xstart + 'px;width:' + divisionSize + 'px;"><div class="value">' + Math.abs(v) + '</div>';
- for (var i = 1; i <= 9; i++) {
- var cls = '';
- if (i === 5) {
- cls += ' middle';
- }
- xruler += '<div class="subdivision ' + cls + '" style="left:' + ((i * divisionSize) / 10) + 'px;"></div>';
- }
- xruler += '</div>';
- }
- // Draw right page horizontal ruler
- if (!single) {
- x0 = x0 + pw * fs * zoom;
- for (var x = 0; x <= nbDivisions + margin + 1; x++) {
- // Draw subdivision
- var v = divider * x;
- var xstart = x0 + (x * divisionSize);
- if (xstart + divisionSize < 0 || xstart > canvasRect.width) {
- continue;
- }
- xruler += '<div class="division" style="left:' + xstart + 'px;width:' + divisionSize + 'px;"><div class="value">' + Math.abs(v) + '</div>';
- for (var i = 1; i <= 9; i++) {
- var cls = '';
- if (i === 5) {
- cls += ' middle';
- }
- xruler += '<div class="subdivision ' + cls + '" style="left:' + ((i * divisionSize) / 10) + 'px;"></div>';
- }
- xruler += '</div>';
- }
- }
- $("#linkeditor-ruler-x").html(xruler);
- updateFBElements()
- updateMousePositionRulers();
-}
-
-function resizeCanvas() {
- canvasRect = $("#linkeditor-canvas").get(0).getBoundingClientRect();
- editorRect = $("#linkeditor-editor").get(0).getBoundingClientRect();
- var aw = canvasRect.width - 30;
- var ah = canvasRect.height - 30;
- fs = Math.min(aw / fw, ah / fh);
- var left = (canvasRect.width - fw * fs) / 2;
- var top = (canvasRect.height - fh * fs) / 2;
- $("#linkeditor-fluidbook").css({left: left, top: top, transform: 'scale(' + fs + ')'});
-}
-
-
-function splitPages(str) {
- str = str.toString();
- var res = [];
- if (str == '') {
- return res;
- }
- var pages = str.split(',');
- for (var p in pages) {
- res.push(parseInt(pages[p]));
- }
- return res;
-}
window.$ = window.jQuery = require('jquery');
+window.key = require('keymaster');
import tippy from 'tippy.js';
import 'tippy.js/dist/tippy.css';
-import key from 'keymaster';
+
+window.tippy = tippy;
require('jquery.scrollto');
require('jquery-contextmenu');
-var single = ['mobilefirst', 'portrait'].indexOf(FLUIDBOOK_DATA.settings.mobileNavigationType) >= 0;
-var pw = FLUIDBOOK_DATA.settings.width;
-var ph = FLUIDBOOK_DATA.settings.height;
-var fw = pw * (single ? 1 : 2);
-var fh = ph;
-var fs = 1;
-var mx = 0, my = 0;
-var zoom = 1;
-var zoomdragging = false;
-var dividers = [1, 2, 5, 10, 20, 50, 100, 200];
-var fluidbookRect, canvasRect, editorRect;
-var currentPage;
-var movingRuler = null;
-var rasterizePages = splitPages(FLUIDBOOK_DATA.settings.rasterizePages);
-var vectorPages = splitPages(FLUIDBOOK_DATA.settings.vectorPages);
-var unsavedChanges = false;
-var automaticSaveTimeout;
-var runningAutomaticSaveTimeout = false;
-var dimensionProperties = ['left', 'top', 'width', 'height'];
-var rulersMagnetValuesX = [];
-var rulersMagnetValuesY = [];
-var currentSelection = [];
-var dragLinkPos = null;
-
-$(function () {
- init();
-});
-
+import LinkeditorLinks from './linkeditor.links';
+import LinkeditorLoader from './linkeditor.loader';
+import LinkeditorResize from './linkeditor.resize';
+import LinkeditorRulers from './linkeditor.rulers';
+import LinkeditorToolbar from './linkeditor.toolbar';
+import LinkeditorUtils from './linkeditor.utils';
+import LinkeditorZoom from './linkeditor.zoom';
+import LinkeditorSave from './linkeditor.save';
+
+function LinkEditor() {
+ this.single = ['mobilefirst', 'portrait'].indexOf(FLUIDBOOK_DATA.settings.mobileNavigationType) >= 0;
+ this.pw = FLUIDBOOK_DATA.settings.width;
+ this.ph = FLUIDBOOK_DATA.settings.height;
+ this.fw = this.pw * (this.single ? 1 : 2);
+ this.fh = this.ph;
+ this.fs = 1;
+ this.mx = 0;
+ this.my = 0;
+
+ this.fluidbookRect = null;
+ this.canvasRect = null;
+ this.editorRect = null;
+ this.currentPage = -1;
+
+ this.dimensionProperties = ['left', 'top', 'width', 'height'];
+
+ this.init();
+}
+
+LinkEditor.prototype = {
+ init: function () {
+ this.toolbar = new LinkeditorToolbar(this);
+ this.resize = new LinkeditorResize(this);
+ this.rulers = new LinkeditorRulers(this);
+ this.zoom = new LinkeditorZoom(this);
+ this.links = new LinkeditorLinks(this);
+ this.utils = new LinkeditorUtils(this);
+ this.loader = new LinkeditorLoader(this);
+ this.save = new LinkeditorSave(this);
+
+ this.initEvents();
+ },
+
+ initEvents: function () {
+ var $this = this;
+ $(window).on('hashchange', function () {
+ $this.changePage();
+ });
-function init() {
- $(window).on('hashchange', function () {
- changePage();
- });
- $(window).on('resize', function () {
- resize();
- });
- $(window).on('beforeunload', function () {
- if (unsavedChanges) {
- return TRANSLATIONS.warning_unsaved_changes;
- }
- })
- // Disable scroll by spacebar
- $(window).on('keydown', function (e) {
- if (e.keyCode == 32) {
- $("#linkeditor-main").addClass('grab');
- return false;
- }
- moveRuler();
- });
- $(window).on('keyup', function (e) {
- if (e.keyCode == 32) {
- resetZoomDrag();
- }
- moveRuler();
- });
-
- $("#linkeditor-canvas").on('scroll', function () {
- updateRulers();
- });
-
- $(document).on('mousedown', '.link', function (e) {
- e.preventDefault();
- e.stopPropagation();
- if (!$(this).hasClass('selected')) {
- if (!e.ctrlKey) {
- deselectAllLinks();
+ // Disable scroll by spacebar
+ $(window).on('keydown', function (e) {
+ if (e.keyCode == 32) {
+ $("#linkeditor-main").addClass('grab');
+ return false;
}
- selectLink($(this));
- }
- startDragLink();
-
- return false;
- });
-
- $(document).on('mousedown', "#linkeditor-main", function (e) {
- if ($(this).hasClass('grab') && zoom > 1) {
- zoomdragging = {
- x: e.pageX,
- y: e.pageY,
- scrollX: $("#linkeditor-canvas").scrollLeft(),
- scrollY: $("#linkeditor-canvas").scrollTop()
- };
- $(this).addClass('grabbing');
- } else {
- resetZoomDrag();
- }
- deselectAllLinks();
- });
-
-
- $("#linkeditor-ruler-x").on('mousedown', function (e) {
- addRuler('y');
- });
+ $this.rulers.moveRuler();
+ });
+ $(window).on('keyup', function (e) {
+ if (e.keyCode == 32) {
+ $this.zoom.resetZoomDrag();
+ }
+ $this.rulers.moveRuler();
+ });
- $("#linkeditor-ruler-y").on('mousedown', function (e) {
- addRuler('x');
- });
+ $(document).on('mousedown', "#linkeditor-main", function (e) {
+ if ($(this).hasClass('grab') && $this.zoom.zoom > 1) {
+ $this.zoomdragging = {
+ x: e.pageX,
+ y: e.pageY,
+ scrollX: $("#linkeditor-canvas").scrollLeft(),
+ scrollY: $("#linkeditor-canvas").scrollTop()
+ };
+ $(this).addClass('grabbing');
+ } else {
+ $this.zoom.resetZoomDrag();
+ }
+ $this.links.deselectAllLinks();
+ });
- $(document).on('mousedown', ".ruler", function (e) {
- movingRuler = $(this);
+ $(window).on('mousemove', function (e) {
+ $this.updateMousePosition(e);
+ });
- });
+ $(window).on('mouseup', function (e) {
+ $this.zoom.mouseUp();
+ $this.rulers.mouseUp();
+ $this.links.mouseUp();
+ });
- $(window).on('mousemove', function (e) {
- if (!$("#linkeditor-main").hasClass('grab') || zoom === 1) {
- resetZoomDrag();
- }
- if (zoomdragging !== false) {
- moveZoomDrag(e);
- }
- updateMousePosition(e);
- moveDragLink();
- });
- $(window).on('mouseup', function (e) {
- if (zoomdragging !== false) {
- moveZoomDrag(e);
- }
- stopDragLink();
- stopMoveRuler();
- resetZoomDrag();
- });
- $("#linkeditor-main").on('wheel', function (e) {
- var delta = e.originalEvent.deltaY;
- if (delta == 0) {
- return true;
- }
- e.stopPropagation();
- e.stopImmediatePropagation();
- e.preventDefault();
- if (delta < 0) {
- if (setZoom(zoom + 0.25)) {
- moveZoom(e);
- }
+ if (this.single) {
+ $("#linkeditor").addClass('single');
} else {
- setZoom(zoom - 0.25);
+ $("#linkeditor").addClass('double');
}
- return false;
- });
-
- if (single) {
- $("#linkeditor").addClass('single');
- } else {
- $("#linkeditor").addClass('double');
- }
- $('.linkeditor-page').css({
- width: pw, height: ph
- });
- $("#linkeditor-page-right").css({left: pw})
- $('#linkeditor-fluidbook').css({
- width: fw, height: ph
- });
-
- key('left', function () {
- offsetSelectedLinks('left', -1);
- });
- key('ctrl+left', function () {
- offsetSelectedLinks('left', -10);
- });
- key('right', function () {
- offsetSelectedLinks('left', 1);
- });
- key('ctrl+right', function () {
- offsetSelectedLinks('left', 10);
- });
- key('up', function () {
- offsetSelectedLinks('top', -1);
- });
- key('ctrl+up', function () {
- offsetSelectedLinks('top', -10);
- });
- key('down', function () {
- offsetSelectedLinks('top', 1);
- });
- key('ctrl+down', function () {
- offsetSelectedLinks('top', 10);
- });
-
-
- initToolbar();
- resize();
- changePage();
-}
-
-function startDragLink() {
- dragLinkPos = {x: mx, y: my};
- $(".link.selected").each(function () {
- $(this).data('drag-orig-left', parseFloat($(this).attr('fb-left')));
- $(this).data('drag-orig-top', parseFloat($(this).attr('fb-top')));
- });
-}
-
-function stopDragLink() {
- moveDragLink();
- dragLinkPos = null;
-}
-
-function moveDragLink() {
- if (dragLinkPos === null) {
- return;
- }
- var f = 1 / (fs * zoom);
- var dx = (mx - dragLinkPos.x) * f;
- var dy = (my - dragLinkPos.y) * f;
- $(".link.selected").each(function () {
- $(this).attr('fb-left', $(this).data('drag-orig-left') + dx).attr('fb-top', $(this).data('drag-orig-top') + dy).attr('fb-update', '1');
- });
- updateFBElements(false);
-}
-
-function selectLink(l) {
- if ($(l).find('.corners').length === 0) {
- $(l).append('<div class="corners"><div class="nw"></div><div class="n"></div><div class="ne"></div><div class="e"></div><div class="se"></div><div class="s"></div><div class="sw"></div><div class="w"></div></div>')
- }
- $(l).addClass('selected');
- currentSelection.push(l);
-}
-
-
-function deselectAllLinks() {
- currentSelection = [];
- $(".link.selected").removeClass('selected');
-}
-
-function offsetSelectedLinks(dim, value) {
- console.log(dim, value);
- $('.link.selected').each(function () {
- var v = parseFloat($(this).attr('fb-' + dim));
- $(this).attr('fb-' + dim, v + value).attr('fb-update', '1');
- });
- updateFBElements();
-}
-function initToolbar() {
- $("#linkeditor-page-field input").on('change', function () {
- changePage($(this).val());
- $(this).blur();
- return false;
- });
-
- $("#linkeditor-toolbar [data-icon]").each(function () {
- $(this).append(getSpriteIcon('linkeditor-' + $(this).data('icon')));
- });
-
- $("[data-key]").each(function () {
- var e = $(this);
- key($(this).data('key'), function () {
- $(e).addClass('hover');
- runAction($(e).data('action'));
- setTimeout(function () {
- $(e).removeClass('hover')
- }, 150);
- return false;
+ $('.linkeditor-page').css({
+ width: this.pw, height: this.ph
});
- });
- $('[data-action]').click(function () {
- runAction($(this).data('action'));
- return false;
- });
-
- $('[data-tooltip]').each(function () {
- tippy($(this).get(0), {content: $(this).data('tooltip')});
- });
-}
-
-function runAction(act) {
- eval(act + '()');
-}
-
-function saveLinks(message) {
- if (message === undefined) {
- message = TRANSLATIONS.manual_save_message;
- }
- $.ajax({
- url: '/fluidbook-publication/' + FLUIDBOOK_DATA.id + '/save/links', method: 'post', data: {
- _method: 'put', 'message': message, rulers: window.RULERS, links: window.LINKS,
- }, success: function (data) {
- new Noty({
- type: "success", text: TRANSLATIONS.success_save,
- }).show();
- clearTimeout(automaticSaveTimeout);
- unsavedChanges = false;
- runningAutomaticSaveTimeout = false;
- }, error: function (jqXHR, status, error) {
- hasChanged();
- new Noty({
- type: "error", text: TRANSLATIONS.error_save + ' : ' + error,
- }).show();
- },
- });
-}
-
-function automaticSaveLinks() {
- saveLinks(TRANSLATIONS.automatic_save_message);
-}
-
-function firstPage() {
- changePage(1);
-}
-
-function nextPage() {
- changePage(currentPage + (single ? 1 : 2));
-}
-
-function previousPage() {
- changePage(currentPage - (single ? 1 : 2));
-}
-
-function lastPage() {
- changePage(FLUIDBOOK_DATA.settings.pages);
-}
-
-function focusPageField() {
- var i = $("#linkeditor-page-field input").get(0);
- i.focus();
- i.select();
-}
-
-function zoomReset() {
- setZoom(1);
- resetZoomDrag();
-}
-
-function generateUID() {
- var length = 12;
- var result = '';
- var characters = 'abcdefghijklmnopqrstuvwxyz0123456789';
- var charactersLength = characters.length;
- for (var i = 0; i < length; i++) {
- result += characters.charAt(Math.floor(Math.random() * charactersLength));
- }
- return result;
-}
-
-function addRuler(axis, pos, uid) {
- if (undefined === uid) {
- uid = generateUID();
- RULERS[uid] = {page: currentPage, type: axis, uid: uid};
- hasChanged();
- }
- var ruler = $('<div class="ruler" data-uid="' + uid + '" fb-update="1" fb-ref="editor" data-axis="' + axis + '"></div>');
- if (pos === undefined) {
- movingRuler = ruler;
- } else {
- var dim = axis == 'x' ? 'left' : 'top';
- $(ruler).attr('fb-' + dim, pos);
- }
- $("#linkeditor-editor").append(ruler);
- moveRuler();
-}
-
-function deleteRuler(ruler) {
- if (ruler === undefined) {
- ruler = movingRuler;
- }
- var uid = $(ruler).data('uid');
- delete RULERS[uid];
- $(ruler).remove();
- movingRuler = null;
- hasChanged();
-}
-
-function hasChanged() {
- unsavedChanges = true;
- if (runningAutomaticSaveTimeout === false) {
- runningAutomaticSaveTimeout = true;
- automaticSaveTimeout = setTimeout(function () {
- automaticSaveLinks();
- }, 1000 * 5 * 60);
- }
-}
-
-function moveRuler() {
- if (movingRuler === null || movingRuler === undefined) {
- return;
- }
- var magnet = !key.ctrl;
- var editorMouse = globalToEditor(mx, my);
- var fbMouse = globalToFluidbook(mx, my, false);
- var css = {};
- var attrs = {'fb-update': '1'};
- var v, fbv;
- if ($(movingRuler).data('axis') === 'x') {
- v = editorMouse.x;
- fbv = attrs['fb-left'] = magnet ? magnetize(fbMouse.x, rulersMagnetValuesX) : fbMouse.x;
- } else {
- v = editorMouse.y;
- fbv = attrs['fb-top'] = magnet ? magnetize(fbMouse.y, rulersMagnetValuesY) : fbMouse.y;
- }
- if (v < 16) {
- $(movingRuler).addClass('pending-delete');
- } else {
- $(movingRuler).removeClass('pending-delete');
- }
- $(movingRuler).css(css).attr(attrs);
- RULERS[$(movingRuler).data('uid')].pos = fbv;
- updateFBElements();
-}
+ $("#linkeditor-page-right").css({left: this.pw})
+ $('#linkeditor-fluidbook').css({
+ width: this.fw, height: this.ph
+ });
-function magnetize(value, values) {
- var sensibility = 8 / (zoom * fs);
- var min = 100000;
- var magnetValue;
- if (values.length === 0) {
- return value;
- }
-
- for (var i in values) {
- var v = values[i];
- var diff = Math.abs(v - value);
- if (diff < min) {
- min = diff;
- magnetValue = v;
+ this.resize.resize();
+ this.changePage();
+ },
+
+ runAction: function (act) {
+ var a = act.split('.');
+ var o = this;
+ let po = this;
+ for (let i in a) {
+ po = o;
+ o = o[a[i]];
}
- }
-
- if (min > sensibility) {
- return value;
- }
- return magnetValue;
-}
+ return o.call(po);
+ },
+
+ firstPage: function () {
+ this.changePage(1);
+ },
+
+ nextPage: function () {
+ this.changePage(this.currentPage + (this.single ? 1 : 2));
+ },
+
+ previousPage: function () {
+ this.changePage(this.currentPage - (this.single ? 1 : 2));
+ },
+
+ lastPage: function () {
+ this.changePage(FLUIDBOOK_DATA.settings.pages);
+ },
+
+ focusPageField: function () {
+ let i = $("#linkeditor-page-field input").get(0);
+ i.focus();
+ i.select();
+ },
+
+ hasChanged: function () {
+ this.save.hasChanged();
+ },
+
+ updateFBElements: function (force) {
+ let $this = this;
+ requestAnimationFrame(function () {
+ $this._updateFBElements(force);
+ });
+ },
-function getLinksOfPage(p) {
- let pages = [];
- if (!single) {
- if (p % 2 === 1) {
- p--;
- }
- pages.push(p);
- pages.push(p + 1);
- } else {
- pages.push(p);
- }
- let res = {};
- $.each(LINKS, function (uid, link) {
- if (pages.indexOf(parseInt(link.page)) >= 0) {
- res[uid] = link;
+ _updateFBElements: function (force) {
+ let $this = this;
+ let selector = '[fb-ref]';
+ if (force !== true) {
+ selector += '[fb-update="1"]';
}
- });
- return res;
-}
-function updateFBElements(force) {
- var selector = '[fb-ref]';
- if (force !== true) {
- selector += '[fb-update="1"]';
- }
-
- $(selector).each(function () {
- var e = $(this);
- var rect = $(this).attr('fb-ref');
- var css = {};
- $.each(dimensionProperties, function (k, dim) {
- if ($(e).is('[fb-' + dim + ']')) {
- var v = parseFloat($(e).attr('fb-' + dim));
- if (dim === 'width' || dim === 'height') {
- css[dim] = v * (fs * zoom);
- } else {
- css[dim] = fluidbookTo(v, dim, rect);
+ $(selector).each(function () {
+ let e = $(this);
+ let rect = $(this).attr('fb-ref');
+ let css = {};
+ $.each($this.dimensionProperties, function (k, dim) {
+ if ($(e).is('[fb-' + dim + ']')) {
+ let v = parseFloat($(e).attr('fb-' + dim));
+ if (dim === 'width' || dim === 'height') {
+ css[dim] = v * ($this.fs * $this.zoom.zoom);
+ } else {
+ css[dim] = $this.fluidbookTo(v, dim, rect);
+ }
}
- }
+ });
+ $(e).css(css).attr('fb-update', '0');
});
- $(e).css(css).attr('fb-update', '0');
- });
-}
-
-function fluidbookTo(dim, name, rect) {
- switch (rect) {
- case 'editor':
- rect = editorRect;
- break;
- case 'canvas':
- rect = canvasRect;
- break;
- }
- return fluidbookToGlobal(dim, name) - rect[name];
-}
-
-function stopMoveRuler() {
- moveRuler();
- if ($(movingRuler).hasClass('pending-delete')) {
- deleteRuler($(movingRuler));
- }
- movingRuler = null;
-}
-
-function updateMousePosition(e) {
- mx = e.pageX;
- my = e.pageY;
- updateMousePositionRulers();
- moveRuler();
-}
-
-function updateMousePositionRulers() {
- var rulersRect = $("#linkeditor-rulers").get(0).getBoundingClientRect();
- var rx = mx - rulersRect.x;
- var ry = my - rulersRect.y;
- $("#linkeditor-ruler-x .info").css('left', rx);
- $("#linkeditor-ruler-y .info").css('top', ry);
-
- var rrect = $("#linkeditor-rulers").get(0).getBoundingClientRect();
-
- if (mx - rrect.x < 0 || my - rrect.y < 0 || mx - rrect.x > rrect.width || my - rrect.y > rrect.height) {
- $("#linkeditor-rulers .info").hide();
- return;
- }
-
- var fb = globalToFluidbook(mx, my, true);
- $("#linkeditor-ruler-y .info span").text(fb.y.toFixed(2));
- $("#linkeditor-ruler-x .info span").text(fb.x.toFixed(2));
- $("#linkeditor-rulers .info").css('display', 'inline-block');
-}
-
-function resetZoomDrag() {
- $("#linkeditor-main").removeClass('grab').removeClass('grabbing');
- if (zoom === 1) {
- $("#linkeditor-canvas").scrollTo({left: 0, top: 0});
- }
- zoomdragging = false;
-}
-
-function moveZoomDrag(e) {
- var deltaX = e.pageX - zoomdragging.x;
- var deltaY = e.pageY - zoomdragging.y;
- $("#linkeditor-canvas").scrollTo({
- top: zoomdragging.scrollY - deltaY, left: zoomdragging.scrollX - deltaX
- });
- updateRulers();
-}
-
-function moveZoom(e) {
- var rect = $("#linkeditor-zoom").get(0).getBoundingClientRect();
- var lx = (e.originalEvent.pageX - rect.x) / rect.width;
- var ly = (e.originalEvent.pageY - rect.y) / rect.height;
- $("#linkeditor-canvas").scrollTo({left: pct(lx), top: pct(ly)});
- updateRulers();
-}
-
-function pct(v) {
- return (v * 100) + '%';
-}
-
-function setZoom(z) {
- z = Math.max(1, Math.min(6, z));
- if (z === zoom) {
- return false;
- }
- zoom = z;
- $("#linkeditor-canvas").attr('data-z', zoom);
- $("#linkeditor-zoom").css({transform: 'scale(' + zoom + ')', overflow: 'visible'});
-
- setTimeout(function () {
- $("#linkeditor-zoom").css({overflow: 'hidden'});
- if (zoom === 1) {
- resetZoomDrag();
+ },
+
+ fluidbookTo: function (dim, name, rect) {
+ switch (rect) {
+ case 'editor':
+ rect = this.editorRect;
+ break;
+ case 'canvas':
+ rect = this.canvasRect;
+ break;
}
- updateRulers();
-
- }, 10);
-
- return true;
-}
-
-function changePage(page) {
- if (page === undefined) {
- var h = window.location.hash;
- if (h.length === 0) {
- page = 0;
- } else {
- page = window.location.hash.substring(1);
+ return this.fluidbookToGlobal(dim, name) - rect[name];
+ },
+
+
+ updateMousePosition: function (e) {
+ this.mx = e.pageX;
+ this.my = e.pageY;
+
+ this.rulers.updateMousePositionRulers();
+ this.rulers.moveRuler();
+ this.links.moveDragLink();
+ this.links.moveResizeLink();
+ this.zoom.updateMousePosition();
+ },
+
+ changePage: function (page) {
+ if (page === undefined) {
+ let h = window.location.hash;
+ if (h.length === 0) {
+ page = 0;
+ } else {
+ page = window.location.hash.substring(1);
+ }
}
- }
- page = parseInt(page);
- if (page % 2 === 1 && !single) {
- page--;
- }
- var normPage = Math.max(0, Math.min(page, FLUIDBOOK_DATA.settings.pages));
- if (normPage === currentPage) {
- return;
- }
- currentPage = normPage;
-
- window.location.hash = '#' + currentPage;
- clearLinksAndRulers();
- loadPage(currentPage, 'left');
- if (!single) {
- loadPage(currentPage + 1, 'right');
- }
- $("#linkeditor-page-field input").val(currentPage);
- updateRulersMagnetValues();
- resize();
- preloadPages();
-}
-
-function updateRulersMagnetValues() {
- rulersMagnetValuesX = [0, pw, pw * 2];
- rulersMagnetValuesY = [0, ph];
- $.each(getLinksOfPage(currentPage), function (uid, link) {
- const left = parseFloat(link.left);
- const top = parseFloat(link.top);
- const width = parseFloat(link.width);
- const height = parseFloat(link.height);
- rulersMagnetValuesX.push(left, left + width);
- rulersMagnetValuesY.push(top, top + height);
- });
-}
-
-// Convert global coordinates to fluidbook ones
-function globalToFluidbook(x, y, onePage) {
- var res = _globalTo(x, y, fluidbookRect, 1 / (fs * zoom));
- if (onePage) {
- res.xside = 'left';
- if (!single && res.x >= pw) {
- res.xside = 'right';
- res.x -= pw;
+ let normPage = this.utils.normalizePage(page);
+ if (normPage === this.currentPage) {
+ return;
}
- }
- return res;
-}
-
-function fluidbookToGlobal(dim, name) {
- return fluidbookRect[name] + (dim * fs * zoom);
-}
-
-function globalToCanvas(x, y) {
- return _globalTo(x, y, canvasRect, 1);
-}
-
-function globalToEditor(x, y) {
- return _globalTo(x, y, editorRect, 1);
-}
-
-function _globalTo(x, y, rect, multi) {
- return {x: multi * (x - rect.x), y: multi * (y - rect.y)};
-}
-
-function loadPage(p, side) {
- var container = $("#linkeditor-page-" + side);
- $(container).attr('data-page', p);
-
- if (p === 0 || p > FLUIDBOOK_DATA.settings.pages) {
- $(container).html('');
- } else {
- _loadPage(p, container);
- }
-
- loadLinks(p, side);
- loadRulers(p, side);
-}
+ this.currentPage = normPage;
-function preloadPages() {
- let j = 1;
- for (let i = Math.max(1, currentPage - 4); i <= Math.min(currentPage + 16, FLUIDBOOK_DATA.settings.pages); i++) {
- if ($('.preload[data-page="' + i + '"]').length >= 1) {
- continue;
+ window.location.hash = '#' + this.currentPage;
+ this.clearLinksAndRulers();
+ this.loader.loadPage(this.currentPage, 'left');
+ if (!this.loader.single) {
+ this.loader.loadPage(this.currentPage + 1, 'right');
}
- setTimeout(function () {
- var c = $('<div class="preload" data-page="i"></div>');
- $("#linkeditor-preload").append(c);
- _loadPage(i, c);
- }, j * 500);
- j++;
- }
-}
+ $("#linkeditor-page-field input").val(this.currentPage);
+ this.rulers.updateRulersMagnetValues();
+ this.resize.resize();
+ this.loader.preloadPages();
+ },
-function _loadPage(p, container) {
- var imageFormat = FLUIDBOOK_DATA.settings.imageFormat;
- var c = '<div class="contents">';
- if (rasterizePages.indexOf(p) >= 0) {
- c += '<img draggable="false" src="raster_' + p + '.' + imageFormat + '" />';
- } else if (vectorPages.indexOf(p) >= 0) {
- c += '<img draggable="false" src="vector_' + p + '.svg" />';
- } else {
- c += '<img draggable="false" class="images" src="images_' + p + '.' + imageFormat + '" />';
- c += '<img draggable="false" class="texts" src="texts_' + p + '.svg" />';
- }
- c += '</div>';
- $(container).html(c);
-}
-function loadLinks(page, side) {
- $.each(LINKS, function (uid, link) {
- if (link.page != page) {
- return;
- }
- if (side === 'right') {
- link.left = parseInt(link.left) + pw;
+// Convert global coordinates to fluidbook ones
+ globalToFluidbook: function (x, y, onePage) {
+ let res = this._globalTo(x, y, this.fluidbookRect, 1 / (this.fs * this.zoom.zoom));
+ if (onePage) {
+ res.xside = 'left';
+ if (!this.single && res.x >= this.pw) {
+ res.xside = 'right';
+ res.x -= this.pw;
+ }
}
- addLink(link, side);
- });
-}
+ return res;
+ },
-function addLink(link) {
- if (link.uid === undefined) {
- link.uid = generateUID();
- LINKS[link.uid] = link;
- updateRulersMagnetValues();
- hasChanged();
- }
-
- var attrs = {};
- $.each(link, function (k, v) {
- if (dimensionProperties.indexOf(k) >= 0) {
- attrs['fb-' + k] = v;
- } else {
- attrs['data-' + k] = v;
- }
- });
+ fluidbookToGlobal: function (dim, name) {
+ return this.fluidbookRect[name] + (dim * this.fs * this.zoom.zoom);
+ },
- var e = $('<div class="link" fb-ref="editor" fb-update="1"></div>');
- $(e).attr(attrs);
- $("#linkeditor-links").append(e);
-}
+ globalToCanvas: function (x, y) {
+ return this._globalTo(x, y, this.canvasRect, 1);
+ },
-function clearLinksAndRulers() {
- $('#linkeditor-editor .ruler').remove();
-}
+ globalToEditor: function (x, y) {
+ return this._globalTo(x, y, this.editorRect, 1);
+ },
-function loadRulers(page, side) {
- $.each(RULERS, function (uid, ruler) {
- if (ruler.page != page) {
- return;
- }
- addRuler(ruler.type, ruler.pos, ruler.uid);
- });
-}
+ _globalTo: function (x, y, rect, multi) {
+ return {x: multi * (x - rect.x), y: multi * (y - rect.y)};
+ },
-
-function resize() {
- resizeCanvas();
- updateRulers();
+ clearLinksAndRulers: function () {
+ this.rulers.clear();
+ this.links.clear();
+ },
}
-function updateRulers() {
- // Update rects
- fluidbookRect = $("#linkeditor-fluidbook").get(0).getBoundingClientRect();
-
- $("#linkeditor-ruler-y,#linkeditor-ruler-x").html('');
- // Measure of visible fluidbook px at current zoom
-
- var factor = fs / zoom;
- var visible_w = (canvasRect.width / fs) / zoom;
- var visible_h = (canvasRect.height / fs) / zoom;
- // Find the best divider to have around 10 main divisions
- var divider = 0;
- for (var i in dividers) {
- divider = dividers[i];
- var v = visible_h / divider;
- if (v <= 10) {
- break;
- }
- }
-
- var divisionSize = divider * fs * zoom;
- // Draw vertical ruler
- var margin = 100;
- var nbDivisions = Math.floor(visible_h / divider);
- var y0 = 16 + fluidbookRect.y - canvasRect.y;
-
- var yruler = '<div class="info"><span>1234.12</span></div>';
- for (var y = -margin; y <= nbDivisions + (margin * 2) + 1; y++) {
- // Draw subdivision
- var v = divider * y;
- var ystart = y0 + (y * divisionSize);
- if (ystart + divisionSize < 0 || ystart > canvasRect.height) {
- continue;
- }
- yruler += '<div class="division" style="top:' + ystart + 'px;height:' + divisionSize + 'px;"><div class="value">' + Math.abs(v) + '</div>';
- for (var i = 1; i <= 9; i++) {
- yruler += '<div class="subdivision ' + (i === 5 ? ' middle' : '') + '" style="top:' + ((i * divisionSize) / 10) + 'px;"></div>';
- }
- yruler += '</div>';
- }
- $("#linkeditor-ruler-y").html(yruler);
-
- // Draw horizontal ruler
- nbDivisions = Math.floor(visible_w / divider);
- var x0 = 16 + fluidbookRect.x - canvasRect.x;
- var xruler = '<div class="info"><span></span></div>';
-
- for (var x = -margin; x <= nbDivisions + (margin * 2) + 1; x++) {
- // Draw subdivision
- var v = divider * x;
- var xstart = x0 + (x * divisionSize);
- if (xstart + divisionSize < 0 || xstart > canvasRect.width) {
- continue;
- }
- xruler += '<div class="division" style="left:' + xstart + 'px;width:' + divisionSize + 'px;"><div class="value">' + Math.abs(v) + '</div>';
- for (var i = 1; i <= 9; i++) {
- var cls = '';
- if (i === 5) {
- cls += ' middle';
- }
- xruler += '<div class="subdivision ' + cls + '" style="left:' + ((i * divisionSize) / 10) + 'px;"></div>';
- }
- xruler += '</div>';
- }
- // Draw right page horizontal ruler
- if (!single) {
- x0 = x0 + pw * fs * zoom;
- for (var x = 0; x <= nbDivisions + margin + 1; x++) {
- // Draw subdivision
- var v = divider * x;
- var xstart = x0 + (x * divisionSize);
- if (xstart + divisionSize < 0 || xstart > canvasRect.width) {
- continue;
- }
- xruler += '<div class="division" style="left:' + xstart + 'px;width:' + divisionSize + 'px;"><div class="value">' + Math.abs(v) + '</div>';
- for (var i = 1; i <= 9; i++) {
- var cls = '';
- if (i === 5) {
- cls += ' middle';
- }
- xruler += '<div class="subdivision ' + cls + '" style="left:' + ((i * divisionSize) / 10) + 'px;"></div>';
- }
- xruler += '</div>';
- }
- }
- $("#linkeditor-ruler-x").html(xruler);
- updateFBElements(true);
- updateMousePositionRulers();
-}
+$(function () {
+ window.linkeditor = new LinkEditor();
+});
-function resizeCanvas() {
- canvasRect = $("#linkeditor-canvas").get(0).getBoundingClientRect();
- editorRect = $("#linkeditor-editor").get(0).getBoundingClientRect();
- var aw = canvasRect.width - 30;
- var ah = canvasRect.height - 30;
- fs = Math.min(aw / fw, ah / fh);
- var left = (canvasRect.width - fw * fs) / 2;
- var top = (canvasRect.height - fh * fs) / 2;
- $("#linkeditor-fluidbook").css({left: left, top: top, transform: 'scale(' + fs + ')'});
-}
-function splitPages(str) {
- str = str.toString();
- var res = [];
- if (str == '') {
- return res;
- }
- var pages = str.split(',');
- for (var p in pages) {
- res.push(parseInt(pages[p]));
- }
- return res;
-}
--- /dev/null
+var LinkeditorLinks = function (linkeditor) {
+ this.linkeditor = linkeditor;
+
+ this.currentSelection = [];
+ this.dragLinkPos = null;
+ this.resizeLinkPos = null;
+
+ this.init();
+}
+
+LinkeditorLinks.prototype = {
+ init: function () {
+ var $this = this;
+ $(document).on('mousedown', '.link .corners div', function (e) {
+ e.preventDefault();
+ e.stopPropagation();
+ $this.deselectAllLinks();
+ let link = $(this).closest('.link');
+ $this.selectLink(link);
+ $this.startResizeLink($(this).attr('class'));
+ });
+
+ $(document).on('mousedown', '.link', function (e) {
+ e.preventDefault();
+ e.stopPropagation();
+ if (!$(this).hasClass('selected')) {
+ if (!e.ctrlKey) {
+ $this.deselectAllLinks();
+ }
+ $this.selectLink($(this));
+ }
+ $this.startDragLink();
+ return false;
+ });
+
+ key('left', function () {
+ $this.offsetSelectedLinks('left', -1);
+ });
+ key('ctrl+left', function () {
+ $this.offsetSelectedLinks('left', -10);
+ });
+ key('right', function () {
+ $this.offsetSelectedLinks('left', 1);
+ });
+ key('ctrl+right', function () {
+ $this.offsetSelectedLinks('left', 10);
+ });
+ key('up', function () {
+ $this.offsetSelectedLinks('top', -1);
+ });
+ key('ctrl+up', function () {
+ $this.offsetSelectedLinks('top', -10);
+ });
+ key('down', function () {
+ $this.offsetSelectedLinks('top', 1);
+ });
+ key('ctrl+down', function () {
+ $this.offsetSelectedLinks('top', 10);
+ });
+ },
+
+ mouseUp: function () {
+ this.stopDragLink();
+ this.stopResizeLink();
+ },
+
+ startResizeLink: function (corner) {
+ this.resizeLinkPos = {x: this.linkeditor.mx, y: this.linkeditor.my, corner: corner};
+ $(".link.selected").each(function () {
+ $(this).data('drag-orig-left', parseFloat($(this).attr('fb-left')));
+ $(this).data('drag-orig-top', parseFloat($(this).attr('fb-top')));
+ $(this).data('drag-orig-width', parseFloat($(this).attr('fb-width')));
+ $(this).data('drag-orig-height', parseFloat($(this).attr('fb-height')));
+ });
+ console.log(this.resizeLinkPos);
+ },
+
+ stopResizeLink: function () {
+ this.moveResizeLink();
+ this.resizeLinkPos = null;
+ },
+
+ moveResizeLink: function () {
+ if (this.resizeLinkPos === null) {
+ return;
+ }
+ var f = 1 / (this.linkeditor.fs * this.linkeditor.zoom.zoom);
+ var dx = (this.linkeditor.mx - this.resizeLinkPos.x) * f;
+ var dy = (this.linkeditor.my - this.resizeLinkPos.y) * f;
+
+ var top = 0, left = 0, width = 0, height = 0;
+
+ if (['n', 'ne', 'nw'].indexOf(this.resizeLinkPos.corner) >= 0) {
+ top = dy;
+ height = -dy;
+ } else if (['s', 'se', 'sw'].indexOf(this.resizeLinkPos.corner) >= 0) {
+ height = dy;
+ }
+ if (['nw', 'w', 'sw'].indexOf(this.resizeLinkPos.corner) >= 0) {
+ left = dx;
+ width = -dx;
+ } else if (['ne', 'e', 'se'].indexOf(this.resizeLinkPos.corner) >= 0) {
+ width = dx;
+ }
+
+ $(".link.selected").each(function () {
+ var newWidth = $(this).data('drag-orig-width') + width;
+ var newHeight = $(this).data('drag-orig-height') + height;
+
+ if (key.ctrl) {
+ // Keep ratio
+ var ratio = $(this).data('drag-orig-width') / $(this).data('drag-orig-height');
+ var xscale = newWidth / $(this).data('drag-orig-width');
+ var yscale = newHeight / $(this).data('drag-orig-height');
+ if (['ne', 'nw', 'se', 'sw'].indexOf(this.resizeLinkPos.corner) >= 0) {
+ if (xscale < yscale) {
+ newHeight = newWidth / ratio;
+ } else {
+ newWidth = newHeight * ratio;
+ }
+ } else if (['e', 'w'].indexOf(this.resizeLinkPos.corner) >= 0) {
+ newHeight = newWidth / ratio;
+ } else if (['n', 's'].indexOf(this.resizeLinkPos.corner) >= 0) {
+ newWidth = newHeight * ratio;
+ }
+
+ width = newWidth - $(this).data('drag-orig-width');
+ height = newHeight - $(this).data('drag-orig-height');
+
+ if (['ne', 'e', 'se'].indexOf(this.resizeLinkPos.corner) >= 0) {
+ left = 0;
+ } else if (['nw', 'w', 'sw'].indexOf(this.resizeLinkPos.corner) >= 0) {
+ left = width;
+ }
+ if (['ne', 'n', 'nw'].indexOf(this.resizeLinkPos.corner) >= 0) {
+ top = height;
+ } else if (['se', 's', 'sw'].indexOf(this.resizeLinkPos.corner) >= 0) {
+ top = 0;
+ }
+ }
+
+ var newLeft = $(this).data('drag-orig-left') + left;
+ var newTop = $(this).data('drag-orig-top') + top;
+
+ $(this).attr('fb-left', newLeft)
+ .attr('fb-top', newTop)
+ .attr('fb-width', newWidth)
+ .attr('fb-height', newHeight)
+ .attr('fb-update', '1');
+ });
+ this.linkeditor.updateFBElements(false);
+ },
+
+ startDragLink: function () {
+ this.dragLinkPos = {x: this.linkeditor.mx, y: this.linkeditor.my};
+ $(".link.selected").each(function () {
+ $(this).data('drag-orig-left', parseFloat($(this).attr('fb-left')));
+ $(this).data('drag-orig-top', parseFloat($(this).attr('fb-top')));
+ });
+ },
+
+ stopDragLink: function () {
+ this.moveDragLink();
+ this.dragLinkPos = null;
+ },
+
+ moveDragLink: function () {
+ if (this.dragLinkPos === null) {
+ return;
+ }
+ var f = 1 / (this.linkeditor.fs * this.linkeditor.zoom.zoom);
+ var dx = (this.linkeditor.mx - this.dragLinkPos.x) * f;
+ var dy = (this.linkeditor.my - this.dragLinkPos.y) * f;
+ $(".link.selected").each(function () {
+ $(this).attr('fb-left', $(this).data('drag-orig-left') + dx).attr('fb-top', $(this).data('drag-orig-top') + dy).attr('fb-update', '1');
+ });
+ this.linkeditor.updateFBElements(false);
+ },
+
+ selectLink: function (l) {
+ if ($(l).find('.corners').length === 0) {
+ $(l).append('<div class="corners"><div class="nw"></div><div class="n"></div><div class="ne"></div><div class="e"></div><div class="se"></div><div class="s"></div><div class="sw"></div><div class="w"></div></div>')
+ }
+ $(l).addClass('selected');
+ this.currentSelection.push(l);
+ },
+
+
+ deselectAllLinks: function () {
+ this.currentSelection = [];
+ $(".link.selected").removeClass('selected');
+ },
+
+ offsetSelectedLinks: function (dim, value) {
+ $('.link.selected').each(function () {
+ var v = parseFloat($(this).attr('fb-' + dim));
+ $(this).attr('fb-' + dim, v + value).attr('fb-update', '1');
+ });
+ this.linkeditor.updateFBElements();
+ },
+
+ getLinksOfPage: function (p) {
+ let pages = [];
+ if (!this.linkeditor.single) {
+ if (p % 2 === 1) {
+ p--;
+ }
+ pages.push(p);
+ pages.push(p + 1);
+ } else {
+ pages.push(p);
+ }
+ let res = {};
+ $.each(LINKS, function (uid, link) {
+ if (pages.indexOf(parseInt(link.page)) >= 0) {
+ res[uid] = link;
+ }
+ });
+ return res;
+ },
+
+ loadLinks: function (page, side) {
+ var $this = this;
+ $.each(LINKS, function (uid, link) {
+ if (link.page != page) {
+ return;
+ }
+ if (side === 'right') {
+ link.left = parseInt(link.left) + $this.linkeditor.pw;
+ }
+ $this.addLink(link, side);
+ });
+ },
+
+ addLink: function (link) {
+ var $this = this;
+ if (link.uid === undefined) {
+ link.uid = generateUID();
+ LINKS[link.uid] = link;
+ this.linkeditor.rulers.updateRulersMagnetValues();
+ this.linkeditor.hasChanged();
+ }
+
+ var attrs = {};
+ $.each(link, function (k, v) {
+ if ($this.linkeditor.dimensionProperties.indexOf(k) >= 0) {
+ attrs['fb-' + k] = v;
+ } else {
+ attrs['data-' + k] = v;
+ }
+ });
+
+ var e = $('<div class="link" fb-ref="editor" fb-update="1"></div>');
+ $(e).attr(attrs);
+ $("#linkeditor-links").append(e);
+ },
+
+
+ clear: function () {
+
+ },
+};
+module.exports = LinkeditorLinks;
--- /dev/null
+function LinkeditorLoader(linkeditor) {
+ this.linkeditor = linkeditor;
+ this.init();
+}
+
+LinkeditorLoader.prototype = {
+
+ init: function () {
+ this.rasterizePages = this.linkeditor.utils.splitPages(FLUIDBOOK_DATA.settings.rasterizePages);
+ this.vectorPages = this.linkeditor.utils.splitPages(FLUIDBOOK_DATA.settings.vectorPages);
+ },
+
+ loadPage: function (p, side) {
+ var container = $("#linkeditor-page-" + side);
+ $(container).attr('data-page', p);
+
+ if (p === 0 || p > FLUIDBOOK_DATA.settings.pages) {
+ $(container).html('');
+ } else {
+ this._loadPage(p, container);
+ }
+
+ this.linkeditor.links.loadLinks(p, side);
+ this.linkeditor.rulers.loadRulers(p, side);
+ },
+
+
+ preloadPages: function () {
+ let j = 1;
+ var $this = this;
+ for (let i = Math.max(1, this.linkeditor.currentPage - 4); i <= Math.min(this.linkeditor.currentPage + 16, FLUIDBOOK_DATA.settings.pages); i++) {
+ if ($('.preload[data-page="' + i + '"]').length >= 1) {
+ continue;
+ }
+ setTimeout(function () {
+ var c = $('<div class="preload" data-page="i"></div>');
+ $("#linkeditor-preload").append(c);
+ $this._loadPage(i, c);
+ }, j * 500);
+ j++;
+ }
+ },
+
+ _loadPage: function (p, container) {
+ var imageFormat = FLUIDBOOK_DATA.settings.imageFormat;
+ var c = '<div class="contents">';
+ if (this.rasterizePages.indexOf(p) >= 0) {
+ c += '<img draggable="false" src="raster_' + p + '.' + imageFormat + '" />';
+ } else if (this.vectorPages.indexOf(p) >= 0) {
+ c += '<img draggable="false" src="vector_' + p + '.svg" />';
+ } else {
+ c += '<img draggable="false" class="images" src="images_' + p + '.' + imageFormat + '" />';
+ c += '<img draggable="false" class="texts" src="texts_' + p + '.svg" />';
+ }
+ c += '</div>';
+ $(container).html(c);
+ },
+}
+module.exports = LinkeditorLoader;
--- /dev/null
+function LinkeditorResize(linkeditor) {
+ this.linkeditor = linkeditor;
+ this.init();
+}
+
+LinkeditorResize.prototype = {
+ init: function () {
+ var $this = this;
+ $(window).on('resize', function () {
+ $this.resize();
+ });
+ },
+
+ resize: function () {
+ this.resizeCanvas();
+ this.linkeditor.rulers.updateRulers();
+ },
+
+ resizeCanvas: function () {
+ this.linkeditor.canvasRect = $("#linkeditor-canvas").get(0).getBoundingClientRect();
+ this.linkeditor.editorRect = $("#linkeditor-editor").get(0).getBoundingClientRect();
+ var aw = this.linkeditor.canvasRect.width - 30;
+ var ah = this.linkeditor.canvasRect.height - 30;
+ this.linkeditor.fs = Math.min(aw / this.linkeditor.fw, ah / this.linkeditor.fh);
+ var left = (this.linkeditor.canvasRect.width - this.linkeditor.fw * this.linkeditor.fs) / 2;
+ var top = (this.linkeditor.canvasRect.height - this.linkeditor.fh * this.linkeditor.fs) / 2;
+ $("#linkeditor-fluidbook").css({left: left, top: top, transform: 'scale(' + this.linkeditor.fs + ')'});
+ },
+};
+module.exports = LinkeditorResize;
--- /dev/null
+function LinkeditorRulers(linkeditor) {
+ this.linkeditor = linkeditor;
+
+ this.movingRuler = null;
+ this.rulersMagnetValuesX = [];
+ this.rulersMagnetValuesY = [];
+ this.dividers = [1, 2, 5, 10, 20, 50, 100, 200];
+
+ this.init();
+}
+
+LinkeditorRulers.prototype = {
+ init: function () {
+ let $this = this;
+ $("#linkeditor-canvas").on('scroll', function () {
+ $this.updateRulers();
+ });
+
+ $("#linkeditor-ruler-x").on('mousedown', function (e) {
+ $this.addRuler('y');
+ });
+
+ $("#linkeditor-ruler-y").on('mousedown', function (e) {
+ $this.addRuler('x');
+ });
+
+ $(document).on('mousedown', ".ruler", function (e) {
+ $this.movingRuler = $(this);
+ });
+ },
+
+ mouseUp: function () {
+ this.stopMoveRuler();
+ },
+
+ loadRulers: function (page, side) {
+ let $this = this;
+ $.each(RULERS, function (uid, ruler) {
+ if (ruler.page != page) {
+ return;
+ }
+ $this.addRuler(ruler.type, ruler.pos, ruler.uid);
+ });
+ },
+
+
+ updateRulers: function () {
+ // Update rects
+ this.linkeditor.fluidbookRect = $("#linkeditor-fluidbook").get(0).getBoundingClientRect();
+
+ $("#linkeditor-ruler-y,#linkeditor-ruler-x").html('');
+ // Measure of visible fluidbook px at current zoom
+
+ let factor = this.linkeditor.fs / this.linkeditor.zoom.zoom;
+ let visible_w = (this.linkeditor.canvasRect.width / this.linkeditor.fs) / this.linkeditor.zoom.zoom;
+ let visible_h = (this.linkeditor.canvasRect.height / this.linkeditor.fs) / this.linkeditor.zoom.zoom;
+
+ // Find the best divider to have around 10 main divisions
+ let divider = 0;
+ for (let d in this.dividers) {
+ divider = this.dividers[d];
+ let v = visible_h / divider;
+ if (v <= 10) {
+ break;
+ }
+ }
+
+ let divisionSize = divider * this.linkeditor.fs * this.linkeditor.zoom.zoom;
+ // Draw vertical ruler
+ let margin = 100;
+ let nbDivisions = Math.floor(visible_h / divider);
+ let y0 = 16 + this.linkeditor.fluidbookRect.y - this.linkeditor.canvasRect.y;
+
+ let yruler = '<div class="info"><span>1234.12</span></div>';
+ for (let y = -margin; y <= nbDivisions + (margin * 2) + 1; y++) {
+ // Draw subdivision
+ let v = divider * y;
+ let ystart = y0 + (y * divisionSize);
+ if (ystart + divisionSize < 0 || ystart > this.linkeditor.canvasRect.height) {
+ continue;
+ }
+ yruler += '<div class="division" style="top:' + ystart + 'px;height:' + divisionSize + 'px;"><div class="value">' + Math.abs(v) + '</div>';
+ for (let j = 1; j <= 9; j++) {
+ yruler += '<div class="subdivision ' + (j === 5 ? ' middle' : '') + '" style="top:' + ((j * divisionSize) / 10) + 'px;"></div>';
+ }
+ yruler += '</div>';
+ }
+ $("#linkeditor-ruler-y").html(yruler);
+
+ // Draw horizontal ruler
+ nbDivisions = Math.floor(visible_w / divider);
+ let x0 = 16 + this.linkeditor.fluidbookRect.x - this.linkeditor.canvasRect.x;
+ let xruler = '<div class="info"><span></span></div>';
+
+ for (let x = -margin; x <= nbDivisions + (margin * 2) + 1; x++) {
+ // Draw subdivision
+ xruler += this._drawHorizontalSubdiv(x, x0, divider, divisionSize);
+ }
+ // Draw right page horizontal ruler
+ if (!this.linkeditor.single) {
+ x0 = x0 + this.linkeditor.pw * this.linkeditor.fs * this.linkeditor.zoom.zoom;
+ for (let x = 0; x <= nbDivisions + margin + 1; x++) {
+ // Draw subdivision
+ xruler += this._drawHorizontalSubdiv(x, x0, divider, divisionSize);
+ }
+ }
+ $("#linkeditor-ruler-x").html(xruler);
+ this.linkeditor.updateFBElements(true);
+ this.updateMousePositionRulers();
+ },
+
+ _drawHorizontalSubdiv: function (x, x0, divider, divisionSize) {
+ let v = divider * x;
+ let xstart = x0 + (x * divisionSize);
+ if (xstart + divisionSize < 0 || xstart > this.linkeditor.canvasRect.width) {
+ return '';
+ }
+ let res = '<div class="division" style="left:' + xstart + 'px;width:' + divisionSize + 'px;"><div class="value">' + Math.abs(v) + '</div>';
+ for (let i = 1; i <= 9; i++) {
+ let cls = '';
+ if (i === 5) {
+ cls += ' middle';
+ }
+ res += '<div class="subdivision ' + cls + '" style="left:' + ((i * divisionSize) / 10) + 'px;"></div>';
+ }
+ res += '</div>';
+ return res;
+ },
+
+ updateRulersMagnetValues: function () {
+ var $this = this;
+ this.rulersMagnetValuesX = [0, this.linkeditor.pw, this.linkeditor.pw * 2];
+ this.rulersMagnetValuesY = [0, this.linkeditor.ph];
+ $.each(this.linkeditor.links.getLinksOfPage(this.linkeditor.currentPage), function (uid, link) {
+ const left = parseFloat(link.left);
+ const top = parseFloat(link.top);
+ const width = parseFloat(link.width);
+ const height = parseFloat(link.height);
+ $this.rulersMagnetValuesX.push(left, left + width);
+ $this.rulersMagnetValuesY.push(top, top + height);
+ });
+ },
+
+ updateMousePositionRulers: function () {
+ let rulersRect = $("#linkeditor-rulers").get(0).getBoundingClientRect();
+ let rx = this.linkeditor.mx - rulersRect.x;
+ let ry = this.linkeditor.my - rulersRect.y;
+ $("#linkeditor-ruler-x .info").css('left', rx);
+ $("#linkeditor-ruler-y .info").css('top', ry);
+
+ let rrect = $("#linkeditor-rulers").get(0).getBoundingClientRect();
+
+ if (this.linkeditor.mx - rrect.x < 0 || this.linkeditor.my - rrect.y < 0 || this.linkeditor.mx - rrect.x > rrect.width || this.linkeditor.my - rrect.y > rrect.height) {
+ $("#linkeditor-rulers .info").hide();
+ return;
+ }
+
+ let fb = this.linkeditor.globalToFluidbook(this.linkeditor.mx, this.linkeditor.my, true);
+ $("#linkeditor-ruler-y .info span").text(fb.y.toFixed(2));
+ $("#linkeditor-ruler-x .info span").text(fb.x.toFixed(2));
+ $("#linkeditor-rulers .info").css('display', 'inline-block');
+ },
+
+ stopMoveRuler: function () {
+ this.moveRuler();
+ if ($(this.movingRuler).hasClass('pending-delete')) {
+ this.deleteRuler($(this.movingRuler));
+ }
+ this.movingRuler = null;
+ },
+
+ moveRuler: function () {
+ if (this.movingRuler === null || this.movingRuler === undefined) {
+ return;
+ }
+ let magnet = !key.ctrl;
+ let editorMouse = this.linkeditor.globalToEditor(this.linkeditor.mx, this.linkeditor.my);
+ let fbMouse = this.linkeditor.globalToFluidbook(this.linkeditor.mx, this.linkeditor.my, false);
+ let css = {};
+ let attrs = {'fb-update': '1'};
+ let v, fbv;
+ if ($(this.movingRuler).data('axis') === 'x') {
+ v = editorMouse.x;
+ fbv = attrs['fb-left'] = magnet ? this.linkeditor.utils.magnetize(fbMouse.x, this.rulersMagnetValuesX) : fbMouse.x;
+ } else {
+ v = editorMouse.y;
+ fbv = attrs['fb-top'] = magnet ? this.linkeditor.utils.magnetize(fbMouse.y, this.rulersMagnetValuesY) : fbMouse.y;
+ }
+ if (v < 16) {
+ $(this.movingRuler).addClass('pending-delete');
+ } else {
+ $(this.movingRuler).removeClass('pending-delete');
+ }
+ $(this.movingRuler).css(css).attr(attrs);
+ RULERS[$(this.movingRuler).data('uid')].pos = fbv;
+ this.linkeditor.updateFBElements();
+ },
+
+ addRuler: function (axis, pos, uid) {
+ if (undefined === uid) {
+ uid = this.linkeditor.utils.generateUID();
+ RULERS[uid] = {page: this.linkeditor.currentPage, type: axis, uid: uid};
+ this.linkeditor.hasChanged();
+ }
+ let ruler = $('<div class="ruler" data-uid="' + uid + '" fb-update="1" fb-ref="editor" data-axis="' + axis + '"></div>');
+ if (pos === undefined) {
+ this.movingRuler = ruler;
+ } else {
+ let dim = axis == 'x' ? 'left' : 'top';
+ $(ruler).attr('fb-' + dim, pos);
+ }
+ $("#linkeditor-editor").append(ruler);
+ this.moveRuler();
+ },
+
+ deleteRuler: function (ruler) {
+ if (ruler === undefined) {
+ ruler = this.movingRuler;
+ }
+ delete RULERS[$(ruler).data('uid')];
+ $(ruler).remove();
+ this.movingRuler = null;
+ this.linkeditor.hasChanged();
+ },
+
+ clear: function () {
+ $('#linkeditor-editor .ruler').remove();
+ },
+};
+module.exports = LinkeditorRulers;
--- /dev/null
+
+function LinkeditorSave(linkeditor) {
+ this.linkeditor = linkeditor;
+ this.init();
+}
+
+LinkeditorSave.prototype = {
+ init: function () {
+ let $this = this;
+
+ this.automaticSaveFrequency = 1000 * 5 * 60;
+ this.unsavedChanges = false;
+ this.automaticSaveTimeout = null;
+ this.runningAutomaticSaveTimeout = false;
+
+ $(window).on('beforeunload', function () {
+ if ($this.unsavedChanges) {
+ return TRANSLATIONS.warning_unsaved_changes;
+ }
+ })
+ },
+
+ hasChanged: function () {
+ let $this = this;
+ this.unsavedChanges = true;
+ if (this.runningAutomaticSaveTimeout === false) {
+ this.runningAutomaticSaveTimeout = true;
+ this.automaticSaveTimeout = setTimeout(function () {
+ $this.automaticSave();
+ }, this.automaticSaveFrequency);
+ }
+ },
+
+ save: function (message) {
+ var $this = this;
+ if (message === undefined) {
+ message = TRANSLATIONS.manual_save_message;
+ }
+ $.ajax({
+ url: '/fluidbook-publication/' + FLUIDBOOK_DATA.id + '/save/links', method: 'post', data: {
+ _method: 'put', 'message': message, rulers: window.RULERS, links: window.LINKS,
+ },
+ success: function (data) {
+ new Noty({
+ type: "success", text: TRANSLATIONS.success_save,
+ }).show();
+ clearTimeout(automaticSaveTimeout);
+ $this.unsavedChanges = false;
+ $this.runningAutomaticSaveTimeout = false;
+ },
+ error: function (jqXHR, status, error) {
+ $this.linkeditor.hasChanged();
+ new Noty({
+ type: "error", text: TRANSLATIONS.error_save + ' : ' + error,
+ }).show();
+ },
+ });
+ },
+
+ automaticSave: function () {
+ this.save(TRANSLATIONS.automatic_save_message);
+ },
+};
+
+module.exports = LinkeditorSave;
--- /dev/null
+function LinkeditorToolbar(linkeditor) {
+ this.linkeditor = linkeditor;
+ this.init();
+}
+
+LinkeditorToolbar.prototype = {
+ init: function () {
+ var $this=this;
+ $("#linkeditor-page-field input").on('change', function () {
+ $this.linkeditor.changePage($(this).val());
+ $(this).blur();
+ return false;
+ });
+
+ $("#linkeditor-toolbar [data-icon]").each(function () {
+ $(this).append(getSpriteIcon('linkeditor-' + $(this).data('icon')));
+ });
+
+ $("[data-key]").each(function () {
+ let e = $(this);
+ key($(this).data('key'), function () {
+ $(e).addClass('hover');
+ $this.linkeditor.runAction($(e).data('action'));
+ setTimeout(function () {
+ $(e).removeClass('hover')
+ }, 150);
+ return false;
+ });
+ });
+
+ $('[data-action]').click(function () {
+ $this.linkeditor.runAction($(this).data('action'));
+ return false;
+ });
+
+ $('[data-tooltip]').each(function () {
+ tippy($(this).get(0), {content: $(this).data('tooltip')});
+ });
+ },
+};
+module.exports = LinkeditorToolbar;
--- /dev/null
+var LinkeditorUtils = function (linkeditor) {
+ this.linkeditor = linkeditor;
+ this.init();
+};
+
+LinkeditorUtils.prototype = {
+ init: function () {
+
+ },
+
+ normalizePage: function (page) {
+ page = parseInt(page);
+ if (page % 2 === 1 && !this.linkeditor.single) {
+ page--;
+ }
+ return Math.max(0, Math.min(page, FLUIDBOOK_DATA.settings.pages));
+ },
+
+ splitPages: function (str) {
+ str = str.toString();
+ let res = [];
+ if (str == '') {
+ return res;
+ }
+ let pages = str.split(',');
+ for (let p in pages) {
+ res.push(parseInt(pages[p]));
+ }
+ return res;
+ },
+
+ pct: function (v) {
+ return (v * 100) + '%';
+ },
+
+ generateUID: function () {
+ const length = 12;
+ let result = '';
+ const characters = 'abcdefghijklmnopqrstuvwxyz0123456789';
+ const charactersLength = characters.length;
+ for (let i = 0; i < length; i++) {
+ result += characters.charAt(Math.floor(Math.random() * charactersLength));
+ }
+ return result;
+ },
+
+ magnetize: function (value, values) {
+ let sensibility = 8 / (this.linkeditor.zoom.zoom * this.linkeditor.fs);
+ let min = 100000;
+ let magnetValue;
+ if (values.length === 0) {
+ return value;
+ }
+
+ for (let i in values) {
+ let v = values[i];
+ let diff = Math.abs(v - value);
+ if (diff < min) {
+ min = diff;
+ magnetValue = v;
+ }
+ }
+
+ if (min > sensibility) {
+ return value;
+ }
+ return magnetValue;
+ },
+};
+
+module.exports = LinkeditorUtils;
--- /dev/null
+function LinkeditorZoom(linkeditor) {
+ this.linkeditor = linkeditor;
+ this.init();
+}
+
+LinkeditorZoom.prototype = {
+ init: function () {
+ var $this = this;
+
+ this.zoom = 1;
+ this.zoomdragging = false;
+
+ $("#linkeditor-main").on('wheel', function (e) {
+ let delta = e.originalEvent.deltaY;
+ if (delta == 0) {
+ return true;
+ }
+ e.stopPropagation();
+ e.stopImmediatePropagation();
+ e.preventDefault();
+ if (delta < 0) {
+ if ($this.setZoom($this.zoom + 0.25)) {
+ $this.moveZoom(e);
+ }
+ } else {
+ $this.setZoom($this.zoom - 0.25);
+ }
+ return false;
+ });
+ },
+
+ mouseUp: function () {
+ if (this.zoomdragging !== false) {
+ this.moveZoomDrag(e);
+ }
+ this.resetZoomDrag();
+ },
+
+ updateMousePosition: function () {
+ if (!$("#linkeditor-main").hasClass('grab') || this.zoom === 1) {
+ this.resetZoomDrag();
+ }
+ if (this.zoomdragging !== false) {
+ this.moveZoomDrag(e);
+ }
+ },
+
+ resetZoomDrag: function () {
+ $("#linkeditor-main").removeClass('grab').removeClass('grabbing');
+ if (this.zoom === 1) {
+ $("#linkeditor-canvas").scrollTo({left: 0, top: 0});
+ }
+ this.zoomdragging = false;
+ },
+
+ moveZoomDrag: function (e) {
+ let deltaX = e.pageX - this.zoomdragging.x;
+ let deltaY = e.pageY - this.zoomdragging.y;
+ $("#linkeditor-canvas").scrollTo({
+ top: this.zoomdragging.scrollY - deltaY, left: this.zoomdragging.scrollX - deltaX
+ });
+ this.linkeditor.rulers.updateRulers();
+ },
+
+ moveZoom: function (e) {
+ let rect = $("#linkeditor-zoom").get(0).getBoundingClientRect();
+ let lx = (e.originalEvent.pageX - rect.x) / rect.width;
+ let ly = (e.originalEvent.pageY - rect.y) / rect.height;
+ $("#linkeditor-canvas").scrollTo({left: this.linkeditor.utils.pct(lx), top: this.linkeditor.utils.pct(ly)});
+ this.linkeditor.rulers.updateRulers();
+ },
+
+ setZoom: function (z) {
+ let $this = this;
+ z = Math.max(1, Math.min(6, z));
+ if (z === this.zoom) {
+ return false;
+ }
+ this.zoom = z;
+ $("#linkeditor-canvas").attr('data-z', this.zoom);
+ $("#linkeditor-zoom").css({transform: 'scale(' + this.zoom + ')', overflow: 'visible'});
+
+ setTimeout(function () {
+ $("#linkeditor-zoom").css({overflow: 'hidden'});
+ if (this.zoom === 1) {
+ $this.resetZoomDrag();
+ }
+ $this.linkeditor.rulers.updateRulers();
+
+ }, 10);
+ return true;
+ },
+
+ reset: function () {
+ setZoom(1);
+ resetZoomDrag();
+ },
+};
+module.exports = LinkeditorZoom;
cursor: cell
&.selected
+ cursor: move
.corners
visibility: visible
<div id="linkeditor-main">
<div draggable="false" id="linkeditor-toolbar">
<nav id="linkeditor-toolbar-left">
- <a href="#" data-icon="save" data-action="saveLinks" data-tooltip="{{__('Sauvegarder')}} (Ctrl+S)"
+ <a href="#" data-icon="save" data-action="save.save" data-tooltip="{{__('Sauvegarder')}} (Ctrl+S)"
data-key="ctrl+s"></a>
<a href="#" data-action="openVersions" data-icon="wayback-machine"
data-tooltip="{{__('Restaurer une version précédente')}}"></a>
<div class="separator"></div>
- <a href="#" data-action="zoomReset" data-icon="zoom-reset"
+ <a href="#" data-action="zoom.reset" data-icon="zoom-reset"
data-tooltip="{{__('Réinitialiser le zoom')}} (Esc)" data-key="esc"></a>
<div class="separator"></div>
<a href="#" data-action="importExcel" data-icon="import-links"