Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
officejs
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
officejs
Commits
5516d803
Commit
5516d803
authored
May 21, 2014
by
Thibaut Frain
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
added presentation editor gadget
parent
409f3ae0
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
590 additions
and
1 deletion
+590
-1
Gruntfile.js
Gruntfile.js
+10
-1
src/presentation-editor/index.html
src/presentation-editor/index.html
+129
-0
src/presentation-editor/presentation-editor.css
src/presentation-editor/presentation-editor.css
+112
-0
src/presentation-editor/presentation-editor.js
src/presentation-editor/presentation-editor.js
+339
-0
No files found.
Gruntfile.js
View file @
5516d803
...
@@ -189,8 +189,17 @@ module.exports = function (grunt) {
...
@@ -189,8 +189,17 @@ module.exports = function (grunt) {
src
:
'
<%= curl.jquerymobilejs.src_base %>.css
'
,
src
:
'
<%= curl.jquerymobilejs.src_base %>.css
'
,
relative_dest
:
'
lib/jquerymobile.css
'
,
relative_dest
:
'
lib/jquerymobile.css
'
,
dest
:
'
<%= global_config.dest %>/<%= curl.jquerymobilecss.relative_dest %>
'
dest
:
'
<%= global_config.dest %>/<%= curl.jquerymobilecss.relative_dest %>
'
},
html
-
beautify
:
{
src
:
'
https://raw.githubusercontent.com/einars/js-beautify/master/js/lib/beautify-html.js
'
relative_dest
:
'
lib/html-beautify.js
'
,
dest
:
'
<%= global_config.dest %>/<%= curl.html-beautify.relative_dest %>
'
},
animatecss
:
{
src
:
'
https://raw.github.com/daneden/animate.css/master/animate.css
'
relative_dest
:
'
lib/animate.css
'
,
dest
:
'
<%= global_config.dest %>/<%= curl.animatecss.relative_dest %>
'
}
}
// qunit: {
// qunit: {
// all: ['test/index.html']
// all: ['test/index.html']
},
},
...
...
src/presentation-editor/index.html
0 → 100644
View file @
5516d803
<!DOCTYPE html>
<html
lang=
"en"
>
<head>
<meta
charset=
"utf-8"
>
<title>
Presentation editor
</title>
<!-- Presentation editor dependencies -->
<script
src=
"../lib/jquery.min.js"
></script>
<script
src=
"../lib/jquery-ui.min.js"
></script>
<script
src=
"../lib/jquery.mobile.min.js"
></script>
<script
src=
"../lib/beautify-html.js"
></script>
<!-- Renderjs -->
<script
src=
"../lib/rsvp.min.js"
></script>
<script
src=
"../lib/renderjs.js"
></script>
<!-- Jquery ui and jquery-mobile stylesheet -->
<link
rel=
"stylesheet"
href=
"../lib/jquery-ui.min.css"
>
<link
rel=
"stylesheet"
href=
"../lib/jquery.mobile.min.css"
>
<link
rel=
"stylesheet"
href=
"../lib/animate.min.css"
>
<!-- Presentation editor stylesheet -->
<link
rel=
"stylesheet"
href=
"presentation-editor.css"
>
<!-- Presentation editor gadget -->
<script
src=
"presentation-editor.js"
></script>
</head>
<body>
<div
data-role=
"page"
>
<div
id=
"form-panel"
data-role=
"panel"
data-display=
"push"
>
<div
class=
"panel-content page"
>
<form
id=
"slide-form"
>
<div
data-role=
"fieldcontain"
>
<label
for=
"title"
><strong>
Title
</strong></label>
<input
type=
"text"
name=
"title"
id=
"title"
placeholder=
"Type here the slide title"
data-clear-btn=
"true"
required
/>
</div>
<br/>
<div
data-role=
"fieldcontain"
>
<label
for=
"type"
><strong>
Type
</strong></label>
<fieldset
data-role=
"controlgroup"
data-mini=
"true"
id=
"type"
>
<input
type=
"radio"
name=
"type"
id=
"basic-type"
value=
""
checked=
"checked"
/>
<label
for=
"basic-type"
>
basic
</label>
<input
type=
"radio"
name=
"type"
id=
"chapter-type"
value=
"chapter"
/>
<label
for=
"chapter-type"
>
chapter
</label>
<input
type=
"radio"
name=
"type"
id=
"screenshot-type"
value=
"screenshot"
/>
<label
for=
"screenshot-type"
>
screenshot
</label>
<input
type=
"radio"
name=
"type"
id=
"illustration-type"
value=
"illustration"
/>
<label
for=
"illustration-type"
>
illustration
</label>
<input
type=
"radio"
name=
"type"
id=
"code-type"
value=
"code"
/>
<label
for=
"code-type"
>
code
</label>
<input
type=
"radio"
name=
"type"
id=
"master-type"
value=
"master"
/>
<label
for=
"master-type"
>
master
</label>
</fieldset>
</div>
<br/>
<div
data-role=
"fieldcontain"
id=
"image-field"
>
<label
for=
"image"
><strong>
Image URL
</strong></label>
<input
type=
"text"
name=
"image"
id=
"image-url"
/>
<img
id=
"image-preview"
class=
"ui-shadow ui-corner-all"
>
<br/>
</div>
<br/>
<div
data-role=
"fieldcontain"
>
<label
for=
"content"
><strong>
Slide text
</strong></label>
<textarea
name=
"content"
id=
"content"
placeholder=
"This text will appear in the slide"
></textarea>
</div>
<div
data-role=
"fieldcontain"
>
<label
for=
"details"
><strong>
Slide details
</strong></label>
<textarea
name=
"details"
id=
"details"
placeholder=
"This text will be hidden"
></textarea>
</div>
<br/>
<div
id=
"slide-form-buttons"
class=
"ui-grid-a"
>
<div
class=
"ui-block-a"
><input
type=
"button"
id=
"cancel"
value=
"Cancel"
data-theme=
"b"
></div>
<div
class=
"ui-block-b"
><input
type=
"submit"
id=
"submit"
value=
"Add slide"
class=
"ui-block-b"
></div>
</div>
</form>
</div>
</div>
<div
role=
"main"
class=
"ui-content"
>
<div
id=
"slide-list"
>
</div>
<section
id=
"add-slide"
class=
"block ui-shadow ui-corner-all ui-btn"
>
<div
class=
"dummy"
></div>
<div
class=
"slide"
>
New slide
</div>
</section>
</div>
<template
id=
"slide-html"
>
<section
class=
"block slide-thumb ui-shadow ui-corner-all"
>
<button
class=
"edit ui-shadow ui-corner-all ui-btn ui-btn-inline ui-icon-edit ui-btn-icon-notext"
data-inline=
"true"
>
</button>
<button
class=
"delete ui-shadow ui-corner-all ui-btn ui-btn-inline ui-icon-delete ui-btn-icon-notext"
data-inline=
"true"
>
</button>
<div
class=
"dummy"
></div>
<div
class=
"slide"
>
<h1></h1>
<img>
<div
class=
"content"
></div>
</div>
</section>
</template>
<template
id=
"slide-data"
>
<section>
<h1></h1>
</section>
</template>
</div>
</body>
</html>
src/presentation-editor/presentation-editor.css
0 → 100644
View file @
5516d803
.block
{
display
:
inline-block
;
float
:
left
;
margin
:
1%
;
position
:
relative
;
padding
:
2%
;
cursor
:
pointer
;
position
:
relative
;
width
:
7.9vw
;
min-width
:
150px
;
z-index
:
10
;
overflow
:
hidden
;
}
.block.slide-thumb
{
background-color
:
white
;
/* box-shadow: 2px 2px 2px 3px #ccc; */
border
:
2px
solid
grey
;
}
.block
#add-slide
.slide
{
margin-left
:
auto
;
margin-right
:
auto
;
margin-top
:
30%
;
font-size
:
150%
;
}
.block
>
.dummy
{
margin-top
:
100%
;
}
.block
>
.slide
{
position
:
absolute
;
top
:
2%
;
bottom
:
2%
;
left
:
2%
;
right
:
2%
;
}
.block
>
button
.edit
{
position
:
absolute
;
bottom
:
-2%
;
right
:
-2%
;
z-index
:
20
;
}
.block
>
button
.delete
{
position
:
absolute
;
top
:
-2%
;
right
:
-2%
;
z-index
:
20
;
}
.block
.slide
>
h1
{
text-align
:
center
;
}
.block
>
.slide
*
{
position
:
relative
;
max-width
:
98%
;
word-wrap
:
break-word
;
}
.ui-panel-page-content-open.ui-panel-page-content-position-left.ui-panel-page-content-display-push
{
padding-right
:
35vw
;
}
.ui-panel-page-content-open.ui-panel-page-content-display-push
{
width
:
auto
;
}
.ui-panel-dismiss-display-push
{
display
:
none
;
}
body
{
background
:
url('images/tweed.png')
;
background-repeat
:
repeat
;
background-position
:
center
center
;
background-attachment
:
scroll
;
background-size
:
100%
100%
;
}
.ui-page
.ui-overlay-a
,
.ui-page-theme-a
,
.ui-page-theme-a
.ui-panel-wrapper
{
background
:
url('images/tweed.png')
;
}
.ui-content
{
background
:
transparent
;
}
@media
(
max-width
:
1000px
)
{
.ui-panel
{
width
:
100%
;
}
.ui-panel-position-left
{
left
:
100%
;
}
.ui-panel-animate.ui-panel-page-content-position-left
{
-webkit-transform
:
translate3d
(
100%
,
0
,
0
);
-moz-transform
:
translate3d
(
100%
,
0
,
0
);
transform
:
translate3d
(
100%
,
0
,
0
);
}
}
#image-preview
{
position
:
relative
;
float
:
right
;
width
:
24%
;
margin
:
3%
}
\ No newline at end of file
src/presentation-editor/presentation-editor.js
0 → 100644
View file @
5516d803
/*globals window, document, $, html_beautify, FileReader, */
/*jslint unparam: true */
$
(
function
(
window
,
$
,
html_beautify
,
rJS
)
{
"
use strict
"
;
var
presentation
=
null
,
slideForm
,
newSlideButton
=
$
(
'
#add-slide
'
),
formPanel
=
$
(
'
#form-panel
'
);
formPanel
.
panel
({
beforeclose
:
function
()
{
newSlideButton
.
show
(
"
fade
"
);
slideForm
.
bindToAdd
();
}});
function
openForm
()
{
formPanel
.
panel
(
"
open
"
);
newSlideButton
.
hide
(
"
fade
"
);
}
function
closeForm
()
{
formPanel
.
panel
(
"
close
"
);
}
function
animate
(
selector
,
animation
)
{
var
$selector
=
$
(
selector
);
$selector
.
off
(
"
animationend webkitAnimationEnd
"
);
$selector
.
on
(
"
animationend webkitAnimationEnd
"
,
function
()
{
$selector
.
removeClass
(
"
animated
"
+
animation
);
});
$selector
.
addClass
(
"
animated
"
+
animation
);
}
function
Slide
(
params
)
{
var
that
=
this
;
this
.
html
=
document
.
importNode
(
this
.
htmlTemplate
,
true
);
this
.
update
(
params
);
$
(
this
.
editBtn
()).
click
(
function
()
{
if
(
slideForm
.
currentSlide
!==
that
)
{
slideForm
.
bindToEdit
(
that
);
openForm
();
}
});
$
(
this
.
deleteBtn
()).
click
(
function
()
{
presentation
.
deleteSlide
(
that
);
});
}
function
readSlide
(
domElement
)
{
var
$el
=
$
(
domElement
),
title
=
$el
.
find
(
'
h1
'
).
first
().
text
(),
type
=
$el
.
attr
(
'
class
'
),
img
,
content
=
""
;
if
(
type
===
'
screenshot
'
||
type
===
'
illustration
'
)
{
img
=
$el
.
find
(
'
img
'
).
first
().
attr
(
'
src
'
);
}
$el
.
contents
().
filter
(
function
()
{
return
$
(
this
).
is
(
'
:not(img, h1, details)
'
)
||
this
.
nodeType
===
3
;
}).
each
(
function
()
{
content
+=
this
.
outerHTML
||
this
.
textContent
;
});
return
new
Slide
({
title
:
title
,
type
:
type
,
content
:
content
,
image
:
img
});
}
Slide
.
prototype
=
{
dataTemplate
:
document
.
querySelector
(
'
template#slide-data
'
).
content
.
firstElementChild
,
htmlTemplate
:
document
.
querySelector
(
'
template#slide-html
'
).
content
.
firstElementChild
,
editBtn
:
function
()
{
return
this
.
html
.
querySelector
(
"
button.edit
"
);
},
deleteBtn
:
function
()
{
return
this
.
html
.
querySelector
(
"
button.delete
"
);
},
htmlContent
:
function
()
{
return
this
.
html
.
querySelector
(
"
.content
"
);
},
htmlImage
:
function
()
{
return
this
.
html
.
querySelector
(
"
img
"
);
},
htmlTitle
:
function
()
{
return
this
.
html
.
querySelector
(
"
h1
"
);
},
data
:
function
()
{
var
res
=
document
.
importNode
(
this
.
dataTemplate
,
true
),
img
;
res
.
className
=
this
.
type
;
res
.
querySelector
(
'
h1
'
).
textContent
=
this
.
title
;
$
(
res
).
append
(
this
.
content
);
if
(
this
.
type
===
"
screenshot
"
||
this
.
type
===
"
illustration
"
)
{
img
=
document
.
createElement
(
'
img
'
);
img
.
src
=
this
.
image
;
res
.
appendChild
(
img
);
}
return
res
;
},
update
:
function
(
params
)
{
$
.
extend
(
this
,
params
);
this
.
htmlTitle
().
textContent
=
this
.
title
;
this
.
htmlContent
().
innerHTML
=
this
.
content
;
if
(
this
.
type
===
"
screenshot
"
||
this
.
type
===
"
illustration
"
)
{
this
.
htmlImage
().
src
=
this
.
image
;
}
else
{
this
.
htmlImage
().
src
=
""
;
}
}
};
function
SlideForm
()
{
var
that
=
this
;
this
.
elt
=
document
.
querySelector
(
"
#slide-form
"
);
this
.
bindToAdd
();
$
(
this
.
elt
).
find
(
"
#cancel
"
).
click
(
closeForm
);
$
(
this
.
elt
).
find
(
'
input[type="radio"]
'
).
click
(
function
()
{
that
.
updateFieldVisibility
(
true
);
});
$
(
"
#image-url
"
).
on
(
"
change
"
,
function
()
{
that
.
updatePreview
(
that
.
attrImageURL
());
});
}
SlideForm
.
prototype
=
{
attrTextInput
:
function
(
inputElt
,
content
)
{
if
(
content
!==
undefined
)
{
inputElt
.
value
=
content
;
}
else
{
return
inputElt
.
value
;
}
},
attrTitle
:
function
(
content
)
{
return
this
.
attrTextInput
(
this
.
elt
.
querySelector
(
'
#title
'
),
content
);
},
attrContent
:
function
(
content
)
{
return
this
.
attrTextInput
(
this
.
elt
.
querySelector
(
'
#content
'
),
content
);
},
attrDetails
:
function
(
content
)
{
return
this
.
attrTextInput
(
this
.
elt
.
querySelector
(
'
#details
'
),
content
);
},
attrType
:
function
(
type
)
{
var
radios
=
$
(
this
.
elt
).
find
(
'
input[type="radio"]
'
);
if
(
type
!==
undefined
)
{
radios
.
prop
(
'
checked
'
,
false
);
if
(
type
===
""
)
{
type
=
"
basic
"
;
}
radios
.
filter
(
"
#
"
+
type
+
"
-type
"
).
prop
(
'
checked
'
,
true
);
radios
.
checkboxradio
(
'
refresh
'
);
this
.
updateFieldVisibility
();
}
else
{
return
radios
.
filter
(
'
:checked
'
).
val
();
}
},
attrImageURL
:
function
(
content
)
{
return
this
.
attrTextInput
(
this
.
elt
.
querySelector
(
'
#image-url
'
),
content
);
},
updatePreview
:
function
(
content
)
{
var
preview
=
this
.
elt
.
querySelector
(
'
#image-preview
'
);
if
(
content
)
{
$
(
preview
).
show
();
preview
.
src
=
content
;
}
else
{
$
(
preview
).
hide
();
}
},
attrAll
:
function
(
slide
)
{
if
(
slide
!==
undefined
)
{
this
.
attrTitle
(
slide
.
title
);
this
.
attrType
(
slide
.
type
);
this
.
attrContent
(
slide
.
content
);
this
.
attrDetails
(
slide
.
details
);
this
.
attrImageURL
(
slide
.
image
);
this
.
updatePreview
(
slide
.
image
);
}
else
{
return
{
title
:
this
.
attrTitle
(),
type
:
this
.
attrType
(),
content
:
this
.
attrContent
(),
details
:
this
.
attrDetails
(),
image
:
this
.
attrImageURL
()
};
}
},
updateFieldVisibility
:
function
(
withEffect
)
{
var
type
=
this
.
attrType
(),
$imageField
=
$
(
this
.
elt
).
find
(
'
#image-field
'
),
$imageInputURL
=
$
(
this
.
elt
).
find
(
'
input#image-url
'
);
if
(
type
===
"
screenshot
"
||
type
===
"
illustration
"
)
{
if
(
withEffect
)
{
$imageField
.
show
(
"
blind
"
,
{
direction
:
"
up
"
});
}
else
{
$imageField
.
show
();
}
$imageInputURL
.
attr
(
'
required
'
,
true
);
}
else
{
if
(
withEffect
)
{
$imageField
.
hide
(
"
blind
"
,
{
direction
:
"
up
"
});
}
else
{
$imageField
.
hide
();
}
$imageInputURL
.
attr
(
'
required
'
,
false
);
}
},
setSubmitLabel
:
function
(
label
)
{
var
submit
=
$
(
this
.
elt
).
find
(
"
#submit
"
);
submit
.
prop
(
"
value
"
,
label
).
button
(
'
refresh
'
);
},
reset
:
function
()
{
this
.
attrAll
({
title
:
""
,
type
:
"
basic
"
,
content
:
""
,
details
:
""
,
image
:
""
});
this
.
currentSlide
=
null
;
$
(
this
.
elt
).
off
(
"
submit
"
);
},
bindToEdit
:
function
(
slide
)
{
var
that
=
this
;
this
.
reset
();
animate
(
this
.
elt
,
"
fadeIn
"
);
that
.
currentSlide
=
slide
;
this
.
attrAll
(
slide
);
$
(
this
.
elt
).
submit
(
function
(
e
)
{
slide
.
update
(
that
.
attrAll
());
animate
(
slide
.
html
,
"
bounce
"
);
e
.
preventDefault
();
that
.
bindToAdd
();
});
this
.
setSubmitLabel
(
"
Save
"
);
},
bindToAdd
:
function
()
{
var
that
=
this
;
this
.
reset
();
$
(
this
.
elt
).
submit
(
function
(
e
)
{
presentation
.
addSlide
(
new
Slide
(
that
.
attrAll
()));
that
.
bindToAdd
();
e
.
preventDefault
();
});
this
.
setSubmitLabel
(
"
Add
"
);
}
};
function
Presentation
(
DOMElement
)
{
this
.
html
=
DOMElement
;
slideForm
=
new
SlideForm
();
this
.
slides
=
[];
$
(
"
#add-slide
"
).
click
(
openForm
);
$
(
this
.
html
).
sortable
({
update
:
function
(
event
,
ui
)
{
presentation
.
updateOrder
(
ui
.
item
);
}
});
}
Presentation
.
prototype
=
{
addSlide
:
function
(
slide
)
{
this
.
slides
.
push
(
slide
);
this
.
html
.
appendChild
(
slide
.
html
);
animate
(
slide
.
html
,
"
pulse
"
);
return
slide
;
},
deleteSlide
:
function
(
slide
)
{
if
(
slideForm
.
currentSlide
===
slide
)
{
slideForm
.
bindToAdd
();
}
var
index
=
this
.
slides
.
indexOf
(
slide
);
this
.
slides
.
splice
(
index
,
1
);
animate
(
slide
.
html
,
'
rollOut
'
);
$
(
slide
.
html
).
on
(
"
animationend webkitAnimationEnd
"
,
function
()
{
slide
.
html
.
remove
();
});
return
index
;
},
updateOrder
:
function
(
DOMElement
)
{
var
newIndex
=
$
(
this
.
html
.
children
).
index
(
DOMElement
),
oldIndex
,
i
,
tmp
;
for
(
i
=
0
;
i
<
this
.
slides
.
length
;
i
++
)
{
if
(
this
.
slides
[
i
].
html
===
DOMElement
[
0
])
{
oldIndex
=
i
;
break
;
}
}
tmp
=
this
.
slides
.
splice
(
oldIndex
,
1
)[
0
];
this
.
slides
.
splice
(
newIndex
,
0
,
tmp
);
},
getContent
:
function
()
{
var
i
,
container
=
document
.
createElement
(
'
div
'
);
for
(
i
=
0
;
i
<
this
.
slides
.
length
;
i
++
)
{
container
.
appendChild
(
this
.
slides
[
i
].
data
());
}
return
html_beautify
(
container
.
innerHTML
);
},
setContent
:
function
(
content
)
{
var
i
,
sections
,
container
=
document
.
createElement
(
'
div
'
);
container
.
innerHTML
=
content
;
sections
=
container
.
children
;
for
(
i
=
0
;
i
<
sections
.
length
;
i
++
)
{
this
.
addSlide
(
readSlide
(
sections
[
i
]));
}
}
};
$
.
fn
.
extend
({
presentation
:
function
()
{
presentation
=
new
Presentation
(
this
[
0
]);
window
.
prez
=
presentation
;
return
presentation
;
}
});
rJS
(
window
)
.
declareMethod
(
'
setContent
'
,
function
(
content
)
{
rJS
(
this
).
editor
.
setContent
(
content
);
})
.
declareMethod
(
'
getContent
'
,
function
()
{
return
rJS
(
this
).
editor
.
getContent
();
})
.
ready
(
function
(
g
)
{
g
.
editor
=
$
(
'
#slide-list
'
).
presentation
();
});
}(
window
,
$
,
html_beautify
,
rJS
));
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