From f7155cbe1faa7ce796e7477f0ada42b8a342f782 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Satoru=20MATSUSHIMA=20=28=E2=84=A0=29?= Date: Wed, 13 Sep 2017 19:34:01 +0900 Subject: [PATCH 01/12] Update development environment. --- gulpfile.js | 56 +++++++++++++++++++++++------------------------------ 1 file changed, 24 insertions(+), 32 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index 03c53805..bd9501ca 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -71,28 +71,22 @@ S.getBuildNumber = function() { //---------------------------------------------------------------------------------------------------------------------------------------------- -S.clean = function(list) { - $.del.sync(list); - return gulp; -}; - -gulp.task('clean: Scripts', function() { - return S.clean(ToBeCleaned.Scripts); -}); +S.clean = function(List) { $.del.sync(List); return gulp; }; -gulp.task('clean: Styles', function() { - return S.clean(ToBeCleaned.Styles); -}); - -gulp.task('clean: Metafiles', function() { - return S.clean(ToBeCleaned.Metafiles); -}); +var ToBeCleaned = {}; -gulp.task('clean: All', function() { - return S.clean(ToBeCleaned.All); -}); - -var ToBeCleaned = { +(function(TBC) { + ToBeCleaned.All = []; + for(var Category in TBC) { + ToBeCleaned[Category] = TBC[Category]; + ToBeCleaned.All = ToBeCleaned.All.concat(ToBeCleaned[Category]); + } + for(var Category in ToBeCleaned) { + gulp.task('clean: ' + Category, function() { + return S.clean(ToBeCleaned[Category]); + }); + } +})({ Scripts: [ 'bib/i/res/scripts', 'bib/i.js' @@ -104,15 +98,10 @@ var ToBeCleaned = { Metafiles: [ 'bib/LICENSE', 'bib/README.md' - ] -}; - -S.Extensions.forEach(function(Extension) { - ToBeCleaned.Scripts.push('bib/i/extensions/' + Extension); + ], + Extensions: S.Extensions }); -ToBeCleaned.All = S.concat(ToBeCleaned.Scripts, ToBeCleaned.Styles, ToBeCleaned.Metafiles); - //============================================================================================================================================== //---------------------------------------------------------------------------------------------------------------------------------------------- @@ -216,8 +205,8 @@ S.makeScript = function(Param) { .pipe($.uglify({ preserveComments: 'some' })) .pipe($.replace('0.000.0', S.getVersion())) .pipe($.replace('198106091234', S.getBuildNumber())) - .pipe($.replace(/(.)(\/\*!)/g, '$1\n$2')) - .pipe($.replace(/(\*\/)(.)/g, '$1\n$2')) + .pipe($.replace(/(.)(\/\*!)\n/g, '$1\n$2\n')) + .pipe($.replace(/\n( \*\/)(.)/g, '\n$1\n$2')) .pipe(gulp.dest('')) .pipe($.browserSync.reload({ stream: true })); }; @@ -301,11 +290,14 @@ S.makeStyle = function(Param) { warnForDuplicates: false }), $.cssnano({ - zindex: false + zindex: false, + discardUnused: { + fontFace: false + } }) ])) - .pipe($.replace(/(.)(\/\*!)/g, '$1\n$2')) - .pipe($.replace(/(\*\/)(.)/g, '$1\n$2')) + .pipe($.replace(/(.)(\/\*!)\n/g, '$1\n$2\n')) + .pipe($.replace(/\n( \*\/)(.)/g, '\n$1\n$2')) .pipe(gulp.dest('')) .pipe($.browserSync.reload({ stream: true })); }; From 516773c2c20545445d19963b87c516a5e825b2fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Satoru=20MATSUSHIMA=20=28=E2=84=A0=29?= Date: Tue, 26 Sep 2017 15:22:15 +0900 Subject: [PATCH 02/12] (cosmetic edit) --- dev-bib/i/res/scripts/bibi.heart.js | 103 ++++++++++++++-------------- 1 file changed, 50 insertions(+), 53 deletions(-) diff --git a/dev-bib/i/res/scripts/bibi.heart.js b/dev-bib/i/res/scripts/bibi.heart.js index a184126f..d553888c 100644 --- a/dev-bib/i/res/scripts/bibi.heart.js +++ b/dev-bib/i/res/scripts/bibi.heart.js @@ -5,7 +5,7 @@ * */ -Bibi = { "version": "0.000.0", "build": 198106091234 }; +Bibi = { "version": "0.000.0", "build": 198106091234, "href": "http://bibi.epub.link" }; @@ -20,14 +20,10 @@ Bibi = { "version": "0.000.0", "build": 198106091234 }; document.addEventListener("DOMContentLoaded", function() { setTimeout(Bibi.welcome, 0); }); -Bibi.SiteHref = "http://bibi.epub.link"; -Bibi.WelcomeMessage = 'Welcome! - BiB/i v' + Bibi["version"] + ' (' + Bibi["build"] + ') - [ja] ' + Bibi.SiteHref + ' - [en] https://github.com/satorumurmur/bibi'; - - Bibi.welcome = function() { O.stamp("Welcome!"); - O.log(Bibi.WelcomeMessage, "-0"); + O.log('Welcome! - BiB/i v' + Bibi["version"] + ' (' + Bibi["build"] + ') - [ja] ' + Bibi["href"] + ' - [en] https://github.com/satorumurmur/bibi', "-0"); E.dispatch("bibi:says-welcome"); O.RequestedURL = location.href; @@ -102,7 +98,7 @@ Bibi.initialize = function() { innerHTML: [ '', Msg["en"], '', '', Msg["ja"], '', - ].join("").replace(/(BiB\/i|ビビ)/g, '$1') + ].join("").replace(/(BiB\/i|ビビ)/g, '$1') }) ); I.note('(Your Browser Is Not Compatible)', 99999999999); @@ -2977,7 +2973,7 @@ I.createMenu.createSettingMenu.createLinkageSection = function() { default: { default: "BiB/i | Official Website" } }, Icon: '', - href: Bibi.SiteHref, + href: Bibi["href"], target: "_blank" }); @@ -3205,7 +3201,7 @@ I.createPoweredBy = function() { I.PoweredBy = O.Body.appendChild(sML.create("div", { id: "bibi-poweredby", innerHTML: [ '

', - '', + '', 'BiB/i', '', '', @@ -3426,7 +3422,7 @@ I.createSlider = function() { E.add("bibi:commands:close-slider", function(Opt) { I.Slider.close(Opt); }); E.add("bibi:commands:toggle-slider", function(Opt) { I.Slider.toggle(Opt); }); E.add("bibi:tapped", function(Eve) { - if(!L.Opened) return; + if(!L.Opened) return false; var BibiEvent = O.getBibiEvent(Eve); if(BibiEvent.Target.tagName) { if(/bibi-slider/.test(BibiEvent.Target.id)) return false; @@ -4355,61 +4351,62 @@ O.log = function(Msg, Tag) { if(sML.UA.Gecko && typeof Msg == "string") Msg = Msg.replace(/(https?:\/\/)/g, ""); var Pre = 'BiB/i: '; switch(Tag) { - case "-*": Tag = "-" + (O.log.Depth); break; - case "*:": Tag = (O.log.Depth) + ":"; break; - case "/*" : Tag = "/" + (O.log.Depth - 1); break; + case "*:": Tag = (O.log.Depth ) + ":"; break; + case "/*" : Tag = "/" + (O.log.Depth - 1) ; break; + default : Tag = "-" + (O.log.Depth ) ; break; } switch(Tag) { - case "-x" : Pre += "[ERROR] "; console.info(Pre + Msg); return; - case "-0" : Pre += "━━ "; console.info(Pre + Msg); return; - case "-1" : Pre += " - "; O.log.Depth = 1; break; - case "1:": Pre += "┌ "; O.log.Depth = 2; break; - case "-2" : Pre += "│ - "; O.log.Depth = 2; break; - case "2:": Pre += "│┌ "; O.log.Depth = 3; break; - case "-3" : Pre += "││ - "; O.log.Depth = 3; break; - case "3:": Pre += "││┌ "; O.log.Depth = 4; break; - case "-4" : Pre += "│││ - "; O.log.Depth = 4; break; - case "4:": Pre += "│││┌ "; O.log.Depth = 5; break; - case "-5" : Pre += "││││ - "; O.log.Depth = 5; break; - case "5:": Pre += "││││┌ "; O.log.Depth = 6; break; - case "-6" : Pre += "│││││ - "; O.log.Depth = 6; break; - case "/5" : Pre += "││││└ "; O.log.Depth = 5; break; - case "/4" : Pre += "│││└ "; O.log.Depth = 4; break; - case "/3" : Pre += "││└ "; O.log.Depth = 3; break; - case "/2" : Pre += "│└ "; O.log.Depth = 2; break; - case "/1" : Pre += "└ "; O.log.Depth = 1; break; + case "-x" : Pre += "[ERROR] "; console.info(Pre + Msg); return; + case "-0" : Pre += "━━ "; console.info(Pre + Msg); return; + case "-1" : Pre += " - "; O.log.Depth = 1; break; + case "1:": Pre += "┌ "; O.log.Depth = 2; break; + case "-2" : Pre += "│ - "; O.log.Depth = 2; break; + case "2:": Pre += "│┌ "; O.log.Depth = 3; break; + case "-3" : Pre += "││ - "; O.log.Depth = 3; break; + case "3:": Pre += "││┌ "; O.log.Depth = 4; break; + case "-4" : Pre += "│││ - "; O.log.Depth = 4; break; + case "4:": Pre += "│││┌ "; O.log.Depth = 5; break; + case "-5" : Pre += "││││ - "; O.log.Depth = 5; break; + case "5:": Pre += "││││┌ "; O.log.Depth = 6; break; + case "-6" : Pre += "│││││ - "; O.log.Depth = 6; break; + case "/5" : Pre += "││││└ "; O.log.Depth = 5; break; + case "/4" : Pre += "│││└ "; O.log.Depth = 4; break; + case "/3" : Pre += "││└ "; O.log.Depth = 3; break; + case "/2" : Pre += "│└ "; O.log.Depth = 2; break; + case "/1" : Pre += "└ "; O.log.Depth = 1; break; } console.log(Pre + Msg); }; /*O.log = function(Msg, Tag) { var Pre = 'BiB/i: '; switch(Tag) { - case "-*": Tag = "-" + (O.log.Depth); break; - case "*:": Tag = (O.log.Depth) + ":"; break; - case "/*" : Tag = "/" + (O.log.Depth - 1); break; + case "-*" : Tag = "-" + (O.log.Depth ) ; break; + case "*:": Tag = (O.log.Depth ) + ":"; break; + case "/*" : Tag = "/" + (O.log.Depth - 1) ; break; } switch(Tag) { - case "-x" : Pre += "[ERROR] "; console.error(Pre + Msg); break; - case "-0" : Pre += "━━━━━━━━━━━━ "; console.info(Pre + Msg); break; - case "-1" : O.log.Depth = 1; console.log(Pre + Msg); break; - case "1:": O.log.Depth = 2; console.group(Pre + Msg); break; - case "-2" : O.log.Depth = 2; console.log(Pre + Msg); break; - case "2:": O.log.Depth = 3; console.group(Pre + Msg); break; - case "-3" : O.log.Depth = 3; console.log(Pre + Msg); break; - case "3:": O.log.Depth = 4; console.group(Pre + Msg); break; - case "-4" : O.log.Depth = 4; console.log(Pre + Msg); break; - case "4:": O.log.Depth = 5; console.group(Pre + Msg); break; - case "-5" : O.log.Depth = 5; console.log(Pre + Msg); break; - case "5:": O.log.Depth = 6; console.group(Pre + Msg); break; - case "-6" : O.log.Depth = 6; console.log(Pre + Msg); break; - case "/5" : O.log.Depth = 5; console.log(Pre + Msg); console.groupEnd(); break; - case "/4" : O.log.Depth = 4; console.log(Pre + Msg); console.groupEnd(); break; - case "/3" : O.log.Depth = 3; console.log(Pre + Msg); console.groupEnd(); break; - case "/2" : O.log.Depth = 2; console.log(Pre + Msg); console.groupEnd(); break; - case "/1" : O.log.Depth = 1; console.log(Pre + Msg); console.groupEnd(); break; + case "-x" : Pre += "[ERROR] "; console.error(Pre + Msg); break; + case "-0" : Pre += "━━ "; console.info( Pre + Msg); break; + case "-1" : O.log.Depth = 1; console.log( Pre + Msg); break; + case "1:": O.log.Depth = 2; console.group(Pre + Msg); break; + case "-2" : O.log.Depth = 2; console.log( Pre + Msg); break; + case "2:": O.log.Depth = 3; console.group(Pre + Msg); break; + case "-3" : O.log.Depth = 3; console.log( Pre + Msg); break; + case "3:": O.log.Depth = 4; console.group(Pre + Msg); break; + case "-4" : O.log.Depth = 4; console.log( Pre + Msg); break; + case "4:": O.log.Depth = 5; console.group(Pre + Msg); break; + case "-5" : O.log.Depth = 5; console.log( Pre + Msg); break; + case "5:": O.log.Depth = 6; console.group(Pre + Msg); break; + case "-6" : O.log.Depth = 6; console.log( Pre + Msg); break; + case "/5" : O.log.Depth = 5; console.log( Pre + Msg); console.groupEnd(); break; + case "/4" : O.log.Depth = 4; console.log( Pre + Msg); console.groupEnd(); break; + case "/3" : O.log.Depth = 3; console.log( Pre + Msg); console.groupEnd(); break; + case "/2" : O.log.Depth = 2; console.log( Pre + Msg); console.groupEnd(); break; + case "/1" : O.log.Depth = 1; console.log( Pre + Msg); console.groupEnd(); break; } };*/ -O.log.Depth = 1; if(parent && parent != window) O.log = function() { return false; }; +O.log.Depth = 1; +if(parent && parent != window) O.log = function() { return false; }; O.error = function(Msg) { From 217a6203045ffcdc6e30c9b61a9a9d5393294ee8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Satoru=20MATSUSHIMA=20=28=E2=84=A0=29?= Date: Fri, 15 Dec 2017 19:32:59 +0900 Subject: [PATCH 03/12] Hide the UI for changing font-size when the book is pre-paginated. --- dev-bib/i/extensions/fontsize/fontsize.js | 2 +- dev-bib/i/extensions/fontsize/fontsize.scss | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/dev-bib/i/extensions/fontsize/fontsize.js b/dev-bib/i/extensions/fontsize/fontsize.js index efff175f..fc28740d 100644 --- a/dev-bib/i/extensions/fontsize/fontsize.js +++ b/dev-bib/i/extensions/fontsize/fontsize.js @@ -84,7 +84,7 @@ Bibi.x({ } }); - X.FontSize.ButtonGroup = I.createButtonGroup({ Area: I.Menu.R, Sticky: true }); + X.FontSize.ButtonGroup = I.createButtonGroup({ Area: I.Menu.R, Sticky: true, id: "bibi-buttongroup_fontsize" }); // FontSize Button X.FontSize.Button = X.FontSize.ButtonGroup.addButton({ diff --git a/dev-bib/i/extensions/fontsize/fontsize.scss b/dev-bib/i/extensions/fontsize/fontsize.scss index 315d40a1..e5a9f218 100644 --- a/dev-bib/i/extensions/fontsize/fontsize.scss +++ b/dev-bib/i/extensions/fontsize/fontsize.scss @@ -4,6 +4,12 @@ $scaling: 1.44; +#bibi-buttongroup_fontsize { + html.book-pre-paginated & { + display: none; + } +} + .bibi-button { .bibi-button-iconbox { .bibi-icon-fontsize { From cab5e9c91ebd6b5fc5f5e53f151771680ff4c003 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Satoru=20MATSUSHIMA=20=28=E2=84=A0=29?= Date: Fri, 15 Dec 2017 19:40:37 +0900 Subject: [PATCH 04/12] Add some features for future. And apply refactoring and cosmetic edit. --- dev-bib/i/res/scripts/bibi.heart.js | 152 +++++++++++++++++------ dev-bib/i/res/styles/_bibi-controls.scss | 128 ++++++++++++++++--- dev-bib/i/res/styles/_bibi-stage.scss | 52 ++++++-- dev-bib/i/res/styles/_common-icons.scss | 16 +-- 4 files changed, 273 insertions(+), 75 deletions(-) diff --git a/dev-bib/i/res/scripts/bibi.heart.js b/dev-bib/i/res/scripts/bibi.heart.js index d553888c..be8805b0 100644 --- a/dev-bib/i/res/scripts/bibi.heart.js +++ b/dev-bib/i/res/scripts/bibi.heart.js @@ -1426,7 +1426,7 @@ R = {}; // Bibi.Reader R.initialize = function() { - R.Main = O.Body.insertBefore(sML.create("div", { id: "bibi-main" }), O.Body.firstElementChild); + R.Main = O.Body.insertBefore(sML.create("div", { id: "bibi-main", Transformation: { Scale: 1, Translation: { X: 0, Y: 0 } } }), O.Body.firstElementChild); R.Sub = O.Body.insertBefore(sML.create("div", { id: "bibi-sub" }), R.Main.nextSibling); R.Main.Book = R.Main.appendChild(sML.create("div", { id: "bibi-main-book" })); @@ -1463,10 +1463,14 @@ R.initialize = function() { //} I.observeTap(O.HTML); - O.HTML.addTapEventListener("tap", R.ontap); + O.HTML.addTapEventListener("tap", R.ontap); + O.HTML.addEventListener(O["pointerdown"], R.onpointerdown); + O.HTML.addEventListener(O["pointerup"], R.onpointerup); E.add("bibi:loaded-item", function(Item) { I.observeTap(Item.HTML); - Item.HTML.addTapEventListener("tap", R.ontap); + Item.HTML.addTapEventListener("tap", R.ontap); + Item.HTML.addEventListener(O["pointerdown"], R.onpointerdown); + Item.HTML.addEventListener(O["pointerup"], R.onpointerup); }); }; @@ -1486,8 +1490,8 @@ R.resetStage = function() { R.Stage = {}; R.Columned = false; R.Main.Book.style.padding = R.Main.Book.style.width = R.Main.Book.style.height = ""; - R.Stage.Width = O.HTML.clientWidth; - R.Stage.Height = O.HTML.clientHeight; + R.Stage.Width = O.Body.clientWidth; + R.Stage.Height = O.Body.clientHeight; if(/FBAN/.test(navigator.userAgent)) { R.Stage.Height = window.innerHeight; O.HTML.style.height = window.innerHeight + "px"; @@ -1779,17 +1783,25 @@ R.resetItem.asPrePaginatedItem = function(Item) { } if(Item.SpreadPair) Item.SpreadPair.Scale = Scale; } + var SO /*= ScaleOptimizing*/ = 1 / Scale; PageL = Math.floor(ItemRef["viewport"][S.SIZE.l] * Scale); PageB = Math.floor(ItemRef["viewport"][S.SIZE.b] * (PageL / ItemRef["viewport"][S.SIZE.l])); - ItemBox.style[S.SIZE.l] = Item.style[S.SIZE.l] = PageL + "px"; - ItemBox.style[S.SIZE.b] = Item.style[S.SIZE.b] = PageB + "px"; + ItemBox.style[S.SIZE.l] = PageL + "px"; + ItemBox.style[S.SIZE.b] = PageB + "px"; + Item.style[S.SIZE.l] = PageL * SO + "px"; + Item.style[S.SIZE.b] = PageB * SO + "px"; var TransformOrigin = (/rl/.test(Item.HTML.WritingMode)) ? "100% 0" : "0 0"; sML.style(Item.HTML, { "width": ItemRef["viewport"].width + "px", "height": ItemRef["viewport"].height + "px", "transform-origin": TransformOrigin, "transformOrigin": TransformOrigin, - "transform": "scale(" + Scale + ")" + "transform": "scale(" + (Scale * SO) + ")" + }); + sML.style(Item, { + "transform-origin": "0 0", + "transformOrigin": "0 0", + "transform": "scale(" + (1 / SO) + ")" }); var Page = ItemBox.appendChild(sML.create("span", { className: "page" })); if(ItemRef["page-spread"] == "right") Page.style.right = 0; @@ -2048,6 +2060,18 @@ R.ontap = function(Eve) { E.dispatch("bibi:tapped", Eve); } +R.onpointerdown = function(Eve) { + E.dispatch("bibi:downs-pointer", Eve); + R.PointerIsDowned = true; + E.dispatch("bibi:downed-pointer", Eve); +}; + +R.onpointerup = function(Eve) { + E.dispatch("bibi:ups-pointer", Eve); + R.PointerIsDowned = false; + E.dispatch("bibi:upped-pointer", Eve); +}; + R.onpointermove = function(Eve) { var CC = O.getBibiEventCoord(Eve), PC = R.onpointermove.PreviousCoord; if(PC.X != CC.X || PC.Y != CC.Y) E.dispatch("bibi:moved-pointer", Eve); @@ -2723,6 +2747,7 @@ I.createMenu = function() { }); if(!O.Mobile) { E.add("bibi:moved-pointer", function(Eve) { + if(I.isPointerStealth()) return false; var BibiEvent = O.getBibiEvent(Eve); clearTimeout(I.Menu.Timer_close); if(BibiEvent.Coord.Y < I.Menu.offsetHeight * 1.5) { @@ -2735,6 +2760,7 @@ I.createMenu = function() { }); } E.add("bibi:tapped", function(Eve) { + if(I.isPointerStealth()) return false; var BibiEvent = O.getBibiEvent(Eve); //if(BibiEvent.Coord.Y < I.Menu.offsetHeight) return false; if(S.RVM == "horizontal") { @@ -2992,7 +3018,7 @@ I.createButtonGroup = function(Par) { // classifies ButtonGroup if(typeof Par.className != "string" || !Par.className) delete Par.className; if(typeof Par.id != "string" || !Par.id) delete Par.id; var ClassName = ["bibi-buttongroup"]; - if(Par.Tiled) ClassName.push("bibi-tiledbuttongroup"); + if(Par.Tiled) ClassName.push("bibi-buttongroup-tiled"); if(Par.Sticky) ClassName.push("sticky"); Par.className = ClassName.join(" "); Par.IsButtonGroup = true; @@ -3136,23 +3162,29 @@ I.createSubPanel.addSection = function(Par) { // classifies of Subpanel / classi sML.create("span", { className: "bibi-h-label", innerHTML: SubPanelSection.Labels["default"][O.Language] }) ); } - // PGroup + // PGroup: Setting if(SubPanelSection.Notes) { - var PGroup = SubPanelSection.appendChild( - sML.create("div", { className: "bibi-pgroup" }) - ); SubPanelSection.Notes.forEach(function(Note) { + if(!Note.Position || Note.Position == "before") { + if(!SubPanelSection.PGroup_Before) SubPanelSection.PGroup_Before = sML.create("div", { className: "bibi-pgroup bibi-pgroup_before" }); + var PGroup = SubPanelSection.PGroup_Before; + } else if(Note.Position == "after") { + if(!SubPanelSection.PGroup_After) SubPanelSection.PGroup_After = sML.create("div", { className: "bibi-pgroup bibi-pgroup_after" }); + var PGroup = SubPanelSection.PGroup_After; + } Note = I.distillLabels(Note); - PGroup.appendChild( - sML.create("p", { className: "bibi-p", innerHTML: Note["default"][O.Language] }) - ); + PGroup.appendChild(sML.create("p", { className: "bibi-p", innerHTML: Note["default"][O.Language] })); }); } + // PGroup: Before + if(SubPanelSection.PGroup_Before) SubPanelSection.appendChild(SubPanelSection.PGroup_Before); // ButtonGroup SubPanelSection.addButtonGroup = I.createSubPanel.addSection.addButtonGroup; if(SubPanelSection.ButtonGroup) SubPanelSection.addButtonGroup(SubPanelSection.ButtonGroup); this.appendChild(SubPanelSection); this.Sections.push(SubPanelSection); + // PGroup: After + if(SubPanelSection.PGroup_After) SubPanelSection.appendChild(SubPanelSection.PGroup_After); return SubPanelSection; }; @@ -3423,6 +3455,7 @@ I.createSlider = function() { E.add("bibi:commands:toggle-slider", function(Opt) { I.Slider.toggle(Opt); }); E.add("bibi:tapped", function(Eve) { if(!L.Opened) return false; + if(I.isPointerStealth()) return false; var BibiEvent = O.getBibiEvent(Eve); if(BibiEvent.Target.tagName) { if(/bibi-slider/.test(BibiEvent.Target.id)) return false; @@ -3511,7 +3544,7 @@ I.createArrows = function() { sML.addClass(O.HTML, "arrows-active"); - I.Arrows.Back = I.Arrows["back"] = R.Main.appendChild( + I.Arrows.Back = I.Arrows["back"] = O.Body.appendChild( sML.create("div", { id: "bibi-arrow-back", Distance: -1, Labels: { @@ -3522,7 +3555,7 @@ I.createArrows = function() { } }) ); - I.Arrows.Forward = I.Arrows["forward"] = R.Main.appendChild( + I.Arrows.Forward = I.Arrows["forward"] = O.Body.appendChild( sML.create("div", { id: "bibi-arrow-forward", Distance: +1, Labels: { @@ -3546,6 +3579,7 @@ I.createArrows = function() { if(!O.Mobile) { E.add("bibi:moved-pointer", function(Eve) { // try hovering if(!L.Opened) return false; + if(I.isPointerStealth()) return false; var BibiEvent = O.getBibiEvent(Eve); if(I.Arrows.areAvailable(BibiEvent)) { var Dir = (S.RVM == "vertical") ? BibiEvent.Division.Y : BibiEvent.Division.X; @@ -3571,6 +3605,7 @@ I.createArrows = function() { E.add("bibi:tapped", function(Eve) { // try moving if(!L.Opened) return false; + if(I.isPointerStealth()) return false; var BibiEvent = O.getBibiEvent(Eve); if(/^bibi-arrow-/.test(BibiEvent.Target.id)) return false; if(!I.Arrows.areAvailable(BibiEvent)) return false; @@ -3619,6 +3654,7 @@ I.createKeyListener = function() { // Keys I.KeyListener = { + ActiveKeys: {}, KeyCodes: { "keydown": {}, "keyup": {}, "keypress": {} }, updateKeyCodes: function(EventTypes, KeyCodesToUpdate) { if(typeof EventTypes.join != "function") EventTypes = [EventTypes]; @@ -3664,14 +3700,31 @@ I.createKeyListener = function() { if(Eve.altKey) Eve.BibiModifierKeys.push("Alt"); if(Eve.metaKey) Eve.BibiModifierKeys.push("Meta"); //if(!Eve.BibiKeyName) return false; + if(Eve.BibiKeyName) Eve.preventDefault(); return true; }, onkeydown: function(Eve) { if(!I.KeyListener.onEvent(Eve)) return false; + if(Eve.BibiKeyName) { + if(!I.KeyListener.ActiveKeys[Eve.BibiKeyName]) { + I.KeyListener.ActiveKeys[Eve.BibiKeyName] = Date.now(); + } else { + E.dispatch("bibi:is-holding-key", Eve); + } + } E.dispatch("bibi:downs-key", Eve); }, onkeyup: function(Eve) { if(!I.KeyListener.onEvent(Eve)) return false; + if(I.KeyListener.ActiveKeys[Eve.BibiKeyName] && Date.now() - I.KeyListener.ActiveKeys[Eve.BibiKeyName] < 300) { + E.dispatch("bibi:touches-key", Eve); + E.dispatch("bibi:touched-key", Eve); + } + if(Eve.BibiKeyName) { + if(I.KeyListener.ActiveKeys[Eve.BibiKeyName]) { + delete I.KeyListener.ActiveKeys[Eve.BibiKeyName]; + } + } E.dispatch("bibi:ups-key", Eve); }, onkeypress: function(Eve) { @@ -3687,8 +3740,7 @@ I.createKeyListener = function() { }, tryMoving: function(Eve) { if(!Eve.BibiKeyName) return false; - if(Eve.shiftKey) Eve.BibiKeyName = Eve.BibiKeyName.toUpperCase(); - var MovingParameter = I.KeyListener.MovingParameters[Eve.BibiKeyName]; + var MovingParameter = I.KeyListener.MovingParameters[!Eve.shiftKey ? Eve.BibiKeyName : Eve.BibiKeyName.toUpperCase()]; if(!MovingParameter) return false; Eve.preventDefault(); if(typeof MovingParameter == "number") E.dispatch("bibi:commands:move-by", { Distance: MovingParameter }); @@ -3707,7 +3759,8 @@ I.createKeyListener = function() { E.add("bibi:updated-settings", function( ) { I.KeyListener.updateMovingParameters(); }); E.add("bibi:opened", function( ) { I.KeyListener.updateMovingParameters(); I.KeyListener.observe(); }); - E.add("bibi:ups-key", function(Eve) { I.KeyListener.tryMoving(Eve); }); + + E.add("bibi:touched-key", function(Eve) { I.KeyListener.tryMoving(Eve); }); E.dispatch("bibi:created-keylistener"); @@ -3882,8 +3935,9 @@ I.setToggleAction = function(Ele, Par) { I.distillLabels = function(Labels) { if(typeof Labels != "object" || !Labels) Labels = {}; for(var State in Labels) Labels[State] = I.distillLabels.distillLanguage(Labels[State]); - if(!Labels["default"]) Labels["default"] = I.distillLabels.distillLanguage(); - if(!Labels["active"] && Labels["default"]) Labels["active"] = Labels["default"]; + if(!Labels["default"]) Labels["default"] = I.distillLabels.distillLanguage(); + if(!Labels["active"] && Labels["default"]) Labels["active"] = Labels["default"]; + if(!Labels["disabled"] && Labels["default"]) Labels["disabled"] = Labels["default"]; return Labels; }; @@ -3942,24 +3996,25 @@ I.observeTap = function(Ele, Opt) { return Ele; }; Ele.addEventListener(O["pointerdown"], function(Eve) { - if(Opt.PreventDefault) Eve.preventDefault(); - if(Opt.StopPropagation) Eve.stopPropagation(); clearTimeout(Ele.Timer_tap); - Ele.TouchStart = { Time: new Date(), Event: Eve, Coord: O.getBibiEventCoord(Eve) }; - Ele.TouchEnd = undefined; - Ele.Timer_tap = setTimeout(function() { - Ele.TouchStart = undefined; - }, 300); + Ele.TouchStart = { Time: Date.now(), Event: Eve, Coord: O.getBibiEventCoord(Eve) }; + Ele.Timer_tap = setTimeout(function() { delete Ele.TouchStart; }, 333); + if(Opt.PreventDefault) Eve.preventDefault(); + if(Opt.StopPropagation) Eve.stopPropagation(); }); Ele.addEventListener(O["pointerup"], function(Eve) { - if(Opt.PreventDefault) Eve.preventDefault(); - if(Opt.StopPropagation) Eve.stopPropagation(); - if(!Ele.TouchStart) return; - Ele.TouchEnd = { Time: new Date(), Event: Eve, Coord: O.getBibiEventCoord(Eve) }; - if((Ele.TouchEnd.Time - Ele.TouchStart.Time) < 300 && Math.abs(Ele.TouchEnd.Coord.X - Ele.TouchStart.Coord.X) < 5 && Math.abs(Ele.TouchEnd.Coord.Y - Ele.TouchStart.Coord.Y) < 5) { - E.dispatch("bibi:taps", Ele.TouchStart.Event, Ele); - E.dispatch("bibi:tapped", Ele.TouchStart.Event, Ele); + if(Ele.TouchStart) { + if((Date.now() - Ele.TouchStart.Time) < 300) { + var TouchEndCoord = O.getBibiEventCoord(Eve); + if(Math.abs(TouchEndCoord.X - Ele.TouchStart.Coord.X) < 5 && Math.abs(TouchEndCoord.Y - Ele.TouchStart.Coord.Y) < 5) { + E.dispatch("bibi:taps", Ele.TouchStart.Event, Ele); + E.dispatch("bibi:tapped", Ele.TouchStart.Event, Ele); + } + } + delete Ele.TouchStart; } + if(Opt.PreventDefault) Eve.preventDefault(); + if(Opt.StopPropagation) Eve.stopPropagation(); }); } return Ele; @@ -3970,15 +4025,18 @@ I.setTapAction = function(Ele) { var ontapped = (function() { switch(Ele.Type) { case "toggle": return function(Eve) { + if(Ele.UIState == "disabled") return false; I.setUIState(Ele, Ele.UIState == "default" ? "active" : "default"); }; case "radio": return function(Eve) { + if(Ele.UIState == "disabled") return false; Ele.ButtonGroup.Buttons.forEach(function(Button) { if(Button != Ele) I.setUIState(Button, ""); }); I.setUIState(Ele, "active"); }; default: return function(Eve) { + if(Ele.UIState == "disabled") return false; I.setUIState(Ele, "active"); clearTimeout(Ele.Timer_deactivate); Ele.Timer_deactivate = setTimeout(function() { @@ -3990,6 +4048,7 @@ I.setTapAction = function(Ele) { Ele.addTapEventListener("tapped", function(Eve) { if(Ele.isAvailable && !Ele.isAvailable(Eve)) return Ele; if(Ele.Type == "radio" && Ele.UIState == "active") return Ele; + if(Ele.UIState == "disabled") return Ele; ontapped.call(Ele, Eve); if(Ele.hideHelp) Ele.hideHelp(); if(Ele.note) Ele.note(); @@ -4049,6 +4108,16 @@ I.setUIState = function(UI, UIState) { return UI.UIState; }; +I.isPointerStealth = function() { + var IsPointerStealth = false; + I.isPointerStealth.Checkers.forEach(function(checker) { if(checker()) IsPointerStealth = true; }); + return IsPointerStealth; +}; +I.isPointerStealth.Checkers = []; +I.isPointerStealth.addChecker = function(Fun) { + if(typeof Fun == "function" && !I.isPointerStealth.Checkers.includes(Fun)) I.isPointerStealth.Checkers.push(Fun); +}; + @@ -4575,12 +4644,15 @@ O.getBibiEventCoord = function(Eve) { Coord.X = Eve.pageX; Coord.Y = Eve.pageY; } - if(Eve.target.ownerDocument.documentElement != O.HTML) { + if(Eve.target.ownerDocument.documentElement == O.HTML) { + Coord.X -= O.Body.scrollLeft; + Coord.Y -= O.Body.scrollTop; + } else { var Item = Eve.target.ownerDocument.documentElement.Item; ItemCoord = O.getElementCoord(Item); if(!Item.PrePaginated && !Item.Outsourcing) ItemCoord.X += S["item-padding-left"], ItemCoord.Y += S["item-padding-top"]; - Coord.X += ItemCoord.X - R.Main.scrollLeft; - Coord.Y += ItemCoord.Y - R.Main.scrollTop; + Coord.X = (Coord.X + ItemCoord.X - R.Main.scrollLeft) * R.Main.Transformation.Scale + R.Main.Transformation.Translation.X; + Coord.Y = (Coord.Y + ItemCoord.Y - R.Main.scrollTop ) * R.Main.Transformation.Scale + R.Main.Transformation.Translation.Y; } return Coord; }; diff --git a/dev-bib/i/res/styles/_bibi-controls.scss b/dev-bib/i/res/styles/_bibi-controls.scss index fe14f977..f195de44 100644 --- a/dev-bib/i/res/styles/_bibi-controls.scss +++ b/dev-bib/i/res/styles/_bibi-controls.scss @@ -436,6 +436,7 @@ div#bibi-panel { transform: none; opacity: 1; transition: 0.15s ease-in; + user-select: auto; } } @@ -780,10 +781,14 @@ div.bibi-subpanel { display: block; box-sizing: border-box; } - .bibi-h, .bibi-p, + .bibi-h, .bibi-button { padding-left: ($button-group-margin * 2); padding-right: ($button-group-margin * 2); + } + .bibi-p { + padding-left: ($button-group-margin * 2.5); + padding-right: ($button-group-margin * 2); } a.bibi-button { text-decoration: none; @@ -819,15 +824,20 @@ div.bibi-subpanel { } } .bibi-pgroup { - border: solid rgba(black, 0.1); border-width: 1px 0; + border: solid 0 rgba(black, 0.1); + &.bibi-pgroup_before { border-top-width: 1px; } + &.bibi-pgroup_after { border-bottom-width: 1px; } overflow: hidden; color: rgb(64,64,64); background: white;//rgba(white, 0.9); } .bibi-p { - margin: 8px 0; - line-height: 1.5; - font-size: 14px; + margin: 4px 0 0; + &:first-child { margin-top: 8px; } + &:last-child { margin-bottom: 6px; } + line-height: 1.4; + font-size: 12px; + text-align: justify; small { font-size: 10px; } @@ -846,6 +856,12 @@ div.bibi-subpanel { border: solid 1px rgb(234,234,234); padding: .5em; } + strong { + font-weight: bold; + } + em { + background: rgba(black, 0.075); + } } .bibi-buttongroup { // ul border: solid rgba(black, 0.1); border-width: 1px 0; @@ -916,6 +932,14 @@ div.bibi-subpanel { color: $color-in-subpanel; } } + &.disabled, + &.disabled.hover, + &.disabled:hover { + .bibi-button-iconbox, + .bibi-button-label { + opacity: 0.5 !important; + } + } } .bibi-button-link { &:after { @@ -963,7 +987,7 @@ div.bibi-subpanel { } } } - .bibi-tiledbuttongroup { + .bibi-buttongroup-tiled { display: flex; align-items: stretch; align-content: center; @@ -1075,6 +1099,11 @@ div#bibi-menu-r { width: $icon-size; height: $icon-size; .bibi-button { + position: relative; + z-index: 1; + &.hover, &.active { + z-index: 10; + } span.bibi-button-label { font-size: 0; color: transparent; @@ -1089,6 +1118,17 @@ div#bibi-menu-r { opacity: 1; } } + ul.bibi-buttongroup-tiled { + li:not(:first-child):not(:last-child) { + .bibi-button { + .bibi-button-iconbox { + .bibi-icon { + border-radius: 0; + } + } + } + } + } } div#bibi-menu-l { @@ -1110,6 +1150,31 @@ div#bibi-menu-l { margin-left: $button-group-margin / 2; &:first-child { margin-left: 0; } } } + ul.bibi-buttongroup-tiled { + li { + margin-left: -1px; + } + li:first-child { + .bibi-button { + .bibi-button-iconbox { + .bibi-icon { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + } + } + } + li:last-child { + .bibi-button { + .bibi-button-iconbox { + .bibi-icon { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + } + } + } + } } div#bibi-menu-r { @@ -1131,6 +1196,31 @@ div#bibi-menu-r { margin-right: $button-group-margin / 2; &:first-child { margin-right: 0; } } } + ul.bibi-buttongroup-tiled { + li { + margin-right: -1px; + } + li:first-child { + .bibi-button { + .bibi-button-iconbox { + .bibi-icon { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + } + } + } + li:last-child { + .bibi-button { + .bibi-button-iconbox { + .bibi-icon { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + } + } + } + } } @@ -1309,7 +1399,7 @@ html.panel-opened div#bibi-poweredby { div#bibi-nombre { box-sizing: border-box; overflow: hidden; - position: absolute; + position: fixed; z-index: $z-index_nombre; margin: auto; border-radius: $nombre-box-height * 0.5; @@ -1322,14 +1412,20 @@ div#bibi-nombre { background: $nombre-box-background-color; opacity: 0; transition: 0.125s ease-out; + html.view-paged &, + html.view-horizontal & { + top: auto; + left: -100%; right: -100%; + } html.view-paged & { - @include trbl(auto, -100%, 2px, -100%); + bottom: 2px; } html.view-horizontal & { - @include trbl(auto, -100%, $scrollbar-track-size + 2px, -100%); // `bottom` is to be overwritten by JavaScript ... (O.ScrollBars.Height + 2) + "px" + bottom: $scrollbar-track-size + 2px; // `bottom` is to be overwritten by JavaScript ... (O.ScrollBars.Height + 2) + "px" } html.view-vertical & { - @include trbl(-100%, $scrollbar-track-size + 2px, -100%, auto); // `right` is to be overwritten by JavaScript ... (O.ScrollBars.Width + 2) + "px" + top: -100%; bottom: -100%; + left: auto; right: $scrollbar-track-size + 2px; // `right` is to be overwritten by JavaScript ... (O.ScrollBars.Width + 2) + "px" transform: rotate(90deg) translateY(($nombre-box-width - $nombre-box-height) * -0.5); } html.slider-opened.view-paged &, @@ -1420,7 +1516,7 @@ div#bibi-slider { box-sizing: border-box; display: block; overflow: hidden; - position: absolute; + position: fixed; z-index: $z-index_slider; border: solid 0 $scrollbar-track-border-color; background: $scrollbar-track-background-color; @@ -1667,7 +1763,7 @@ div#bibi-slider { $arrow-bar-length: $top-bar-height; -$arrow-icon-size: $arrow-bar-length * 0.5; +$arrow-icon-size: $arrow-bar-length * 1; div#bibi-arrow-back, @@ -1692,7 +1788,7 @@ div#bibi-arrow-forward { height: $arrow-icon-size; text-align: center; vertical-align: middle; - line-height: $arrow-icon-size; + line-height: $arrow-icon-size * .96; text-indent: -.05em; font-size: $arrow-icon-size; border-radius: 50%; @@ -1744,7 +1840,7 @@ div#bibi-arrow-forward { transition-duration: .2s; } &:before { - transform: scale(1); + transform: scale(1.1); opacity: 1; } } @@ -1753,7 +1849,7 @@ div#bibi-arrow-forward { transition-duration: .1s; } &:before { - transform: scale(1.1); + transform: scale(1.0); opacity: .75; } } @@ -1762,7 +1858,7 @@ div#bibi-arrow-forward { transition-duration: .1s; } &:before { - transform: scale(2); + transform: scale(1.1); opacity: 1; } } diff --git a/dev-bib/i/res/styles/_bibi-stage.scss b/dev-bib/i/res/styles/_bibi-stage.scss index 65ea9111..ee266bda 100644 --- a/dev-bib/i/res/styles/_bibi-stage.scss +++ b/dev-bib/i/res/styles/_bibi-stage.scss @@ -7,7 +7,7 @@ // -------------------------------------------------------------------------------- html { - overflow: hidden; &.welcome { overflow: scroll; } + overflow: hidden; &.welcome { overflow: scroll !important; } position: absolute; // for InAppBrowsers @include trbl(0); // for InAppBrowsers width: 100%; @@ -27,6 +27,7 @@ html { &[data-bibi-cursor="right"], &[data-bibi-cursor="top"], &[data-bibi-cursor="bottom"] { cursor: pointer; } + user-select: none; } body { @@ -62,6 +63,25 @@ html.WebKit, html.Blink { background: $scrollbar-thumb-background-color_active; } } + &.zoomed-in { + ::-webkit-scrollbar { // scrollbar + height: 0; + width: 0; + } + ::-webkit-scrollbar-track { // scrollbar track + background: transparent; + } + ::-webkit-scrollbar-thumb { // scrollbar thumb + border-color: transparent; + background: transparent; + &:hover { + background: transparent; + } + &:active { + background: transparent; + } + } + } &.view-horizontal, &.view-vertical { body:after { // scrollbar border content: ""; @@ -140,6 +160,8 @@ div#bibi-main { width: 100%; height: 100%; transition: .15s ease; + transform-origin: 0 0; + will-change: scroll-position, transform, opacity; html.view-horizontal & { overflow-x: scroll; } html.view-vertical & { overflow-y: scroll; } html.laying-out & { @@ -155,7 +177,7 @@ div#bibi-main { }*/ html.slider-opened & { opacity: 0.75; - } + }/* html.page-ltr.flipping-ahead &, html.page-rtl.flipping-astern & { transform: translateX(-100px); @@ -165,7 +187,7 @@ div#bibi-main { html.page-rtl.flipping-ahead & { transform: translateX(100px); opacity: 0; - } + }*/ } div#bibi-main-book { position: relative; @@ -182,12 +204,16 @@ div#bibi-main { position: relative; html.spread-ltr & { float: left; } html.spread-rtl & { float: right; } - html.swipe-active &.image-spread-box:after { - content: ""; - display: block; - position: absolute; - z-index: 2; - left: 0; top: 0; right: 0; bottom: 0; margin: 0; width: 100%; height: 100%; + //html.dragging &, + //html.loupe-active &, + html.swipe-active &.image-spread-box { + &:after { + content: ""; + display: block; + position: absolute; + z-index: 2; + @include trbl(0); margin: 0; width: 100%; height: 100%; + } } //&.non-linear-spread-box { display: none; } } @@ -211,11 +237,11 @@ div#bibi-main { div.spread-box.pre-paginated &.page-spread-right { float: right; } html.book-pre-paginated.view-paged & { //transition: opacity 0.05s linear; - //opacity: 0.4; - //filter: blur(1px); + opacity: 0.25; + //filter: blur(2px); &.current { opacity: 1; - filter: none; + //filter: none; } } //&.non-linear-item-box { display: none; } @@ -242,6 +268,8 @@ div#bibi-main { border: none 0; line-height: 1; vertical-align: top; + html.zoomed-in & { will-change: transform; } + html.transforming & { will-change: none !important; } html.page-ltr & { transform-origin: 0 0; } html.page-rtl & { transform-origin: 100% 0; } //&.non-linear-item { display: none; } diff --git a/dev-bib/i/res/styles/_common-icons.scss b/dev-bib/i/res/styles/_common-icons.scss index 726b8230..cc79a274 100644 --- a/dev-bib/i/res/styles/_common-icons.scss +++ b/dev-bib/i/res/styles/_common-icons.scss @@ -417,7 +417,7 @@ $icon-color_active_border: darken(pink, 5%); color: $color_border; border-color: $color_border; background-color: $color_background; - &:before { + &:before, &:after { color: $color_font-paint; @include outline-color("text", $color_font-outline); } @@ -460,7 +460,7 @@ $icon-color_active_border: darken(pink, 5%); $icon-color_border_in-subpanel ); } - &, &:before, * { + &, &:before, &:after, * { transition: color 0.125s linear, background-color 0.125s linear, @@ -517,7 +517,7 @@ $icon-color_active_border: darken(pink, 5%); $icon-color_active_background, $icon-color_active_border ); - &:before { + &:before, &:after { transform: rotate(360deg); } .bibi-subpanel & { @@ -578,14 +578,16 @@ $icon-color_active_border: darken(pink, 5%); font-size: $icon-size_in-subpanel * .6; line-height: $icon-size_in-subpanel * .96; } - &:before { - @include font-icon("FontAwesome"); + &:before, &:after { display: inline-block; - content: $content; color: $color !important; - left: 0; right: 0; top: 0; bottom: 0; margin: auto; + @include trbl(0); margin: auto; box-shadow: none !important; } + &:before { + @include font-icon("FontAwesome"); + content: $content; + } } @mixin fa-icon-SNS($content, $color) { From cabc06b34a315ebd246b0b647baac825d6e54d83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Satoru=20MATSUSHIMA=20=28=E2=84=A0=29?= Date: Fri, 15 Dec 2017 19:44:46 +0900 Subject: [PATCH 05/12] Add "Loupe" extension that enables to zoom pre-paginated books in/out. --- bib/i/presets/default.js | 1 + dev-bib/i/extensions/loupe/loupe.js | 304 ++++++++++++++++++++++++++ dev-bib/i/extensions/loupe/loupe.scss | 114 ++++++++++ gulpfile.js | 1 + 4 files changed, 420 insertions(+) create mode 100644 dev-bib/i/extensions/loupe/loupe.js create mode 100644 dev-bib/i/extensions/loupe/loupe.scss diff --git a/bib/i/presets/default.js b/bib/i/presets/default.js index b6e546d4..47f1d0aa 100644 --- a/bib/i/presets/default.js +++ b/bib/i/presets/default.js @@ -66,6 +66,7 @@ Bibi.Preset = { { "name": "Unzipper", "src": "extensions/unzipper/unzipper.js" }, { "name": "Analytics", "src" : "extensions/analytics/analytics.js", "tracking-id": "" }, // "tracking-id": Your own Google Analytics tracking id, as "UA-********-*" { "name": "FontSize", "src": "extensions/fontsize/fontsize.js", "base": "auto", "scale-per-step": 1.25 }, // "base": "auto" or pixel-number (if you want to change the default font-size based on the size used most frequently in each HTML) + { "name": "Loupe", "src": "extensions/loupe/loupe.js", "mode": "", "max-scale": 4 }, { "name": "Share", "src" : "extensions/share/share.js" }, //{ "name": "EPUBCFI", "src": "extensions/epubcfi/epubcfi.js" }, //{ "name": "OverReflow", "src": "extensions/overreflow/overreflow.js" }, diff --git a/dev-bib/i/extensions/loupe/loupe.js b/dev-bib/i/extensions/loupe/loupe.js new file mode 100644 index 00000000..cae5db63 --- /dev/null +++ b/dev-bib/i/extensions/loupe/loupe.js @@ -0,0 +1,304 @@ +/*! + * + * # BiB/i Extension: Loupe (for Pointing Devices) + * + * - "Zooming-in Utility: Users can zoom-in the book with pointing devices." + * - Copyright (c) Satoru MATSUSHIMA - http://bibi.epub.link or https://github.com/satorumurmur/bibi + * - Licensed under the MIT license. - http://www.opensource.org/licenses/mit-license.php + * + */ + +Bibi.x({ + + name: "Loupe", + description: "Zooming-in Feature for BiB/i with Pointing Devices", + author: "Satoru MATSUSHIMA (@satorumurmur)", + version: "1.0.0", + build: Bibi["build"] + +})(function() { + + if(O.Mobile) return; + + if(typeof X.Presets.Loupe["mode"] != "string" || X.Presets.Loupe["mode"] != "with-keys") X.Presets.Loupe["mode"] = "pointer-only"; + if(typeof X.Presets.Loupe["max-scale"] != "number" || X.Presets.Loupe["max-scale"] <= 1) X.Presets.Loupe["max-scale"] = 4; + + if(X.Presets.Loupe["mode"] == "with-keys" && !S["use-keys"]) return; + + O.appendStyleSheetLink({ + className: "bibi-extension-stylesheet", + id: "bibi-extension-stylesheet_Loupe", + href: O.RootPath + "extensions/loupe/loupe.css" + }); + + sML.edit(X.Loupe, { + scale: function(Scl, BibiEvent) { // Scl: Scale + if(typeof Scl != "number") return false; + Scl = Math.round(Scl * 100) / 100; + if(Scl == R.Main.Transformation.Scale) return; + E.dispatch("bibi:changes-scale", Scl); + if(Scl == 1) { + this.transform({ Scale: 1, Translation: { X: 0, Y: 0 } }); + } else { + if(this.UIState != "active") return false; + if(!BibiEvent) BibiEvent = { Coord: { X: R.Main.offsetWidth / 2, Y: R.Main.offsetHeight / 2 } }; + this.transform({ + Scale: Scl, + Translation: { + X: BibiEvent.Coord.X - (BibiEvent.Coord.X - R.Main.Transformation.Translation.X) * (Scl / R.Main.Transformation.Scale), + Y: BibiEvent.Coord.Y - (BibiEvent.Coord.Y - R.Main.Transformation.Translation.Y) * (Scl / R.Main.Transformation.Scale) + } + }); + } + E.dispatch("bibi:changed-scale", R.Main.Transformation.Scale); + }, + transform: function(Tfm) { // Tfm: Transformation + if(!Tfm) return; + clearTimeout(this.Timer_onTransformEnd); + sML.addClass(O.HTML, "transforming"); + if(Tfm.Translation.X > 0) Tfm.Translation.X = 0; + if(Tfm.Translation.Y > 0) Tfm.Translation.Y = 0; + if(Tfm.Translation.X < R.Main.offsetWidth * (1 - Tfm.Scale)) Tfm.Translation.X = R.Main.offsetWidth * (1 - Tfm.Scale); + if(Tfm.Translation.Y < R.Main.offsetHeight * (1 - Tfm.Scale)) Tfm.Translation.Y = R.Main.offsetHeight * (1 - Tfm.Scale); + sML.style(R.Main, { + transform: (function(Ps) { + if(Tfm.Translation.X && Tfm.Translation.Y) Ps.push( "translate(" + Tfm.Translation.X + "px" + ", " + Tfm.Translation.Y + "px" + ")"); + else if(Tfm.Translation.X ) Ps.push("translateX(" + Tfm.Translation.X + "px" + ")"); + else if( Tfm.Translation.Y) Ps.push("translateY(" + Tfm.Translation.Y + "px" + ")"); + if(Tfm.Scale != 1 ) Ps.push( "scale(" + Tfm.Scale + ")"); + return Ps.join(" "); + })([]) + }); + R.Main.Transformation = Tfm; + this.Timer_onTransformEnd = setTimeout(function() { + if(R.Main.Transformation.Scale == 1) sML.removeClass(O.HTML, "zoomed-in" ), sML.removeClass(O.HTML, "zoomed-out"); + else if(R.Main.Transformation.Scale < 1) sML.removeClass(O.HTML, "zoomed-in" ), sML.addClass(O.HTML, "zoomed-out"); + else sML.removeClass(O.HTML, "zoomed-out"), sML.addClass(O.HTML, "zoomed-in" ); + sML.removeClass(O.HTML, "transforming"); + X.Loupe.onTransformEnd(); + if(S["use-cookie"]) O.Cookie.eat(O.BookURL, { Loupe: { Transformation: R.Main.Transformation } }); + }, 345); + }, + isAvailable: function(Mode, Eve) { + if(!L.Opened) return false; + if(this.UIState != "active") return false; + if(S.BRL == "reflowable") return false; + if(Mode == "CHECK-STEALTH") { + if(!I.KeyListener.ActiveKeys["Space"] && !X.Loupe.Dragging) return false; + } else if(Mode == "TAP") { + if(!I.KeyListener.ActiveKeys["Space"]) return false; + } else if(Mode == "MOVE") { + if(R.Main.Transformation.Scale == 1) return false; + } else { + if(!R.PointerIsDowned) return false; + } + return true; + }, + onTransformEnd: function() { + if(X.Presets.Loupe["mode"] == "with-keys") { + I.setUIState(X.Loupe.SubPanel.Sections[0].ButtonGroup.Buttons[1], (R.Main.Transformation.Scale == 1) ? "disabled" : "default"); + } else { + I.setUIState(X.Loupe.ZoomInButton, (R.Main.Transformation.Scale == X.Presets.Loupe["max-scale"]) ? "disabled" : "default"); + I.setUIState(X.Loupe.ZoomResetButton, (R.Main.Transformation.Scale == 1) ? "disabled" : "default"); + I.setUIState(X.Loupe.ZoomOutButton, (R.Main.Transformation.Scale == 1) ? "disabled" : "default"); + } + }, + adjustScale: function(Scl) { + if(Scl < 1 ) return 1; + else if(Scl > X.Presets.Loupe["max-scale"]) return X.Presets.Loupe["max-scale"]; + return Scl; + }, + ontapped: function(Eve) { + if(!this.isAvailable("TAP", Eve)) return false; + var BibiEvent = O.getBibiEvent(Eve); + if(BibiEvent.Target.tagName) { + if(/bibi-menu|bibi-slider/.test(BibiEvent.Target.id)) return false; + if(O.isAnchorContent(BibiEvent.Target)) return false; + if(S.RVM == "horizontal" && BibiEvent.Coord.Y > window.innerHeight - O.Scrollbars.Height) return false; + } + this.scale(this.adjustScale(R.Main.Transformation.Scale + 0.5 * (Eve.shiftKey ? -1 : 1)), BibiEvent); + }, + onpointerdown: function(Eve) { + this.PointerDownCoord = O.getBibiEvent(Eve).Coord; + this.PointerDownTransformation = { + Scale: R.Main.Transformation.Scale, + Translation: { + X: R.Main.Transformation.Translation.X, + Y: R.Main.Transformation.Translation.Y + } + }; + }, + onpointerup: function(Eve) { + sML.removeClass(O.HTML, "dragging"); + X.Loupe.Dragging = false; + delete this.PointerDownCoord; + delete this.PointerDownTransformation; + }, + onpointermove: function(Eve) { + if(!this.isAvailable("MOVE", Eve)) return false; + if(R.Main.Transformation.Scale == 1 || !this.PointerDownCoord) return; + X.Loupe.Dragging = true; + sML.addClass(O.HTML, "dragging"); + var BibiEvent = O.getBibiEvent(Eve); + clearTimeout(this.Timer_TransitionRestore); + sML.style(R.Main, { transition: "none", cursor: "move" }); + this.transform({ + Scale: R.Main.Transformation.Scale, + Translation: { + X: this.PointerDownTransformation.Translation.X + (BibiEvent.Coord.X - this.PointerDownCoord.X), + Y: this.PointerDownTransformation.Translation.Y + (BibiEvent.Coord.Y - this.PointerDownCoord.Y) + } + }); + this.Timer_TransitionRestore = setTimeout(function() { sML.style(R.Main, { transition: "", cursor: "" }); }, 234); + } + }); + I.isPointerStealth.addChecker(function() { + return X.Loupe.isAvailable("CHECK-STEALTH"); + }); + + I.setToggleAction(X.Loupe, { + onopened: function() { + sML.addClass(O.HTML, "loupe-active"); + sML.addClass(O.HTML, "loupe-" + X.Presets.Loupe["mode"]); + if(X.Presets.Loupe["mode"] == "with-keys") I.setUIState(this.SubPanel.Sections[0].ButtonGroup.Buttons[0], "active"); + }, + onclosed: function() { + this.scale(1); + sML.removeClass(O.HTML, "loupe-" + X.Presets.Loupe["mode"]); + sML.removeClass(O.HTML, "loupe-active"); + if(X.Presets.Loupe["mode"] == "with-keys") I.setUIState(this.SubPanel.Sections[0].ButtonGroup.Buttons[0], "default"); + } + }); + + E.add("bibi:commands:activate-loupe", function() { X.Loupe.open(); }); + E.add("bibi:commands:deactivate-loupe", function() { X.Loupe.close(); }); + E.add("bibi:commands:toggle-loupe", function() { X.Loupe.toggle(); }); + E.add("bibi:commands:scale", function(Scale) { X.Loupe.scale(Scale); }); + + E.add("bibi:tapped", function(Eve) { X.Loupe.ontapped( Eve); }); + E.add("bibi:downed-pointer", function(Eve) { X.Loupe.onpointerdown(Eve); }); + E.add("bibi:upped-pointer", function(Eve) { X.Loupe.onpointerup( Eve); }); + E.add("bibi:moved-pointer", function(Eve) { X.Loupe.onpointermove(Eve); }); + + E.add("bibi:changed-scale", function(Scale) { O.log('Changed Scale: ' + Scale); }); + + // Button Group + X.Loupe.ButtonGroup = I.createButtonGroup({ Area: I.Menu.R, Sticky: true, Tiled: true, id: "bibi-buttongroup_loupe" }); + + if(X.Presets.Loupe["mode"] == "with-keys") { + // Button + X.Loupe.MenuButton = X.Loupe.ButtonGroup.addButton({ + Type: "toggle", + Labels: { + default: { + default: 'Zoom-in/out', + ja: '拡大機能' + }, + active: { + default: 'Close Zoom-in/out Menu', + ja: '拡大機能メニューを閉じる' + } + }, + Icon: '', + Help: true + }); + // SubPanel + X.Loupe.SubPanel = I.createSubPanel({ + Opener: X.Loupe.MenuButton, + id: "bibi-subpanel_loupe", + open: function() {} + }); + X.Loupe.SubPanel.addSection({ + Labels: { + default: { + default: 'Zoom-in/out or Reset', + ja: '拡大縮小とリセット' + } + }, + ButtonGroup: { + Buttons: [{ + Type: "toggle", + Labels: { + default: { + default: 'Zoom-in/out', + ja: '拡大機能' + }, + active: { + default: 'Zoom-in/out (activated)', + ja: '拡大機能(現在有効)' + } + }, + Icon: '', + action: function() { X.Loupe.toggle(); } + }, { + Type: "normal", + Labels: { + default: { default: 'Reset Zoom-in/out', ja: '元のサイズに戻す' } + }, + Icon: '', + action: function() { X.Loupe.scale(1); } + }] + }, + Notes: [{ + Position: "after", + default: { + default: ['Zoom-in/out is activated:', '* Space + Click to Zoom-in'].join('
'), + ja: ['拡大機能が有効のとき:', '・スペースキーを押しながらクリックで拡大'].join('
') + } + }, { + Position: "after", + default: { + default: ['Zoomed-in:', '* Space + Shift + Click to Zoom-out', '* Space + Drag to Move the Book'].join('
'), + ja: ['拡大中:', '・スペース + Shift キーを押しながらクリックで縮小', '・スペースキーを押しながらドラッグで本を移動'].join('
') + } + }] + }); + } else { + X.Loupe.ZoomInButton = X.Loupe.ButtonGroup.addButton({ + Type: "normal", + Labels: { + default: { default: 'Zoom-in', ja: '拡大する' } + }, + Icon: '', + Help: true, + action: function() { X.Loupe.scale(X.Loupe.adjustScale(R.Main.Transformation.Scale + 0.5)); } + }); + X.Loupe.ZoomResetButton = X.Loupe.ButtonGroup.addButton({ + Type: "normal", + Labels: { + default: { default: 'Reset Zoom-in/out', ja: '元のサイズに戻す' } + }, + Icon: '', + Help: true, + action: function() { X.Loupe.scale(1); } + }); + X.Loupe.ZoomOutButton = X.Loupe.ButtonGroup.addButton({ + Type: "normal", + Labels: { + default: { default: 'Zoom-out', ja: '縮小する' } + }, + Icon: '', + Help: true, + action: function() { X.Loupe.scale(X.Loupe.adjustScale(R.Main.Transformation.Scale - 0.5)); } + }); + } + + E.dispatch("bibi:created-loupe-menu"); + E.dispatch("bibi:created-loupe"); + +})( + +)(function() { + + if(O.Mobile) return; + + if(X.Presets.Loupe["mode"] == "with-keys") I.setUIState(X.Loupe.SubPanel.Sections[0].ButtonGroup.Buttons[0], "active"); + + X.Loupe.toggle(); + + if(S["use-cookie"]) try { X.Loupe.transform(O.Cookie.remember(O.BookURL).Loupe.Transformation); } catch(Err) {} + + X.Loupe.onTransformEnd(); + +}); + diff --git a/dev-bib/i/extensions/loupe/loupe.scss b/dev-bib/i/extensions/loupe/loupe.scss new file mode 100644 index 00000000..c35e9a29 --- /dev/null +++ b/dev-bib/i/extensions/loupe/loupe.scss @@ -0,0 +1,114 @@ +@charset "utf-8"; + +@import "../../res/styles/_common-lib"; + +#bibi-buttongroup_loupe { + html.waiting &, + html.book-reflowable & { + display: none; + } +} + +.bibi-button { + .bibi-button-iconbox { + .bibi-icon-loupe { + &:before, &:after { + display: block; + position: absolute; + margin: auto; + width: 1em; + height: 1em; + line-height: 1; + } + &:before { + @include font-icon("FontAwesome"); + @include trbl(-100%); + } + } + .bibi-icon-loupe-menu { + &:before { + content: "\f00e"; + font-size: 22px; + } + } + .bibi-icon-loupe-zoomin, + .bibi-icon-loupe-zoomout, + .bibi-icon-loupe-reset { + &:before { + font-size: 18px; + } + } + .bibi-icon-loupe-zoomin { + &:before { + content: "\f00e"; + } + } + .bibi-icon-loupe-zoomout { + &:before { + content: "\f010"; + } + } + .bibi-icon-loupe-reset { + &:before { + content: "\f002"; + } + &:after { + content: "="; + display: block; + position: absolute; + @include trbl(23%, auto, auto, 25%); + margin: auto; + width: 1em; + height: 1em; + font-size: 1em * (13px / 18px); + line-height: 1; + } + html.Windows &:after { + @include trbl(29%, auto, auto, 25%); + } + #bibi-subpanel_loupe &:after { + @include trbl(11%, auto, auto, 17%); + } + } + } + .bibi-button-label { + span.non-visual-in-label { + @extend .non-visual; + } + } +} +.bibi-button.active { + .bibi-button-iconbox { + .bibi-icon-loupe-zoomin { + &:before { + html.loupe-with-keys & { + transform: rotate(360deg); + } + html.loupe-pointer-only & { + transform: scale(1.5); + } + } + } + .bibi-icon-loupe-zoomout { + &:before { + transform: scale(0.67); + } + } + .bibi-icon-loupe-reset { + &:before, &:after { + transform: scale(0.67); + } + } + } +} +.bibi-button.disabled { + .bibi-button-iconbox { + .bibi-icon-loupe-zoomin, + .bibi-icon-loupe-zoomout, + .bibi-icon-loupe-reset { + &:before, &:after { + opacity: 0.33; + } + } + } +} \ No newline at end of file diff --git a/gulpfile.js b/gulpfile.js index bd9501ca..c2d18af6 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -32,6 +32,7 @@ S.Extensions = [ "epubcfi", "fontsize", "jatex", + "loupe", "overreflow", "share", "unaccessibilizer", From 50fa635086f8d20469e30482d974b05ce4074148 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Satoru=20MATSUSHIMA=20=28=E2=84=A0=29?= Date: Wed, 20 Dec 2017 03:57:39 +0900 Subject: [PATCH 06/12] Add "use-full-height" and "use-menubar" setting. --- bib/i/presets/default.js | 2 ++ dev-bib/i.js | 3 +++ dev-bib/i/res/scripts/bibi.heart.js | 10 ++++++++++ dev-bib/i/res/styles/_bibi-controls.scss | 20 +++++++++++++------- dev-bib/i/res/styles/_bibi-stage.scss | 3 ++- 5 files changed, 30 insertions(+), 8 deletions(-) diff --git a/bib/i/presets/default.js b/bib/i/presets/default.js index 47f1d0aa..da2001f1 100644 --- a/bib/i/presets/default.js +++ b/bib/i/presets/default.js @@ -27,6 +27,8 @@ Bibi.Preset = { "autostart" : "no", // "yes" or "no" or "desktop" or "mobile" "start-in-new-window" : "mobile", // "yes" or "no" or "desktop" or "mobile" +"use-full-height" : "yes", // "yes" or "no" or "desktop" or "mobile" +"use-menubar" : "yes", // "yes" or "no" or "desktop" or "mobile" "use-nombre" : "yes", // "yes" or "no" or "desktop" or "mobile" "use-slider" : "yes", // "yes" or "no" or "desktop" or "mobile" "use-arrows" : "yes", // "yes" or "no" or "desktop" or "mobile" diff --git a/dev-bib/i.js b/dev-bib/i.js index 9ca482f9..8087e0b8 100644 --- a/dev-bib/i.js +++ b/dev-bib/i.js @@ -59,8 +59,11 @@ "nav", "reader-view-mode", "fix-reader-view-mode", + "single-page-always", "autostart", "start-in-new-window", + "use-full-height", + "use-menubar", "use-nombre", "use-slider", "use-arrows", diff --git a/dev-bib/i/res/scripts/bibi.heart.js b/dev-bib/i/res/scripts/bibi.heart.js index 4ae18722..8a75e163 100644 --- a/dev-bib/i/res/scripts/bibi.heart.js +++ b/dev-bib/i/res/scripts/bibi.heart.js @@ -1497,6 +1497,12 @@ R.resetStage = function() { O.HTML.style.height = window.innerHeight + "px"; window.scrollTo(0, 0); } + if(S["use-full-height"]) { + sML.addClass(O.HTML, "book-full-height"); + } else { + sML.removeClass(O.HTML, "book-full-height"); + R.Stage.Height -= I.Menu.Height; + } if(S.RVM == "paged") { if(I.Slider) R.Stage.Height -= O.Scrollbars.Height; R.Stage.PageGap = R.Main.Book.style["padding" + S.BASE.S] = R.Main.Book.style["padding" + S.BASE.E] = 0; @@ -2720,7 +2726,9 @@ I.createPanel.createShade = function() { I.createMenu = function() { // Menus + if(!S["use-menubar"]) sML.addClass(O.HTML, "without-menubar"); I.Menu = O.Body.appendChild(sML.create("div", { id: "bibi-menu", on: { "click": function(Eve) { Eve.stopPropagation(); } } })); + I.Menu.Height = I.Menu.offsetHeight; I.setHoverActions(I.Menu); I.setToggleAction(I.Menu, { onopened: function() { @@ -4772,6 +4780,8 @@ O.SettingTypes = { "wait", "autostart", "start-in-new-window", + "use-full-height", + "use-menubar", "use-nombre", "use-slider", "use-arrows", diff --git a/dev-bib/i/res/styles/_bibi-controls.scss b/dev-bib/i/res/styles/_bibi-controls.scss index f195de44..16554315 100644 --- a/dev-bib/i/res/styles/_bibi-controls.scss +++ b/dev-bib/i/res/styles/_bibi-controls.scss @@ -1026,27 +1026,33 @@ div.bibi-subpanel { // -------------------------------------------------------------------------------- div#bibi-menu { + html.without-menubar & { display: none !important; } box-sizing: border-box; position: fixed; html.waiting-file & { display: none; } z-index: $z-index_menu; left: 0; right: auto; top: 0; bottom: auto; - border-bottom: solid 1px rgba(128,128,128, 0); + border-bottom: solid 1px rgba(128,128,128, 0.1); height: $top-bar-height; width: 100%; - background: rgba(255,255,255, 0); - &.hover, - html.menu-opened & { + background: rgba(255,255,255, 0.9); + html.book-full-height & { + border-bottom-color: rgba(128,128,128, 0); + background-color: rgba(255,255,255, 0); + } + html.book-full-height &.hover, + html.book-full-height.menu-opened &, + html.book-full-height.menu-fixed & { border-bottom-color: rgba(128,128,128, 0.1); - background: rgba(255,255,255, 0.9); + background-color: rgba(255,255,255, 0.9); } html.veil-opened & { border-bottom-color: rgba(128,128,128, 0); - background: rgba(255,255,255, 0); + background-color: rgba(255,255,255, 0); } html.panel-opened &, html.subpanel-opened & { border-bottom-color: rgba(128,128,128, 0.1); - background: rgba(255,255,255, 1); + background-color: rgba(255,255,255, 1); } &.hover { // box-shadow: 0 0 ($top-bar-height / 2) rgba(128,128,128, 0.1); diff --git a/dev-bib/i/res/styles/_bibi-stage.scss b/dev-bib/i/res/styles/_bibi-stage.scss index ee266bda..e1a887fb 100644 --- a/dev-bib/i/res/styles/_bibi-stage.scss +++ b/dev-bib/i/res/styles/_bibi-stage.scss @@ -156,12 +156,13 @@ div#bibi-main { position: absolute; z-index: $z-index_main; @include trbl(0); - //padding-top: $top-bar-height; + padding-top: $top-bar-height; width: 100%; height: 100%; transition: .15s ease; transform-origin: 0 0; will-change: scroll-position, transform, opacity; + html.book-full-height & { padding-top: 0; } html.view-horizontal & { overflow-x: scroll; } html.view-vertical & { overflow-y: scroll; } html.laying-out & { From fd87d187da85ca0704feee670bb1e1ff014751d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Satoru=20MATSUSHIMA=20=28=E2=84=A0=29?= Date: Mon, 2 Apr 2018 18:14:04 +0900 Subject: [PATCH 07/12] Fix console logging. --- dev-bib/i/res/scripts/bibi.heart.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-bib/i/res/scripts/bibi.heart.js b/dev-bib/i/res/scripts/bibi.heart.js index 8a75e163..352171f4 100644 --- a/dev-bib/i/res/scripts/bibi.heart.js +++ b/dev-bib/i/res/scripts/bibi.heart.js @@ -4428,6 +4428,7 @@ O.log = function(Msg, Tag) { if(sML.UA.Gecko && typeof Msg == "string") Msg = Msg.replace(/(https?:\/\/)/g, ""); var Pre = 'BiB/i: '; switch(Tag) { + case "-x" : break; case "*:": Tag = (O.log.Depth ) + ":"; break; case "/*" : Tag = "/" + (O.log.Depth - 1) ; break; default : Tag = "-" + (O.log.Depth ) ; break; @@ -4493,7 +4494,6 @@ O.error = function(Msg) { sML.removeClass(O.HTML, "waiting"); E.dispatch("bibi:x_x", Msg); O.log(Msg, "-x"); - O.log.Depth = 1; }; From 5c9800612abfa3196ed8565b63ecc8e0e494fca9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Satoru=20MATSUSHIMA=20=28=E2=84=A0=29?= Date: Mon, 2 Apr 2018 18:14:58 +0900 Subject: [PATCH 08/12] Optimize pre/postprocessing (and add "preprocess-html-always" option). --- bib/i/presets/default.js | 2 ++ dev-bib/i.js | 3 ++- dev-bib/i/res/scripts/bibi.heart.js | 40 ++++++++++++++++++++++++----- 3 files changed, 37 insertions(+), 8 deletions(-) diff --git a/bib/i/presets/default.js b/bib/i/presets/default.js index da2001f1..96a6ed1a 100644 --- a/bib/i/presets/default.js +++ b/bib/i/presets/default.js @@ -57,6 +57,8 @@ Bibi.Preset = { "flipper-width" : 0.3, // ratio (lower than 1) or px (1 or higher) +"preprocess-html-always" : "no", // "yes" or "no" or "desktop" or "mobile" + "page-breaking" : false, // true or false (if true, CSS "page-break-before/after: always;" will work, partially) "epub-additional-stylesheet" : "", // path from spine-item or http:// URI or "" diff --git a/dev-bib/i.js b/dev-bib/i.js index 8087e0b8..f41a564a 100644 --- a/dev-bib/i.js +++ b/dev-bib/i.js @@ -69,7 +69,8 @@ "use-arrows", "use-keys", "use-swipe", - "use-cookie" + "use-cookie", + "preprocess-html-always" ].forEach(function(PresetKey) { var PresetValue = Anchor.getAttribute("data-bibi-" + PresetKey); if(!PresetValue) return; diff --git a/dev-bib/i/res/scripts/bibi.heart.js b/dev-bib/i/res/scripts/bibi.heart.js index 352171f4..0cf0ad43 100644 --- a/dev-bib/i/res/scripts/bibi.heart.js +++ b/dev-bib/i/res/scripts/bibi.heart.js @@ -775,12 +775,18 @@ L.loadItemsInSpreads = function() { L.preprocessResources = function() { + return new Promise(function(resolve, reject) { if(B.Unzipped) { - if(!(sML.UA.Gecko || sML.UA.Edge)) return resolve(); + var FileExtensionRE = (function() { + if(sML.UA.Gecko || sML.UA.Edge) return /\.(xhtml|xml|html?|css)$/; + if(S["preprocess-html-always"]) return /\.(xhtml|xml|html?)$/; + return null; + })(); + if(!FileExtensionRE) return resolve(); var FilesToBeLoaded = 0; for(var FilePath in B.Package.Manifest.Files) { - if(/\.(css|xhtml|xml|html?)$/.test(FilePath)) { + if(FileExtensionRE.test(FilePath)) { B.Files[FilePath] = ""; FilesToBeLoaded++; } @@ -854,7 +860,7 @@ L.preprocessResources.Settings = { CSS: { FileExtensionRE: /\.css$/, ReplaceRules: [ - [/\/\*[.\s\S]*?\*\/|[^\{\}]+\{\s*\}/gm, ""],, + [/\/\*[.\s\S]*?\*\/|[^\{\}]+\{\s*\}/gm, ""], [/(-(epub|webkit)-)?column-count\s*:\s*1\s*([;\}])/g, '$1column-count: auto$4'] ], NestingRE: /(@import\s*(?:url\()?["']?)(?!(?:https?|data):)(.+?\.css)(['"]?(?:\))?\s*;)/g, @@ -1008,9 +1014,28 @@ L.postprocessItem = function(Item) { Item.stamp("Postprocess"); - Item.HTML = sML.edit(Item.contentDocument.getElementsByTagName("html")[0], { Item: Item }); - Item.Head = sML.edit(Item.contentDocument.getElementsByTagName("head")[0], { Item: Item }); - Item.Body = sML.edit(Item.contentDocument.getElementsByTagName("body")[0], { Item: Item }); + Item.PostprocessTrialCount = Item.PostprocessTrialCount || 1; + + if( + !Item.contentDocument.documentElement || + !Item.contentDocument.head || + !Item.contentDocument.body + ) { + if(Item.PostprocessTrialCount > 10) { + return O.error("Faled to load an Item: " + Item.Path); + } else { + return setTimeout(function() { + Item.PostprocessTrialCount++; + L.postprocessItem(Item); + }, 100); + } + } + + Item.HTML = Item.contentDocument.documentElement; + Item.Head = Item.contentDocument.head; + Item.Body = Item.contentDocument.body; + + Item.HTML.Item = Item.Head.Item = Item.Body.Item = Item; var XMLLang = Item.HTML.getAttribute("xml:lang"), Lang = Item.HTML.getAttribute("lang"); if(!XMLLang && !Lang) Item.HTML.setAttribute("xml:lang", B.Language), Item.HTML.setAttribute("lang", B.Language); @@ -4787,7 +4812,8 @@ O.SettingTypes = { "use-arrows", "use-keys", "use-swipe", - "use-cookie" + "use-cookie", + "preprocess-html-always" ], Integer: [ "spread-gap", From 6cf87e4c5fd324099d71b0142b807362baaf2b22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Satoru=20MATSUSHIMA=20=28=E2=84=A0=29?= Date: Mon, 2 Apr 2018 18:17:13 +0900 Subject: [PATCH 09/12] Update development environment. --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 03f07da9..c80fd71e 100644 --- a/package.json +++ b/package.json @@ -27,8 +27,8 @@ "distribute": "gulp distribute" }, "devDependencies": { - "bower": "^1.8.0", - "browser-sync": "^2.18.8", + "bower": "^1.8.4", + "browser-sync": "^2.23.6", "cssnano": "^3.10.0", "del": "^2.2.2", "fs": "0.0.2", @@ -37,7 +37,7 @@ "gulp-concat": "^2.6.1", "gulp-if": "^2.0.2", "gulp-notify": "^2.2.0", - "gulp-plumber": "^1.1.0", + "gulp-plumber": "^1.2.0", "gulp-postcss": "^6.4.0", "gulp-rename": "^1.2.2", "gulp-replace": "^0.5.4", From 9950e2fabd0e4d9d679e073a015cda98de0333d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Satoru=20MATSUSHIMA=20=28=E2=84=A0=29?= Date: Mon, 2 Apr 2018 18:24:16 +0900 Subject: [PATCH 10/12] Fix an issue that zipped EPUBs can't be opened with Chrome 65+. --- dev-bib/i/extensions/fontsize/fontsize.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-bib/i/extensions/fontsize/fontsize.js b/dev-bib/i/extensions/fontsize/fontsize.js index fc28740d..8d56a177 100644 --- a/dev-bib/i/extensions/fontsize/fontsize.js +++ b/dev-bib/i/extensions/fontsize/fontsize.js @@ -45,7 +45,7 @@ Bibi.x({ Default: getComputedStyle(Item.HTML).fontSize.replace(/[^\d]*$/, "") * 1 }; Item.FontSize.Base = Item.FontSize.Default; - if(sML.UA.InternetExplorer && L.Preprocessed) { + if(L.Preprocessed && (sML.UA.Chrome || sML.UA.InternetExplorer)) { Array.prototype.forEach.call(Item.contentDocument.documentElement.querySelectorAll("body, body *"), function(Ele) { Ele.style.fontSize = parseInt(getComputedStyle(Ele).fontSize) / Item.FontSize.Base + "rem"; }); From c768c372d1014a4734e755f33224051c67194cf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Satoru=20MATSUSHIMA=20=28=E2=84=A0=29?= Date: Mon, 2 Apr 2018 19:04:16 +0900 Subject: [PATCH 11/12] (cosmetic) --- dev-bib/i/res/scripts/bibi.heart.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dev-bib/i/res/scripts/bibi.heart.js b/dev-bib/i/res/scripts/bibi.heart.js index 0cf0ad43..a142bfc7 100644 --- a/dev-bib/i/res/scripts/bibi.heart.js +++ b/dev-bib/i/res/scripts/bibi.heart.js @@ -4147,8 +4147,8 @@ I.isPointerStealth = function() { return IsPointerStealth; }; I.isPointerStealth.Checkers = []; -I.isPointerStealth.addChecker = function(Fun) { - if(typeof Fun == "function" && !I.isPointerStealth.Checkers.includes(Fun)) I.isPointerStealth.Checkers.push(Fun); +I.isPointerStealth.addChecker = function(fun) { + if(typeof fun == "function" && !I.isPointerStealth.Checkers.includes(fun)) I.isPointerStealth.Checkers.push(fun); }; From ca60687167aedd57fda59d464b8c3e2e642b944a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Satoru=20MATSUSHIMA=20=28=E2=84=A0=29?= Date: Mon, 2 Apr 2018 20:43:29 +0900 Subject: [PATCH 12/12] Update version number. (v0.999.9-r7 -> v0.999.9-r8) --- bower.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bower.json b/bower.json index f76ebd45..514b719a 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "bibi", - "version": "0.999.9-r7", + "version": "0.999.9-r8", "authors": [ "Satoru MATSUSHIMA" ], diff --git a/package.json b/package.json index c80fd71e..1f705fe4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bibi", - "version": "0.999.9-r7", + "version": "0.999.9-r8", "author": { "name": "Satoru MATSUSHIMA" },