Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
P
pagedjs
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Guillaume
pagedjs
Commits
b82b64fe
Commit
b82b64fe
authored
Nov 07, 2019
by
julien
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'target-text-update' into 'master'
Target text update See merge request
tools/pagedjs!71
parents
3b893392
0bc1a786
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
318 additions
and
16 deletions
+318
-16
.gitignore
.gitignore
+1
-0
target-text-spec-js-target-text-should-create-a-pdf-1-snap.png
...t-text-spec-js-target-text-should-create-a-pdf-1-snap.png
+0
-0
target-text-spec-js-target-text-should-create-a-pdf-1-snap.png
...t-text-spec-js-target-text-should-create-a-pdf-1-snap.png
+0
-0
target-text.html
specs/target/target-text/target-text.html
+138
-0
target-text.spec.js
specs/target/target-text/target-text.spec.js
+49
-0
target-text.js
src/modules/generated-content/target-text.js
+96
-16
polisher.js
src/polisher/polisher.js
+3
-0
sheet.js
src/polisher/sheet.js
+31
-0
No files found.
.gitignore
View file @
b82b64fe
...
...
@@ -4,3 +4,4 @@ dist
lib
__diff_output__
specs/**/*.pdf
issues
\ No newline at end of file
specs/target/target-text/__image_snapshots_linux__/target-text-spec-js-target-text-should-create-a-pdf-1-snap.png
0 → 100644
View file @
b82b64fe
28.6 KB
specs/target/target-text/__image_snapshots_mac__/target-text-spec-js-target-text-should-create-a-pdf-1-snap.png
0 → 100644
View file @
b82b64fe
28.6 KB
specs/target/target-text/target-text.html
0 → 100644
View file @
b82b64fe
<!DOCTYPE html PUBLIC>
<html
lang=
"en"
lang=
"en"
>
<head>
<meta
http-equiv=
"Content-Type"
content=
"text/html;charset=utf-8"
/>
<meta
http-equiv=
"Content-Style-Type"
content=
"text/css"
/>
<title>
targer-counter
</title>
<script
src=
"../../../dist/paged.polyfill.js"
></script>
<style>
:root
{
font-size
:
18px
;
}
@page
{
size
:
6in
8in
;
margin
:
20mm
20mm
;
/* border: solid 1px black; */
@bottom-left
{
content
:
counter
(
page
);
}
}
section
{
break-before
:
page
;
}
p
{
line-height
:
22px
;
}
h1
{
font-size
:
24px
;
margin-top
:
0
;
}
a
{
text-decoration
:
none
;
color
:
currentColor
;
}
a
::after
{
color
:
blueviolet
;
display
:
block
;
margin-bottom
:
3em
;
}
nav
li
:nth-of-type
(
1
)
a
[
href
]
::after
{
content
:
target-text
(
attr
(
href
url
));
}
nav
li
:nth-of-type
(
2
)
a
[
href
]
::after
{
content
:
target-text
(
attr
(
href
url
),
content
);
}
nav
li
:nth-of-type
(
3
)
a
[
href
]
::after
{
content
:
target-text
(
attr
(
href
url
),
first-letter
);
}
nav
li
:nth-of-type
(
4
)
a
[
href
]
::after
{
content
:
target-text
(
attr
(
href
url
),
before
);
}
nav
li
:nth-of-type
(
5
)
a
[
href
]
::after
{
content
:
target-text
(
attr
(
href
url
),
after
);
}
/* before and after */
#chap3
::before
{
content
:
" This is inside the before: "
;
color
:
orange
;
}
#chap4
::after
{
content
:
": This is inside the after "
;
color
:
orange
;
}
</style>
<style>
/* interface */
@media
screen
{
body
{
background
:
whitesmoke
;
}
.pagedjs_page
{
background
:
white
;
margin-bottom
:
10px
;
box-shadow
:
0
0
0
1px
rgba
(
0
,
0
,
0
,
0.2
);
}
.pagedjs_pages
{
width
:
calc
(
var
(
--pagedjs-width
)
*
2
);
display
:
flex
;
flex-direction
:
column
;
margin
:
0
auto
;
}
}
</style>
</head>
<body>
<section>
<nav>
<h1>
Table of contents
</h1>
<ul>
<li><a
href=
"#chap0"
>
target-text:
</a></li>
<li><a
href=
"#chap1"
>
target-text content:
</a></li>
<li><a
href=
"#chap2"
>
target-text first-letter:
</a></li>
<li><a
href=
"#chap3"
>
target-text:: before:
</a></li>
<li><a
href=
"#chap4"
>
target-text:: after:
</a></li>
</ul>
</nav>
</section>
<section>
<h1
id=
"chap0"
>
Lorem ipsum dolor sit amet
</h1>
</section>
<section>
<h1
id=
"chap1"
>
Lorem ipsum dolor sit amet
</h1>
</section>
<section>
<h1
id=
"chap2"
>
Praesent placerat lectus
</h1>
</section>
<section>
<h1
id=
"chap3"
>
Aliquam eget massa loborti
</h1>
</section>
<section>
<h1
id=
"chap4"
>
Aliquam eget massa loborti
</h1>
</section>
</body>
</html>
\ No newline at end of file
specs/target/target-text/target-text.spec.js
0 → 100644
View file @
b82b64fe
const
TIMEOUT
=
10000
;
// Some book might take longer than this to renderer
describe
(
'
target-text
'
,
async
()
=>
{
let
page
;
let
rendered
;
beforeAll
(
async
()
=>
{
page
=
await
loadPage
(
'
target/target-text/target-text.html
'
)
return
page
.
rendered
;
},
TIMEOUT
)
afterAll
(
async
()
=>
{
if
(
!
DEBUG
)
{
await
page
.
close
();
}
})
it
(
'
Table of content should include chapter titles
'
,
async
()
=>
{
let
text
=
await
page
.
$eval
(
"
nav li:nth-of-type(1) a
"
,
(
r
)
=>
window
.
getComputedStyle
(
r
,
'
::after
'
).
content
);
expect
(
text
).
toContain
(
"
Lorem ipsum dolor sit amet
"
);
})
it
(
'
Table of content should include chapter titles
'
,
async
()
=>
{
let
text
=
await
page
.
$eval
(
"
nav li:nth-of-type(2) a
"
,
(
r
)
=>
window
.
getComputedStyle
(
r
,
'
::after
'
).
content
);
expect
(
text
).
toContain
(
"
Lorem ipsum dolor sit amet
"
);
})
it
(
'
Table of content should include first-letter of the chapter title
'
,
async
()
=>
{
let
text
=
await
page
.
$eval
(
"
nav li:nth-of-type(3) a
"
,
(
r
)
=>
window
.
getComputedStyle
(
r
,
'
::after
'
).
content
);
expect
(
text
).
toContain
(
"
P
"
);
})
it
(
'
Table of content should include the content of the before pseudo element
'
,
async
()
=>
{
let
text
=
await
page
.
$eval
(
"
nav li:nth-of-type(4) a
"
,
(
r
)
=>
window
.
getComputedStyle
(
r
,
'
::after
'
).
content
);
expect
(
text
).
toContain
(
"
This is inside the before:
"
);
})
it
(
'
Table of content should include the content of the before pseudo element
'
,
async
()
=>
{
let
text
=
await
page
.
$eval
(
"
nav li:nth-of-type(5) a
"
,
(
r
)
=>
window
.
getComputedStyle
(
r
,
'
::after
'
).
content
);
expect
(
text
).
toContain
(
"
: This is inside the after
"
);
})
if
(
!
DEBUG
)
{
it
(
'
should create a pdf
'
,
async
()
=>
{
let
pdf
=
await
page
.
pdf
(
PDF_SETTINGS
);
expect
(
pdf
).
toMatchPDFSnapshot
(
1
);
})
}
}
)
src/modules/generated-content/target-text.js
View file @
b82b64fe
import
Handler
from
"
../handler
"
;
import
{
UUID
,
attr
,
querySelectorEscape
}
from
"
../../utils/utils
"
;
import
csstree
from
"
css-tree
"
;
import
{
nodeAfter
}
from
"
../../utils/dom
"
;
class
TargetText
extends
Handler
{
constructor
(
chunker
,
polisher
,
caller
)
{
...
...
@@ -8,11 +9,14 @@ class TargetText extends Handler {
this
.
styleSheet
=
polisher
.
styleSheet
;
this
.
textTargets
=
{};
this
.
beforeContent
=
""
;
this
.
afterContent
=
""
;
this
.
selector
=
{};
}
onContent
(
funcNode
,
fItem
,
fList
,
declaration
,
rule
)
{
if
(
funcNode
.
name
===
"
target-text
"
)
{
let
selector
=
csstree
.
generate
(
rule
.
ruleNode
.
prelude
);
this
.
selector
=
csstree
.
generate
(
rule
.
ruleNode
.
prelude
);
let
first
=
funcNode
.
children
.
first
();
let
last
=
funcNode
.
children
.
last
();
let
func
=
first
.
name
;
...
...
@@ -21,7 +25,7 @@ class TargetText extends Handler {
let
args
=
[];
first
.
children
.
forEach
(
(
child
)
=>
{
first
.
children
.
forEach
(
child
=>
{
if
(
child
.
type
===
"
Identifier
"
)
{
args
.
push
(
child
.
name
);
}
...
...
@@ -34,14 +38,14 @@ class TargetText extends Handler {
let
variable
=
"
--pagedjs-
"
+
UUID
();
selector
.
split
(
"
,
"
).
forEach
((
s
)
=>
{
this
.
selector
.
split
(
"
,
"
).
forEach
(
s
=>
{
this
.
textTargets
[
s
]
=
{
func
:
func
,
args
:
args
,
value
:
value
,
style
:
style
||
"
content
"
,
selector
:
s
,
fullSelector
:
selector
,
fullSelector
:
this
.
selector
,
variable
:
variable
};
});
...
...
@@ -57,8 +61,34 @@ class TargetText extends Handler {
}
}
// parse this on the ONCONTENT : get all before and after and replace the value with a variable
onPseudoSelector
(
pseudoNode
,
pItem
,
pList
,
selector
,
rule
)
{
// console.log(pseudoNode);
// console.log(rule);
rule
.
ruleNode
.
block
.
children
.
forEach
(
properties
=>
{
if
(
pseudoNode
.
name
===
"
before
"
&&
properties
.
property
===
"
content
"
)
{
let
beforeVariable
=
"
--pagedjs-
"
+
UUID
();
let
contenu
=
properties
.
value
.
children
;
console
.
log
(
contenu
);
contenu
.
forEach
(
prop
=>
{
if
(
prop
.
type
===
"
String
"
)
{
this
.
beforeContent
=
prop
.
value
;
}
});
}
else
if
(
pseudoNode
.
name
===
"
after
"
&&
properties
.
property
===
"
content
"
)
{
let
content
=
properties
.
value
.
children
.
forEach
(
prop
=>
{
if
(
prop
.
type
===
"
String
"
)
{
this
.
afterContent
=
prop
.
value
;
}
});
}
});
}
afterParsed
(
fragment
)
{
Object
.
keys
(
this
.
textTargets
).
forEach
(
(
name
)
=>
{
Object
.
keys
(
this
.
textTargets
).
forEach
(
name
=>
{
let
target
=
this
.
textTargets
[
name
];
let
split
=
target
.
selector
.
split
(
"
::
"
);
let
query
=
split
[
0
];
...
...
@@ -68,29 +98,79 @@ class TargetText extends Handler {
let
element
=
fragment
.
querySelector
(
querySelectorEscape
(
val
));
if
(
element
)
{
if
(
target
.
style
===
"
content
"
)
{
let
selector
=
UUID
();
selected
.
setAttribute
(
"
data-target-text
"
,
selector
);
this
.
selector
=
UUID
();
selected
.
setAttribute
(
"
data-target-text
"
,
this
.
selector
);
let
psuedo
=
""
;
if
(
split
.
length
>
1
)
{
psuedo
+=
"
::
"
+
split
[
1
];
}
let
textContent
=
element
.
textContent
.
trim
().
replace
(
/
[
"'
]
/g
,
(
match
)
=>
{
return
"
\\
"
+
match
;
}).
replace
(
/
[\n]
/g
,
(
match
)
=>
{
return
"
\\
00000A
"
;
});
let
textContent
=
element
.
textContent
.
trim
()
.
replace
(
/
[
"'
]
/g
,
match
=>
{
return
"
\\
"
+
match
;
})
.
replace
(
/
[\n]
/g
,
match
=>
{
return
"
\\
00000A
"
;
});
// this.styleSheet.insertRule(`[data-target-text="${selector}"]${psuedo} { content: "${element.textContent}" }`, this.styleSheet.cssRules.length);
this
.
styleSheet
.
insertRule
(
`[data-target-text="
${
selector
}
"]
${
psuedo
}
{
${
target
.
variable
}
: "
${
textContent
}
" }`
,
this
.
styleSheet
.
cssRules
.
length
);
this
.
styleSheet
.
insertRule
(
`[data-target-text="
${
this
.
selector
}
"]
${
psuedo
}
{
${
target
.
variable
}
: "
${
textContent
}
" }`
);
}
// first-letter
else
if
(
target
.
style
===
"
first-letter
"
)
{
this
.
selector
=
UUID
();
selected
.
setAttribute
(
"
data-target-text
"
,
this
.
selector
);
let
psuedo
=
""
;
if
(
split
.
length
>
1
)
{
psuedo
+=
"
::
"
+
split
[
1
];
}
let
textContent
=
element
.
textContent
.
trim
()
.
replace
(
/
[
"'
]
/g
,
match
=>
{
return
"
\\
"
+
match
;
})
.
replace
(
/
[\n]
/g
,
match
=>
{
return
"
\\
00000A
"
;
});
this
.
styleSheet
.
insertRule
(
`[data-target-text="
${
this
.
selector
}
"]
${
psuedo
}
{
${
target
.
variable
}
: "
${
textContent
.
charAt
(
0
)}
" }`
);
}
// before
else
if
(
target
.
style
===
"
before
"
)
{
selected
.
setAttribute
(
"
data-target-text
"
,
this
.
selector
);
let
psuedo
=
""
;
if
(
split
.
length
>
1
)
{
psuedo
+=
"
::
"
+
split
[
1
];
}
let
textContent
=
this
.
beforeContent
.
trim
().
replace
(
/
[
"'
]
/g
,
""
);
this
.
styleSheet
.
insertRule
(
`[data-target-text="
${
this
.
selector
}
"]
${
psuedo
}
{
${
target
.
variable
}
: "
${
textContent
}
" }`
);
}
// after
else
if
(
target
.
style
===
"
after
"
)
{
selected
.
setAttribute
(
"
data-target-text
"
,
this
.
selector
);
let
psuedo
=
""
;
if
(
split
.
length
>
1
)
{
psuedo
+=
"
::
"
+
split
[
1
];
}
let
textContent
=
this
.
afterContent
.
trim
().
replace
(
/
[
"'
]
/g
,
""
);
this
.
styleSheet
.
insertRule
(
`[data-target-text="
${
this
.
selector
}
"]
${
psuedo
}
{
${
target
.
variable
}
: "
${
textContent
}
" }`
);
}
else
{
console
.
warn
(
"
missed target
"
,
val
);
}
}
else
{
console
.
warn
(
"
missed target
"
,
val
);
}
});
});
}
}
...
...
src/polisher/polisher.js
View file @
b82b64fe
...
...
@@ -15,6 +15,9 @@ class Polisher {
this
.
hooks
.
onRule
=
new
Hook
(
this
);
this
.
hooks
.
onDeclaration
=
new
Hook
(
this
);
this
.
hooks
.
onContent
=
new
Hook
(
this
);
this
.
hooks
.
onSelector
=
new
Hook
(
this
);
this
.
hooks
.
onPseudoSelector
=
new
Hook
(
this
);
this
.
hooks
.
onImport
=
new
Hook
(
this
);
this
.
hooks
.
beforeTreeParse
=
new
Hook
(
this
);
...
...
src/polisher/sheet.js
View file @
b82b64fe
...
...
@@ -14,6 +14,9 @@ class Sheet {
this
.
hooks
.
onAtMedia
=
new
Hook
(
this
);
this
.
hooks
.
onRule
=
new
Hook
(
this
);
this
.
hooks
.
onDeclaration
=
new
Hook
(
this
);
this
.
hooks
.
onSelector
=
new
Hook
(
this
);
this
.
hooks
.
onPseudoSelector
=
new
Hook
(
this
);
this
.
hooks
.
onContent
=
new
Hook
(
this
);
this
.
hooks
.
onImport
=
new
Hook
(
this
);
...
...
@@ -65,6 +68,8 @@ class Sheet {
return
this
.
ast
;
}
insertRule
(
rule
)
{
let
inserted
=
this
.
ast
.
children
.
appendData
(
rule
);
inserted
.
forEach
((
item
)
=>
{
...
...
@@ -114,6 +119,8 @@ class Sheet {
this
.
hooks
.
onRule
.
trigger
(
ruleNode
,
ruleItem
,
rulelist
);
this
.
declarations
(
ruleNode
,
ruleItem
,
rulelist
);
this
.
onSelector
(
ruleNode
,
ruleItem
,
rulelist
);
}
});
}
...
...
@@ -139,6 +146,30 @@ class Sheet {
});
}
// add pseudo elements to parser
onSelector
(
ruleNode
,
ruleItem
,
rulelist
)
{
csstree
.
walk
(
ruleNode
,
{
visit
:
"
Selector
"
,
enter
:
(
selectNode
,
selectItem
,
selectList
)
=>
{
// console.log(selectNode);
this
.
hooks
.
onSelector
.
trigger
(
selectNode
,
selectItem
,
selectList
,
{
ruleNode
,
ruleItem
,
rulelist
});
if
(
selectNode
.
children
.
forEach
(
node
=>
{
if
(
node
.
type
===
"
PseudoElementSelector
"
)
{
csstree
.
walk
(
node
,
{
visit
:
"
PseudoElementSelector
"
,
enter
:
(
pseudoNode
,
pItem
,
pList
)
=>
{
this
.
hooks
.
onPseudoSelector
.
trigger
(
pseudoNode
,
pItem
,
pList
,
{
selectNode
,
selectItem
,
selectList
},
{
ruleNode
,
ruleItem
,
rulelist
});
}
});
}}));
// else {
// console.log("dommage");
// }
}
});
}
replaceUrls
(
ast
)
{
csstree
.
walk
(
ast
,
{
visit
:
"
Url
"
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment