]> _ Git - fluidbook_tools.git/commitdiff
wip #4697 @1
authorVincent Vanwaelscappel <vincent@cubedesigners.com>
Thu, 23 Sep 2021 17:50:36 +0000 (19:50 +0200)
committerVincent Vanwaelscappel <vincent@cubedesigners.com>
Thu, 23 Sep 2021 17:50:36 +0000 (19:50 +0200)
src/Compiler/Compiler.php
src/Compiler/Links.php
src/Compiler/Styles.php [new file with mode: 0644]

index 4e6d1397a5845d9aeef13c83b54157dde636e55d..6f75227d9fcca2fe5e50ca5f1457a8fb0a42b0f9 100644 (file)
@@ -7,7 +7,6 @@ use Cubist\Util\PHP;
 use Exception;
 use Fluidbook\Tools\Jobs\ProcessFile;
 use Fluidbook\Tools\Jobs\ProcessPage;
-use Fluidbook\Tools\Links\Link;
 use Fluidbook\Tools\PDF\Document;
 use Fluidbook\Tools\Search\SearchIndex;
 use Illuminate\Bus\Queueable;
@@ -25,6 +24,7 @@ class Compiler implements ShouldQueue, ShouldBeUnique
     use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
 
     use Links;
+    use Styles;
 
     /** @var VirtualDirectory */
     protected $vdir;
@@ -214,7 +214,7 @@ class Compiler implements ShouldQueue, ShouldBeUnique
         $this->compileDimensions();
         $this->compilePageNumbers();
         $this->compileChapters();
-        $this->config->links = $this->compileLinks();
+        $this->compileLinks();
 
         $c = 'var SETTINGS=' . json_encode($this->config, JSON_THROW_ON_ERROR) . ';';
         $this->vdir->file_put_contents('data/datas.js', $c);
@@ -277,11 +277,13 @@ class Compiler implements ShouldQueue, ShouldBeUnique
         return $this->getWidth() * $this->getHeight();
     }
 
-    public function getWidth(){
+    public function getWidth()
+    {
         return $this->getSourceOfPage(1)->getSource()->getDocument()->getWidth();
     }
 
-    public function getHeight(){
+    public function getHeight()
+    {
         return $this->getSourceOfPage(1)->getSource()->getDocument()->getHeight();
     }
 
index 58bc22f94431468d663bb86a64c89d34dc19da66..0044da6470689934e0e9903d68550ba5731268cf 100644 (file)
@@ -218,7 +218,7 @@ trait Links
                 );
         }
 
-        if (isset($this->writeLinksData) && $this->writeLinksData) {
+        if (!isset($this->writeLinksData) || $this->writeLinksData) {
             $this->config->linksData = $allLinksData;
         }
         $this->config->gamifyCoins = $gamifyCoins;
diff --git a/src/Compiler/Styles.php b/src/Compiler/Styles.php
new file mode 100644 (file)
index 0000000..dba98d6
--- /dev/null
@@ -0,0 +1,329 @@
+<?php
+
+namespace Fluidbook\Tools\Compiler;
+
+use Cubist\Util\CommandLine;
+use Cubist\Util\Graphics\Color;
+
+trait Styles
+{
+    protected $lessVariables = [];
+
+    protected function writeCSS($links)
+    {
+        $res = array();
+
+        $this->addFontKit('OpenSans');
+
+        $lessContents = '';
+
+        $this->lessVariables['font'] = $this->_font($this->config->interfaceFont);
+        $this->lessVariables['text-transform'] = $this->_themeBoolean($this->config->interfaceFontUppercase) ? 'uppercase' : 'inherit';
+
+        $this->lessVariables['css-scale'] = $this->cssScale;
+
+        $this->lessVariables['slider-background'] = Color::colorToCSS(!$this->config->sliderBackground ? 'rgba(0,0,0,0.1)' : $this->config->sliderBackground);
+        $this->lessVariables['slider-handle'] = Color::colorToCSS(!$this->config->sliderHandle ? '#ffffff' : $this->config->sliderHandle);
+        $this->lessVariables['slider-display'] = $this->_lessBoolean($this->config->pagesBar);
+        $this->lessVariables['slider-thumb-background'] = Color::colorToCSS($this->config->pageBarThumbBack);
+        $this->lessVariables['pages-background'] = $this->config->forceWhiteBackground ? '#ffffff' : 'transparent';
+
+
+        // General theme
+        $cssWidth = $this->cssWidth;
+        $cssHeight = $this->cssHeight;
+        $cssScale = $this->cssScale;
+        $w2 = ($cssWidth * 2) . 'px';
+        $h = $cssHeight . 'px';
+
+        $wm = ($this->getWidth() * $this->multiply) . 'px';
+        $hm = ($this->getHeight() * $this->multiply) . 'px';
+        $w = $cssWidth . 'px';
+        $offsetLeft = round(($this->optimalWidth - $cssWidth) / 2, 3);
+        $offsetLeft2 = $offsetLeft * 2;
+        $offsetTop = round(($this->optimalHeight - $cssHeight) / 2, 3);
+        $navTop = ($cssHeight - 40 - 100) / 2;
+        $leftOfRightPage = (floor($cssWidth) - 1) . 'px';
+
+        $this->lessVariables['z'] = $this->z;
+        $this->lessVariables['book-page-width'] = $w;
+
+        if ($this->config->correctCenter && !$this->isMobileFirst()) {
+            $this->lessVariables['book-page-correct-width'] = ceil($w) + 1;
+            $this->lessVariables['book-page-correct-height'] = ceil($h) + 1;
+        } else {
+            $this->lessVariables['book-page-correct-width'] = $w;
+            $this->lessVariables['book-page-correct-height'] = $h;
+        }
+
+
+        $this->lessVariables['book-page-height'] = $h;
+        $this->lessVariables['book-page-ratio'] = floatval($w) / floatval($h);
+
+        $this->lessVariables['page-shade-opacity'] = min(1, $this->config->shadeAlpha / 50);
+        $c = new Color($this->config->bookShadeColor);
+        $this->lessVariables['shadow-opacity'] = $c->getAlpha() * 1.2;
+        $this->lessVariables['edges-display'] = $this->_lessBoolean($this->config->usePageEdges);
+        $this->lessVariables['edge-left-offset'] = 0;
+        $this->lessVariables['edge-right-offset'] = 0;
+        $this->lessVariables['edges-opacity'] = 1;
+
+
+        $this->lessVariables['page-number-color'] = Color::colorToCSS($this->config->colorPageNumber);
+        $this->lessVariables['display-page-number'] = $this->_lessBoolean($this->config->displayPageNumber);
+        $this->lessVariables['page-transition-duration'] = $this->config->mobileTransitionDuration . 's';
+
+        $corrText = $this->isMobileFirst() ? 0 : 4;
+
+        if ($this->cssSVGScale != 1) {
+            $texts = '.texts{' . wsHTML5::writeCSSUA('transform-origin', 'top left') . ';';
+            $texts .= wsHTML5::writeCSSUA('transform', 'scale(' . round((1 / $this->multiply) * $cssScale * $this->cssSVGScale, 3) . ')') . ';';
+            $texts .= 'width:' . ($wm / $this->cssSVGScale) . 'px; max-width:' . ($wm / $this->cssSVGScale) . 'px;';
+            $texts .= 'height:' . ($hm / $this->cssSVGScale) . 'px; max-height:' . ($hm / $this->cssSVGScale) . 'px;';
+            $texts .= '}';
+        } else {
+            $texts = '.texts{width:' . floor(floatval($w) + $corrText) . 'px;height:' . floor(floatval($h) + $corrText) . 'px;}';
+        }
+
+        $res[] = $texts;
+
+        // Theme
+        $shade = '.page .shade{';
+        $shade .= 'opacity:' . min(($this->config->shadeAlpha * 2) / 100, 1) . ';';
+        $shade .= '}';
+        $res[] = $shade;
+
+        // SVG
+        $res[] = 'svg .fill-c-menu-back{fill:' . Color::colorToCSS($this->config->couleurB) . ';}';
+        $res[] = 'svg .fill-c-menu-text{fill:' . Color::colorToCSS($this->config->subTextColor) . ';}';
+
+        // Background
+        $res[] = $this->_cssBackground();
+
+        // Archives
+        // Header
+        $header = 'header{';
+        $header .= 'height:' . $this->config->menuHeight . 'px;';
+        if ($mi = $this->checkThemeImage($this->config->menuImage)) {
+            $this->vdir->copy($mi, 'data/images/' . $this->config->menuImage);
+            $header .= 'background-image:url(../images/' . $this->config->menuImage . ');';
+            $header .= 'background-repeat:no-repeat;';
+            $header .= 'background-size:100% ' . $this->config->menuHeight . 'px;';
+        } else {
+            // Force redo
+            $header .= 'background-color:' . Color::colorToCSS($this->config->menuColor) . ';';
+        }
+        $header .= '}';
+        $res[] = $header;
+
+        // Logo
+        $logo = '#logo{';
+        if ($l = $this->checkThemeImage($this->config->logo)) {
+            $this->vdir->copy($l, 'data/images/' . $this->config->logo);
+            $dim = CubeIT_Image::getimagesize($l);
+            $logo .= 'background-image:url(../images/' . $this->config->logo . ');width:' . $dim[0] . 'px;height:' . $dim[1] . 'px;';
+        }
+        $logo .= '}';
+        $res[] = $logo;
+
+        // Credits
+        $res[] = 'footer,footer a{color:' . Color::colorToCSS($this->config->creditsColor) . ';}';
+
+        // Arrows
+        $this->lessVariables['arrows-background'] = Color::colorToCSS($this->config->couleurA);
+        $this->lessVariables['arrows-color'] = Color::colorToCSS($this->config->arrowsColor);
+
+        // Loader
+        $this->lessVariables['loader-background-color'] = Color::colorToCSS($this->config->couleurL);
+        $this->lessVariables['loader-foreground-color'] = Color::colorToCSS($this->config->loadingSecColor);
+
+        // Audio description buttons
+        $this->lessVariables['audiodescription-background'] = Color::colorToCSS($this->config->couleurA);
+        $this->lessVariables['audiodescription-color'] = Color::colorToCSS($this->config->couleurA);
+
+        // Links Styles
+        $this->lessVariables['links-color'] = Color::colorToCSS($this->config->linksColor);
+        $this->lessVariables['inlineslideshow-transition-time'] = ((float)$this->config->inlineSlideshowTransitionDuration * 1000) . 'ms';
+        $this->lessVariables['slideshow-caption-size'] = $this->config->slideshowCaptionSize ?: '16px';
+
+        $res = array_merge($res, $links);
+
+        // Bookmarks
+        if (!isset($this->config->bookmarkCornerSize)) {
+            $this->config->bookmarkCornerSize = 10;
+        }
+
+        $this->lessVariables['bookmark-star-disabled-color'] = Color::colorToCSS($this->config->bookmarkStarDisabledColor);
+        $this->lessVariables['bookmark-star-enabled-color'] = Color::colorToCSS($this->config->bookmarkStarEnabledColor);
+        $this->lessVariables['bookmark-color'] = Color::colorToCSS($this->config->bookmarkBackgroundColor);
+        $this->lessVariables['bookmark-corner-size'] = round($this->getWidth() * $this->config->bookmarkCornerSize * 0.0075 * $this->z) . 'px';
+        $this->lessVariables['bookmark-corner-offset'] = $this->config->bookmarkOffset . 'px';
+
+        // Menus
+        $menuColor = new Color($this->config->couleurB);
+        $menuColor->setAlpha(1);
+        $menuTextColor = Color::colorToCSS($this->config->subTextColor);
+        $menuBreakpoint = empty($this->config->menuBreakpoint) ? '1023px' : $this->config->menuBreakpoint;
+
+        $this->lessVariables['menu-breakpoint'] = $menuBreakpoint;
+        $this->lessVariables['menu-background'] = $menuColor->toCSS();
+        if ($this->config->subSecondaryColor) {
+            $this->lessVariables['menu-button-background'] = Color::colorToCSS($this->config->subSecondaryColor);
+        } else {
+            $this->lessVariables['menu-background-green'] = 'max(45, min(255-45, green(@menu-background)))';
+            $this->lessVariables['menu-background-red'] = 'max(45, min(255-45, red(@menu-background)))';
+            $this->lessVariables['menu-background-blue'] = 'max(45, min(255-45, blue(@menu-background)))';
+            $this->lessVariables['menu-button-background'] = 'overlay(rgb(@menu-background-red, @menu-background-green, @menu-background-blue), #c0c0c0)';
+        }
+
+        $this->lessVariables['menu-text'] = $menuTextColor;
+        $this->lessVariables['menu-field-background'] = Color::colorToCSS($this->config->subFieldColor);
+        $this->lessVariables['menu-field-text'] = Color::colorToCSS($this->config->subTextFieldColor);
+        $this->lessVariables['menu-select-background'] = Color::colorToCSS($this->config->subSelectColor);
+        $this->lessVariables['menu-select-text'] = Color::colorToCSS($this->config->subTextSelectColor);
+        $this->lessVariables['icon-color'] = Color::colorToCSS($this->config->couleurI);
+        $this->lessVariables['menu-overlay'] = Color::colorToCSS($this->config->popupVideoOverlay);
+
+        // Chapters
+        $this->lessVariables['menu-chapters-columns-count'] = max(1, min(6, $this->config->chaptersColumns));
+        $this->lessVariables['menu-chapters-columns-width'] = $this->config->chaptersColMaxWidth;
+        $this->lessVariables['menu-chapters-font-size'] = $this->config->chaptersFontSize;
+
+        foreach ($this->book->chapters as $chapter) {
+            if (substr($chapter->page, 0, 1) != '#') {
+                continue;
+            }
+            if ($chapter->color == '') {
+                continue;
+            }
+            $color = trim($chapter->color, '#');
+            $lessContents .= '.mview.c_' . $color . '{.menu-color(' . Color::colorToCSS($color) . ');}';
+        }
+
+        // Archives
+        if ($this->config->externalArchivesBack) {
+            $this->vdir->copy($this->wdir . '/' . $this->config->externalArchivesBack, 'data/images/' . $this->config->externalArchivesBack);
+            $res[] = '.mview.archives{background-image:url("../images/' . $this->config->externalArchivesBack . '");}';
+        }
+
+        # Index
+        $thumbw = $this->config->mobileNavigationType === 'portrait' ? 200 : 100;
+        $this->lessVariables['thumb-width'] = $thumbw . 'px';
+        $ratio = $this->getWidth() / $this->getHeight();
+        $thumbh = round($thumbw / $ratio);
+        $this->config->thumbWidth = $thumbw;
+        $this->config->thumbHeight = $thumbh;
+
+        $this->lessVariables['thumb-height'] = $thumbh . 'px';
+
+        #tooltip
+        $this->lessVariables['tooltip-background'] = Color::colorToCSS($this->config->tooltipBackColor);
+        $this->lessVariables['tooltip-color'] = Color::colorToCSS($this->config->tooltipTextColor);
+        $this->lessVariables['tooltip-font-size'] = 14 * (($this->config->tooltipTextSize ?: 100) / 100);
+
+        #Videos
+        if ($this->config->bigPlayImage) {
+            $this->lessVariables['video-bigplay-image'] = '~"../data/links/' . $this->config->bigPlayImage . '"';
+            $this->vdir->copy($this->wdir . '/' . $this->config->bigPlayImage, 'data/links/' . $this->config->bigPlayImage);
+        } else {
+            $this->lessVariables['video-bigplay-image'] = '~"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMTMuNCAxMTMuNCI+PHN0eWxlPi5zdDB7b3BhY2l0eTowLjg7fSAuc3Qxe2ZpbGw6I0ZGRkZGRjt9PC9zdHlsZT48cGF0aCBjbGFzcz0ic3QwIiBkPSJNMTEwLjUgMTEzLjRIMi45Yy0xLjYgMC0yLjktMS4zLTIuOS0yLjlWMi45QzAgMS4zIDEuMyAwIDIuOSAwaDEwNy42YzEuNiAwIDIuOSAxLjMgMi45IDIuOXYxMDcuNmMwIDEuNi0xLjMgMi45LTIuOSAyLjl6Ii8+PHBhdGggY2xhc3M9InN0MSIgZD0iTTQ1LjggMzcuOGwzMS41IDE3LjljLjguNS44IDEuNiAwIDIuMUw0NS44IDc1LjZjLS44LjUtMS44LS4xLTEuOC0xVjM4LjhjMC0uOSAxLTEuNSAxLjgtMXoiLz48L3N2Zz4="';
+        }
+
+        #fonts
+        foreach ($this->cssfont as $hash => $item) {
+            $res[] = '@font-face{font-family: "' . $hash . '";src:url("../../data/fonts/' . $hash . '.woff") format("woff");}';
+        }
+
+        if ($this->config->textPopupStylesheet) {
+            $res[] = file_get_contents($this->wdir . '/' . $this->config->textPopupStylesheet);
+        }
+
+        $this->compileLess($this->lessVariables, $lessContents);
+        $this->stylesheets[] = 'data/style/style.css';
+        $this->vdir->file_put_contents('data/style/style.css', implode("\n", $res));
+
+    }
+
+    protected function compileLess($variables, $lessContents = '')
+    {
+        if ($this->widget) {
+            $this->lessFiles[] = 'widget';
+        }
+        foreach ($this->specialCSS as $s) {
+            $this->lessFiles[] = 'special/' . $s;
+        }
+
+        $tmp = CubeIT_Files::tmpdir();
+
+        $from = $this->assets . '/style/*';
+        `cp -r $from $tmp`;
+
+        $bookVariables = array();
+        foreach ($variables as $k => $v) {
+            $bookVariables[] = '@' . trim($k) . ':' . $v . ';';
+        }
+        file_put_contents($tmp . '/book-variables.less', implode("\n", $bookVariables));
+        file_put_contents($tmp . '/additional.less', $lessContents);
+
+        foreach ($this->lessFiles as $f) {
+            $source_less = $this->assets . '/style/' . $f . '.less';
+            $destination_less = $tmp . '/' . $f . '.less';
+            $destination_css = $tmp . '/' . $f . '.css';
+
+            if (!file_exists($source_less)) {
+                die($source_less);
+                continue;
+            }
+
+            $dir = dirname($destination_css);
+
+            if (file_exists($dir) && !is_dir($dir)) {
+                unlink($dir);
+            }
+            // LESS file might be in a subfolder, so create if it doesn't exist
+            if (!file_exists($dir)) {
+                mkdir($dir, 0777, true);
+            }
+
+            // Less files must be copied to temporary directory so they'll
+            // have access to the variables generated in book-variables.less
+            copy($source_less, $destination_less);
+            $less = new CommandLine('lessc');
+            $less->setArg(null, $destination_less);
+            $less->setArg(null, $destination_css);
+            $less->execute();
+            if (!file_exists($destination_css)) {
+                die($less->getOutput());
+                continue;
+            }
+            $this->vdir->copy($destination_css, 'style/' . $f . '.css');
+            if ($f != 'widget') {
+                $this->stylesheets[] = 'style/' . $f . '.css';
+            }
+        }
+    }
+
+    protected function checkThemeImage($path)
+    {
+        $path = trim($path);
+        $path = trim($path, '/');
+        if (!$path) {
+            return false;
+        }
+        $p = $this->themeRoot . '/' . $path;
+        if (file_exists($p)) {
+            return $p;
+        }
+        $po = str_replace('.svg', '.o.svg', $p);
+        if (file_exists($po)) {
+            copy($po, $p);
+            return $p;
+        }
+        return false;
+    }
+
+    protected function _themeBoolean($v): bool
+    {
+        return !(null === $v || $v === '0' || $v === 0 || $v === false || !$v);
+    }
+}