initial commit

This commit is contained in:
Julie Blanc 2026-01-10 18:33:22 +01:00
commit 21711bd5dd
253 changed files with 78415 additions and 0 deletions

View file

@ -0,0 +1 @@
.DS_Store

View file

@ -0,0 +1,126 @@
---
name: fullPage
tags: recommended, stable
description: Create full page elements and full spread elements in the flow of your book.
---
# Full page elements (paged.js)
This script help you to create full page elements and full spread elements in the flow of your book.
You need to use [csstree.js](https://github.com/csstree/csstree) in order to transform custom properties.
If you use CSS PageMaker is inclued by default
## How to install
**With CSS Page Marker**
Make sure the csstree library is included in the `<head>` of your HTML:
```html
<script src="/csspageweaver/lib/csstree.min.js"></script>
```
Register the `fullPage` plugin in your `manifest.json`:
```json
[
"fullPage",
// other plugins
]
```
**Without CSS PageMaker**
Include both csstree and the fullPage script in your HTML `<head>`:
```html
<script src="js/csstree.min.js"></script>
<script src="path/to/fullPage/fullPage.js"></script>
```
## How to use it
In the CSS, on the element(s) you want in full page add the following custom property(works with id and classes):
```css
elem{
--pagedjs-full-page: page
}
```
You have multiple keywords for the custom property:
- `--pagedjs-full-page: page` → The element will be remove from flow and put in the next page.
- `--pagedjs-full-page: left` → The element will be remove from flow and put in the next left page.
- `--pagedjs-full-page: right` → The element will be remove from flow and put in the next right page.
- `--pagedjs-full-page: spread` → The element will be remove from flow and put in the next spread.
- `--pagedjs-full-page: <number>` → The element will be remove from flow and put in the page you specify (with `--pagedjs-full-page: 4`, the element is put on page number 4).
Note that this script works on any elements, even if the element contains several child elements.
### Images in full page
If you want an image in full page, we advise you to use the usual `objet-fit` properties.
```css
#figure{
--pagedjs-full-page: page;
width: 100%;
height: 100%;
margin: 0px;
}
img {
object-fit: cover;
object-position: 0px 0px;
width: 100%;
height: 100%;
}
```
- To change the size of you image, use `width` and `height`.
- To change the position of your image, use `object-position`.
- In the case of the `spread` option, all the spread will be considered, i.e. `width: 100%` cover all the spread.
### Spread and central fold
Sometimes, when a book is binding, the elements that cover the spread need to be offset from the central fold. A custom value can be added to the page to take it into account.
```css
@page {
--pagedjs-fold: 10mm;
}
```
### Bleeds of full page and full spread elements
In order to avoid that your elements moves when you change the bleeds and the crop marks of your document, the bleeds of full page elements was set up to `6mm`. This is due to the way Paged.js modifies the DOM (full page elements are contained in the page sheet and depend on the dimensions of this page sheet).
If you want to change the dimensions of these specific bleeds, you just have to change the value of the `bleedFull` variable in the first line of the `full-page.js` file
### Examples
You can find examples of use in `css/full-page.css`.
![](images/full-page-example.png)
## Credits
- [pagedjs.org](https://www.pagedjs.org/)
- [csstree.js](https://github.com/csstree/csstree)
MIT licence, Julie Blanc, 2021

View file

@ -0,0 +1,9 @@
{
"name": "Full page",
"description": "Create full page elements and full spread elements in the flow of your book",
"licence": "MIT",
"author": ["Julie Blanc"],
"version": "2.0",
"hook": "fullPage.js",
"stylesheet": "fullPage.css"
}

View file

@ -0,0 +1,49 @@
.pagedjs_page_fullLeft .pagedjs_full-spread_container{
margin: 0;
width: calc(var(--pagedjs-pagebox-width) + var(--bleed-images));
height: calc(var(--pagedjs-pagebox-height) + var(--bleed-images)*2)!important;
position: absolute;
top: calc((var(--pagedjs-margin-top) + var(--bleed-images))*-1);
left: calc((var(--pagedjs-margin-left) + var(--bleed-images))*-1);
overflow: hidden;
}
.pagedjs_page_fullRight .pagedjs_full-spread_container{
margin: 0;
width: calc(var(--pagedjs-pagebox-width) + var(--bleed-images));
height: calc(var(--pagedjs-pagebox-height) + var(--bleed-images)*2)!important;
position: absolute;
top: calc((var(--pagedjs-margin-top) + var(--bleed-images))*-1);
left: calc(var(--pagedjs-margin-left)*-1);
overflow: hidden;
}
.pagedjs_full-spread_content{
margin: 0;
width: calc(var(--pagedjs-pagebox-width)*2 + var(--bleed-images)*2);
height: calc(var(--pagedjs-pagebox-height) + var(--bleed-images)*2)!important;
position: absolute;
top: 0;
left: 0;
}
.pagedjs_page_fullLeft .pagedjs_full-spread_content{
left: calc(var(--pagedjs-fold)*-1);
}
.pagedjs_page_fullRight .pagedjs_full-spread_content{
left: calc((var(--pagedjs-pagebox-width) + var(--bleed-images))*-1 + var(--pagedjs-fold))
}
.pagedjs_full-page_content {
margin: 0;
position: absolute;
top: calc((var(--pagedjs-margin-top) + var(--bleed-images))*-1);
}
.pagedjs_left_page .pagedjs_full-page_content {
width: calc(var(--pagedjs-pagebox-width) + var(--bleed-images));
height: calc(var(--pagedjs-pagebox-height) + var(--bleed-images) + var(--bleed-images))!important;
left: calc((var(--pagedjs-margin-left) + var(--bleed-images))*-1);
}
.pagedjs_right_page .pagedjs_full-page_content {
width: calc(var(--pagedjs-pagebox-width) + var(--bleed-images));
height: calc(var(--pagedjs-pagebox-height) + var(--bleed-images) * 2)!important;
left: calc(var(--pagedjs-margin-left)*-1);
}

View file

@ -0,0 +1,294 @@
/**
* @name Fullpage
* @author Julie Blanc <contact@julie-blanc.fr>
* @see { @link https://gitlab.com/csspageweaver/plugins/fullPage }
*/
import { Handler } from '/csspageweaver/lib/paged.esm.js';
let bleedFull = '6mm';
export default class fullPage extends Handler {
constructor(chunker, polisher, caller) {
super(chunker, polisher, caller);
this.selectorFullSpread = new Set();
this.fullSpreadEls = new Set();
this.selectorFullPage = new Set();
this.fullPageEls = new Set();
this.selectorFullRight = new Set();
this.fullRightEls = new Set();
this.selectorFullLeft= new Set();
this.fullLeftEls = new Set();
this.usedPagedEls = new Set();
this.specificPage = new Set();
this.specificPageClone = new Set();
}
onDeclaration(declaration, dItem, dList, rule) {
// Read customs properties
if (declaration.property == "--pagedjs-full-page") {
// get selector of the declaration (NOTE: need csstree.js)
let selector = csstree.generate(rule.ruleNode.prelude);
// Push selector in correct set
if (declaration.value.value.includes("page")) {
this.selectorFullPage.add(selector);
}else if(declaration.value.value.includes("spread")) {
this.selectorFullSpread.add(selector);
}else if(declaration.value.value.includes("right")) {
this.selectorFullRight.add(selector);
}else if(declaration.value.value.includes("left")) {
this.selectorFullLeft.add(selector);
}else{
let obj = { page: declaration.value.value, elem: selector };
this.specificPage.add(JSON.stringify(obj));
}
}
}
afterParsed(parsed){
console.log("FULL PAGE loaded");
// ADD pagedjs classes to elements
for (let item of this.selectorFullPage) {
let elems = parsed.querySelectorAll(item);
for (let elem of elems) {
elem.classList.add("pagedjs_full-page-elem");
}
}
for (let item of this.selectorFullSpread) {
let elems = parsed.querySelectorAll(item);
for (let elem of elems) {
elem.classList.add("pagedjs_full-spread-elem");
}
}
for (let item of this.selectorFullLeft) {
let elems = parsed.querySelectorAll(item);
for (let elem of elems) {
elem.classList.add("pagedjs_full-page-left-elem");
}
}
for (let item of this.selectorFullRight) {
let elems = parsed.querySelectorAll(item);
for (let elem of elems) {
elem.classList.add("pagedjs_full-page-right-elem");
}
}
// SPECIFICPAGE ------------------------------------
this.specificPage.forEach(entry => {
const obj = JSON.parse(entry);
const elements = parsed.querySelectorAll(obj.elem);
if (elements.length > 0) {
// pourquoi cest ajouté même si lélément nexiste pas ?
elements[0].classList.add("pagedjs_full-page-specific");
const clone = elements[0].cloneNode(true);
obj.elemClone = clone.outerHTML;
elements[0].remove();
}
this.specificPageClone.add(JSON.stringify(obj));
});
}
renderNode(clone, node) {
// FULL SPREAD
// if you find a full page element, move it in the array
if (node.nodeType == 1 && node.classList.contains("pagedjs_full-spread-elem")) {
this.fullSpreadEls.add(node);
this.usedPagedEls.add(node);
// remove the element from the flow by hiding it.
clone.style.display = "none";
}
// FULL PAGE
if (node.nodeType == 1 && node.classList.contains("pagedjs_full-page-left-elem")) {
this.fullLeftEls.add(node);
this.usedPagedEls.add(node);
clone.style.display = "none";
}else if (node.nodeType == 1 && node.classList.contains("pagedjs_full-page-right-elem")) {
this.fullRightEls.add(node);
this.usedPagedEls.add(node);
clone.style.display = "none";
}else if (node.nodeType == 1 && node.classList.contains("pagedjs_full-page-elem")) {
this.fullPageEls.add(node);
this.usedPagedEls.add(node);
clone.style.display = "none";
}
}
afterPageLayout(pageElement, page, breakToken, chunker) {
if(page.id == "page-1"){
let allPages = document.querySelector(".pagedjs_pages");
allPages.style.setProperty('--bleed-images', bleedFull);
}
// ADD --pagedjs-fold on body if doesn't exist
if(pageElement.classList.contains("pagedjs_first_page")){
let body = document.getElementsByTagName("body")[0];
let style = window.getComputedStyle(body);
let fold = style.getPropertyValue('--pagedjs-fold');
if(!fold){
body.style.setProperty('--pagedjs-fold', '0mm')
}
}
// FULL SPREAD
// if there is an element in the fullSpreadEls Set, (goodbye arrays!)
for (let img of this.fullSpreadEls) {
if (page.element.classList.contains("pagedjs_right_page")) {
let imgLeft;
let imgRight;
if (img.nodeName == "IMG") {
/* Add outside + inside container if the element is an img */
let containerLeft = document.createElement("div");
containerLeft.classList.add("pagedjs_full-spread_container");
let containerLeftInside = document.createElement("div");
containerLeftInside.classList.add("pagedjs_full-spread_content");
containerLeft.appendChild(containerLeftInside).appendChild(img);
imgLeft = containerLeft;
let containerRight = document.createElement("div");
containerRight.classList.add("pagedjs_full-spread_container");
let containerRightInside = document.createElement("div");
containerRightInside.classList.add("pagedjs_full-spread_content");
containerRight.appendChild(containerRightInside).appendChild(img.cloneNode(true));
imgRight = containerRight;
} else {
/* Add outside container if the element is an img */
let containerLeft = document.createElement("div");
containerLeft.classList.add("pagedjs_full-spread_container");
img.classList.add("pagedjs_full-spread_content");
containerLeft.appendChild(img);
imgLeft = containerLeft;
let containerRight = document.createElement("div");
containerRight.classList.add("pagedjs_full-spread_container");
img.classList.add("pagedjs_full-spread_content");
containerRight.appendChild(img.cloneNode(true));
imgRight = containerRight;
}
// put the first element on the page
let fullPage = chunker.addPage();
fullPage.element
.querySelector(".pagedjs_page_content")
.insertAdjacentElement("afterbegin", imgLeft);
fullPage.element.classList.add("pagedjs_page_fullLeft");
// page right
let fullPageRight = chunker.addPage();
fullPageRight.element
.querySelector(".pagedjs_page_content")
.insertAdjacentElement("afterbegin", imgRight);
fullPageRight.element.classList.add("pagedjs_page_fullRight");
img.style.removeProperty("display");
this.fullSpreadEls.delete(img);
}
}
// FULL PAGE
// if there is an element in the fullPageEls Set
for (let img of this.fullPageEls) {
let container = document.createElement("div");
container.classList.add("pagedjs_full-page_content");
container.appendChild(img);
let fullPage = chunker.addPage();
fullPage.element
.querySelector(".pagedjs_page_content")
.insertAdjacentElement("afterbegin", container);
fullPage.element.classList.add("pagedjs_page_fullPage");
img.style.removeProperty("display");
this.fullPageEls.delete(img);
}
// FULL Left PAGE
// if there is an element in the fullLeftEls Set
for (let img of this.fullLeftEls) {
if (page.element.classList.contains("pagedjs_right_page")) {
let container = document.createElement("div");
container.classList.add("pagedjs_full-page_content");
container.appendChild(img);
let fullPage = chunker.addPage();
fullPage.element
.querySelector(".pagedjs_page_content")
.insertAdjacentElement("afterbegin", container);
fullPage.element.classList.add("pagedjs_page_fullPage");
img.style.removeProperty("display");
this.fullLeftEls.delete(img);
}
}
// FULL RIGHT PAGE
// if there is an element in the fullRightEls Set
for (let img of this.fullRightEls) {
if (page.element.classList.contains("pagedjs_left_page")) {
let container = document.createElement("div");
container.classList.add("pagedjs_full-page_content");
container.appendChild(img);
let fullPage = chunker.addPage();
fullPage.element
.querySelector(".pagedjs_page_content")
.insertAdjacentElement("afterbegin", container);
fullPage.element.classList.add("pagedjs_page_fullPage");
img.style.removeProperty("display");
this.fullRightEls.delete(img);
}
}
// SPECIFICPAGE ------------------------------------
let pageNum = pageElement.id.split('page-')[1];
pageNum = parseInt(pageNum);
this.specificPageClone.forEach(entry => {
const obj = JSON.parse(entry);
let targetedPage = obj.page;
let prevPage = parseInt(targetedPage) - 1;
let elem = obj.elemClone;
if(prevPage == pageNum){
let container = document.createElement("div");
container.classList.add("pagedjs_full-page_content");
container.innerHTML = elem;
let fullPage = chunker.addPage();
fullPage.element
.querySelector(".pagedjs_page_content")
.insertAdjacentElement("afterbegin", container);
fullPage.element.classList.add("pagedjs_page_fullPage");
}
});
}
}