Reindent code by 2 spaces, instead of 4

This commit is contained in:
Tautvidas Sipavičius
2015-08-27 13:50:05 +03:00
parent 21a4843a48
commit e6d59496eb
72 changed files with 7216 additions and 7264 deletions

View File

@ -23,196 +23,194 @@ $range-border-radius = 3px
$range-thumb-hover-background-color = $primary-active-color $range-thumb-hover-background-color = $primary-active-color
a a
color: $link-color color: $link-color
text-decoration: none text-decoration: none
.mailpoet_hidden .mailpoet_hidden
display: none !important display: none !important
input.mailpoet_color input.mailpoet_color
width: 5em width: 5em
select.mailpoet_font-family select.mailpoet_font-family
width: 8em width: 8em
select.mailpoet_font-size select.mailpoet_font-size
width: 5em width: 5em
.mailpoet_input, .mailpoet_select .mailpoet_input, .mailpoet_select
border-radius(1px) border-radius(1px)
box-shadow(none !important) box-shadow(none !important)
appearance: none appearance: none
padding: $form-control-padding = 3px padding: $form-control-padding = 3px
line-height: 28px - $form-control-padding*2 line-height: 28px - $form-control-padding*2
.mailpoet_input .mailpoet_input
width: 283px width: 283px
border: 1px solid $select-border-color border: 1px solid $select-border-color
.mailpoet_input_small .mailpoet_input_small
width: 48px width: 48px
.mailpoet_input_medium .mailpoet_input_medium
width: 150px width: 150px
.mailpoet_input_full .mailpoet_input_full
width: 100% width: 100%
box-sizing: border-box box-sizing: border-box
.mailpoet_range .mailpoet_range
width: 283px width: 283px
-webkit-appearance: none
padding: 0
vertical-align: middle
&:focus
outline: none
&::-webkit-slider-runnable-track
width: 100%
height: $range-track-height
cursor: pointer
animate: 0.2s
background: $range-track-background-color
border-radius($range-border-radius)
border: 1px solid $range-track-border-color
&::-webkit-slider-thumb
border: 1px solid $range-thumb-border-color
height: $range-thumb-height
width: $range-thumb-width
border-radius($range-border-radius)
background: $range-thumb-background-color
cursor: pointer
-webkit-appearance: none -webkit-appearance: none
padding: 0 margin-top: (-1 * $range-thumb-height / 3)
vertical-align: middle &:hover::-webkit-slider-thumb
background: $range-thumb-hover-background-color
&:focus &::-moz-range-track
outline: none width: 100%
&::-webkit-slider-runnable-track height: $range-track-height
width: 100% cursor: pointer
height: $range-track-height animate: 0.2s
cursor: pointer background: $range-track-background-color
animate: 0.2s border-radius($range-border-radius)
background: $range-track-background-color border: 1px solid $range-track-border-color
border-radius($range-border-radius) &::-moz-range-thumb
border: 1px solid $range-track-border-color border: 1px solid $range-thumb-border-color
&::-webkit-slider-thumb height: $range-thumb-height
border: 1px solid $range-thumb-border-color width: $range-thumb-width
height: $range-thumb-height border-radius($range-border-radius)
width: $range-thumb-width background: $range-thumb-background-color
border-radius($range-border-radius) cursor: pointer
background: $range-thumb-background-color &:hover::-moz-range-thumb
cursor: pointer background: $range-thumb-hover-background-color
-webkit-appearance: none &::-ms-fill-lower
margin-top: (-1 * $range-thumb-height / 3) border: 1px solid $range-track-border-color
&:hover::-webkit-slider-thumb background: $range-track-background-color
background: $range-thumb-hover-background-color &::-ms-fill-upper
&::-moz-range-track border: 1px solid $range-track-border-color
width: 100% background: $range-track-background-color
height: $range-track-height &::-ms-track
cursor: pointer width: 100%
animate: 0.2s height: $range-track-height
background: $range-track-background-color cursor: pointer
border-radius($range-border-radius) animate: 0.2s
border: 1px solid $range-track-border-color background: transparent
&::-moz-range-thumb border-color: transparent
border: 1px solid $range-thumb-border-color border-width: ($range-track-height * 2) 0
height: $range-thumb-height color: transparent
width: $range-thumb-width &::-ms-thumb
border-radius($range-border-radius) border: 1px solid $range-thumb-border-color
background: $range-thumb-background-color height: $range-thumb-height
cursor: pointer width: $range-thumb-width
&:hover::-moz-range-thumb border-radius($range-border-radius)
background: $range-thumb-hover-background-color background: $range-thumb-background-color
&::-ms-fill-lower cursor: pointer
border: 1px solid $range-track-border-color &:hover::-ms-thumb
background: $range-track-background-color background: $range-thumb-hover-background-color
&::-ms-fill-upper &:focus::-ms-fill-lower
border: 1px solid $range-track-border-color border: 1px solid $range-track-border-color
background: $range-track-background-color background: $range-track-background-color
&::-ms-track &:focus::-ms-fill-upper
width: 100% border: 1px solid $range-track-border-color
height: $range-track-height background: $range-track-background-color
cursor: pointer
animate: 0.2s
background: transparent
border-color: transparent
border-width: ($range-track-height * 2) 0
color: transparent
&::-ms-thumb
border: 1px solid $range-thumb-border-color
height: $range-thumb-height
width: $range-thumb-width
border-radius($range-border-radius)
background: $range-thumb-background-color
cursor: pointer
&:hover::-ms-thumb
background: $range-thumb-hover-background-color
&:focus::-ms-fill-lower
border: 1px solid $range-track-border-color
background: $range-track-background-color
&:focus::-ms-fill-upper
border: 1px solid $range-track-border-color
background: $range-track-background-color
.mailpoet_range_small .mailpoet_range_small
width: 100px width: 100px
.mailpoet_range_medium .mailpoet_range_medium
width: 180px width: 180px
.mailpoet_select .mailpoet_select
border-color: $select-border-color border-color: $select-border-color
color: $select-text-color color: $select-text-color
margin: 0 margin: 0
.mailpoet_select_large .mailpoet_select_large
width: 139px width: 139px
.mailpoet_select_medium .mailpoet_select_medium
width: 103px width: 103px
.mailpoet_select_small .mailpoet_select_small
width: 68px width: 68px
.mailpoet_select_half_width .mailpoet_select_half_width
width: 50% width: 50%
#mailpoet_editor_content ol #mailpoet_editor_content ol
#mailpoet_editor_content ul #mailpoet_editor_content ul
list-style-position: inside list-style-position: inside
margin-left: 0 margin-left: 0
#mailpoet_editor_content ul #mailpoet_editor_content ul
list-style-type: disc list-style-type: disc
.mailpoet_button .mailpoet_button
margin: 0 margin: 0
border: 1px solid $button-default-border-color border: 1px solid $button-default-border-color
background-color: $button-default-background-color background-color: $button-default-background-color
padding: 6px 20px padding: 6px 20px
color: $button-default-text-color color: $button-default-text-color
border-radius(3px) border-radius(3px)
line-height: normal line-height: normal
vertical-align: top
vertical-align: top
.mailpoet_button_full .mailpoet_button_full
width: 100% width: 100%
box-sizing: border-box box-sizing: border-box
.mailpoet_button_primary .mailpoet_button_primary
border-color: $button-primary-border-color border-color: $button-primary-border-color
background-color: $button-primary-background-color background-color: $button-primary-background-color
color: $button-primary-text-color color: $button-primary-text-color
&:hover &:hover
background-color: $button-primary-hover-background-color background-color: $button-primary-hover-background-color
.mailpoet_button_group .mailpoet_button_group
display: inline display: inline
.mailpoet_button:first-child .mailpoet_button:first-child
margin-right: 0 margin-right: 0
padding: 6px 12px 6px padding: 6px 12px 6px
border-top-right-radius: 0 border-top-right-radius: 0
border-bottom-right-radius: 0 border-bottom-right-radius: 0
.mailpoet_button:last-child .mailpoet_button:last-child
margin-left: 0 margin-left: 0
padding-left: 10px padding-left: 10px
padding-right: 10px padding-right: 10px
border-left: 0 border-left: 0
border-top-left-radius: 0 border-top-left-radius: 0
border-bottom-left-radius: 0 border-bottom-left-radius: 0
.mailpoet_text_content p .mailpoet_text_content p
margin: 0 margin: 0
.mailpoet_separator .mailpoet_separator
margin: 17px 20px margin: 17px 20px
.mailpoet_option_offset_left_small .mailpoet_option_offset_left_small
margin-left: 10px margin-left: 10px
input.mailpoet_option_offset_left_small input.mailpoet_option_offset_left_small
margin-left: 10px !important margin-left: 10px !important

View File

@ -10,114 +10,114 @@ $master-column-tool-width = 24px
$layer-selector-width = 30px $layer-selector-width = 30px
.mailpoet_tools .mailpoet_tools
position: absolute
top: 0
right: 0
display: none
z-index: 20
padding: 2px
text-align: right
a
vertical-align: top
.mailpoet_container_horizontal + &
left: 100%
padding-left: 5px
.mailpoet_tool
width: $master-column-tool-width
height: $master-column-tool-width
.mailpoet_tool_icon
width: $master-column-tool-width
height: $master-column-tool-width
.mailpoet_delete_block_activated
width: auto
height: auto
.mailpoet_tool
display: inline-block
width: $tool-width
height: $tool-width
padding: 2px
&:hover
filter-shadow(1px, 2px, 0px, $tool-active-color)
.mailpoet_tool_icon
fill: $tool-inactive-color
width: $tool-width
height: $tool-width
.mailpoet_tool_icon_foreground
fill: $tool-inactive-secondary-color
&:hover
fill: $tool-hover-color
.mailpoet_tool_icon_foreground
fill: $tool-hover-secondary-color
&:active
fill: $primary-active-color
.mailpoet_tool_icon_foreground
fill: $tool-active-secondary-color
.mailpoet_delete_block_confirmation
position: absolute position: absolute
top: 0 top: 0
right: 0 right: 0
display: none width: 200px
z-index: 20
padding: 2px
text-align: right
a
vertical-align: top
.mailpoet_container_horizontal + &
left: 100%
padding-left: 5px
.mailpoet_tool
width: $master-column-tool-width
height: $master-column-tool-width
.mailpoet_tool_icon
width: $master-column-tool-width
height: $master-column-tool-width
.mailpoet_delete_block_activated
width: auto
height: auto
.mailpoet_tool
display: inline-block
width: $tool-width
height: $tool-width
padding: 2px
&:hover
filter-shadow(1px, 2px, 0px, $tool-active-color)
.mailpoet_tool_icon
fill: $tool-inactive-color
width: $tool-width
height: $tool-width
.mailpoet_tool_icon_foreground
fill: $tool-inactive-secondary-color
&:hover
fill: $tool-hover-color
.mailpoet_tool_icon_foreground
fill: $tool-hover-secondary-color
&:active
fill: $primary-active-color
.mailpoet_tool_icon_foreground
fill: $tool-active-secondary-color
.mailpoet_delete_block_confirmation
position: absolute
top: 0
right: 0
width: 200px
.mailpoet_delete_block .mailpoet_delete_block
display: inline-block display: inline-block
padding: 2px padding: 2px
vertical-align: top vertical-align: top
.mailpoet_tool .mailpoet_tool
padding: 0 padding: 0
.mailpoet_delete_block_confirm, .mailpoet_delete_block_confirm,
.mailpoet_delete_block_cancel .mailpoet_delete_block_cancel
display: none display: none
.mailpoet_delete_block_activated .mailpoet_delete_block_activated
width: auto width: auto
border-radius(3px) border-radius(3px)
background-color: $warning-background-color background-color: $warning-background-color
padding: 3px 5px padding: 3px 5px
line-height: 1.2em line-height: 1.2em
height: auto height: auto
.mailpoet_delete_block_activate .mailpoet_delete_block_activate
display: none display: none
.mailpoet_delete_block_confirm, .mailpoet_delete_block_confirm,
.mailpoet_delete_block_cancel .mailpoet_delete_block_cancel
display: inline-block display: inline-block
.mailpoet_delete_block_confirm .mailpoet_delete_block_confirm
color: $warning-text-color color: $warning-text-color
&:hover &:hover
color: $warning-text-color color: $warning-text-color
text-decoration: underline text-decoration: underline
.mailpoet_delete_block_cancel .mailpoet_delete_block_cancel
color: $warning-alternate-text-color color: $warning-alternate-text-color
&:hover &:hover
color: $warning-alternate-text-color color: $warning-alternate-text-color
text-decoration: underline text-decoration: underline
.mailpoet_newsletter_layer_selector .mailpoet_newsletter_layer_selector
&.mailpoet_container_layer_active &.mailpoet_container_layer_active
.mailpoet_tool_icon .mailpoet_tool_icon
fill: $primary-active-color fill: $primary-active-color
z-index: 100001 !important z-index: 100001 !important
.mailpoet_tool_icon_foreground .mailpoet_tool_icon_foreground
fill: $white-color fill: $white-color

View File

@ -6,58 +6,58 @@ $marker-z-index = 1
$draggable-widget-z-index = 2 $draggable-widget-z-index = 2
.mailpoet_drop_marker .mailpoet_drop_marker
background-color: $primary-active-color background-color: $primary-active-color
position: absolute
min-width: $marker-width
min-height: $marker-width
z-index: $marker-z-index
box-shadow(0px 0px 1px 0px $primary-active-color)
&::before, &::after
position: absolute position: absolute
min-width: $marker-width margin-top: -18px
min-height: $marker-width font: 400 40px/1 dashicons
z-index: $marker-z-index color: $primary-active-color
&::before
box-shadow(0px 0px 1px 0px $primary-active-color) left: -25px
content: "\f139"
&::before, &::after &::after
position: absolute right: -23px
margin-top: -18px content: "\f141";
font: 400 40px/1 dashicons
color: $primary-active-color
&::before
left: -25px
content: "\f139"
&::after
right: -23px
content: "\f141";
// Offset middle markers slightly above, so that the middle of the marker is // Offset middle markers slightly above, so that the middle of the marker is
// right on the boundary between two adjacent content blocks // right on the boundary between two adjacent content blocks
.mailpoet_drop_marker.mailpoet_drop_marker_middle .mailpoet_drop_marker.mailpoet_drop_marker_middle
.mailpoet_drop_marker.mailpoet_drop_marker_first.mailpoet_drop_marker_after .mailpoet_drop_marker.mailpoet_drop_marker_first.mailpoet_drop_marker_after
.mailpoet_drop_marker.mailpoet_drop_marker_last.mailpoet_drop_marker_before .mailpoet_drop_marker.mailpoet_drop_marker_last.mailpoet_drop_marker_before
margin-top: -1 * ($marker-width / 2) margin-top: -1 * ($marker-width / 2)
// Offset the last marker up, so that the bottom of it matches the bottom of the // Offset the last marker up, so that the bottom of it matches the bottom of the
// container // container
.mailpoet_drop_marker.mailpoet_drop_marker_last.mailpoet_drop_marker_after .mailpoet_drop_marker.mailpoet_drop_marker_last.mailpoet_drop_marker_after
margin-top: -1 * $marker-width margin-top: -1 * $marker-width
#mailpoet_editor .mailpoet_droppable_active #mailpoet_editor .mailpoet_droppable_active
z-index: 21000 z-index: 21000
.mailpoet_block.mailpoet_droppable_active .mailpoet_block.mailpoet_droppable_active
border: 1px dashed $drop-active-color !important border: 1px dashed $drop-active-color !important
width: $newsletter-width width: $newsletter-width
.mailpoet_tools .mailpoet_tools
display: none !important display: none !important
.mailpoet_widget.mailpoet_droppable_active .mailpoet_widget.mailpoet_droppable_active
padding: 0
margin: 0
z-index: $draggable-widget-z-index
.mailpoet_widget_icon
padding: 0 padding: 0
margin: 0 margin: 0
z-index: $draggable-widget-z-index
.mailpoet_widget_icon
padding: 0
margin: 0
.mailpoet_drop_active > .mailpoet_container > div > .mailpoet_container_empty .mailpoet_drop_active > .mailpoet_container > div > .mailpoet_container_empty
background-color: $primary-active-color background-color: $primary-active-color
box-shadow(inset 1px 2px 1px $primary-inset-shadow-color) box-shadow(inset 1px 2px 1px $primary-inset-shadow-color)
color: $white-color color: $white-color

View File

@ -1,39 +1,39 @@
.mailpoet_form_field .mailpoet_form_field
margin-top: 15px margin-top: 15px
margin-bottom: 15px margin-bottom: 15px
.mailpoet_form_field_title .mailpoet_form_field_title
clear: both clear: both
font-size: 1.1em font-size: 1.1em
margin-bottom: 5px margin-bottom: 5px
.mailpoet_form_field_title_small .mailpoet_form_field_title_small
width: 120px width: 120px
.mailpoet_form_field_title_inline .mailpoet_form_field_title_inline
display: inline-block display: inline-block
margin-bottom: 0 margin-bottom: 0
margin-top: 6px margin-top: 6px
.mailpoet_form_field_optional .mailpoet_form_field_optional
font-size: 0.8em font-size: 0.8em
color: $primary-inactive-color color: $primary-inactive-color
.mailpoet_form_field_radio_option, .mailpoet_form_field_radio_option,
.mailpoet_form_field_checkbox_option .mailpoet_form_field_checkbox_option
display: inline-block display: inline-block
vertical-align: top vertical-align: top
margin-right: 5px margin-right: 5px
line-height: 30px line-height: 30px
&:last-child &:last-child
margin-right: 0 margin-right: 0
.mailpoet_form_field_input_option .mailpoet_form_field_input_option
display: inline-block display: inline-block
input[type=checkbox] input[type=checkbox]
vertical-align:top vertical-align:top
input[type=text] input[type=text]
vertical-align: middle vertical-align: middle

View File

@ -1,20 +1,20 @@
.mailpoet_heading_form_field .mailpoet_heading_form_field
margin-top: 5px margin-top: 5px
margin-bottom: 5px margin-bottom: 5px
.mailpoet_input_title, .mailpoet_input_title,
.mailpoet_input_preheader .mailpoet_input_preheader
width: 400px width: 400px
padding: 3px padding: 3px
line-height: normal line-height: normal
.mailpoet_input_title .mailpoet_input_title
font-size: 23px font-size: 23px
.mailpoet_breadcrumbs .mailpoet_breadcrumbs
float: right float: right
clear: both clear: both
margin-bottom: 13px margin-bottom: 13px
margin-right: 17px margin-right: 17px
font-size: 0.9em font-size: 0.9em
text-transform: uppercase text-transform: uppercase

View File

@ -1,32 +1,32 @@
.mailpoet_container_layer_active .mailpoet_container_layer_active
.mailpoet_block .mailpoet_block
pointer-events: none pointer-events: none
opacity: 0.4 opacity: 0.4
.mailpoet_container_block .mailpoet_container_block
pointer-events: auto pointer-events: auto
opacity: 1 opacity: 1
.mailpoet_container_block > .mailpoet_tools .mailpoet_container_block > .mailpoet_tools
display: block !important display: block !important
& > .mailpoet_tools & > .mailpoet_tools
z-index: 100001 !important; z-index: 100001 !important;
.mailpoet_layer_overlay .mailpoet_layer_overlay
height: 100% height: 100%
left: 0 left: 0
overflow-y: auto overflow-y: auto
overflow-x: hidden overflow-x: hidden
position: fixed position: fixed
top: 0 top: 0
width: 100% width: 100%
z-index: 100000 z-index: 100000
background-color: rgba(0, 0, 0, 0.6) background-color: rgba(0, 0, 0, 0.6)
margin: 0 !important margin: 0 !important
.mailpoet_layer_highlight .mailpoet_layer_highlight
pointer-events:none; pointer-events:none;
background-color: #f1f1f1; background-color: #f1f1f1;
position: relative; position: relative;
z-index: 100001 !important; z-index: 100001 !important;

View File

@ -6,45 +6,45 @@ $resize-handle-width = 30px
$resize-handle-z-index = 2 $resize-handle-z-index = 2
.mailpoet_resize_handle_container .mailpoet_resize_handle_container
position: absolute position: absolute
bottom: 0 bottom: 0
text-align: center text-align: center
width: 100% width: 100%
.mailpoet_resize_handle .mailpoet_resize_handle
padding: 6px 15px 10px 6px padding: 6px 15px 10px 6px
position: relative position: relative
top: 5px top: 5px
background: $resize-handle-background-color background: $resize-handle-background-color
border-radius(3px) border-radius(3px)
display: inline-block display: inline-block
width: $resize-handle-width width: $resize-handle-width
cursor: ns-resize cursor: ns-resize
z-index: $resize-handle-z-index z-index: $resize-handle-z-index
.mailpoet_resize_handle_text, .mailpoet_resize_handle_text,
.mailpoet_resize_handle_icon .mailpoet_resize_handle_icon
pointer-events: none pointer-events: none
.mailpoet_resize_handle_text .mailpoet_resize_handle_text
line-height: 1.5em line-height: 1.5em
font-size: 11px font-size: 11px
font-weight: bold font-weight: bold
color: $resize-handle-font-color color: $resize-handle-font-color
text-align: center text-align: center
.mailpoet_resize_handle_icon .mailpoet_resize_handle_icon
position: absolute position: absolute
top: 9px top: 9px
right: 1px right: 1px
& > svg & > svg
width: 15px width: 15px
height: 15px height: 15px
fill: $resize-handle-font-color fill: $resize-handle-font-color
.mailpoet_block.mailpoet_resize_active > .mailpoet_block_highlight .mailpoet_block.mailpoet_resize_active > .mailpoet_block_highlight
border: 1px dashed $resize-active-color border: 1px dashed $resize-active-color
.mailpoet_resize_handle .mailpoet_resize_handle
display: inline-block display: inline-block

View File

@ -1,68 +1,67 @@
#mailpoet_editor_bottom #mailpoet_editor_bottom
margin-top: 39px margin-top: 39px
margin-left: 29px margin-left: 29px
.mailpoet_save_options .mailpoet_save_options
border-radius(3px) border-radius(3px)
float: left float: left
overflow: hidden overflow: hidden
margin: 5px 0 0 0 margin: 5px 0 0 0
clear: both clear: both
vertical-align: top vertical-align: top
background: $white-color background: $white-color
border: 1px solid $content-border-color border: 1px solid $content-border-color
.mailpoet_save_option .mailpoet_save_option
margin: 0 margin: 0
& > a & > a
display: block display: block
padding-left: 20px padding-left: 20px
padding-right: 20px padding-right: 20px
line-height: 2em line-height: 2em
.mailpoet_save_option:hover .mailpoet_save_option:hover
background-color: $primary-active-background-color background-color: $primary-active-background-color
color: $white-color
& > a
color: $white-color color: $white-color
& > a
color: $white-color
.mailpoet_save_show_options .mailpoet_save_show_options
padding: 6px 3px 4px padding: 6px 3px 4px
&.mailpoet_save_show_options_active &.mailpoet_save_show_options_active
.mailpoet_save_show_options_icon::before .mailpoet_save_show_options_icon::before
content: '\f142' content: '\f142'
.mailpoet_save_show_options_icon .mailpoet_save_show_options_icon
width: auto width: auto
height: auto height: auto
line-height: auto line-height: auto
&::before
content: '\f140'
&::before
content: '\f140'
.mailpoet_save_as_template_container .mailpoet_save_as_template_container
border-radius(3px) border-radius(3px)
float: left float: left
clear: both clear: both
margin-top: 5px margin-top: 5px
padding: 0 10px padding: 0 10px
background-color: $white-color background-color: $white-color
border: 1px solid $structure-border-color border: 1px solid $structure-border-color
.mailpoet_save_as_template_title .mailpoet_save_as_template_title
font-size: 1.1em font-size: 1.1em
.mailpoet_editor_last_saved .mailpoet_editor_last_saved
color: $primary-inactive-color color: $primary-inactive-color
font-size: 0.9em font-size: 0.9em
display: inline display: inline
.mailpoet_save_error .mailpoet_save_error
color: $error-text-color color: $error-text-color

View File

@ -14,118 +14,118 @@ $widget-icon-hover-color = $primary-active-color
$widget-icon-width = 30px $widget-icon-width = 30px
#mailpoet_editor_sidebar #mailpoet_editor_sidebar
border-left: $content-border-color border-left: $content-border-color
border-bottom: $content-border-color border-bottom: $content-border-color
color: $sidebar-text-color color: $sidebar-text-color
.mailpoet_sidebar_region .mailpoet_sidebar_region
margin-bottom: 0 margin-bottom: 0
border-left: 1px solid $content-border-color border-left: 1px solid $content-border-color
border-bottom: 1px solid $content-border-color border-bottom: 1px solid $content-border-color
border-top: 0 border-top: 0
border-right: 0 border-right: 0
&.closed .mailpoet_region_content &.closed .mailpoet_region_content
max-height: 0px max-height: 0px
overflow: hidden overflow: hidden
margin-top: 0 margin-top: 0
.mailpoet_region_content .mailpoet_region_content
max-height: 2000px max-height: 2000px
transition: max-height 0.2s ease transition: max-height 0.2s ease
padding: 0 20px padding: 0 20px
margin-top: 12px margin-top: 12px
&, .postbox &, .postbox
background-color: $sidebar-background-color background-color: $sidebar-background-color
.postbox .postbox
padding-bottom: 20px padding-bottom: 20px
&.closed &.closed
padding-bottom: 0 padding-bottom: 0
&.closed h3 &.closed h3
color: $sidebar-inactive-heading-color color: $sidebar-inactive-heading-color
cursor: pointer cursor: pointer
h3 h3
&:hover h3 &:hover h3
margin: 0 margin: 0
padding: 17px 20px padding: 17px 20px
text-transform: uppercase text-transform: uppercase
color: $sidebar-active-heading-color color: $sidebar-active-heading-color
h3 h3
.handlediv .handlediv
cursor: auto cursor: auto
border: 0 border: 0
.handlediv::before .handlediv::before
top: 18px top: 18px
right: 18px right: 18px
font: 400 20px/1 dashicons font: 400 20px/1 dashicons
speak: none speak: none
display: inline-block display: inline-block
position: relative position: relative
-webkit-font-smoothing: antialiased -webkit-font-smoothing: antialiased
-moz-osx-font-smoothing: grayscale -moz-osx-font-smoothing: grayscale
text-decoration: none!important text-decoration: none!important
content: '\f142' content: '\f142'
color: $sidebar-active-heading-color color: $sidebar-active-heading-color
&.closed .handlediv::before &.closed .handlediv::before
content: '\f140' content: '\f140'
color: $sidebar-inactive-heading-color color: $sidebar-inactive-heading-color
&.closed:hover .handlediv::before &.closed:hover .handlediv::before
color: $sidebar-active-heading-color color: $sidebar-active-heading-color
.mailpoet_widget .mailpoet_widget
display: inline-block display: inline-block
width: $widget-width width: $widget-width
text-align: center text-align: center
float: left float: left
padding: 0 13px 15px 13px padding: 0 13px 15px 13px
// Place 3 widgets per row // Place 3 widgets per row
&:nth-child(3n+1) &:nth-child(3n+1)
clear: left clear: left
.mailpoet_widget_icon
width: $widget-width
height: $widget-width
background-color: $widget-background-color
border-radius(3px)
box-shadow(1px 2px $widget-shadow-color)
color: $widget-icon-color
fill: $widget-icon-color
text-align: center
line-height: $widget-width
box-sizing: border-box
margin-bottom: 9px
/* Vertically align widget icon glyphs */
& > *
vertical-align: middle
width: $widget-icon-width
height: $widget-icon-width
font-size: $widget-icon-width
&:hover
color: $widget-icon-hover-color
fill: $widget-icon-hover-color
border: 1px solid $widget-icon-hover-color
&.mailpoet_droppable_active
color: $widget-icon-hover-color
fill: $widget-icon-hover-color
.mailpoet_widget_icon .mailpoet_widget_icon
width: $widget-width border: 1px solid $widget-icon-hover-color
height: $widget-width color: $widget-icon-hover-color
background-color: $widget-background-color fill: $widget-icon-hover-color
border-radius(3px) box-shadow(none)
box-shadow(1px 2px $widget-shadow-color)
color: $widget-icon-color
fill: $widget-icon-color
text-align: center
line-height: $widget-width
box-sizing: border-box
margin-bottom: 9px
/* Vertically align widget icon glyphs */ .mailpoet_widget_title
& > * display: none
vertical-align: middle
width: $widget-icon-width
height: $widget-icon-width
font-size: $widget-icon-width
&:hover
color: $widget-icon-hover-color
fill: $widget-icon-hover-color
border: 1px solid $widget-icon-hover-color
&.mailpoet_droppable_active
color: $widget-icon-hover-color
fill: $widget-icon-hover-color
.mailpoet_widget_icon
border: 1px solid $widget-icon-hover-color
color: $widget-icon-hover-color
fill: $widget-icon-hover-color
box-shadow(none)
.mailpoet_widget_title
display: none

View File

@ -2,54 +2,53 @@ $sidepanel-active-heading-color = $primary-active-color
/* Sidepanel */ /* Sidepanel */
.mailpoet_editor_settings .mailpoet_editor_settings
color: $sidebar-text-color color: $sidebar-text-color
p p
font-size: 1em font-size: 1em
h3 h3
font-size: 1.4em font-size: 1.4em
color: $sidepanel-active-heading-color color: $sidepanel-active-heading-color
text-transform: uppercase text-transform: uppercase
.mailpoet_sidepanel_field .mailpoet_sidepanel_field
margin-top: 15px margin-top: 15px
margin-bottom: 15px margin-bottom: 15px
.mailpoet_sidepanel_field_title .mailpoet_sidepanel_field_title
clear: both clear: both
font-size: 1.1em font-size: 1.1em
margin-bottom: 5px margin-bottom: 5px
.mailpoet_sidepanel_field_title_small .mailpoet_sidepanel_field_title_small
width: 120px width: 120px
.mailpoet_sidepanel_field_title_inline .mailpoet_sidepanel_field_title_inline
//clear: left display: inline-block
display: inline-block vertical-align: middle
vertical-align: middle line-height: 30px
line-height: 30px margin-bottom: 0
margin-bottom: 0
.mailpoet_sidepanel_field_optional .mailpoet_sidepanel_field_optional
font-size: 0.8em font-size: 0.8em
color: $primary-inactive-color color: $primary-inactive-color
.mailpoet_sidepanel_radio_option, .mailpoet_sidepanel_radio_option,
.mailpoet_sidepanel_checkbox_option .mailpoet_sidepanel_checkbox_option
display: inline-block display: inline-block
vertical-align: top vertical-align: top
margin-right: 15px margin-right: 15px
line-height: 30px line-height: 30px
&:last-child &:last-child
margin-right: 0 margin-right: 0
.mailpoet_sidepanel_input_option .mailpoet_sidepanel_input_option
display: inline-block display: inline-block
input[type=checkbox] input[type=checkbox]
vertical-align:top vertical-align:top
input[type=text] input[type=text]
vertical-align: middle vertical-align: middle

View File

@ -1,15 +1,15 @@
.mailpoet_automated_latest_content_block .mailpoet_automated_latest_content_block
padding: 0 padding: 0
.mailpoet_automated_latest_content_block_overlay .mailpoet_automated_latest_content_block_overlay
position: absolute position: absolute
z-index: 19 z-index: 19
width: 100% width: 100%
height: 100% height: 100%
background: rgba(255, 255, 255, 0.7) background: rgba(255, 255, 255, 0.7)
.mailpoet_automated_latest_content_block_posts .mailpoet_automated_latest_content_block_posts
overflow: auto overflow: auto
& > .mailpoet_block & > .mailpoet_block
width: 100% width: 100%

View File

@ -1,32 +1,32 @@
$block-hover-highlight-color = $primary-active-color $block-hover-highlight-color = $primary-active-color
.mailpoet_block .mailpoet_block
box-sizing: border-box box-sizing: border-box
position: relative position: relative
float: left float: left
background-color: inherit background-color: inherit
box-sizing: border-box box-sizing: border-box
margin-bottom: 20px margin-bottom: 20px
padding-left: 20px padding-left: 20px
padding-right: 20px padding-right: 20px
& > .mailpoet_block_highlight & > .mailpoet_block_highlight
position: absolute position: absolute
top: 0 top: 0
right: 0 right: 0
bottom: 0 bottom: 0
left: 0 left: 0
pointer-events: none pointer-events: none
border: 1px solid $transparent-color border: 1px solid $transparent-color
&:hover > .mailpoet_block_highlight &:hover > .mailpoet_block_highlight
border: 1px dashed $block-hover-highlight-color border: 1px dashed $block-hover-highlight-color
.mailpoet_block:last-child .mailpoet_block:last-child
margin-bottom: 0 margin-bottom: 0
.mailpoet_content .mailpoet_content
position: relative position: relative

View File

@ -1,20 +1,19 @@
$button-vertical-padding = 13px $button-vertical-padding = 13px
.mailpoet_button_block .mailpoet_button_block
padding-top: $button-vertical-padding padding-top: $button-vertical-padding
padding-bottom: $button-vertical-padding padding-bottom: $button-vertical-padding
overflow: hidden overflow: hidden
.mailpoet_editor_button .mailpoet_editor_button
display: block display: block
margin: auto margin: auto
line-height: 2em line-height: 2em
text-align: center text-align: center
text-decoration: none text-decoration: none
box-sizing: border-box box-sizing: border-box
max-width: 100% max-width: 100%
&:hover
cursor: all-scroll
&:hover
cursor: all-scroll

View File

@ -1,26 +1,26 @@
.mailpoet_container .mailpoet_container
width: 100% width: 100%
min-height: 15px min-height: 15px
position: relative position: relative
.mailpoet_container_block .mailpoet_container_block
margin-left: 0 margin-left: 0
margin-right: 0 margin-right: 0
position: relative position: relative
box-sizing: border-box box-sizing: border-box
border: 0 border: 0
padding-left: 0 padding-left: 0
padding-right: 0 padding-right: 0
&:hover &:hover
border: 0 border: 0
.mailpoet_container_vertical > * .mailpoet_container_vertical > *
width: 100% width: 100%
box-sizing: border-box box-sizing: border-box
.mailpoet_container_horizontal > * .mailpoet_container_horizontal > *
vertical-align: top vertical-align: top
/** /**
* Enforce column widths: * Enforce column widths:
@ -30,47 +30,47 @@
*/ */
#mailpoet_editor_content #mailpoet_editor_content
.mailpoet_container .mailpoet_container
box-sizing: border-box box-sizing: border-box
float: left float: left
// One column // One column
& > .mailpoet_container_block & > .mailpoet_container_block
width: $newsletter-width width: $newsletter-width
border: 0 border: 0
& > .mailpoet_container_block > .mailpoet_container > .mailpoet_container_block & > .mailpoet_container_block > .mailpoet_container > .mailpoet_container_block
margin-bottom: 0 margin-bottom: 0
.mailpoet_container_horizontal > .mailpoet_container_block .mailpoet_container_horizontal > .mailpoet_container_block
margin-bottom: 0 margin-bottom: 0
width: 20px + 560px + 20px width: 20px + 560px + 20px
// More than one column // More than one column
& > .mailpoet_container_block > .mailpoet_container > .mailpoet_container_block > .mailpoet_container_horizontal & > .mailpoet_container_block > .mailpoet_container > .mailpoet_container_block > .mailpoet_container_horizontal
// Column number detection technique found here: // Column number detection technique found here:
// http://stackoverflow.com/questions/8720931/can-css-detect-the-number-of-children-an-element-has // http://stackoverflow.com/questions/8720931/can-css-detect-the-number-of-children-an-element-has
// Two columns // Two columns
& > .mailpoet_block:first-child:nth-last-child(2) & > .mailpoet_block:first-child:nth-last-child(2)
& > .mailpoet_block:first-child:nth-last-child(2) ~ .mailpoet_block & > .mailpoet_block:first-child:nth-last-child(2) ~ .mailpoet_block
//padding-left: 20px //padding-left: 20px
//padding-right: 20px //padding-right: 20px
width: 260px + 20px + 20px width: 260px + 20px + 20px
// Three columns // Three columns
& > .mailpoet_block:first-child:nth-last-child(3) & > .mailpoet_block:first-child:nth-last-child(3)
& > .mailpoet_block:first-child:nth-last-child(3) ~ .mailpoet_block & > .mailpoet_block:first-child:nth-last-child(3) ~ .mailpoet_block
//padding-left: 20px //padding-left: 20px
//padding-right: 20px //padding-right: 20px
width: 160px + 20px + 20px width: 160px + 20px + 20px
.mailpoet_container_empty .mailpoet_container_empty
text-align: center text-align: center
background-color: #f2f2f2 background-color: #f2f2f2
margin: 20px margin: 20px
padding: 15px padding: 15px
box-shadow(inset 1px 2px 1px $primary-inactive-color) box-shadow(inset 1px 2px 1px $primary-inactive-color)
color: #656565 color: #656565
border-radius(3px) border-radius(3px)

View File

@ -3,27 +3,27 @@ $active-divider-background-color = #daebf2
$divider-hover-border-color = $primary-active-color $divider-hover-border-color = $primary-active-color
.mailpoet_divider_block .mailpoet_divider_block
padding-left: 0 padding-left: 0
padding-right: 0 padding-right: 0
margin-bottom: 0 margin-bottom: 0
cursor: all-scroll cursor: all-scroll
.mailpoet_divider .mailpoet_divider
margin-left: 20px margin-left: 20px
margin-right: 20px margin-right: 20px
.mailpoet_field_divider_style .mailpoet_field_divider_style
max-width: $newsletter-width max-width: $newsletter-width
margin: auto margin: auto
display: block display: block
width: 100% width: 100%
border: 1px solid transparent border: 1px solid transparent
.mailpoet_field_divider_style:hover .mailpoet_field_divider_style:hover
border: 1px solid $divider-hover-border-color border: 1px solid $divider-hover-border-color
.mailpoet_divider_selector img .mailpoet_divider_selector img
width: 100% width: 100%
.mailpoet_field_divider_style .mailpoet_field_divider_style
padding: 10px 0 padding: 10px 0

View File

@ -1,6 +1,6 @@
.mailpoet_footer_block .mailpoet_footer_block
padding-left: 0 padding-left: 0
padding-right: 0 padding-right: 0
.mailpoet_content .mailpoet_content
padding: 5px 20px padding: 5px 20px

View File

@ -1,6 +1,6 @@
.mailpoet_header_block .mailpoet_header_block
padding-left: 0 padding-left: 0
padding-right: 0 padding-right: 0
.mailpoet_content .mailpoet_content
padding: 5px 20px padding: 5px 20px

View File

@ -1,15 +1,15 @@
.mailpoet_image_block .mailpoet_image_block
&.mailpoet_full_image &.mailpoet_full_image
padding-left: 0 padding-left: 0
padding-right: 0 padding-right: 0
margin-bottom: 0 margin-bottom: 0
.mailpoet_content a:hover .mailpoet_content a:hover
cursor: all-scroll cursor: all-scroll
img img
vertical-align: bottom vertical-align: bottom
max-width: $newsletter-width max-width: $newsletter-width
width: 100% width: 100%
height: auto height: auto

View File

@ -1,46 +1,46 @@
.mailpoet_posts_block .mailpoet_posts_block
box-shadow(none) box-shadow(none)
& > .mailpoet_content & > .mailpoet_content
font-size: 1em font-size: 1em
text-align: center text-align: center
background-color: $primary-active-color background-color: $primary-active-color
margin: 20px 0 margin: 20px 0
padding: 15px padding: 15px
box-shadow(inset 1px 2px 1px $primary-inset-shadow-color) box-shadow(inset 1px 2px 1px $primary-inset-shadow-color)
color: $white-color color: $white-color
border-radius(3px) border-radius(3px)
.mailpoet_post_selection_filter_row .mailpoet_post_selection_filter_row
margin-top: 5px margin-top: 5px
margin-bottom: 5px margin-bottom: 5px
.mailpoet_posts_categories_and_tags .mailpoet_posts_categories_and_tags
width: 100% width: 100%
.mailpoet_settings_posts_show_display_options .mailpoet_settings_posts_show_display_options
.mailpoet_settings_posts_show_post_selection .mailpoet_settings_posts_show_post_selection
display: block display: block
margin-top: 10px margin-top: 10px
.mailpoet_post_selection_container .mailpoet_post_selection_container
margin-top: 20px margin-top: 20px
margin-bottom: 20px margin-bottom: 20px
.mailpoet_settings_posts_single_post .mailpoet_settings_posts_single_post
border-radius(1px) border-radius(1px)
width: 100% width: 100%
margin-top: 5px margin-top: 5px
margin-bottom: 5px margin-bottom: 5px
height: 38px height: 38px
line-height: 38px line-height: 38px
overflow: hidden overflow: hidden
border: 1px solid $content-border-color border: 1px solid $content-border-color
background-color: $white-color background-color: $white-color
&:hover &:hover
border-color: $primary-active-color border-color: $primary-active-color
.mailpoet_select_post_checkbox .mailpoet_select_post_checkbox
margin-left: 10px margin-left: 10px
margin-right: 8px margin-right: 8px

View File

@ -12,105 +12,102 @@ $tool-active-color = #d2d2d4
$tool-width = 16px $tool-width = 16px
.mailpoet_social_block .mailpoet_social_block
padding-top: $social-block-vertical-padding padding-top: $social-block-vertical-padding
padding-bottom: $social-block-vertical-padding padding-bottom: $social-block-vertical-padding
.mailpoet_social .mailpoet_social
text-align: center text-align: center
.mailpoet_social .mailpoet_social
span span
display: inline-block display: inline-block
padding: 2px 3px padding: 2px 3px
span, span,
a, a,
img img
vertical-align: top vertical-align: top
a a
cursor: all-scroll cursor: all-scroll
.mailpoet_social_icon_set .mailpoet_social_icon_set
border: 1px solid transparent border: 1px solid transparent
padding: 5px padding: 5px
margin-bottom: 5px margin-bottom: 5px
&:hover &:hover
border: 1px solid $social-icon-set-hover-border-color border: 1px solid $social-icon-set-hover-border-color
img img
width: $social-icon-width width: $social-icon-width
height: $social-icon-width height: $social-icon-width
vertical-align: middle vertical-align: middle
padding: 2px 3px padding: 2px 3px
.mailpoet_active_icon_set .mailpoet_active_icon_set
border: 1px dashed $active-social-icon-set-border-color border: 1px dashed $active-social-icon-set-border-color
background-color: $active-social-icon-set-background-color background-color: $active-social-icon-set-background-color
.mailpoet_social_icon_settings .mailpoet_social_icon_settings
position: relative position: relative
padding: 28px 9px (18px - 10px) 9px padding: 28px 9px (18px - 10px) 9px
margin-bottom: 9px margin-bottom: 9px
background: $white-color background: $white-color
border: 1px solid $content-border-color border: 1px solid $content-border-color
.mailpoet_social_icon_settings_row .mailpoet_social_icon_settings_row
clear: both clear: both
overflow: auto overflow: auto
margin-bottom: 10px margin-bottom: 10px
line-height: 30px line-height: 30px
.mailpoet_social_icon_settings_label .mailpoet_social_icon_settings_label
margin-right: 5px margin-right: 5px
text-align: left
text-align: left .mailpoet_social_icon_image
width: 30px
height: 30px
.mailpoet_social_icon_image &.mailpoet_social_icon_image_label
width: 30px line-height: initial
height: 30px
&.mailpoet_social_icon_image_label
line-height: initial
.mailpoet_social_icon_settings_form_element .mailpoet_social_icon_settings_form_element
float: left float: left
width: 100%
input, select
width: 100% width: 100%
height: 30px
input, select box-sizing: border-box
width: 100% margin: 0
height: 30px vertical-align: middle
box-sizing: border-box display: inline-block
margin: 0
vertical-align: middle
display: inline-block
.mailpoet_social_icon_settings_tool .mailpoet_social_icon_settings_tool
position: absolute position: absolute
top: 10px top: 10px
.mailpoet_tool_icon .mailpoet_tool_icon
fill: $tool-inactive-color fill: $tool-inactive-color
width: $tool-width width: $tool-width
height: $tool-width height: $tool-width
&:hover &:hover
fill: $tool-hover-color fill: $tool-hover-color
&:active &:active
fill: $primary-active-color fill: $primary-active-color
&:active &:active
filter-shadow(1px, 2px, 0px, $tool-active-color) filter-shadow(1px, 2px, 0px, $tool-active-color)
.mailpoet_social_icon_settings_move_icon .mailpoet_social_icon_settings_move_icon
right: 5px right: 5px
.mailpoet_social_icon_settings_delete_icon .mailpoet_social_icon_settings_delete_icon
right: 5px + 5px + $tool-width right: 5px + 5px + $tool-width

View File

@ -1,8 +1,8 @@
.mailpoet_spacer .mailpoet_spacer
text-align: center text-align: center
.mailpoet_spacer_block .mailpoet_spacer_block
padding-left: 0 padding-left: 0
padding-right: 0 padding-right: 0
margin-bottom: 0 margin-bottom: 0
cursor: all-scroll cursor: all-scroll

View File

@ -1,17 +1,17 @@
$text-vertical-padding = 3px $text-vertical-padding = 3px
.mailpoet_text_block .mailpoet_text_block
padding-left: 0 padding-left: 0
padding-right: 0 padding-right: 0
& > .mailpoet_content & > .mailpoet_content
overflow: hidden overflow: hidden
padding-top: 13px padding-top: 13px
padding-bottom: 13px padding-bottom: 13px
padding-left: 20px padding-left: 20px
padding-right: 20px padding-right: 20px
blockquote blockquote
margin: 1em margin: 1em
padding-left: 1em padding-left: 1em
border-left: 2px #565656 solid border-left: 2px #565656 solid

View File

@ -2,31 +2,31 @@ $sidebar-width = 330px
$content-border-color = $structure-border-color $content-border-color = $structure-border-color
#mailpoet_editor #mailpoet_editor
width: 100% width: 100%
clear: both clear: both
#mailpoet_editor_heading #mailpoet_editor_heading
padding-left: 15px padding-left: 15px
margin-left: 2px margin-left: 2px
#mailpoet_editor_main_wrapper #mailpoet_editor_main_wrapper
border: 1px solid $content-border-color border: 1px solid $content-border-color
border-left: 0 border-left: 0
position: relative position: relative
min-width: 1050px min-width: 1050px
#mailpoet_editor_content_container #mailpoet_editor_content_container
width: 100% width: 100%
padding-right: $sidebar-width padding-right: $sidebar-width
box-sizing: border-box box-sizing: border-box
#mailpoet_editor_sidebar #mailpoet_editor_sidebar
float: right float: right
width: $sidebar-width width: $sidebar-width
box-sizing: border-box box-sizing: border-box
.mailpoet_newsletter_wrapper .mailpoet_newsletter_wrapper
max-width: $newsletter-width max-width: $newsletter-width
width: $newsletter-width width: $newsletter-width
margin: auto margin: auto
position: relative position: relative

View File

@ -1,119 +1,118 @@
/* Fix select2 z-index to work with MailPoet.Modal */ /* Fix select2 z-index to work with MailPoet.Modal */
.select2-drop .select2-drop
z-index: 101000 z-index: 101000
/* Remove input field styles from select2 type input */ /* Remove input field styles from select2 type input */
.select2-container .select2-container
border: none border: none
padding: 0 padding: 0
/* Fix inline TinyMCE toolbar to have minimal width instead of being close to 100% of the screen */ /* Fix inline TinyMCE toolbar to have minimal width instead of being close to 100% of the screen */
div.mce-toolbar-grp.mce-container div.mce-toolbar-grp.mce-container
position: absolute position: absolute
.mce-tinymce.mce-tinymce-inline .mce-tinymce.mce-tinymce-inline
border-radius(3px) border-radius(3px)
background-color: $primary-background-color background-color: $primary-background-color
border: 1px solid $content-border-color border: 1px solid $content-border-color
box-shadow(0px 0px 3px 1px rgba(0, 0, 0, 0.05))
box-shadow(0px 0px 3px 1px rgba(0, 0, 0, 0.05))
.mce-window .mce-window
/* Fix TinyMCE mailpoet_custom_fields window lack of hiding overflow */ /* Fix TinyMCE mailpoet_custom_fields window lack of hiding overflow */
div.mce-container-body.mce-abs-layout div.mce-container-body.mce-abs-layout
overflow: hidden overflow: hidden
/* Fix TinyMCE popup window's close button to not be covered by draggable section */ /* Fix TinyMCE popup window's close button to not be covered by draggable section */
.mce-window-head div.mce-dragh .mce-window-head div.mce-dragh
width: -webkit-calc( 100% - 36px ) width: -webkit-calc( 100% - 36px )
width: calc( 100% - 36px ) width: calc( 100% - 36px )
/* TinyMCE mailpoet_custom_fields toolbar icon */ /* TinyMCE mailpoet_custom_fields toolbar icon */
.mce-i-mailpoet_custom_fields:before .mce-i-mailpoet_custom_fields:before
font: 400 20px/1 dashicons!important font: 400 20px/1 dashicons!important
content: "\f307" content: "\f307"
/* TinyMCE remove active border from the editor */ /* TinyMCE remove active border from the editor */
.mce-edit-focus .mce-edit-focus
outline: none outline: none
/* Style "No search term specified" in TinyMCE link editor */ /* Style "No search term specified" in TinyMCE link editor */
#wp-link li, #wp-link div.query-notice #wp-link li, #wp-link div.query-notice
clear: both clear: both
margin-bottom: 0 margin-bottom: 0
border-bottom: 1px solid #f1f1f1 border-bottom: 1px solid #f1f1f1
color: #333 color: #333
padding: 4px 6px padding: 4px 6px
cursor: pointer cursor: pointer
position: relative position: relative
/* Remove empty space between WP admin sidebar and content */ /* Remove empty space between WP admin sidebar and content */
#wpbody-content > * #wpbody-content > *
margin-left: 20px margin-left: 20px
#wpbody-content > .wrap #wpbody-content > .wrap
margin-left: 0 margin-left: 0
#wpcontent #wpcontent
margin-left: 160px margin-left: 160px
padding-left: 0 padding-left: 0
.folded & .folded &
margin-left: 36px margin-left: 36px
.wrap .wrap
margin-left: 0 margin-left: 0
margin-right: 0 margin-right: 0
/* Reduce WP admin bar z-index in order for TinyMCE toolbar to be visible */ /* Reduce WP admin bar z-index in order for TinyMCE toolbar to be visible */
#wpadminbar #wpadminbar
z-index: 50000 z-index: 50000
/* Allow horizontal scrolling on smaller (tablet/phone) sized screens */ /* Allow horizontal scrolling on smaller (tablet/phone) sized screens */
body body
overflow-x: auto overflow-x: auto
/* Hide the "Details" section of Wordpress Media manager */ /* Hide the "Details" section of Wordpress Media manager */
.media-sidebar .media-sidebar
display: none display: none
#mailpoet-media-manager #mailpoet-media-manager
.attachments-browser .attachments .attachments-browser .attachments
.attachments-browser .uploader-inline .attachments-browser .uploader-inline
margin-right: 0 margin-right: 0
.attachments-browser .attachments .attachments-browser .attachments
.attachments-browser .media-toolbar .attachments-browser .media-toolbar
.attachments-browser .uploader-inline .attachments-browser .uploader-inline
right: 0 right: 0
/* Remove max width from date selector in Wordpress Media Manager */ /* Remove max width from date selector in Wordpress Media Manager */
#media-attachment-date-filters #media-attachment-date-filters
max-width: calc(100% - 12px) max-width: calc(100% - 12px)
/* Alter Spectrum color picker to leave only the color preview, without arrows */ /* Alter Spectrum color picker to leave only the color preview, without arrows */
.sp-replacer .sp-replacer
border-radius(3px) border-radius(3px)
padding: 0 padding: 0
border: 0 border: 0
box-shadow(1px 2px darken($primary-background-color, 13%)) box-shadow(1px 2px darken($primary-background-color, 13%))
.sp-preview .sp-preview
border-width: 0 border-width: 0
margin-right: 0 margin-right: 0
width: 25px width: 25px
height: 25px height: 25px
.sp-dd .sp-dd
display: none display: none
/* Sidepanel overrides */ /* Sidepanel overrides */
.mailpoet_panel_body .mailpoet_panel_body
margin: 19px margin: 19px
padding: 0 padding: 0
.mailpoet_panel_wrapper .mailpoet_panel_wrapper
background-color: $primary-background-color background-color: $primary-background-color
border: 1px solid $content-border-color border: 1px solid $content-border-color
#mailpoet_modal_close #mailpoet_modal_close
display: none display: none

View File

@ -1,4 +1,4 @@
border-radius() border-radius()
-webkit-border-radius: arguments -webkit-border-radius: arguments
-moz-border-radius: arguments -moz-border-radius: arguments
border-radius: arguments border-radius: arguments

View File

@ -1,5 +1,4 @@
box-shadow() box-shadow()
-webkit-box-shadow: arguments -webkit-box-shadow: arguments
-moz-box-shadow: arguments -moz-box-shadow: arguments
box-shadow: arguments box-shadow: arguments

View File

@ -1,5 +1,5 @@
filter-shadow(offset-x, offset-y, blur-radius=0px, color=#ff0000) filter-shadow(offset-x, offset-y, blur-radius=0px, color=#ff0000)
filter: "progid:DXImageTransform.Microsoft.Dropshadow(OffX=%d, OffY=%d, Color='%s')" % (offset-x offset-y color) filter: "progid:DXImageTransform.Microsoft.Dropshadow(OffX=%d, OffY=%d, Color='%s')" % (offset-x offset-y color)
-webkit-filter: drop-shadow(offset-x offset-y blur-radius color) -webkit-filter: drop-shadow(offset-x offset-y blur-radius color)
-ms-filter: "progid:DXImageTransform.Microsoft.Dropshadow(OffX=%d, OffY=%d, Color='%s')" % (offset-x offset-y color) -ms-filter: "progid:DXImageTransform.Microsoft.Dropshadow(OffX=%d, OffY=%d, Color='%s')" % (offset-x offset-y color)
filter: drop-shadow(offset-x offset-y blur-radius color) filter: drop-shadow(offset-x offset-y blur-radius color)

View File

@ -23,5 +23,4 @@ $warning-alternate-text-color = #f4c6c8
$error-text-color = #d54e21 $error-text-color = #d54e21
// Dimensions // Dimensions
$newsletter-width = 600px $newsletter-width = 600px

View File

@ -20,5 +20,4 @@ define('newsletter_editor/behaviors/ColorPickerBehavior', [
}); });
}, },
}); });
}); });

View File

@ -424,5 +424,4 @@ define('newsletter_editor/behaviors/ContainerDropZoneBehavior', [
return depth === 0 || (depth === 1 && orientation === 'horizontal' && childCount <= this.options.columnLimit); return depth === 0 || (depth === 1 && orientation === 'horizontal' && childCount <= this.options.columnLimit);
}, },
}); });
}); });

View File

@ -11,122 +11,121 @@ define('newsletter_editor/behaviors/DraggableBehavior', [
], function(Marionette, BehaviorsLookup, interact) { ], function(Marionette, BehaviorsLookup, interact) {
BehaviorsLookup.DraggableBehavior = Marionette.Behavior.extend({ BehaviorsLookup.DraggableBehavior = Marionette.Behavior.extend({
defaults: { defaults: {
cloneOriginal: false, cloneOriginal: false,
hideOriginal: false, hideOriginal: false,
ignoreSelector: '.mailpoet_ignore_drag, .mailpoet_ignore_drag *', ignoreSelector: '.mailpoet_ignore_drag, .mailpoet_ignore_drag *',
onDragSubstituteBy: undefined, onDragSubstituteBy: undefined,
/** /**
* Constructs a model that will be passed to the receiver on drop * Constructs a model that will be passed to the receiver on drop
* *
* @return Backbone.Model A model that will be passed to the receiver * @return Backbone.Model A model that will be passed to the receiver
*/ */
getDropModel: function() { getDropModel: function() {
throw "Missing 'drop' function for DraggableBehavior"; throw "Missing 'drop' function for DraggableBehavior";
},
onDrop: function(model, view) {},
testAttachToInstance: function(model, view) { return true; },
}, },
onRender: function() {
var that = this,
interactable;
// Give instances more control over whether Draggable should be applied onDrop: function(model, view) {},
if (!this.options.testAttachToInstance(this.view.model, this.view)) return; testAttachToInstance: function(model, view) { return true; },
},
onRender: function() {
var that = this,
interactable;
interactable = interact(this.$el.get(0), { // Give instances more control over whether Draggable should be applied
ignoreFrom: this.options.ignoreSelector, if (!this.options.testAttachToInstance(this.view.model, this.view)) return;
}).draggable({
// allow dragging of multple elements at the same time
max: Infinity,
// Scroll when dragging near edges of a window interactable = interact(this.$el.get(0), {
autoScroll: true, ignoreFrom: this.options.ignoreSelector,
}).draggable({
// allow dragging of multple elements at the same time
max: Infinity,
onstart: function(event) { // Scroll when dragging near edges of a window
console.log('Drag start', event, this); autoScroll: true,
if (that.options.cloneOriginal === true) { onstart: function(event) {
// Use substitution instead of a clone console.log('Drag start', event, this);
var tempClone = (_.isFunction(that.options.onDragSubstituteBy)) ? that.options.onDragSubstituteBy(that) : undefined,
// Or use a clone
clone = tempClone ? tempClone : event.target.cloneNode(true),
$original = jQuery(event.target), if (that.options.cloneOriginal === true) {
$clone = jQuery(clone), // Use substitution instead of a clone
centerXOffset, centerYOffset, parentOffset; var tempClone = (_.isFunction(that.options.onDragSubstituteBy)) ? that.options.onDragSubstituteBy(that) : undefined,
// Or use a clone
clone = tempClone ? tempClone : event.target.cloneNode(true),
$clone.addClass('mailpoet_droppable_active'); $original = jQuery(event.target),
$clone.css('position', 'absolute'); $clone = jQuery(clone),
$clone.css('top', 0); centerXOffset, centerYOffset, parentOffset;
$clone.css('left', 0);
document.body.appendChild(clone);
// Position the clone over the target element with a slight $clone.addClass('mailpoet_droppable_active');
// offset to center the clone under the mouse cursor. $clone.css('position', 'absolute');
// Accurate dimensions can only be taken after insertion to document $clone.css('top', 0);
centerXOffset = $clone.width() / 2; $clone.css('left', 0);
centerYOffset = $clone.height() / 2; document.body.appendChild(clone);
$clone.css('top', event.pageY - centerYOffset);
$clone.css('left', event.pageX - centerXOffset);
event.interaction.element = clone; // Position the clone over the target element with a slight
// offset to center the clone under the mouse cursor.
// Accurate dimensions can only be taken after insertion to document
centerXOffset = $clone.width() / 2;
centerYOffset = $clone.height() / 2;
$clone.css('top', event.pageY - centerYOffset);
$clone.css('left', event.pageX - centerXOffset);
event.interaction.element = clone;
if (that.options.hideOriginal === true) { if (that.options.hideOriginal === true) {
that.view.$el.addClass('mailpoet_hidden'); that.view.$el.addClass('mailpoet_hidden');
} }
}
},
// call this function on every dragmove event
onmove: function (event) {
var target = event.target,
// keep the dragged position in the data-x/data-y attributes
x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx,
y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy;
// translate the element
target.style.webkitTransform =
target.style.transform =
'translate(' + x + 'px, ' + y + 'px)';
// update the posiion attributes
target.setAttribute('data-x', x);
target.setAttribute('data-y', y);
},
onend: function (event) {
var target = event.target;
target.style.webkitTransform = target.style.transform = '';
target.removeAttribute('data-x');
target.removeAttribute('data-y');
jQuery(event.interaction.element).addClass('mailpoet_droppable_active');
if (that.options.cloneOriginal === true) {
jQuery(target).remove();
if (that.options.hideOriginal === true) {
that.view.$el.removeClass('mailpoet_hidden');
}
}
},
}).preventDefault('auto');
if (this.options.drop !== undefined) {
interactable.getDropModel = this.options.drop;
} else {
interactable.getDropModel = this.view.getDropFunc();
} }
interactable.onDrop = function(options) {
if (_.isObject(options)) {
// Inject Draggable behavior if possible
options.dragBehavior = that;
}
// Delegate to view's event handler
that.options.onDrop.apply(that, [options]);
};
},
});
},
// call this function on every dragmove event
onmove: function (event) {
var target = event.target,
// keep the dragged position in the data-x/data-y attributes
x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx,
y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy;
// translate the element
target.style.webkitTransform =
target.style.transform =
'translate(' + x + 'px, ' + y + 'px)';
// update the posiion attributes
target.setAttribute('data-x', x);
target.setAttribute('data-y', y);
},
onend: function (event) {
var target = event.target;
target.style.webkitTransform = target.style.transform = '';
target.removeAttribute('data-x');
target.removeAttribute('data-y');
jQuery(event.interaction.element).addClass('mailpoet_droppable_active');
if (that.options.cloneOriginal === true) {
jQuery(target).remove();
if (that.options.hideOriginal === true) {
that.view.$el.removeClass('mailpoet_hidden');
}
}
},
}).preventDefault('auto');
if (this.options.drop !== undefined) {
interactable.getDropModel = this.options.drop;
} else {
interactable.getDropModel = this.view.getDropFunc();
}
interactable.onDrop = function(options) {
if (_.isObject(options)) {
// Inject Draggable behavior if possible
options.dragBehavior = that;
}
// Delegate to view's event handler
that.options.onDrop.apply(that, [options]);
};
},
});
}); });

View File

@ -10,60 +10,59 @@ define('newsletter_editor/behaviors/ResizableBehavior', [
], function(Marionette, BehaviorsLookup, interact) { ], function(Marionette, BehaviorsLookup, interact) {
BehaviorsLookup.ResizableBehavior = Marionette.Behavior.extend({ BehaviorsLookup.ResizableBehavior = Marionette.Behavior.extend({
defaults: { defaults: {
elementSelector: null, elementSelector: null,
resizeHandleSelector: true, // true will use edges of the element itself resizeHandleSelector: true, // true will use edges of the element itself
transformationFunction: function(y) { return y; }, transformationFunction: function(y) { return y; },
minLength: 0, minLength: 0,
modelField: 'styles.block.height', modelField: 'styles.block.height',
}, },
events: { events: {
"mouseenter": 'showResizeHandle', "mouseenter": 'showResizeHandle',
"mouseleave": 'hideResizeHandle', "mouseleave": 'hideResizeHandle',
}, },
onRender: function() { onRender: function() {
this.attachResize(); this.attachResize();
if (this.isBeingResized !== true) { if (this.isBeingResized !== true) {
this.hideResizeHandle(); this.hideResizeHandle();
} }
}, },
attachResize: function() { attachResize: function() {
var domElement = (this.options.elementSelector === null) ? this.view.$el.get(0) : this.view.$(this.options.elementSelector).get(0), var domElement = (this.options.elementSelector === null) ? this.view.$el.get(0) : this.view.$(this.options.elementSelector).get(0),
that = this; that = this;
interact(domElement).resizable({ interact(domElement).resizable({
//axis: 'y', //axis: 'y',
edges: { edges: {
top: false, top: false,
left: false, left: false,
right: false, right: false,
bottom: (typeof this.options.resizeHandleSelector === 'string') ? this.view.$(this.options.resizeHandleSelector).get(0) : this.options.resizeHandleSelector, bottom: (typeof this.options.resizeHandleSelector === 'string') ? this.view.$(this.options.resizeHandleSelector).get(0) : this.options.resizeHandleSelector,
}, },
}).on('resizestart', function(event) { }).on('resizestart', function(event) {
that.isBeingResized = true; that.isBeingResized = true;
that.$el.addClass('mailpoet_resize_active'); that.$el.addClass('mailpoet_resize_active');
}).on('resizemove', function(event) { }).on('resizemove', function(event) {
var currentLength = parseFloat(that.view.model.get(that.options.modelField)), var currentLength = parseFloat(that.view.model.get(that.options.modelField)),
newLength = currentLength + that.options.transformationFunction(event.dy); newLength = currentLength + that.options.transformationFunction(event.dy);
if (newLength < that.options.minLength) newLength = that.options.minLength; if (newLength < that.options.minLength) newLength = that.options.minLength;
that.view.model.set(that.options.modelField, newLength + 'px'); that.view.model.set(that.options.modelField, newLength + 'px');
}).on('resizeend', function(event) { }).on('resizeend', function(event) {
that.isBeingResized = null; that.isBeingResized = null;
that.$el.removeClass('mailpoet_resize_active'); that.$el.removeClass('mailpoet_resize_active');
}); });
}, },
showResizeHandle: function() { showResizeHandle: function() {
if (typeof this.options.resizeHandleSelector === 'string') { if (typeof this.options.resizeHandleSelector === 'string') {
this.view.$(this.options.resizeHandleSelector).removeClass('mailpoet_hidden'); this.view.$(this.options.resizeHandleSelector).removeClass('mailpoet_hidden');
} }
}, },
hideResizeHandle: function() { hideResizeHandle: function() {
if (typeof this.options.resizeHandleSelector === 'string') { if (typeof this.options.resizeHandleSelector === 'string') {
this.view.$(this.options.resizeHandleSelector).addClass('mailpoet_hidden'); this.view.$(this.options.resizeHandleSelector).addClass('mailpoet_hidden');
} }
}, },
}); });
}); });

View File

@ -9,32 +9,31 @@ define('newsletter_editor/behaviors/SortableBehavior', [
], function(Marionette, BehaviorsLookup) { ], function(Marionette, BehaviorsLookup) {
BehaviorsLookup.SortableBehavior = Marionette.Behavior.extend({ BehaviorsLookup.SortableBehavior = Marionette.Behavior.extend({
onRender: function() { onRender: function() {
var collection = this.view.collection; var collection = this.view.collection;
if (_.isFunction(this.$el.sortable)) { if (_.isFunction(this.$el.sortable)) {
this.$el.sortable({ this.$el.sortable({
cursor: "move", cursor: "move",
start: function(event, ui) { start: function(event, ui) {
ui.item.data('previousIndex', ui.item.index()); ui.item.data('previousIndex', ui.item.index());
}, },
end: function(event, ui) { end: function(event, ui) {
ui.item.removeData('previousIndex'); ui.item.removeData('previousIndex');
}, },
update: function(event, ui) { update: function(event, ui) {
var previousIndex = ui.item.data('previousIndex'), var previousIndex = ui.item.data('previousIndex'),
newIndex = ui.item.index(), newIndex = ui.item.index(),
model = collection.at(previousIndex); model = collection.at(previousIndex);
// Replicate DOM changes. Move target model to a new position // Replicate DOM changes. Move target model to a new position
// within the collection // within the collection
collection.remove(model); collection.remove(model);
collection.add(model, { at: newIndex }); collection.add(model, { at: newIndex });
}, },
items: this.options.items, items: this.options.items,
}); });
}
} }
}
}); });
}); });

View File

@ -14,327 +14,326 @@ define('newsletter_editor/blocks/automatedLatestContent', [
], function(EditorApplication, Backbone, Marionette, MailPoet) { ], function(EditorApplication, Backbone, Marionette, MailPoet) {
EditorApplication.module("blocks.automatedLatestContent", function(Module, App, Backbone, Marionette, $, _) { EditorApplication.module("blocks.automatedLatestContent", function(Module, App, Backbone, Marionette, $, _) {
"use strict"; "use strict";
var base = App.module('blocks.base'); var base = App.module('blocks.base');
Module.AutomatedLatestContentBlockModel = base.BlockModel.extend({ Module.AutomatedLatestContentBlockModel = base.BlockModel.extend({
stale: ['_container'], stale: ['_container'],
defaults: function() { defaults: function() {
return this._getDefaults({ return this._getDefaults({
type: 'automatedLatestContent', type: 'automatedLatestContent',
amount: '5', amount: '5',
contentType: 'post', // 'post'|'page'|'mailpoet_page' contentType: 'post', // 'post'|'page'|'mailpoet_page'
terms: [], // List of category and tag objects terms: [], // List of category and tag objects
inclusionType: 'include', // 'include'|'exclude' inclusionType: 'include', // 'include'|'exclude'
displayType: 'excerpt', // 'excerpt'|'full'|'titleOnly' displayType: 'excerpt', // 'excerpt'|'full'|'titleOnly'
titleFormat: 'h1', // 'h1'|'h2'|'h3'|'ul' titleFormat: 'h1', // 'h1'|'h2'|'h3'|'ul'
titlePosition: 'inTextBlock', // 'inTextBlock'|'aboveBlock', titlePosition: 'inTextBlock', // 'inTextBlock'|'aboveBlock',
titleAlignment: 'left', // 'left'|'center'|'right' titleAlignment: 'left', // 'left'|'center'|'right'
titleIsLink: false, // false|true titleIsLink: false, // false|true
imagePadded: true, // true|false imagePadded: true, // true|false
//imageAlignment: 'centerPadded', // 'centerFull'|'centerPadded'|'left'|'right'|'alternate'|'none' //imageAlignment: 'centerPadded', // 'centerFull'|'centerPadded'|'left'|'right'|'alternate'|'none'
showAuthor: 'no', // 'no'|'aboveText'|'belowText' showAuthor: 'no', // 'no'|'aboveText'|'belowText'
authorPrecededBy: 'Author:', authorPrecededBy: 'Author:',
showCategories: 'no', // 'no'|'aboveText'|'belowText' showCategories: 'no', // 'no'|'aboveText'|'belowText'
categoriesPrecededBy: 'Categories:', categoriesPrecededBy: 'Categories:',
readMoreType: 'button', // 'link'|'button' readMoreType: 'button', // 'link'|'button'
readMoreText: 'Read more', // 'link'|'button' readMoreText: 'Read more', // 'link'|'button'
readMoreButton: { readMoreButton: {
text: 'Read more', text: 'Read more',
url: '[postLink]' url: '[postLink]'
},
sortBy: 'newest', // 'newest'|'oldest',
showDivider: true, // true|false
divider: {},
_container: new (App.getBlockTypeModel('container'))(),
}, EditorApplication.getConfig().get('blockDefaults.automatedLatestContent'));
}, },
relations: function() { sortBy: 'newest', // 'newest'|'oldest',
return { showDivider: true, // true|false
readMoreButton: App.getBlockTypeModel('button'), divider: {},
divider: App.getBlockTypeModel('divider'), _container: new (App.getBlockTypeModel('container'))(),
_container: App.getBlockTypeModel('container'), }, EditorApplication.getConfig().get('blockDefaults.automatedLatestContent'));
}; },
}, relations: function() {
initialize: function() { return {
base.BlockModel.prototype.initialize.apply(this); readMoreButton: App.getBlockTypeModel('button'),
this.fetchPosts(); divider: App.getBlockTypeModel('divider'),
this.on('change:amount change:contentType change:terms change:inclusionType change:displayType change:titleFormat change:titlePosition change:titleAlignment change:titleIsLink change:imagePadded change:showAuthor change:authorPrecededBy change:showCategories change:categoriesPrecededBy change:readMoreType change:readMoreText change:sortBy change:showDivider', this._scheduleFetchPosts, this); _container: App.getBlockTypeModel('container'),
this.listenTo(this.get('readMoreButton'), 'change', this._scheduleFetchPosts); };
this.listenTo(this.get('divider'), 'change', this._scheduleFetchPosts); },
}, initialize: function() {
fetchPosts: function() { base.BlockModel.prototype.initialize.apply(this);
var that = this; this.fetchPosts();
// TODO: Migrate to new AJAX queries this.on('change:amount change:contentType change:terms change:inclusionType change:displayType change:titleFormat change:titlePosition change:titleAlignment change:titleIsLink change:imagePadded change:showAuthor change:authorPrecededBy change:showCategories change:categoriesPrecededBy change:readMoreType change:readMoreText change:sortBy change:showDivider', this._scheduleFetchPosts, this);
//mailpoet_post_wpi('automated_latest_content.php', this.toJSON(), function(response) { this.listenTo(this.get('readMoreButton'), 'change', this._scheduleFetchPosts);
//console.log('ALC fetched', arguments); this.listenTo(this.get('divider'), 'change', this._scheduleFetchPosts);
//that.get('_container').get('blocks').reset(response, {parse: true}); },
//}, function() { fetchPosts: function() {
//console.log('ALC fetchPosts error', arguments); var that = this;
//}); // TODO: Migrate to new AJAX queries
}, //mailpoet_post_wpi('automated_latest_content.php', this.toJSON(), function(response) {
/** //console.log('ALC fetched', arguments);
* Batch more changes during a specific time, instead of fetching //that.get('_container').get('blocks').reset(response, {parse: true});
* ALC posts on each model change //}, function() {
*/ //console.log('ALC fetchPosts error', arguments);
_scheduleFetchPosts: function() { //});
var timeout = 2000, },
that = this; /**
if (this._fetchPostsTimer !== undefined) { * Batch more changes during a specific time, instead of fetching
clearTimeout(this._fetchPostsTimer); * ALC posts on each model change
} */
this._fetchPostsTimer = setTimeout(function() { _scheduleFetchPosts: function() {
that.fetchPosts(); var timeout = 2000,
that._fetchPostsTimer = undefined; that = this;
}, timeout); if (this._fetchPostsTimer !== undefined) {
}, clearTimeout(this._fetchPostsTimer);
}); }
this._fetchPostsTimer = setTimeout(function() {
that.fetchPosts();
that._fetchPostsTimer = undefined;
}, timeout);
},
});
Module.AutomatedLatestContentBlockView = base.BlockView.extend({ Module.AutomatedLatestContentBlockView = base.BlockView.extend({
className: "mailpoet_block mailpoet_automated_latest_content_block mailpoet_droppable_block", className: "mailpoet_block mailpoet_automated_latest_content_block mailpoet_droppable_block",
getTemplate: function() { return templates.automatedLatestContentBlock; }, getTemplate: function() { return templates.automatedLatestContentBlock; },
regions: { regions: {
toolsRegion: '.mailpoet_tools', toolsRegion: '.mailpoet_tools',
postsRegion: '.mailpoet_automated_latest_content_block_posts', postsRegion: '.mailpoet_automated_latest_content_block_posts',
}, },
onDragSubstituteBy: function() { return Module.AutomatedLatestContentWidgetView; }, onDragSubstituteBy: function() { return Module.AutomatedLatestContentWidgetView; },
onRender: function() { onRender: function() {
var ContainerView = App.getBlockTypeView('container'), var ContainerView = App.getBlockTypeView('container'),
renderOptions = { renderOptions = {
disableTextEditor: true, disableTextEditor: true,
disableDragAndDrop: true, disableDragAndDrop: true,
}; };
this.toolsView = new Module.AutomatedLatestContentBlockToolsView({ model: this.model }); this.toolsView = new Module.AutomatedLatestContentBlockToolsView({ model: this.model });
this.toolsRegion.show(this.toolsView); this.toolsRegion.show(this.toolsView);
this.postsRegion.show(new ContainerView({ model: this.model.get('_container'), renderOptions: renderOptions })); this.postsRegion.show(new ContainerView({ model: this.model.get('_container'), renderOptions: renderOptions }));
}, },
}); });
Module.AutomatedLatestContentBlockToolsView = base.BlockToolsView.extend({ Module.AutomatedLatestContentBlockToolsView = base.BlockToolsView.extend({
getSettingsView: function() { return Module.AutomatedLatestContentBlockSettingsView; }, getSettingsView: function() { return Module.AutomatedLatestContentBlockSettingsView; },
}); });
// Sidebar view container // Sidebar view container
Module.AutomatedLatestContentBlockSettingsView = base.BlockSettingsView.extend({ Module.AutomatedLatestContentBlockSettingsView = base.BlockSettingsView.extend({
getTemplate: function() { return templates.automatedLatestContentBlockSettings; }, getTemplate: function() { return templates.automatedLatestContentBlockSettings; },
events: function() { events: function() {
return { return {
"click .mailpoet_automated_latest_content_hide_display_options": 'toggleDisplayOptions', "click .mailpoet_automated_latest_content_hide_display_options": 'toggleDisplayOptions',
"click .mailpoet_automated_latest_content_show_display_options": 'toggleDisplayOptions', "click .mailpoet_automated_latest_content_show_display_options": 'toggleDisplayOptions',
"click .mailpoet_automated_latest_content_select_button": 'showButtonSettings', "click .mailpoet_automated_latest_content_select_button": 'showButtonSettings',
"click .mailpoet_automated_latest_content_select_divider": 'showDividerSettings', "click .mailpoet_automated_latest_content_select_divider": 'showDividerSettings',
"change .mailpoet_automated_latest_content_read_more_type": 'changeReadMoreType', "change .mailpoet_automated_latest_content_read_more_type": 'changeReadMoreType',
"change .mailpoet_automated_latest_content_display_type": 'changeDisplayType', "change .mailpoet_automated_latest_content_display_type": 'changeDisplayType',
"change .mailpoet_automated_latest_content_title_format": 'changeTitleFormat', "change .mailpoet_automated_latest_content_title_format": 'changeTitleFormat',
"change .mailpoet_automated_latest_content_title_as_links": _.partial(this.changeBoolField, 'titleIsLink'), "change .mailpoet_automated_latest_content_title_as_links": _.partial(this.changeBoolField, 'titleIsLink'),
"change .mailpoet_automated_latest_content_show_divider": _.partial(this.changeBoolField, 'showDivider'), "change .mailpoet_automated_latest_content_show_divider": _.partial(this.changeBoolField, 'showDivider'),
"keyup .mailpoet_automated_latest_content_show_amount": _.partial(this.changeField, "amount"), "keyup .mailpoet_automated_latest_content_show_amount": _.partial(this.changeField, "amount"),
"change .mailpoet_automated_latest_content_content_type": _.partial(this.changeField, "contentType"), "change .mailpoet_automated_latest_content_content_type": _.partial(this.changeField, "contentType"),
"change .mailpoet_automated_latest_content_include_or_exclude": _.partial(this.changeField, "inclusionType"), "change .mailpoet_automated_latest_content_include_or_exclude": _.partial(this.changeField, "inclusionType"),
"change .mailpoet_automated_latest_content_title_position": _.partial(this.changeField, "titlePosition"), "change .mailpoet_automated_latest_content_title_position": _.partial(this.changeField, "titlePosition"),
"change .mailpoet_automated_latest_content_title_alignment": _.partial(this.changeField, "titleAlignment"), "change .mailpoet_automated_latest_content_title_alignment": _.partial(this.changeField, "titleAlignment"),
"change .mailpoet_automated_latest_content_image_padded": _.partial(this.changeBoolField, "imagePadded"), "change .mailpoet_automated_latest_content_image_padded": _.partial(this.changeBoolField, "imagePadded"),
"change .mailpoet_automated_latest_content_show_author": _.partial(this.changeField, "showAuthor"), "change .mailpoet_automated_latest_content_show_author": _.partial(this.changeField, "showAuthor"),
"keyup .mailpoet_automated_latest_content_author_preceded_by": _.partial(this.changeField, "authorPrecededBy"), "keyup .mailpoet_automated_latest_content_author_preceded_by": _.partial(this.changeField, "authorPrecededBy"),
"change .mailpoet_automated_latest_content_show_categories": _.partial(this.changeField, "showCategories"), "change .mailpoet_automated_latest_content_show_categories": _.partial(this.changeField, "showCategories"),
"keyup .mailpoet_automated_latest_content_categories": _.partial(this.changeField, "categoriesPrecededBy"), "keyup .mailpoet_automated_latest_content_categories": _.partial(this.changeField, "categoriesPrecededBy"),
"keyup .mailpoet_automated_latest_content_read_more_text": _.partial(this.changeField, "readMoreText"), "keyup .mailpoet_automated_latest_content_read_more_text": _.partial(this.changeField, "readMoreText"),
"change .mailpoet_automated_latest_content_sort_by": _.partial(this.changeField, "sortBy"), "change .mailpoet_automated_latest_content_sort_by": _.partial(this.changeField, "sortBy"),
"click .mailpoet_done_editing": "close", "click .mailpoet_done_editing": "close",
}; };
}, },
behaviors: { behaviors: {
ColorPickerBehavior: {}, ColorPickerBehavior: {},
}, },
templateHelpers: function() { templateHelpers: function() {
return { return {
model: this.model.toJSON(), model: this.model.toJSON(),
}; };
}, },
onRender: function() { onRender: function() {
var that = this; var that = this;
this.$('.mailpoet_automated_latest_content_categories_and_tags').select2({ this.$('.mailpoet_automated_latest_content_categories_and_tags').select2({
multiple: true, multiple: true,
allowClear: true, allowClear: true,
ajax: { ajax: {
url: App.getConfig().get('urls.termSearch'), url: App.getConfig().get('urls.termSearch'),
type: 'POST', type: 'POST',
dataType: 'json', dataType: 'json',
delay: 250, delay: 250,
data: function(searchParameter, page) { data: function(searchParameter, page) {
return JSON.stringify({ return JSON.stringify({
postType: that.model.get('contentType'), postType: that.model.get('contentType'),
search: searchParameter, search: searchParameter,
limit: 10, // TODO: Move this hardcoded limit to Config limit: 10, // TODO: Move this hardcoded limit to Config
page: page, page: page,
});
},
/**
* Parse results for select2.
* Returns object, where `results` key holds a list of
* select item objects
*/
results: function (data, page) {
return {
results: _.map(
data.results,
function(item) {
return _.defaults({
text: data.taxonomies[item.taxonomy].labels.singular_name + ': ' + item.name,
id: item.term_id
}, item);
}
)
};
}
},
initSelection: function(element, callback) {
// On external data load tell select2 which terms to preselect
callback(_.map(
that.model.get('terms').toJSON(),
function(item) {
return {
id: item.id,
text: item.text,
};
}
));
},
}).trigger( 'change' ).on({
'change': function(e){
var data = $(this).data('selected');
if (typeof data === 'string') {
if (data === '') {
data = [];
} else {
data = JSON.parse(data);
}
}
if ( e.added ){
data.push(e.added);
} else {
data = _.filter(data, function(item) {
return item.id !== e.removed.id;
});
}
// Update ALC model
that.model.set('terms', data);
$(this).data('selected', JSON.stringify(data));
}
}); });
}, },
onBeforeDestroy: function() { /**
// Force close select2 if it hasn't closed yet * Parse results for select2.
this.$('.mailpoet_automated_latest_content_categories_and_tags').select2('close'); * Returns object, where `results` key holds a list of
}, * select item objects
toggleDisplayOptions: function(event) { */
var el = this.$('.mailpoet_automated_latest_content_display_options'), results: function (data, page) {
showControl = this.$('.mailpoet_automated_latest_content_show_display_options'); return {
if (el.hasClass('mailpoet_hidden')) { results: _.map(
el.removeClass('mailpoet_hidden'); data.results,
showControl.addClass('mailpoet_hidden'); function(item) {
} else { return _.defaults({
el.addClass('mailpoet_hidden'); text: data.taxonomies[item.taxonomy].labels.singular_name + ': ' + item.name,
showControl.removeClass('mailpoet_hidden'); id: item.term_id
} }, item);
},
showButtonSettings: function(event) {
var buttonModule = App.module('blocks.button');
(new buttonModule.ButtonBlockSettingsView({
model: this.model.get('readMoreButton'),
renderOptions: {
displayFormat: 'subpanel',
hideLink: true,
hideApplyToAll: true,
},
})).render();
},
showDividerSettings: function(event) {
var dividerModule = App.module('blocks.divider');
(new dividerModule.DividerBlockSettingsView({
model: this.model.get('divider'),
renderOptions: {
displayFormat: 'subpanel',
hideApplyToAll: true,
},
})).render();
},
changeReadMoreType: function(event) {
var value = jQuery(event.target).val();
if (value == 'link') {
this.$('.mailpoet_automated_latest_content_read_more_text').removeClass('mailpoet_hidden');
this.$('.mailpoet_automated_latest_content_select_button').addClass('mailpoet_hidden');
} else if (value == 'button') {
this.$('.mailpoet_automated_latest_content_read_more_text').addClass('mailpoet_hidden');
this.$('.mailpoet_automated_latest_content_select_button').removeClass('mailpoet_hidden');
}
this.changeField('readMoreType', event);
},
changeDisplayType: function(event) {
var value = jQuery(event.target).val();
if (value == 'titleOnly') {
this.$('.mailpoet_automated_latest_content_title_position_container').addClass('mailpoet_hidden');
this.$('.mailpoet_automated_latest_content_title_as_list').removeClass('mailpoet_hidden');
} else {
this.$('.mailpoet_automated_latest_content_title_position_container').removeClass('mailpoet_hidden');
this.$('.mailpoet_automated_latest_content_title_as_list').addClass('mailpoet_hidden');
// Reset titleFormat if it was set to List when switching away from displayType=titleOnly
if (this.model.get('titleFormat') === 'ul') {
this.model.set('titleFormat', 'h1');
this.$('.mailpoet_automated_latest_content_title_format').val(['h1']);
this.$('.mailpoet_automated_latest_content_title_as_link').removeClass('mailpoet_hidden');
} }
} )
this.changeField('displayType', event); };
}
}, },
changeTitleFormat: function(event) { initSelection: function(element, callback) {
var value = jQuery(event.target).val(); // On external data load tell select2 which terms to preselect
if (value == 'ul') {
this.$('.mailpoet_automated_latest_content_non_title_list_options').addClass('mailpoet_hidden');
this.model.set('titleIsLink', true); callback(_.map(
this.$('.mailpoet_automated_latest_content_title_as_link').addClass('mailpoet_hidden'); that.model.get('terms').toJSON(),
this.$('.mailpoet_automated_latest_content_title_as_links').val(['true']); function(item) {
return {
id: item.id,
text: item.text,
};
}
));
},
}).trigger( 'change' ).on({
'change': function(e){
var data = $(this).data('selected');
if (typeof data === 'string') {
if (data === '') {
data = [];
} else { } else {
this.$('.mailpoet_automated_latest_content_non_title_list_options').removeClass('mailpoet_hidden'); data = JSON.parse(data);
this.$('.mailpoet_automated_latest_content_title_as_link').removeClass('mailpoet_hidden');
} }
this.changeField('titleFormat', event); }
if ( e.added ){
data.push(e.added);
} else {
data = _.filter(data, function(item) {
return item.id !== e.removed.id;
});
}
// Update ALC model
that.model.set('terms', data);
$(this).data('selected', JSON.stringify(data));
}
});
},
onBeforeDestroy: function() {
// Force close select2 if it hasn't closed yet
this.$('.mailpoet_automated_latest_content_categories_and_tags').select2('close');
},
toggleDisplayOptions: function(event) {
var el = this.$('.mailpoet_automated_latest_content_display_options'),
showControl = this.$('.mailpoet_automated_latest_content_show_display_options');
if (el.hasClass('mailpoet_hidden')) {
el.removeClass('mailpoet_hidden');
showControl.addClass('mailpoet_hidden');
} else {
el.addClass('mailpoet_hidden');
showControl.removeClass('mailpoet_hidden');
}
},
showButtonSettings: function(event) {
var buttonModule = App.module('blocks.button');
(new buttonModule.ButtonBlockSettingsView({
model: this.model.get('readMoreButton'),
renderOptions: {
displayFormat: 'subpanel',
hideLink: true,
hideApplyToAll: true,
}, },
}); })).render();
},
Module.AutomatedLatestContentWidgetView = base.WidgetView.extend({ showDividerSettings: function(event) {
getTemplate: function() { return templates.automatedLatestContentInsertion; }, var dividerModule = App.module('blocks.divider');
behaviors: { (new dividerModule.DividerBlockSettingsView({
DraggableBehavior: { model: this.model.get('divider'),
cloneOriginal: true, renderOptions: {
drop: function() { displayFormat: 'subpanel',
return new Module.AutomatedLatestContentBlockModel({}, { parse: true }); hideApplyToAll: true,
}
}
}, },
})).render();
},
changeReadMoreType: function(event) {
var value = jQuery(event.target).val();
if (value == 'link') {
this.$('.mailpoet_automated_latest_content_read_more_text').removeClass('mailpoet_hidden');
this.$('.mailpoet_automated_latest_content_select_button').addClass('mailpoet_hidden');
} else if (value == 'button') {
this.$('.mailpoet_automated_latest_content_read_more_text').addClass('mailpoet_hidden');
this.$('.mailpoet_automated_latest_content_select_button').removeClass('mailpoet_hidden');
}
this.changeField('readMoreType', event);
},
changeDisplayType: function(event) {
var value = jQuery(event.target).val();
if (value == 'titleOnly') {
this.$('.mailpoet_automated_latest_content_title_position_container').addClass('mailpoet_hidden');
this.$('.mailpoet_automated_latest_content_title_as_list').removeClass('mailpoet_hidden');
} else {
this.$('.mailpoet_automated_latest_content_title_position_container').removeClass('mailpoet_hidden');
this.$('.mailpoet_automated_latest_content_title_as_list').addClass('mailpoet_hidden');
// Reset titleFormat if it was set to List when switching away from displayType=titleOnly
if (this.model.get('titleFormat') === 'ul') {
this.model.set('titleFormat', 'h1');
this.$('.mailpoet_automated_latest_content_title_format').val(['h1']);
this.$('.mailpoet_automated_latest_content_title_as_link').removeClass('mailpoet_hidden');
}
}
this.changeField('displayType', event);
},
changeTitleFormat: function(event) {
var value = jQuery(event.target).val();
if (value == 'ul') {
this.$('.mailpoet_automated_latest_content_non_title_list_options').addClass('mailpoet_hidden');
this.model.set('titleIsLink', true);
this.$('.mailpoet_automated_latest_content_title_as_link').addClass('mailpoet_hidden');
this.$('.mailpoet_automated_latest_content_title_as_links').val(['true']);
} else {
this.$('.mailpoet_automated_latest_content_non_title_list_options').removeClass('mailpoet_hidden');
this.$('.mailpoet_automated_latest_content_title_as_link').removeClass('mailpoet_hidden');
}
this.changeField('titleFormat', event);
},
});
Module.AutomatedLatestContentWidgetView = base.WidgetView.extend({
getTemplate: function() { return templates.automatedLatestContentInsertion; },
behaviors: {
DraggableBehavior: {
cloneOriginal: true,
drop: function() {
return new Module.AutomatedLatestContentBlockModel({}, { parse: true });
}
}
},
});
App.on('before:start', function() {
App.registerBlockType('automatedLatestContent', {
blockModel: Module.AutomatedLatestContentBlockModel,
blockView: Module.AutomatedLatestContentBlockView,
}); });
App.on('before:start', function() { App.registerWidget({
App.registerBlockType('automatedLatestContent', { name: 'automatedLatestContent',
blockModel: Module.AutomatedLatestContentBlockModel, widgetView: Module.AutomatedLatestContentWidgetView,
blockView: Module.AutomatedLatestContentBlockView, priority: 97,
});
App.registerWidget({
name: 'automatedLatestContent',
widgetView: Module.AutomatedLatestContentWidgetView,
priority: 97,
});
}); });
});
}); });
}); });

View File

@ -13,207 +13,206 @@ define('newsletter_editor/blocks/base', [
], function(EditorApplication, Backbone, Marionette, MailPoet) { ], function(EditorApplication, Backbone, Marionette, MailPoet) {
EditorApplication.module("blocks.base", function(Module, App, Backbone, Marionette, $, _) { EditorApplication.module("blocks.base", function(Module, App, Backbone, Marionette, $, _) {
"use strict"; "use strict";
var AugmentedView = Marionette.LayoutView.extend({}); var AugmentedView = Marionette.LayoutView.extend({});
Module.BlockModel = Backbone.SuperModel.extend({ Module.BlockModel = Backbone.SuperModel.extend({
stale: [], // Attributes to be removed upon saving stale: [], // Attributes to be removed upon saving
initialize: function() { initialize: function() {
var that = this; var that = this;
this.on('change', function() { this.on('change', function() {
App.getChannel().trigger('autoSave'); App.getChannel().trigger('autoSave');
}); });
}, },
_getDefaults: function(blockDefaults, configDefaults) { _getDefaults: function(blockDefaults, configDefaults) {
var defaults = (_.isObject(configDefaults) && _.isFunction(configDefaults.toJSON)) ? configDefaults.toJSON() : configDefaults; var defaults = (_.isObject(configDefaults) && _.isFunction(configDefaults.toJSON)) ? configDefaults.toJSON() : configDefaults;
// Patch the resulting JSON object and fix it's constructors to be Object. // Patch the resulting JSON object and fix it's constructors to be Object.
// Otherwise Backbone.SuperModel interprets it not as a simpleObject // Otherwise Backbone.SuperModel interprets it not as a simpleObject
// and misbehaves // and misbehaves
// TODO: Investigate for a better solution // TODO: Investigate for a better solution
return JSON.parse(JSON.stringify(jQuery.extend(blockDefaults, defaults || {}))); return JSON.parse(JSON.stringify(jQuery.extend(blockDefaults, defaults || {})));
}, },
toJSON: function() { toJSON: function() {
// Remove stale attributes from resulting JSON object // Remove stale attributes from resulting JSON object
return _.omit(Backbone.SuperModel.prototype.toJSON.call(this), this.stale); return _.omit(Backbone.SuperModel.prototype.toJSON.call(this), this.stale);
}, },
}); });
Module.BlockView = AugmentedView.extend({ Module.BlockView = AugmentedView.extend({
regions: { regions: {
toolsRegion: '> .mailpoet_tools', toolsRegion: '> .mailpoet_tools',
},
modelEvents: {
'change': 'render',
},
events: {
"mouseenter": "showTools",
"mouseleave": "hideTools",
},
behaviors: {
DraggableBehavior: {
cloneOriginal: true,
hideOriginal: true,
onDrop: function(options) {
// After a clone of model has been dropped, cleanup
// and destroy self
options.dragBehavior.view.model.destroy();
}, },
modelEvents: { onDragSubstituteBy: function(behavior) {
'change': 'render', var WidgetView, node;
// When block is being dragged, display the widget icon instead.
// This will create an instance of block's widget view and
// use it's rendered DOM element instead of the content block
if (_.isFunction(behavior.view.onDragSubstituteBy)) {
WidgetView = new (behavior.view.onDragSubstituteBy())();
WidgetView.render();
node = WidgetView.$el.get(0).cloneNode(true);
WidgetView.destroy();
return node;
}
}, },
events: { },
"mouseenter": "showTools", },
"mouseleave": "hideTools", templateHelpers: function() {
}, return {
behaviors: { model: this.model.toJSON(),
DraggableBehavior: { viewCid: this.cid,
cloneOriginal: true, };
hideOriginal: true, },
onDrop: function(options) { constructor: function() {
// After a clone of model has been dropped, cleanup AugmentedView.apply(this, arguments);
// and destroy self this.$el.addClass('mailpoet_editor_view_' + this.cid);
options.dragBehavior.view.model.destroy(); },
}, showTools: function(_event) {
onDragSubstituteBy: function(behavior) { if (!this.showingToolsDisabled) {
var WidgetView, node; this.$('> .mailpoet_tools').show();
// When block is being dragged, display the widget icon instead. this.toolsView.triggerMethod('showTools');
// This will create an instance of block's widget view and }
// use it's rendered DOM element instead of the content block },
if (_.isFunction(behavior.view.onDragSubstituteBy)) { hideTools: function(e) {
WidgetView = new (behavior.view.onDragSubstituteBy())(); this.$('> .mailpoet_tools').hide();
WidgetView.render(); this.toolsView.triggerMethod('hideTools');
node = WidgetView.$el.get(0).cloneNode(true); },
WidgetView.destroy(); enableShowingTools: function() {
return node; this.showingToolsDisabled = false;
} },
}, disableShowingTools: function() {
}, this.showingToolsDisabled = true;
}, this.hideTools();
templateHelpers: function() { },
return { /**
model: this.model.toJSON(), * Defines drop behavior of BlockView instance
viewCid: this.cid, */
}; getDropFunc: function() {
}, var that = this;
constructor: function() { return function() {
AugmentedView.apply(this, arguments); var newModel = that.model.clone();
this.$el.addClass('mailpoet_editor_view_' + this.cid); //that.model.destroy();
}, return newModel;
showTools: function(_event) { };
if (!this.showingToolsDisabled) { },
this.$('> .mailpoet_tools').show(); });
this.toolsView.triggerMethod('showTools');
}
},
hideTools: function(e) {
this.$('> .mailpoet_tools').hide();
this.toolsView.triggerMethod('hideTools');
},
enableShowingTools: function() {
this.showingToolsDisabled = false;
},
disableShowingTools: function() {
this.showingToolsDisabled = true;
this.hideTools();
},
/**
* Defines drop behavior of BlockView instance
*/
getDropFunc: function() {
var that = this;
return function() {
var newModel = that.model.clone();
//that.model.destroy();
return newModel;
};
},
});
Module.BlockToolsView = AugmentedView.extend({ Module.BlockToolsView = AugmentedView.extend({
getTemplate: function() { return templates.genericBlockTools; }, getTemplate: function() { return templates.genericBlockTools; },
events: { events: {
"click .mailpoet_edit_block": "changeSettings", "click .mailpoet_edit_block": "changeSettings",
"click .mailpoet_delete_block_activate": "showDeletionConfirmation", "click .mailpoet_delete_block_activate": "showDeletionConfirmation",
"click .mailpoet_delete_block_cancel": "hideDeletionConfirmation", "click .mailpoet_delete_block_cancel": "hideDeletionConfirmation",
"click .mailpoet_delete_block_confirm": "deleteBlock", "click .mailpoet_delete_block_confirm": "deleteBlock",
}, },
// Markers of whether these particular tools will be used for this instance // Markers of whether these particular tools will be used for this instance
tools: { tools: {
settings: true, settings: true,
delete: true, delete: true,
move: true, move: true,
}, },
getSettingsView: function() { return Module.BlockSettingsView; }, getSettingsView: function() { return Module.BlockSettingsView; },
initialize: function(options) { initialize: function(options) {
options = options || {}; options = options || {};
if (!_.isUndefined(options.tools)) { if (!_.isUndefined(options.tools)) {
// Make a new block specific tool config object // Make a new block specific tool config object
this.tools = jQuery.extend({}, this.tools, options.tools || {}); this.tools = jQuery.extend({}, this.tools, options.tools || {});
} }
// Automatically cancel deletion // Automatically cancel deletion
this.on('hideTools', this.hideDeletionConfirmation, this); this.on('hideTools', this.hideDeletionConfirmation, this);
},
templateHelpers: function() {
return {
model: this.model.toJSON(),
viewCid: this.cid,
tools: this.tools,
};
},
changeSettings: function() {
var ViewType = this.getSettingsView();
(new ViewType({ model: this.model })).render();
},
showDeletionConfirmation: function() {
this.$('.mailpoet_delete_block').addClass('mailpoet_delete_block_activated');
},
hideDeletionConfirmation: function() {
this.$('.mailpoet_delete_block').removeClass('mailpoet_delete_block_activated');
},
deleteBlock: function(event) {
event.preventDefault();
this.model.destroy();
return false;
}
});
Module.BlockSettingsView = Marionette.LayoutView.extend({
className: 'mailpoet_editor_settings',
initialize: function() {
var that = this;
MailPoet.Modal.panel({
element: this.$el,
template: '',
position: 'right',
width: App.getConfig().get('sidepanelWidth'),
onCancel: function() {
that.destroy();
}, },
templateHelpers: function() { });
return { },
model: this.model.toJSON(), close: function(event) {
viewCid: this.cid, MailPoet.Modal.cancel();
tools: this.tools, this.destroy();
}; },
}, changeField: function(field, event) {
changeSettings: function() { this.model.set(field, jQuery(event.target).val());
var ViewType = this.getSettingsView(); },
(new ViewType({ model: this.model })).render(); changePixelField: function(field, event) {
}, this.changeFieldWithSuffix(field, event, 'px');
showDeletionConfirmation: function() { },
this.$('.mailpoet_delete_block').addClass('mailpoet_delete_block_activated'); changeFieldWithSuffix: function(field, event, suffix) {
}, this.model.set(field, jQuery(event.target).val() + suffix);
hideDeletionConfirmation: function() { },
this.$('.mailpoet_delete_block').removeClass('mailpoet_delete_block_activated'); changeBoolField: function(field, event) {
}, this.model.set(field, (jQuery(event.target).val() === 'true') ? true : false);
deleteBlock: function(event) { },
event.preventDefault(); changeColorField: function(field, event) {
this.model.destroy(); var value = jQuery(event.target).val();
return false; if (value === '') {
value = 'transparent';
}
this.model.set(field, value);
},
});
Module.WidgetView = Marionette.ItemView.extend({
className: 'mailpoet_widget mailpoet_droppable_block mailpoet_droppable_widget',
behaviors: {
DraggableBehavior: {
drop: function() {
throw "Unsupported operation";
} }
}); }
},
Module.BlockSettingsView = Marionette.LayoutView.extend({ });
className: 'mailpoet_editor_settings',
initialize: function() {
var that = this;
MailPoet.Modal.panel({
element: this.$el,
template: '',
position: 'right',
width: App.getConfig().get('sidepanelWidth'),
onCancel: function() {
that.destroy();
},
});
},
close: function(event) {
MailPoet.Modal.cancel();
this.destroy();
},
changeField: function(field, event) {
this.model.set(field, jQuery(event.target).val());
},
changePixelField: function(field, event) {
this.changeFieldWithSuffix(field, event, 'px');
},
changeFieldWithSuffix: function(field, event, suffix) {
this.model.set(field, jQuery(event.target).val() + suffix);
},
changeBoolField: function(field, event) {
this.model.set(field, (jQuery(event.target).val() === 'true') ? true : false);
},
changeColorField: function(field, event) {
var value = jQuery(event.target).val();
if (value === '') {
value = 'transparent';
}
this.model.set(field, value);
},
});
Module.WidgetView = Marionette.ItemView.extend({
className: 'mailpoet_widget mailpoet_droppable_block mailpoet_droppable_widget',
behaviors: {
DraggableBehavior: {
drop: function() {
throw "Unsupported operation";
}
}
},
});
}); });
}); });

View File

@ -9,154 +9,153 @@ define('newsletter_editor/blocks/button', [
], function(EditorApplication, Backbone, Marionette, MailPoet) { ], function(EditorApplication, Backbone, Marionette, MailPoet) {
EditorApplication.module("blocks.button", function(Module, App, Backbone, Marionette, $, _) { EditorApplication.module("blocks.button", function(Module, App, Backbone, Marionette, $, _) {
"use strict"; "use strict";
var base = App.module('blocks.base'); var base = App.module('blocks.base');
Module.ButtonBlockModel = base.BlockModel.extend({ Module.ButtonBlockModel = base.BlockModel.extend({
defaults: function() { defaults: function() {
return this._getDefaults({ return this._getDefaults({
type: 'button', type: 'button',
text: 'Button', text: 'Button',
url: 'http://google.com', url: 'http://google.com',
styles: { styles: {
block: { block: {
backgroundColor: '#ff0000', backgroundColor: '#ff0000',
borderColor: '#cccccc', borderColor: '#cccccc',
borderWidth: '1px', borderWidth: '1px',
borderRadius: '4px', borderRadius: '4px',
borderStyle: 'solid', borderStyle: 'solid',
width: '200px', width: '200px',
lineHeight: '40px', lineHeight: '40px',
fontColor: '#000000', fontColor: '#000000',
fontFamily: 'Arial', fontFamily: 'Arial',
fontSize: '16px', fontSize: '16px',
textAlign: 'center', textAlign: 'center',
}, },
},
}, EditorApplication.getConfig().get('blockDefaults.button'));
}, },
}, EditorApplication.getConfig().get('blockDefaults.button'));
},
});
Module.ButtonBlockView = base.BlockView.extend({
className: "mailpoet_block mailpoet_button_block mailpoet_droppable_block",
getTemplate: function() { return templates.buttonBlock; },
modelEvents: {
'change': 'render',
},
onDragSubstituteBy: function() { return Module.ButtonWidgetView; },
initialize: function() {
base.BlockView.prototype.initialize.apply(this, arguments);
var that = this;
// Listen for attempts to change all dividers in one go
this._replaceButtonStylesHandler = function(data) { that.model.set(data); };
App.getChannel().on('replaceAllButtonStyles', this._replaceButtonStylesHandler);
},
onRender: function() {
this.toolsView = new Module.ButtonBlockToolsView({ model: this.model });
this.toolsRegion.show(this.toolsView);
},
});
Module.ButtonBlockToolsView = base.BlockToolsView.extend({
getSettingsView: function() { return Module.ButtonBlockSettingsView; },
});
Module.ButtonBlockSettingsView = base.BlockSettingsView.extend({
getTemplate: function() { return templates.buttonBlockSettings; },
events: function() {
return {
"keyup .mailpoet_field_button_text": _.partial(this.changeField, "text"),
"keyup .mailpoet_field_button_url": _.partial(this.changeField, "url"),
"change .mailpoet_field_button_alignment": _.partial(this.changeField, "styles.block.textAlign"),
"change .mailpoet_field_button_font_color": _.partial(this.changeColorField, "styles.block.fontColor"),
"change .mailpoet_field_button_font_family": _.partial(this.changeField, "styles.block.fontFamily"),
"change .mailpoet_field_button_font_size": _.partial(this.changeField, "styles.block.fontSize"),
"change .mailpoet_field_button_background_color": _.partial(this.changeColorField, "styles.block.backgroundColor"),
"change .mailpoet_field_button_border_color": _.partial(this.changeColorField, "styles.block.borderColor"),
"input .mailpoet_field_button_border_width": _.partial(this.updateValueAndCall, '.mailpoet_field_button_border_width_input', _.partial(this.changePixelField, "styles.block.borderWidth").bind(this)),
"change .mailpoet_field_button_border_width": _.partial(this.updateValueAndCall, '.mailpoet_field_button_border_width_input', _.partial(this.changePixelField, "styles.block.borderWidth").bind(this)),
"change .mailpoet_field_button_border_width_input": _.partial(this.updateValueAndCall, '.mailpoet_field_button_border_width', _.partial(this.changePixelField, "styles.block.borderWidth").bind(this)),
"keyup .mailpoet_field_button_border_width_input": _.partial(this.updateValueAndCall, '.mailpoet_field_button_border_width', _.partial(this.changePixelField, "styles.block.borderWidth").bind(this)),
"input .mailpoet_field_button_border_radius": _.partial(this.updateValueAndCall, '.mailpoet_field_button_border_radius_input', _.partial(this.changePixelField, "styles.block.borderRadius").bind(this)),
"change .mailpoet_field_button_border_radius": _.partial(this.updateValueAndCall, '.mailpoet_field_button_border_radius_input', _.partial(this.changePixelField, "styles.block.borderRadius").bind(this)),
"change .mailpoet_field_button_border_radius_input": _.partial(this.updateValueAndCall, '.mailpoet_field_button_border_radius', _.partial(this.changePixelField, "styles.block.borderRadius").bind(this)),
"keyup .mailpoet_field_button_border_radius_input": _.partial(this.updateValueAndCall, '.mailpoet_field_button_border_radius', _.partial(this.changePixelField, "styles.block.borderRadius").bind(this)),
"input .mailpoet_field_button_width": _.partial(this.updateValueAndCall, '.mailpoet_field_button_width_input', _.partial(this.changePixelField, "styles.block.width").bind(this)),
"change .mailpoet_field_button_width": _.partial(this.updateValueAndCall, '.mailpoet_field_button_width_input', _.partial(this.changePixelField, "styles.block.width").bind(this)),
"change .mailpoet_field_button_width_input": _.partial(this.updateValueAndCall, '.mailpoet_field_button_width', _.partial(this.changePixelField, "styles.block.width").bind(this)),
"keyup .mailpoet_field_button_width_input": _.partial(this.updateValueAndCall, '.mailpoet_field_button_width', _.partial(this.changePixelField, "styles.block.width").bind(this)),
"input .mailpoet_field_button_line_height": _.partial(this.updateValueAndCall, '.mailpoet_field_button_line_height_input', _.partial(this.changePixelField, "styles.block.lineHeight").bind(this)),
"change .mailpoet_field_button_line_height": _.partial(this.updateValueAndCall, '.mailpoet_field_button_line_height_input', _.partial(this.changePixelField, "styles.block.lineHeight").bind(this)),
"change .mailpoet_field_button_line_height_input": _.partial(this.updateValueAndCall, '.mailpoet_field_button_line_height', _.partial(this.changePixelField, "styles.block.lineHeight").bind(this)),
"keyup .mailpoet_field_button_line_height_input": _.partial(this.updateValueAndCall, '.mailpoet_field_button_line_height', _.partial(this.changePixelField, "styles.block.lineHeight").bind(this)),
"click .mailpoet_field_button_replace_all_styles": "applyToAll",
"click .mailpoet_done_editing": "close",
};
},
behaviors: {
ColorPickerBehavior: {},
},
initialize: function(params) {
var panelParams = {
element: this.$el,
template: '',
position: 'right',
width: App.getConfig().get('sidepanelWidth'),
};
this.renderOptions = params.renderOptions || {};
if (this.renderOptions.displayFormat === 'subpanel') {
MailPoet.Modal.subpanel(panelParams);
} else {
MailPoet.Modal.panel(panelParams);
}
},
templateHelpers: function() {
return {
model: this.model.toJSON(),
availableStyles: App.getAvailableStyles().toJSON(),
renderOptions: this.renderOptions,
};
},
applyToAll: function() {
App.getChannel().trigger('replaceAllButtonStyles', _.pick(this.model.toJSON(), 'styles', 'type'));
},
updateValueAndCall: function(fieldToUpdate, callable, event) {
this.$(fieldToUpdate).val(jQuery(event.target).val());
callable(event);
},
});
Module.ButtonWidgetView = base.WidgetView.extend({
getTemplate: function() { return templates.buttonInsertion; },
behaviors: {
DraggableBehavior: {
cloneOriginal: true,
drop: function() {
return new Module.ButtonBlockModel();
},
}
},
});
App.on('before:start', function() {
App.registerBlockType('button', {
blockModel: Module.ButtonBlockModel,
blockView: Module.ButtonBlockView,
}); });
Module.ButtonBlockView = base.BlockView.extend({ App.registerWidget({
className: "mailpoet_block mailpoet_button_block mailpoet_droppable_block", name: 'button',
getTemplate: function() { return templates.buttonBlock; }, widgetView: Module.ButtonWidgetView,
modelEvents: { priority: 92,
'change': 'render',
},
onDragSubstituteBy: function() { return Module.ButtonWidgetView; },
initialize: function() {
base.BlockView.prototype.initialize.apply(this, arguments);
var that = this;
// Listen for attempts to change all dividers in one go
this._replaceButtonStylesHandler = function(data) { that.model.set(data); };
App.getChannel().on('replaceAllButtonStyles', this._replaceButtonStylesHandler);
},
onRender: function() {
this.toolsView = new Module.ButtonBlockToolsView({ model: this.model });
this.toolsRegion.show(this.toolsView);
},
});
Module.ButtonBlockToolsView = base.BlockToolsView.extend({
getSettingsView: function() { return Module.ButtonBlockSettingsView; },
});
Module.ButtonBlockSettingsView = base.BlockSettingsView.extend({
getTemplate: function() { return templates.buttonBlockSettings; },
events: function() {
return {
"keyup .mailpoet_field_button_text": _.partial(this.changeField, "text"),
"keyup .mailpoet_field_button_url": _.partial(this.changeField, "url"),
"change .mailpoet_field_button_alignment": _.partial(this.changeField, "styles.block.textAlign"),
"change .mailpoet_field_button_font_color": _.partial(this.changeColorField, "styles.block.fontColor"),
"change .mailpoet_field_button_font_family": _.partial(this.changeField, "styles.block.fontFamily"),
"change .mailpoet_field_button_font_size": _.partial(this.changeField, "styles.block.fontSize"),
"change .mailpoet_field_button_background_color": _.partial(this.changeColorField, "styles.block.backgroundColor"),
"change .mailpoet_field_button_border_color": _.partial(this.changeColorField, "styles.block.borderColor"),
"input .mailpoet_field_button_border_width": _.partial(this.updateValueAndCall, '.mailpoet_field_button_border_width_input', _.partial(this.changePixelField, "styles.block.borderWidth").bind(this)),
"change .mailpoet_field_button_border_width": _.partial(this.updateValueAndCall, '.mailpoet_field_button_border_width_input', _.partial(this.changePixelField, "styles.block.borderWidth").bind(this)),
"change .mailpoet_field_button_border_width_input": _.partial(this.updateValueAndCall, '.mailpoet_field_button_border_width', _.partial(this.changePixelField, "styles.block.borderWidth").bind(this)),
"keyup .mailpoet_field_button_border_width_input": _.partial(this.updateValueAndCall, '.mailpoet_field_button_border_width', _.partial(this.changePixelField, "styles.block.borderWidth").bind(this)),
"input .mailpoet_field_button_border_radius": _.partial(this.updateValueAndCall, '.mailpoet_field_button_border_radius_input', _.partial(this.changePixelField, "styles.block.borderRadius").bind(this)),
"change .mailpoet_field_button_border_radius": _.partial(this.updateValueAndCall, '.mailpoet_field_button_border_radius_input', _.partial(this.changePixelField, "styles.block.borderRadius").bind(this)),
"change .mailpoet_field_button_border_radius_input": _.partial(this.updateValueAndCall, '.mailpoet_field_button_border_radius', _.partial(this.changePixelField, "styles.block.borderRadius").bind(this)),
"keyup .mailpoet_field_button_border_radius_input": _.partial(this.updateValueAndCall, '.mailpoet_field_button_border_radius', _.partial(this.changePixelField, "styles.block.borderRadius").bind(this)),
"input .mailpoet_field_button_width": _.partial(this.updateValueAndCall, '.mailpoet_field_button_width_input', _.partial(this.changePixelField, "styles.block.width").bind(this)),
"change .mailpoet_field_button_width": _.partial(this.updateValueAndCall, '.mailpoet_field_button_width_input', _.partial(this.changePixelField, "styles.block.width").bind(this)),
"change .mailpoet_field_button_width_input": _.partial(this.updateValueAndCall, '.mailpoet_field_button_width', _.partial(this.changePixelField, "styles.block.width").bind(this)),
"keyup .mailpoet_field_button_width_input": _.partial(this.updateValueAndCall, '.mailpoet_field_button_width', _.partial(this.changePixelField, "styles.block.width").bind(this)),
"input .mailpoet_field_button_line_height": _.partial(this.updateValueAndCall, '.mailpoet_field_button_line_height_input', _.partial(this.changePixelField, "styles.block.lineHeight").bind(this)),
"change .mailpoet_field_button_line_height": _.partial(this.updateValueAndCall, '.mailpoet_field_button_line_height_input', _.partial(this.changePixelField, "styles.block.lineHeight").bind(this)),
"change .mailpoet_field_button_line_height_input": _.partial(this.updateValueAndCall, '.mailpoet_field_button_line_height', _.partial(this.changePixelField, "styles.block.lineHeight").bind(this)),
"keyup .mailpoet_field_button_line_height_input": _.partial(this.updateValueAndCall, '.mailpoet_field_button_line_height', _.partial(this.changePixelField, "styles.block.lineHeight").bind(this)),
"click .mailpoet_field_button_replace_all_styles": "applyToAll",
"click .mailpoet_done_editing": "close",
};
},
behaviors: {
ColorPickerBehavior: {},
},
initialize: function(params) {
var panelParams = {
element: this.$el,
template: '',
position: 'right',
width: App.getConfig().get('sidepanelWidth'),
};
this.renderOptions = params.renderOptions || {};
if (this.renderOptions.displayFormat === 'subpanel') {
MailPoet.Modal.subpanel(panelParams);
} else {
MailPoet.Modal.panel(panelParams);
}
},
templateHelpers: function() {
return {
model: this.model.toJSON(),
availableStyles: App.getAvailableStyles().toJSON(),
renderOptions: this.renderOptions,
};
},
applyToAll: function() {
App.getChannel().trigger('replaceAllButtonStyles', _.pick(this.model.toJSON(), 'styles', 'type'));
},
updateValueAndCall: function(fieldToUpdate, callable, event) {
this.$(fieldToUpdate).val(jQuery(event.target).val());
callable(event);
},
});
Module.ButtonWidgetView = base.WidgetView.extend({
getTemplate: function() { return templates.buttonInsertion; },
behaviors: {
DraggableBehavior: {
cloneOriginal: true,
drop: function() {
return new Module.ButtonBlockModel();
},
}
},
});
App.on('before:start', function() {
App.registerBlockType('button', {
blockModel: Module.ButtonBlockModel,
blockView: Module.ButtonBlockView,
});
App.registerWidget({
name: 'button',
widgetView: Module.ButtonWidgetView,
priority: 92,
});
}); });
});
}); });
}); });

View File

@ -11,338 +11,337 @@ define('newsletter_editor/blocks/container', [
], function(EditorApplication, Backbone, Marionette, MailPoet) { ], function(EditorApplication, Backbone, Marionette, MailPoet) {
EditorApplication.module("blocks.container", function(Module, App, Backbone, Marionette, $, _) { EditorApplication.module("blocks.container", function(Module, App, Backbone, Marionette, $, _) {
"use strict"; "use strict";
var base = App.module('blocks.base'), var base = App.module('blocks.base'),
BlockCollection; BlockCollection;
Module.ContainerBlockModel = base.BlockModel.extend({ Module.ContainerBlockModel = base.BlockModel.extend({
defaults: function() { defaults: function() {
return this._getDefaults({ return this._getDefaults({
type: 'container', type: 'container',
orientation: 'vertical', orientation: 'vertical',
styles: { styles: {
block: { block: {
backgroundColor: 'transparent', backgroundColor: 'transparent',
}, },
},
blocks: new BlockCollection(),
}, EditorApplication.getConfig().get('blockDefaults.container'));
}, },
parse: function(response) { blocks: new BlockCollection(),
// If container has any blocks - add them to a collection }, EditorApplication.getConfig().get('blockDefaults.container'));
if (response.type === 'container' && _.has(response, 'blocks')) { },
response.blocks = new BlockCollection(response.blocks, { parse: function(response) {
parse: true, // If container has any blocks - add them to a collection
}); if (response.type === 'container' && _.has(response, 'blocks')) {
} response.blocks = new BlockCollection(response.blocks, {
return response; parse: true,
},
validate: function() {
// Recursively propagate validation checks to blocks in the tree
var invalidBlock = this.get('blocks').find(function(block) { return !block.isValid(); });
if (invalidBlock) {
return invalidBlock.validationError;
}
},
});
BlockCollection = Backbone.Collection.extend({
model: base.BlockModel,
initialize: function() {
this.on('add change remove', function() { App.getChannel().trigger('autoSave'); });
},
parse: function(response) {
var self = this;
return _.map(response, function(block) {
var Type = App.getBlockTypeModel(block.type);
// TODO: If type has no registered model, use a backup one
return new Type(block, {parse: true});
});
},
});
Module.ContainerBlockView = Marionette.CompositeView.extend({
regionClass: Marionette.Region,
className: 'mailpoet_block mailpoet_container_block mailpoet_droppable_block mailpoet_droppable_layout_block',
getTemplate: function() { return templates.containerBlock; },
childViewContainer: '> .mailpoet_container',
getEmptyView: function() { return Module.ContainerBlockEmptyView; },
emptyViewOptions: function() { return { renderOptions: this.renderOptions }; },
modelEvents: {
'change': 'render'
},
events: {
"mouseenter": "showTools",
"mouseleave": "hideTools",
"click .mailpoet_newsletter_layer_selector": "toggleEditingLayer",
},
regions: {
toolsRegion: '> .mailpoet_tools',
},
ui: {
tools: '> .mailpoet_tools'
},
behaviors: {
ContainerDropZoneBehavior: {},
DraggableBehavior: {
cloneOriginal: true,
hideOriginal: true,
onDrop: function(options) {
// After a clone of model has been dropped, cleanup
// and destroy self
options.dragBehavior.view.model.destroy();
},
onDragSubstituteBy: function(behavior) {
var WidgetView, node;
// When block is being dragged, display the widget icon instead.
// This will create an instance of block's widget view and
// use it's rendered DOM element instead of the content block
if (_.isFunction(behavior.view.onDragSubstituteBy)) {
WidgetView = new (behavior.view.onDragSubstituteBy())();
WidgetView.render();
node = WidgetView.$el.get(0).cloneNode(true);
WidgetView.destroy();
return node;
}
},
testAttachToInstance: function(model, view) {
// Attach Draggable only to layout containers and disable it
// for root and column containers.
return view.renderOptions.depth === 1;
},
},
},
onDragSubstituteBy: function() {
// For two and three column layouts display their respective widgets,
// otherwise always default to one column layout widget
if (this.renderOptions.depth === 1) {
if (this.model.get('blocks').length === 3) return Module.ThreeColumnContainerWidgetView;
if (this.model.get('blocks').length === 2) return Module.TwoColumnContainerWidgetView;
}
return Module.OneColumnContainerWidgetView;
},
constructor: function() {
// Set the block collection to be handled by this view as well
arguments[0].collection = arguments[0].model.get('blocks');
Marionette.CompositeView.apply(this, arguments);
this.$el.addClass('mailpoet_editor_view_' + this.cid);
},
initialize: function(options) {
this.renderOptions = _.defaults(options.renderOptions || {}, {});
},
// Determines which view type should be used for a child
getChildView: function(model) {
// TODO: If type does not have a type registered, use a generic one
return App.getBlockTypeView(model.get('type'));
},
childViewOptions: function() {
var newRenderOptions = _.clone(this.renderOptions);
if (newRenderOptions.depth !== undefined) {
newRenderOptions.depth += 1;
}
return {
renderOptions: newRenderOptions
};
},
templateHelpers: function() {
return {
model: this.model.toJSON(),
viewCid: this.cid,
};
},
onRender: function() {
this._rebuildRegions();
this.toolsView = new Module.ContainerBlockToolsView({
model: this.model,
tools: {
settings: this.renderOptions.depth > 1,
delete: this.renderOptions.depth === 1,
move: this.renderOptions.depth === 1,
layerSelector: this.renderOptions.depth === 1,
},
});
this.toolsRegion.show(this.toolsView);
},
onBeforeDestroy: function() {
this.regionManager.destroy();
},
showTools: function() {
if (this.renderOptions.depth === 1 && !this.$el.hasClass('mailpoet_container_layer_active')) {
this.$(this.ui.tools).show();
this.toolsView.triggerMethod('showTools');
}
},
hideTools: function() {
if (this.renderOptions.depth === 1 && !this.$el.hasClass('mailpoet_container_layer_active')) {
this.$(this.ui.tools).hide();
this.toolsView.triggerMethod('hideTools');
}
},
toggleEditingLayer: function(event) {
var that = this,
$toggleButton = this.$('> .mailpoet_tools .mailpoet_newsletter_layer_selector'),
$overlay = jQuery('.mailpoet_layer_overlay'),
$container = this.$('> .mailpoet_container'),
enableContainerLayer = function() {
that.$el.addClass('mailpoet_container_layer_active');
$toggleButton.addClass('mailpoet_container_layer_active');
$container.addClass('mailpoet_layer_highlight');
$overlay.click(disableContainerLayer);
$overlay.show();
},
disableContainerLayer = function() {
that.$el.removeClass('mailpoet_container_layer_active');
$toggleButton.removeClass('mailpoet_container_layer_active');
$container.removeClass('mailpoet_layer_highlight');
$overlay.hide();
$overlay.off('click');
};
if ($toggleButton.hasClass('mailpoet_container_layer_active')) {
disableContainerLayer();
} else {
enableContainerLayer();
}
event.stopPropagation();
},
_buildRegions: function(regions) {
var that = this;
var defaults = {
regionClass: this.getOption('regionClass'),
parentEl: function() { return that.$el; }
};
return this.regionManager.addRegions(regions, defaults);
},
_rebuildRegions: function() {
if (this.regionManager === undefined) {
this.regionManager = new Backbone.Marionette.RegionManager();
}
this.regionManager.destroy();
_.extend(this, this._buildRegions(this.regions));
},
getDropFunc: function() {
var that = this;
return function() {
var newModel = that.model.clone();
that.model.destroy();
return newModel;
};
},
});
Module.ContainerBlockEmptyView = Marionette.ItemView.extend({
getTemplate: function() { return templates.containerEmpty; },
initialize: function(options) {
this.renderOptions = _.defaults(options.renderOptions || {}, {});
},
templateHelpers: function() {
return {
isRoot: this.renderOptions.depth === 0,
};
},
});
Module.ContainerBlockToolsView = base.BlockToolsView.extend({
getSettingsView: function() { return Module.ContainerBlockSettingsView; },
});
Module.ContainerBlockSettingsView = base.BlockSettingsView.extend({
getTemplate: function() { return templates.containerBlockSettings; },
events: function() {
return {
"change .mailpoet_field_container_background_color": _.partial(this.changeColorField, "styles.block.backgroundColor"),
"click .mailpoet_done_editing": "close",
};
},
behaviors: {
ColorPickerBehavior: {},
},
});
Module.OneColumnContainerWidgetView = base.WidgetView.extend({
className: base.WidgetView.prototype.className + ' mailpoet_droppable_layout_block',
getTemplate: function() { return templates.oneColumnLayoutInsertion; },
behaviors: {
DraggableBehavior: {
cloneOriginal: true,
drop: function() {
return new Module.ContainerBlockModel({
orientation: 'horizontal',
blocks: [
new Module.ContainerBlockModel(),
]
});
}
}
},
});
Module.TwoColumnContainerWidgetView = base.WidgetView.extend({
className: base.WidgetView.prototype.className + ' mailpoet_droppable_layout_block',
getTemplate: function() { return templates.twoColumnLayoutInsertion; },
behaviors: {
DraggableBehavior: {
cloneOriginal: true,
drop: function() {
return new Module.ContainerBlockModel({
orientation: 'horizontal',
blocks: [
new Module.ContainerBlockModel(),
new Module.ContainerBlockModel(),
]
});
}
}
},
});
Module.ThreeColumnContainerWidgetView = base.WidgetView.extend({
className: base.WidgetView.prototype.className + ' mailpoet_droppable_layout_block',
getTemplate: function() { return templates.threeColumnLayoutInsertion; },
behaviors: {
DraggableBehavior: {
cloneOriginal: true,
drop: function() {
return new Module.ContainerBlockModel({
orientation: 'horizontal',
blocks: [
new Module.ContainerBlockModel(),
new Module.ContainerBlockModel(),
new Module.ContainerBlockModel(),
]
});
}
}
},
});
App.on('before:start', function() {
App.registerBlockType('container', {
blockModel: Module.ContainerBlockModel,
blockView: Module.ContainerBlockView,
}); });
}
return response;
},
validate: function() {
// Recursively propagate validation checks to blocks in the tree
var invalidBlock = this.get('blocks').find(function(block) { return !block.isValid(); });
if (invalidBlock) {
return invalidBlock.validationError;
}
},
});
App.registerLayoutWidget({ BlockCollection = Backbone.Collection.extend({
name: 'oneColumnLayout', model: base.BlockModel,
priority: 100, initialize: function() {
widgetView: Module.OneColumnContainerWidgetView, this.on('add change remove', function() { App.getChannel().trigger('autoSave'); });
}); },
parse: function(response) {
var self = this;
return _.map(response, function(block) {
var Type = App.getBlockTypeModel(block.type);
// TODO: If type has no registered model, use a backup one
return new Type(block, {parse: true});
});
},
});
App.registerLayoutWidget({ Module.ContainerBlockView = Marionette.CompositeView.extend({
name: 'twoColumnLayout', regionClass: Marionette.Region,
priority: 100, className: 'mailpoet_block mailpoet_container_block mailpoet_droppable_block mailpoet_droppable_layout_block',
widgetView: Module.TwoColumnContainerWidgetView, getTemplate: function() { return templates.containerBlock; },
}); childViewContainer: '> .mailpoet_container',
getEmptyView: function() { return Module.ContainerBlockEmptyView; },
emptyViewOptions: function() { return { renderOptions: this.renderOptions }; },
modelEvents: {
'change': 'render'
},
events: {
"mouseenter": "showTools",
"mouseleave": "hideTools",
"click .mailpoet_newsletter_layer_selector": "toggleEditingLayer",
},
regions: {
toolsRegion: '> .mailpoet_tools',
},
ui: {
tools: '> .mailpoet_tools'
},
behaviors: {
ContainerDropZoneBehavior: {},
DraggableBehavior: {
cloneOriginal: true,
hideOriginal: true,
onDrop: function(options) {
// After a clone of model has been dropped, cleanup
// and destroy self
options.dragBehavior.view.model.destroy();
},
onDragSubstituteBy: function(behavior) {
var WidgetView, node;
// When block is being dragged, display the widget icon instead.
// This will create an instance of block's widget view and
// use it's rendered DOM element instead of the content block
if (_.isFunction(behavior.view.onDragSubstituteBy)) {
WidgetView = new (behavior.view.onDragSubstituteBy())();
WidgetView.render();
node = WidgetView.$el.get(0).cloneNode(true);
WidgetView.destroy();
return node;
}
},
testAttachToInstance: function(model, view) {
// Attach Draggable only to layout containers and disable it
// for root and column containers.
return view.renderOptions.depth === 1;
},
},
},
onDragSubstituteBy: function() {
// For two and three column layouts display their respective widgets,
// otherwise always default to one column layout widget
if (this.renderOptions.depth === 1) {
if (this.model.get('blocks').length === 3) return Module.ThreeColumnContainerWidgetView;
if (this.model.get('blocks').length === 2) return Module.TwoColumnContainerWidgetView;
}
return Module.OneColumnContainerWidgetView;
App.registerLayoutWidget({ },
name: 'threeColumnLayout', constructor: function() {
priority: 100, // Set the block collection to be handled by this view as well
widgetView: Module.ThreeColumnContainerWidgetView, arguments[0].collection = arguments[0].model.get('blocks');
}); Marionette.CompositeView.apply(this, arguments);
this.$el.addClass('mailpoet_editor_view_' + this.cid);
},
initialize: function(options) {
this.renderOptions = _.defaults(options.renderOptions || {}, {});
},
// Determines which view type should be used for a child
getChildView: function(model) {
// TODO: If type does not have a type registered, use a generic one
return App.getBlockTypeView(model.get('type'));
},
childViewOptions: function() {
var newRenderOptions = _.clone(this.renderOptions);
if (newRenderOptions.depth !== undefined) {
newRenderOptions.depth += 1;
}
return {
renderOptions: newRenderOptions
};
},
templateHelpers: function() {
return {
model: this.model.toJSON(),
viewCid: this.cid,
};
},
onRender: function() {
this._rebuildRegions();
this.toolsView = new Module.ContainerBlockToolsView({
model: this.model,
tools: {
settings: this.renderOptions.depth > 1,
delete: this.renderOptions.depth === 1,
move: this.renderOptions.depth === 1,
layerSelector: this.renderOptions.depth === 1,
},
});
this.toolsRegion.show(this.toolsView);
},
onBeforeDestroy: function() {
this.regionManager.destroy();
},
showTools: function() {
if (this.renderOptions.depth === 1 && !this.$el.hasClass('mailpoet_container_layer_active')) {
this.$(this.ui.tools).show();
this.toolsView.triggerMethod('showTools');
}
},
hideTools: function() {
if (this.renderOptions.depth === 1 && !this.$el.hasClass('mailpoet_container_layer_active')) {
this.$(this.ui.tools).hide();
this.toolsView.triggerMethod('hideTools');
}
},
toggleEditingLayer: function(event) {
var that = this,
$toggleButton = this.$('> .mailpoet_tools .mailpoet_newsletter_layer_selector'),
$overlay = jQuery('.mailpoet_layer_overlay'),
$container = this.$('> .mailpoet_container'),
enableContainerLayer = function() {
that.$el.addClass('mailpoet_container_layer_active');
$toggleButton.addClass('mailpoet_container_layer_active');
$container.addClass('mailpoet_layer_highlight');
$overlay.click(disableContainerLayer);
$overlay.show();
},
disableContainerLayer = function() {
that.$el.removeClass('mailpoet_container_layer_active');
$toggleButton.removeClass('mailpoet_container_layer_active');
$container.removeClass('mailpoet_layer_highlight');
$overlay.hide();
$overlay.off('click');
};
if ($toggleButton.hasClass('mailpoet_container_layer_active')) {
disableContainerLayer();
} else {
enableContainerLayer();
}
event.stopPropagation();
},
_buildRegions: function(regions) {
var that = this;
var defaults = {
regionClass: this.getOption('regionClass'),
parentEl: function() { return that.$el; }
};
return this.regionManager.addRegions(regions, defaults);
},
_rebuildRegions: function() {
if (this.regionManager === undefined) {
this.regionManager = new Backbone.Marionette.RegionManager();
}
this.regionManager.destroy();
_.extend(this, this._buildRegions(this.regions));
},
getDropFunc: function() {
var that = this;
return function() {
var newModel = that.model.clone();
that.model.destroy();
return newModel;
};
},
});
Module.ContainerBlockEmptyView = Marionette.ItemView.extend({
getTemplate: function() { return templates.containerEmpty; },
initialize: function(options) {
this.renderOptions = _.defaults(options.renderOptions || {}, {});
},
templateHelpers: function() {
return {
isRoot: this.renderOptions.depth === 0,
};
},
});
Module.ContainerBlockToolsView = base.BlockToolsView.extend({
getSettingsView: function() { return Module.ContainerBlockSettingsView; },
});
Module.ContainerBlockSettingsView = base.BlockSettingsView.extend({
getTemplate: function() { return templates.containerBlockSettings; },
events: function() {
return {
"change .mailpoet_field_container_background_color": _.partial(this.changeColorField, "styles.block.backgroundColor"),
"click .mailpoet_done_editing": "close",
};
},
behaviors: {
ColorPickerBehavior: {},
},
});
Module.OneColumnContainerWidgetView = base.WidgetView.extend({
className: base.WidgetView.prototype.className + ' mailpoet_droppable_layout_block',
getTemplate: function() { return templates.oneColumnLayoutInsertion; },
behaviors: {
DraggableBehavior: {
cloneOriginal: true,
drop: function() {
return new Module.ContainerBlockModel({
orientation: 'horizontal',
blocks: [
new Module.ContainerBlockModel(),
]
});
}
}
},
});
Module.TwoColumnContainerWidgetView = base.WidgetView.extend({
className: base.WidgetView.prototype.className + ' mailpoet_droppable_layout_block',
getTemplate: function() { return templates.twoColumnLayoutInsertion; },
behaviors: {
DraggableBehavior: {
cloneOriginal: true,
drop: function() {
return new Module.ContainerBlockModel({
orientation: 'horizontal',
blocks: [
new Module.ContainerBlockModel(),
new Module.ContainerBlockModel(),
]
});
}
}
},
});
Module.ThreeColumnContainerWidgetView = base.WidgetView.extend({
className: base.WidgetView.prototype.className + ' mailpoet_droppable_layout_block',
getTemplate: function() { return templates.threeColumnLayoutInsertion; },
behaviors: {
DraggableBehavior: {
cloneOriginal: true,
drop: function() {
return new Module.ContainerBlockModel({
orientation: 'horizontal',
blocks: [
new Module.ContainerBlockModel(),
new Module.ContainerBlockModel(),
new Module.ContainerBlockModel(),
]
});
}
}
},
});
App.on('before:start', function() {
App.registerBlockType('container', {
blockModel: Module.ContainerBlockModel,
blockView: Module.ContainerBlockView,
}); });
App.registerLayoutWidget({
name: 'oneColumnLayout',
priority: 100,
widgetView: Module.OneColumnContainerWidgetView,
});
App.registerLayoutWidget({
name: 'twoColumnLayout',
priority: 100,
widgetView: Module.TwoColumnContainerWidgetView,
});
App.registerLayoutWidget({
name: 'threeColumnLayout',
priority: 100,
widgetView: Module.ThreeColumnContainerWidgetView,
});
});
}); });
}); });

View File

@ -9,165 +9,164 @@ define('newsletter_editor/blocks/divider', [
], function(EditorApplication, Backbone, Marionette, MailPoet) { ], function(EditorApplication, Backbone, Marionette, MailPoet) {
EditorApplication.module("blocks.divider", function(Module, App, Backbone, Marionette, $, _) { EditorApplication.module("blocks.divider", function(Module, App, Backbone, Marionette, $, _) {
"use strict"; "use strict";
var base = App.module('blocks.base'); var base = App.module('blocks.base');
Module.DividerBlockModel = base.BlockModel.extend({ Module.DividerBlockModel = base.BlockModel.extend({
defaults: function() { defaults: function() {
return this._getDefaults({ return this._getDefaults({
type: 'divider', type: 'divider',
styles: { styles: {
block: { block: {
backgroundColor: 'transparent', backgroundColor: 'transparent',
padding: '12px', padding: '12px',
borderStyle: 'solid', borderStyle: 'solid',
borderWidth: '1px', borderWidth: '1px',
borderColor: '#000000', borderColor: '#000000',
}, },
},
}, EditorApplication.getConfig().get('blockDefaults.divider'));
}, },
}, EditorApplication.getConfig().get('blockDefaults.divider'));
},
});
Module.DividerBlockView = base.BlockView.extend({
className: "mailpoet_block mailpoet_divider_block mailpoet_droppable_block",
getTemplate: function() { return templates.dividerBlock; },
modelEvents: _.omit(base.BlockView.prototype.modelEvents, 'change'),
behaviors: _.defaults({
ResizableBehavior: {
elementSelector: '.mailpoet_content',
resizeHandleSelector: '.mailpoet_resize_handle',
transformationFunction: function(y) { return y / 2; },
minLength: 0, // TODO: Move this number to editor configuration
modelField: 'styles.block.padding',
},
}, base.BlockView.prototype.behaviors),
onDragSubstituteBy: function() { return Module.DividerWidgetView; },
initialize: function() {
base.BlockView.prototype.initialize.apply(this, arguments);
var that = this;
// Listen for attempts to change all dividers in one go
this._replaceDividerHandler = function(data) { that.model.set(data); that.model.trigger('applyToAll'); };
App.getChannel().on('replaceAllDividers', this._replaceDividerHandler);
this.listenTo(this.model, 'change:src change:styles.block.backgroundColor change:styles.block.borderStyle change:styles.block.borderWidth change:styles.block.borderColor applyToAll', this.render);
this.listenTo(this.model, 'change:styles.block.padding', this.changePadding);
},
templateHelpers: function() {
return {
model: this.model.toJSON(),
viewCid: this.cid,
totalHeight: parseInt(this.model.get('styles.block.padding'), 10)*2 + parseInt(this.model.get('styles.block.borderWidth')) + 'px',
};
},
onRender: function() {
this.toolsView = new Module.DividerBlockToolsView({ model: this.model });
this.toolsRegion.show(this.toolsView);
},
onBeforeDestroy: function() {
App.getChannel().off('replaceAllDividers', this._replaceDividerHandler);
this.stopListening(this.model);
},
changePadding: function() {
this.$('.mailpoet_content').css('padding-top', this.model.get('styles.block.padding'));
this.$('.mailpoet_content').css('padding-bottom', this.model.get('styles.block.padding'));
this.$('.mailpoet_resize_handle_text').text(parseInt(this.model.get('styles.block.padding'), 10)*2 + parseInt(this.model.get('styles.block.borderWidth')) + 'px');
},
});
Module.DividerBlockToolsView = base.BlockToolsView.extend({
getSettingsView: function() { return Module.DividerBlockSettingsView; },
});
Module.DividerBlockSettingsView = base.BlockSettingsView.extend({
getTemplate: function() { return templates.dividerBlockSettings; },
events: function() {
return {
"click .mailpoet_field_divider_style": 'changeStyle',
"input .mailpoet_field_divider_border_width": _.partial(this.updateValueAndCall, '.mailpoet_field_divider_border_width_input', _.partial(this.changePixelField, "styles.block.borderWidth").bind(this)),
"change .mailpoet_field_divider_border_width": _.partial(this.updateValueAndCall, '.mailpoet_field_divider_border_width_input', _.partial(this.changePixelField, "styles.block.borderWidth").bind(this)),
"change .mailpoet_field_divider_border_width_input": _.partial(this.updateValueAndCall, '.mailpoet_field_divider_border_width', _.partial(this.changePixelField, "styles.block.borderWidth").bind(this)),
"keyup .mailpoet_field_divider_border_width_input": _.partial(this.updateValueAndCall, '.mailpoet_field_divider_border_width', _.partial(this.changePixelField, "styles.block.borderWidth").bind(this)),
"change .mailpoet_field_divider_border_color": _.partial(this.changeColorField, "styles.block.borderColor"),
"change .mailpoet_field_divider_background_color": _.partial(this.changeColorField, "styles.block.backgroundColor"),
"click .mailpoet_button_divider_apply_to_all": "applyToAll",
"click .mailpoet_done_editing": "close",
};
},
modelEvents: function() {
return {
'change:styles.block.borderColor': 'repaintDividerStyleOptions',
};
},
behaviors: {
ColorPickerBehavior: {},
},
initialize: function(params) {
var panelParams = {
element: this.$el,
template: '',
position: 'right',
width: App.getConfig().get('sidepanelWidth'),
};
this.renderOptions = params.renderOptions || {};
if (this.renderOptions.displayFormat === 'subpanel') {
MailPoet.Modal.subpanel(panelParams);
} else {
MailPoet.Modal.panel(panelParams);
}
},
templateHelpers: function() {
return {
model: this.model.toJSON(),
availableStyles: App.getAvailableStyles().toJSON(),
renderOptions: this.renderOptions,
};
},
changeStyle: function(event) {
var style = jQuery(event.currentTarget).data('style');
this.model.set('styles.block.borderStyle', style);
this.$('.mailpoet_field_divider_style').removeClass('mailpoet_active_divider_style');
this.$('.mailpoet_field_divider_style[data-style="' + style + '"]').addClass('mailpoet_active_divider_style');
},
repaintDividerStyleOptions: function() {
this.$('.mailpoet_field_divider_style > div').css('border-top-color', this.model.get('styles.block.borderColor'));
},
applyToAll: function(event) {
App.getChannel().trigger('replaceAllDividers', this.model.toJSON());
},
updateValueAndCall: function(fieldToUpdate, callable, event) {
this.$(fieldToUpdate).val(jQuery(event.target).val());
callable(event);
},
});
Module.DividerWidgetView = base.WidgetView.extend({
getTemplate: function() { return templates.dividerInsertion; },
behaviors: {
DraggableBehavior: {
cloneOriginal: true,
drop: function() {
return new Module.DividerBlockModel();
},
}
},
});
App.on('before:start', function() {
App.registerBlockType('divider', {
blockModel: Module.DividerBlockModel,
blockView: Module.DividerBlockView,
}); });
Module.DividerBlockView = base.BlockView.extend({ App.registerWidget({
className: "mailpoet_block mailpoet_divider_block mailpoet_droppable_block", name: 'divider',
getTemplate: function() { return templates.dividerBlock; }, widgetView: Module.DividerWidgetView,
modelEvents: _.omit(base.BlockView.prototype.modelEvents, 'change'), priority: 93,
behaviors: _.defaults({
ResizableBehavior: {
elementSelector: '.mailpoet_content',
resizeHandleSelector: '.mailpoet_resize_handle',
transformationFunction: function(y) { return y / 2; },
minLength: 0, // TODO: Move this number to editor configuration
modelField: 'styles.block.padding',
},
}, base.BlockView.prototype.behaviors),
onDragSubstituteBy: function() { return Module.DividerWidgetView; },
initialize: function() {
base.BlockView.prototype.initialize.apply(this, arguments);
var that = this;
// Listen for attempts to change all dividers in one go
this._replaceDividerHandler = function(data) { that.model.set(data); that.model.trigger('applyToAll'); };
App.getChannel().on('replaceAllDividers', this._replaceDividerHandler);
this.listenTo(this.model, 'change:src change:styles.block.backgroundColor change:styles.block.borderStyle change:styles.block.borderWidth change:styles.block.borderColor applyToAll', this.render);
this.listenTo(this.model, 'change:styles.block.padding', this.changePadding);
},
templateHelpers: function() {
return {
model: this.model.toJSON(),
viewCid: this.cid,
totalHeight: parseInt(this.model.get('styles.block.padding'), 10)*2 + parseInt(this.model.get('styles.block.borderWidth')) + 'px',
};
},
onRender: function() {
this.toolsView = new Module.DividerBlockToolsView({ model: this.model });
this.toolsRegion.show(this.toolsView);
},
onBeforeDestroy: function() {
App.getChannel().off('replaceAllDividers', this._replaceDividerHandler);
this.stopListening(this.model);
},
changePadding: function() {
this.$('.mailpoet_content').css('padding-top', this.model.get('styles.block.padding'));
this.$('.mailpoet_content').css('padding-bottom', this.model.get('styles.block.padding'));
this.$('.mailpoet_resize_handle_text').text(parseInt(this.model.get('styles.block.padding'), 10)*2 + parseInt(this.model.get('styles.block.borderWidth')) + 'px');
},
});
Module.DividerBlockToolsView = base.BlockToolsView.extend({
getSettingsView: function() { return Module.DividerBlockSettingsView; },
});
Module.DividerBlockSettingsView = base.BlockSettingsView.extend({
getTemplate: function() { return templates.dividerBlockSettings; },
events: function() {
return {
"click .mailpoet_field_divider_style": 'changeStyle',
"input .mailpoet_field_divider_border_width": _.partial(this.updateValueAndCall, '.mailpoet_field_divider_border_width_input', _.partial(this.changePixelField, "styles.block.borderWidth").bind(this)),
"change .mailpoet_field_divider_border_width": _.partial(this.updateValueAndCall, '.mailpoet_field_divider_border_width_input', _.partial(this.changePixelField, "styles.block.borderWidth").bind(this)),
"change .mailpoet_field_divider_border_width_input": _.partial(this.updateValueAndCall, '.mailpoet_field_divider_border_width', _.partial(this.changePixelField, "styles.block.borderWidth").bind(this)),
"keyup .mailpoet_field_divider_border_width_input": _.partial(this.updateValueAndCall, '.mailpoet_field_divider_border_width', _.partial(this.changePixelField, "styles.block.borderWidth").bind(this)),
"change .mailpoet_field_divider_border_color": _.partial(this.changeColorField, "styles.block.borderColor"),
"change .mailpoet_field_divider_background_color": _.partial(this.changeColorField, "styles.block.backgroundColor"),
"click .mailpoet_button_divider_apply_to_all": "applyToAll",
"click .mailpoet_done_editing": "close",
};
},
modelEvents: function() {
return {
'change:styles.block.borderColor': 'repaintDividerStyleOptions',
};
},
behaviors: {
ColorPickerBehavior: {},
},
initialize: function(params) {
var panelParams = {
element: this.$el,
template: '',
position: 'right',
width: App.getConfig().get('sidepanelWidth'),
};
this.renderOptions = params.renderOptions || {};
if (this.renderOptions.displayFormat === 'subpanel') {
MailPoet.Modal.subpanel(panelParams);
} else {
MailPoet.Modal.panel(panelParams);
}
},
templateHelpers: function() {
return {
model: this.model.toJSON(),
availableStyles: App.getAvailableStyles().toJSON(),
renderOptions: this.renderOptions,
};
},
changeStyle: function(event) {
var style = jQuery(event.currentTarget).data('style');
this.model.set('styles.block.borderStyle', style);
this.$('.mailpoet_field_divider_style').removeClass('mailpoet_active_divider_style');
this.$('.mailpoet_field_divider_style[data-style="' + style + '"]').addClass('mailpoet_active_divider_style');
},
repaintDividerStyleOptions: function() {
this.$('.mailpoet_field_divider_style > div').css('border-top-color', this.model.get('styles.block.borderColor'));
},
applyToAll: function(event) {
App.getChannel().trigger('replaceAllDividers', this.model.toJSON());
},
updateValueAndCall: function(fieldToUpdate, callable, event) {
this.$(fieldToUpdate).val(jQuery(event.target).val());
callable(event);
},
});
Module.DividerWidgetView = base.WidgetView.extend({
getTemplate: function() { return templates.dividerInsertion; },
behaviors: {
DraggableBehavior: {
cloneOriginal: true,
drop: function() {
return new Module.DividerBlockModel();
},
}
},
});
App.on('before:start', function() {
App.registerBlockType('divider', {
blockModel: Module.DividerBlockModel,
blockView: Module.DividerBlockView,
});
App.registerWidget({
name: 'divider',
widgetView: Module.DividerWidgetView,
priority: 93,
});
}); });
});
}); });
}); });

View File

@ -9,139 +9,138 @@ define('newsletter_editor/blocks/footer', [
], function(EditorApplication, Backbone, Marionette, MailPoet) { ], function(EditorApplication, Backbone, Marionette, MailPoet) {
EditorApplication.module("blocks.footer", function(Module, App, Backbone, Marionette, $, _) { EditorApplication.module("blocks.footer", function(Module, App, Backbone, Marionette, $, _) {
"use strict"; "use strict";
var base = App.module('blocks.base'); var base = App.module('blocks.base');
Module.FooterBlockModel = base.BlockModel.extend({ Module.FooterBlockModel = base.BlockModel.extend({
defaults: function() { defaults: function() {
return this._getDefaults({ return this._getDefaults({
type: 'footer', type: 'footer',
text: '<a href="[unsubscribeUrl]">Unsubscribe</a> | <a href="[manageSubscriptionUrl]">Manage subscription</a><br /><b>Add your postal address here!</b>', text: '<a href="[unsubscribeUrl]">Unsubscribe</a> | <a href="[manageSubscriptionUrl]">Manage subscription</a><br /><b>Add your postal address here!</b>',
styles: { styles: {
block: { block: {
backgroundColor: 'transparent', backgroundColor: 'transparent',
}, },
text: { text: {
fontColor: '#000000', fontColor: '#000000',
fontFamily: 'Arial', fontFamily: 'Arial',
fontSize: '12px', fontSize: '12px',
textAlign: 'center', textAlign: 'center',
}, },
link: { link: {
fontColor: '#0000ff', fontColor: '#0000ff',
textDecoration: 'none', textDecoration: 'none',
}, },
},
}, EditorApplication.getConfig().get('blockDefaults.footer'));
}, },
}, EditorApplication.getConfig().get('blockDefaults.footer'));
},
});
Module.FooterBlockView = base.BlockView.extend({
className: "mailpoet_block mailpoet_footer_block mailpoet_droppable_block",
getTemplate: function() { return templates.footerBlock; },
modelEvents: {
'change:styles.block.backgroundColor change:styles.text.fontColor change:styles.text.fontFamily change:styles.text.fontSize change:styles.text.textAlign change:styles.link.fontColor change:styles.link.textDecoration': 'render',
},
onDragSubstituteBy: function() { return Module.FooterWidgetView; },
onRender: function() {
this.toolsView = new Module.FooterBlockToolsView({ model: this.model });
this.toolsRegion.show(this.toolsView);
},
onDomRefresh: function() {
this.attachTextEditor();
},
attachTextEditor: function() {
var that = this;
this.$('.mailpoet_content').tinymce({
inline: true,
menubar: false,
toolbar: "bold italic link unlink forecolor mailpoet_custom_fields",
valid_elements: "p[class|style],span[class|style],a[href|class|title|target|style],strong[class|style],em[class|style],strike,br",
invalid_elements: "script",
style_formats: [
{title: 'Paragraph', block: 'p'},
],
plugins: "wplink textcolor mailpoet_custom_fields",
setup: function(editor) {
editor.on('change', function(e) {
that.model.set('text', editor.getContent());
});
editor.on('focus', function(e) {
that.disableShowingTools();
});
editor.on('blur', function(e) {
that.enableShowingTools();
});
},
mailpoet_custom_fields: App.getConfig().get('customFields').toJSON(),
mailpoet_custom_fields_window_title: App.getConfig().get('translations.customFieldsWindowTitle'),
});
},
});
Module.FooterBlockToolsView = base.BlockToolsView.extend({
getSettingsView: function() { return Module.FooterBlockSettingsView; },
});
Module.FooterBlockSettingsView = base.BlockSettingsView.extend({
getTemplate: function() { return templates.footerBlockSettings; },
events: function() {
return {
"change .mailpoet_field_footer_text_color": _.partial(this.changeColorField, "styles.text.fontColor"),
"change .mailpoet_field_footer_text_font_family": _.partial(this.changeField, "styles.text.fontFamily"),
"change .mailpoet_field_footer_text_size": _.partial(this.changeField, "styles.text.fontSize"),
"change #mailpoet_field_footer_link_color": _.partial(this.changeColorField, "styles.link.fontColor"),
"change #mailpoet_field_footer_link_underline": function(event) {
this.model.set('styles.link.textDecoration', (event.target.checked) ? event.target.value : 'none');
},
"change .mailpoet_field_footer_background_color": _.partial(this.changeColorField, "styles.block.backgroundColor"),
"change .mailpoet_field_footer_alignment": _.partial(this.changeField, "styles.text.textAlign"),
"click .mailpoet_done_editing": "close",
};
},
behaviors: {
ColorPickerBehavior: {},
},
templateHelpers: function() {
return {
model: this.model.toJSON(),
availableStyles: App.getAvailableStyles().toJSON(),
};
},
});
Module.FooterWidgetView = base.WidgetView.extend({
getTemplate: function() { return templates.footerInsertion; },
behaviors: {
DraggableBehavior: {
cloneOriginal: true,
drop: function() {
return new Module.FooterBlockModel();
},
}
},
});
App.on('before:start', function() {
App.registerBlockType('footer', {
blockModel: Module.FooterBlockModel,
blockView: Module.FooterBlockView,
}); });
Module.FooterBlockView = base.BlockView.extend({ App.registerWidget({
className: "mailpoet_block mailpoet_footer_block mailpoet_droppable_block", name: 'footer',
getTemplate: function() { return templates.footerBlock; }, widgetView: Module.FooterWidgetView,
modelEvents: { priority: 99,
'change:styles.block.backgroundColor change:styles.text.fontColor change:styles.text.fontFamily change:styles.text.fontSize change:styles.text.textAlign change:styles.link.fontColor change:styles.link.textDecoration': 'render',
},
onDragSubstituteBy: function() { return Module.FooterWidgetView; },
onRender: function() {
this.toolsView = new Module.FooterBlockToolsView({ model: this.model });
this.toolsRegion.show(this.toolsView);
},
onDomRefresh: function() {
this.attachTextEditor();
},
attachTextEditor: function() {
var that = this;
this.$('.mailpoet_content').tinymce({
inline: true,
menubar: false,
toolbar: "bold italic link unlink forecolor mailpoet_custom_fields",
valid_elements: "p[class|style],span[class|style],a[href|class|title|target|style],strong[class|style],em[class|style],strike,br",
invalid_elements: "script",
style_formats: [
{title: 'Paragraph', block: 'p'},
],
plugins: "wplink textcolor mailpoet_custom_fields",
setup: function(editor) {
editor.on('change', function(e) {
that.model.set('text', editor.getContent());
});
editor.on('focus', function(e) {
that.disableShowingTools();
});
editor.on('blur', function(e) {
that.enableShowingTools();
});
},
mailpoet_custom_fields: App.getConfig().get('customFields').toJSON(),
mailpoet_custom_fields_window_title: App.getConfig().get('translations.customFieldsWindowTitle'),
});
},
});
Module.FooterBlockToolsView = base.BlockToolsView.extend({
getSettingsView: function() { return Module.FooterBlockSettingsView; },
});
Module.FooterBlockSettingsView = base.BlockSettingsView.extend({
getTemplate: function() { return templates.footerBlockSettings; },
events: function() {
return {
"change .mailpoet_field_footer_text_color": _.partial(this.changeColorField, "styles.text.fontColor"),
"change .mailpoet_field_footer_text_font_family": _.partial(this.changeField, "styles.text.fontFamily"),
"change .mailpoet_field_footer_text_size": _.partial(this.changeField, "styles.text.fontSize"),
"change #mailpoet_field_footer_link_color": _.partial(this.changeColorField, "styles.link.fontColor"),
"change #mailpoet_field_footer_link_underline": function(event) {
this.model.set('styles.link.textDecoration', (event.target.checked) ? event.target.value : 'none');
},
"change .mailpoet_field_footer_background_color": _.partial(this.changeColorField, "styles.block.backgroundColor"),
"change .mailpoet_field_footer_alignment": _.partial(this.changeField, "styles.text.textAlign"),
"click .mailpoet_done_editing": "close",
};
},
behaviors: {
ColorPickerBehavior: {},
},
templateHelpers: function() {
return {
model: this.model.toJSON(),
availableStyles: App.getAvailableStyles().toJSON(),
};
},
});
Module.FooterWidgetView = base.WidgetView.extend({
getTemplate: function() { return templates.footerInsertion; },
behaviors: {
DraggableBehavior: {
cloneOriginal: true,
drop: function() {
return new Module.FooterBlockModel();
},
}
},
});
App.on('before:start', function() {
App.registerBlockType('footer', {
blockModel: Module.FooterBlockModel,
blockView: Module.FooterBlockView,
});
App.registerWidget({
name: 'footer',
widgetView: Module.FooterWidgetView,
priority: 99,
});
}); });
});
}); });
}); });

View File

@ -9,139 +9,138 @@ define('newsletter_editor/blocks/header', [
], function(EditorApplication, Backbone, Marionette, MailPoet) { ], function(EditorApplication, Backbone, Marionette, MailPoet) {
EditorApplication.module("blocks.header", function(Module, App, Backbone, Marionette, $, _) { EditorApplication.module("blocks.header", function(Module, App, Backbone, Marionette, $, _) {
"use strict"; "use strict";
var base = App.module('blocks.base'); var base = App.module('blocks.base');
Module.HeaderBlockModel = base.BlockModel.extend({ Module.HeaderBlockModel = base.BlockModel.extend({
defaults: function() { defaults: function() {
return this._getDefaults({ return this._getDefaults({
type: 'header', type: 'header',
text: 'Display problems? <a href="[viewInBrowserUrl]">View it in your browser</a>', text: 'Display problems? <a href="[viewInBrowserUrl]">View it in your browser</a>',
styles: { styles: {
block: { block: {
backgroundColor: 'transparent', backgroundColor: 'transparent',
}, },
text: { text: {
fontColor: '#000000', fontColor: '#000000',
fontFamily: 'Arial', fontFamily: 'Arial',
fontSize: '12px', fontSize: '12px',
textAlign: 'center', textAlign: 'center',
}, },
link: { link: {
fontColor: '#0000ff', fontColor: '#0000ff',
textDecoration: 'underline', textDecoration: 'underline',
}, },
},
}, EditorApplication.getConfig().get('blockDefaults.header'));
}, },
}, EditorApplication.getConfig().get('blockDefaults.header'));
},
});
Module.HeaderBlockView = base.BlockView.extend({
className: "mailpoet_block mailpoet_header_block mailpoet_droppable_block",
getTemplate: function() { return templates.headerBlock; },
modelEvents: {
'change:styles.block.backgroundColor change:styles.text.fontColor change:styles.text.fontFamily change:styles.text.fontSize change:styles.text.textAlign change:styles.link.fontColor change:styles.link.textDecoration': 'render',
},
onDragSubstituteBy: function() { return Module.HeaderWidgetView; },
onRender: function() {
this.toolsView = new Module.HeaderBlockToolsView({ model: this.model });
this.toolsRegion.show(this.toolsView);
},
onDomRefresh: function() {
this.attachTextEditor();
},
attachTextEditor: function() {
var that = this;
this.$('.mailpoet_content').tinymce({
inline: true,
menubar: false,
toolbar: "bold italic link unlink forecolor mailpoet_custom_fields",
valid_elements: "p[class|style],span[class|style],a[href|class|title|target|style],strong[class|style],em[class|style],strike,br",
invalid_elements: "script",
style_formats: [
{title: 'Paragraph', block: 'p'},
],
plugins: "wplink textcolor mailpoet_custom_fields",
setup: function(editor) {
editor.on('change', function(e) {
that.model.set('text', editor.getContent());
});
editor.on('focus', function(e) {
that.disableShowingTools();
});
editor.on('blur', function(e) {
that.enableShowingTools();
});
},
mailpoet_custom_fields: App.getConfig().get('customFields').toJSON(),
mailpoet_custom_fields_window_title: App.getConfig().get('translations.customFieldsWindowTitle'),
});
},
});
Module.HeaderBlockToolsView = base.BlockToolsView.extend({
getSettingsView: function() { return Module.HeaderBlockSettingsView; },
});
Module.HeaderBlockSettingsView = base.BlockSettingsView.extend({
getTemplate: function() { return templates.headerBlockSettings; },
events: function() {
return {
"change .mailpoet_field_header_text_color": _.partial(this.changeColorField, "styles.text.fontColor"),
"change .mailpoet_field_header_text_font_family": _.partial(this.changeField, "styles.text.fontFamily"),
"change .mailpoet_field_header_text_size": _.partial(this.changeField, "styles.text.fontSize"),
"change #mailpoet_field_header_link_color": _.partial(this.changeColorField, "styles.link.fontColor"),
"change #mailpoet_field_header_link_underline": function(event) {
this.model.set('styles.link.textDecoration', (event.target.checked) ? event.target.value : 'none');
},
"change .mailpoet_field_header_background_color": _.partial(this.changeColorField, "styles.block.backgroundColor"),
"change .mailpoet_field_header_alignment": _.partial(this.changeField, "styles.text.textAlign"),
"click .mailpoet_done_editing": "close",
};
},
behaviors: {
ColorPickerBehavior: {},
},
templateHelpers: function() {
return {
model: this.model.toJSON(),
availableStyles: App.getAvailableStyles().toJSON(),
};
},
});
Module.HeaderWidgetView = base.WidgetView.extend({
getTemplate: function() { return templates.headerInsertion; },
behaviors: {
DraggableBehavior: {
cloneOriginal: true,
drop: function() {
return new Module.HeaderBlockModel();
},
}
},
});
App.on('before:start', function() {
App.registerBlockType('header', {
blockModel: Module.HeaderBlockModel,
blockView: Module.HeaderBlockView,
}); });
Module.HeaderBlockView = base.BlockView.extend({ App.registerWidget({
className: "mailpoet_block mailpoet_header_block mailpoet_droppable_block", name: 'header',
getTemplate: function() { return templates.headerBlock; }, widgetView: Module.HeaderWidgetView,
modelEvents: { priority: 98,
'change:styles.block.backgroundColor change:styles.text.fontColor change:styles.text.fontFamily change:styles.text.fontSize change:styles.text.textAlign change:styles.link.fontColor change:styles.link.textDecoration': 'render',
},
onDragSubstituteBy: function() { return Module.HeaderWidgetView; },
onRender: function() {
this.toolsView = new Module.HeaderBlockToolsView({ model: this.model });
this.toolsRegion.show(this.toolsView);
},
onDomRefresh: function() {
this.attachTextEditor();
},
attachTextEditor: function() {
var that = this;
this.$('.mailpoet_content').tinymce({
inline: true,
menubar: false,
toolbar: "bold italic link unlink forecolor mailpoet_custom_fields",
valid_elements: "p[class|style],span[class|style],a[href|class|title|target|style],strong[class|style],em[class|style],strike,br",
invalid_elements: "script",
style_formats: [
{title: 'Paragraph', block: 'p'},
],
plugins: "wplink textcolor mailpoet_custom_fields",
setup: function(editor) {
editor.on('change', function(e) {
that.model.set('text', editor.getContent());
});
editor.on('focus', function(e) {
that.disableShowingTools();
});
editor.on('blur', function(e) {
that.enableShowingTools();
});
},
mailpoet_custom_fields: App.getConfig().get('customFields').toJSON(),
mailpoet_custom_fields_window_title: App.getConfig().get('translations.customFieldsWindowTitle'),
});
},
});
Module.HeaderBlockToolsView = base.BlockToolsView.extend({
getSettingsView: function() { return Module.HeaderBlockSettingsView; },
});
Module.HeaderBlockSettingsView = base.BlockSettingsView.extend({
getTemplate: function() { return templates.headerBlockSettings; },
events: function() {
return {
"change .mailpoet_field_header_text_color": _.partial(this.changeColorField, "styles.text.fontColor"),
"change .mailpoet_field_header_text_font_family": _.partial(this.changeField, "styles.text.fontFamily"),
"change .mailpoet_field_header_text_size": _.partial(this.changeField, "styles.text.fontSize"),
"change #mailpoet_field_header_link_color": _.partial(this.changeColorField, "styles.link.fontColor"),
"change #mailpoet_field_header_link_underline": function(event) {
this.model.set('styles.link.textDecoration', (event.target.checked) ? event.target.value : 'none');
},
"change .mailpoet_field_header_background_color": _.partial(this.changeColorField, "styles.block.backgroundColor"),
"change .mailpoet_field_header_alignment": _.partial(this.changeField, "styles.text.textAlign"),
"click .mailpoet_done_editing": "close",
};
},
behaviors: {
ColorPickerBehavior: {},
},
templateHelpers: function() {
return {
model: this.model.toJSON(),
availableStyles: App.getAvailableStyles().toJSON(),
};
},
});
Module.HeaderWidgetView = base.WidgetView.extend({
getTemplate: function() { return templates.headerInsertion; },
behaviors: {
DraggableBehavior: {
cloneOriginal: true,
drop: function() {
return new Module.HeaderBlockModel();
},
}
},
});
App.on('before:start', function() {
App.registerBlockType('header', {
blockModel: Module.HeaderBlockModel,
blockView: Module.HeaderBlockView,
});
App.registerWidget({
name: 'header',
widgetView: Module.HeaderWidgetView,
priority: 98,
});
}); });
});
}); });
}); });

View File

@ -9,381 +9,380 @@ define('newsletter_editor/blocks/image', [
], function(EditorApplication, Backbone, Marionette, MailPoet) { ], function(EditorApplication, Backbone, Marionette, MailPoet) {
EditorApplication.module("blocks.image", function(Module, App, Backbone, Marionette, $, _) { EditorApplication.module("blocks.image", function(Module, App, Backbone, Marionette, $, _) {
"use strict"; "use strict";
var base = App.module('blocks.base'), var base = App.module('blocks.base'),
ImageWidgetView; ImageWidgetView;
Module.ImageBlockModel = base.BlockModel.extend({ Module.ImageBlockModel = base.BlockModel.extend({
defaults: function() { defaults: function() {
return this._getDefaults({ return this._getDefaults({
type: 'image', type: 'image',
link: 'http://example.org', link: 'http://example.org',
src: 'no-image.png', src: 'no-image.png',
alt: 'An image of...', alt: 'An image of...',
padded: true, // true | false - Padded or full width padded: true, // true | false - Padded or full width
width: '64px', width: '64px',
height: '64px', height: '64px',
styles: { styles: {
block: { block: {
textAlign: 'center', textAlign: 'center',
}, },
},
}, EditorApplication.getConfig().get('blockDefaults.image'));
}, },
}); }, EditorApplication.getConfig().get('blockDefaults.image'));
},
});
Module.ImageBlockView = base.BlockView.extend({
className: "mailpoet_block mailpoet_image_block mailpoet_droppable_block",
getTemplate: function() { return templates.imageBlock; },
initialize: function() {
this.on('showSettings', this.showSettings);
},
onDragSubstituteBy: function() { return Module.ImageWidgetView; },
templateHelpers: function() {
return {
model: this.model.toJSON(),
viewCid: this.cid,
imageMissingSrc: App.getConfig().get('urls.imageMissing'),
};
},
onRender: function() {
this.toolsView = new Module.ImageBlockToolsView({ model: this.model });
this.toolsRegion.show(this.toolsView);
if (this.model.get('padded')) {
this.$el.removeClass('mailpoet_full_image');
} else {
this.$el.addClass('mailpoet_full_image');
}
},
showSettings: function(options) {
this.toolsView.triggerMethod('showSettings', options);
},
onBeforeDestroy: function() {
this.off('showSettings');
},
});
Module.ImageBlockToolsView = base.BlockToolsView.extend({
getSettingsView: function() { return Module.ImageBlockSettingsView; },
initialize: function() {
base.BlockToolsView.prototype.initialize.apply(this, arguments);
this.on('showSettings', this.changeSettings);
},
changeSettings: function(options) {
(new Module.ImageBlockSettingsView({
model: this.model,
showImageManager: (options.showImageManager === true),
})).render();
},
onBeforeDestroy: function() {
this.off('showSettings');
},
});
Module.ImageBlockSettingsView = base.BlockSettingsView.extend({
getTemplate: function() { return templates.imageBlockSettings; },
events: function() {
return {
"keyup .mailpoet_field_image_link": _.partial(this.changeField, "link"),
"keyup .mailpoet_field_image_address": _.partial(this.changeField, "src"),
"keyup .mailpoet_field_image_alt_text": _.partial(this.changeField, "alt"),
"change .mailpoet_field_image_padded": _.partial(this.changeBoolField, "padded"),
"change .mailpoet_field_image_alignment": _.partial(this.changeField, "styles.block.textAlign"),
"click .mailpoet_field_image_select_another_image": "showMediaManager",
"click .mailpoet_done_editing": "close",
};
},
initialize: function(options) {
base.BlockSettingsView.prototype.initialize.apply(this, arguments);
if (options.showImageManager) {
this.showMediaManager();
}
},
showMediaManager: function() {
if (this._mediaManager) {
this._mediaManager.resetSelections();
this._mediaManager.open();
return;
}
var MediaManager = wp.media.view.MediaFrame.Select.extend({
Module.ImageBlockView = base.BlockView.extend({
className: "mailpoet_block mailpoet_image_block mailpoet_droppable_block",
getTemplate: function() { return templates.imageBlock; },
initialize: function() { initialize: function() {
this.on('showSettings', this.showSettings); wp.media.view.MediaFrame.prototype.initialize.apply(this, arguments);
_.defaults(this.options, {
multiple: true,
editing: false,
state: 'insert'
});
this.createSelection();
this.createStates();
this.bindHandlers();
this.createIframeStates();
// Hide title
this.$el.addClass('hide-title');
}, },
onDragSubstituteBy: function() { return Module.ImageWidgetView; },
templateHelpers: function() { resetSelections: function() {
return { this.state().get('selection').reset();
model: this.model.toJSON(), },
viewCid: this.cid,
imageMissingSrc: App.getConfig().get('urls.imageMissing'), createQuery: function(options) {
var query = wp.media.query(options);
return query;
},
createStates: function() {
var options = this.options;
// Add the default states.
this.states.add([
// Main states.
new wp.media.controller.Library({
id: 'insert',
title: 'Add images',
priority: 20,
toolbar: 'main-insert',
filterable: 'image',
library: this.createQuery(options.library),
multiple: options.multiple ? 'reset' : false,
editable: false,
// If the user isn't allowed to edit fields,
// can they still edit it locally?
allowLocalEdits: false,
// Show the attachment display settings.
displaySettings: false,
// Update user settings when users adjust the
// attachment display settings.
displayUserSettings: false
}),
]);
if(wp.media.view.settings.post.featuredImageId) {
this.states.add(new wp.media.controller.FeaturedImage());
}
},
bindHandlers: function() {
// from Select
this.on('router:create:browse', this.createRouter, this);
this.on('router:render:browse', this.browseRouter, this);
this.on('content:create:browse', this.browseContent, this);
this.on('content:render:upload', this.uploadContent, this);
this.on('toolbar:create:select', this.createSelectToolbar, this);
this.on('menu:create:gallery', this.createMenu, this);
this.on('toolbar:create:main-insert', this.createToolbar, this);
this.on('toolbar:create:main-gallery', this.createToolbar, this);
this.on('toolbar:create:main-embed', this.mainEmbedToolbar, this);
this.on('updateExcluded', this.browseContent, this);
var handlers = {
content: {
'embed': 'embedContent',
'edit-selection': 'editSelectionContent'
},
toolbar: {
'main-insert': 'mainInsertToolbar'
}
}; };
},
onRender: function() {
this.toolsView = new Module.ImageBlockToolsView({ model: this.model });
this.toolsRegion.show(this.toolsView);
if (this.model.get('padded')) { _.each(handlers, function(regionHandlers, region) {
this.$el.removeClass('mailpoet_full_image'); _.each(regionHandlers, function(callback, handler) {
} else { this.on(region + ':render:' + handler, this[callback], this);
this.$el.addClass('mailpoet_full_image'); }, this);
}, this);
},
uploadContent: function() {
wp.media.view.MediaFrame.Select.prototype.uploadContent.apply(this, arguments);
this.$el.addClass('hide-toolbar');
},
// Content
embedContent: function() {
var view = new wp.media.view.Embed({
controller: this,
model: this.state()
}).render();
this.content.set(view);
view.url.focus();
},
editSelectionContent: function() {
var state = this.state(),
selection = state.get('selection'),
view;
view = new wp.media.view.AttachmentsBrowser({
controller: this,
collection: selection,
selection: selection,
model: state,
sortable: true,
search: false,
dragInfo: true,
AttachmentView: wp.media.view.Attachment.EditSelection
}).render();
view.toolbar.set('backToLibrary', {
text: 'Return to library',
priority: -100,
click: function() {
this.controller.content.mode('browse');
} }
}, });
showSettings: function(options) {
this.toolsView.triggerMethod('showSettings', options);
},
onBeforeDestroy: function() {
this.off('showSettings');
},
});
Module.ImageBlockToolsView = base.BlockToolsView.extend({ // Browse our library of attachments.
getSettingsView: function() { return Module.ImageBlockSettingsView; }, this.content.set(view);
initialize: function() {
base.BlockToolsView.prototype.initialize.apply(this, arguments);
this.on('showSettings', this.changeSettings);
}, },
changeSettings: function(options) {
(new Module.ImageBlockSettingsView({
model: this.model,
showImageManager: (options.showImageManager === true),
})).render();
},
onBeforeDestroy: function() {
this.off('showSettings');
},
});
Module.ImageBlockSettingsView = base.BlockSettingsView.extend({ // Toolbars
getTemplate: function() { return templates.imageBlockSettings; }, selectionStatusToolbar: function(view) {
events: function() { var editable = this.state().get('editable');
return {
"keyup .mailpoet_field_image_link": _.partial(this.changeField, "link"),
"keyup .mailpoet_field_image_address": _.partial(this.changeField, "src"),
"keyup .mailpoet_field_image_alt_text": _.partial(this.changeField, "alt"),
"change .mailpoet_field_image_padded": _.partial(this.changeBoolField, "padded"),
"change .mailpoet_field_image_alignment": _.partial(this.changeField, "styles.block.textAlign"),
"click .mailpoet_field_image_select_another_image": "showMediaManager",
"click .mailpoet_done_editing": "close",
};
},
initialize: function(options) {
base.BlockSettingsView.prototype.initialize.apply(this, arguments);
if (options.showImageManager) { view.set('selection', new wp.media.view.Selection({
this.showMediaManager(); controller: this,
collection: this.state().get('selection'),
priority: -40,
// If the selection is editable, pass the callback to
// switch the content mode.
editable: editable && function() {
this.controller.content.mode('edit-selection');
} }
}).render() );
}, },
showMediaManager: function() {
if (this._mediaManager) { mainInsertToolbar: function(view) {
this._mediaManager.resetSelections(); var controller = this;
this._mediaManager.open();
return; this.selectionStatusToolbar(view);
view.set('insert', {
style: 'primary',
priority: 80,
text: 'Select Image',
requires: { selection: true },
click: function() {
var state = controller.state(),
selection = state.get('selection');
controller.close();
state.trigger('insert', selection).reset();
} }
});
var MediaManager = wp.media.view.MediaFrame.Select.extend({
initialize: function() {
wp.media.view.MediaFrame.prototype.initialize.apply(this, arguments);
_.defaults(this.options, {
multiple: true,
editing: false,
state: 'insert'
});
this.createSelection();
this.createStates();
this.bindHandlers();
this.createIframeStates();
// Hide title
this.$el.addClass('hide-title');
},
resetSelections: function() {
this.state().get('selection').reset();
},
createQuery: function(options) {
var query = wp.media.query(options);
return query;
},
createStates: function() {
var options = this.options;
// Add the default states.
this.states.add([
// Main states.
new wp.media.controller.Library({
id: 'insert',
title: 'Add images',
priority: 20,
toolbar: 'main-insert',
filterable: 'image',
library: this.createQuery(options.library),
multiple: options.multiple ? 'reset' : false,
editable: false,
// If the user isn't allowed to edit fields,
// can they still edit it locally?
allowLocalEdits: false,
// Show the attachment display settings.
displaySettings: false,
// Update user settings when users adjust the
// attachment display settings.
displayUserSettings: false
}),
]);
if(wp.media.view.settings.post.featuredImageId) {
this.states.add(new wp.media.controller.FeaturedImage());
}
},
bindHandlers: function() {
// from Select
this.on('router:create:browse', this.createRouter, this);
this.on('router:render:browse', this.browseRouter, this);
this.on('content:create:browse', this.browseContent, this);
this.on('content:render:upload', this.uploadContent, this);
this.on('toolbar:create:select', this.createSelectToolbar, this);
this.on('menu:create:gallery', this.createMenu, this);
this.on('toolbar:create:main-insert', this.createToolbar, this);
this.on('toolbar:create:main-gallery', this.createToolbar, this);
this.on('toolbar:create:main-embed', this.mainEmbedToolbar, this);
this.on('updateExcluded', this.browseContent, this);
var handlers = {
content: {
'embed': 'embedContent',
'edit-selection': 'editSelectionContent'
},
toolbar: {
'main-insert': 'mainInsertToolbar'
}
};
_.each(handlers, function(regionHandlers, region) {
_.each(regionHandlers, function(callback, handler) {
this.on(region + ':render:' + handler, this[callback], this);
}, this);
}, this);
},
uploadContent: function() {
wp.media.view.MediaFrame.Select.prototype.uploadContent.apply(this, arguments);
this.$el.addClass('hide-toolbar');
},
// Content
embedContent: function() {
var view = new wp.media.view.Embed({
controller: this,
model: this.state()
}).render();
this.content.set(view);
view.url.focus();
},
editSelectionContent: function() {
var state = this.state(),
selection = state.get('selection'),
view;
view = new wp.media.view.AttachmentsBrowser({
controller: this,
collection: selection,
selection: selection,
model: state,
sortable: true,
search: false,
dragInfo: true,
AttachmentView: wp.media.view.Attachment.EditSelection
}).render();
view.toolbar.set('backToLibrary', {
text: 'Return to library',
priority: -100,
click: function() {
this.controller.content.mode('browse');
}
});
// Browse our library of attachments.
this.content.set(view);
},
// Toolbars
selectionStatusToolbar: function(view) {
var editable = this.state().get('editable');
view.set('selection', new wp.media.view.Selection({
controller: this,
collection: this.state().get('selection'),
priority: -40,
// If the selection is editable, pass the callback to
// switch the content mode.
editable: editable && function() {
this.controller.content.mode('edit-selection');
}
}).render() );
},
mainInsertToolbar: function(view) {
var controller = this;
this.selectionStatusToolbar(view);
view.set('insert', {
style: 'primary',
priority: 80,
text: 'Select Image',
requires: { selection: true },
click: function() {
var state = controller.state(),
selection = state.get('selection');
controller.close();
state.trigger('insert', selection).reset();
}
});
},
mainEmbedToolbar: function(toolbar) {
toolbar.view = new wp.media.view.Toolbar.Embed({
controller: this,
text: 'Add images'
});
}
});
var theFrame = this._mediaManager = new MediaManager({
id: 'mailpoet-media-manager',
frame: 'select',
title: 'Select image',
editing: false,
multiple: false,
library: {
type: 'image'
},
displaySettings: false,
button: {
text: 'Select',
},
}),
that = this;
this._mediaManager.on('insert', function() {
// Append media manager image selections to Images tab
var selection = theFrame.state().get('selection');
selection.each(function(attachment) {
var sizes = attachment.get('sizes'),
// Following advice from Becs, the target width should
// be a double of one column width to render well on
// retina screen devices
targetImageWidth = 1200,
// For main image use the size, that's closest to being 600px in width
sizeKeys = _.keys(sizes),
// Pick the width that is closest to target width
increasingByWidthDifference = _.sortBy(
_.keys(sizes),
function(size) { return Math.abs(targetImageWidth - sizes[size].width); }
),
bestWidth = sizes[_.first(increasingByWidthDifference)].width,
imagesOfBestWidth = _.filter(_.values(sizes), function(size) { return size.width === bestWidth; }),
// Maximize the height if there are multiple images with same width
mainSize = _.max(imagesOfBestWidth, function(size) { return size.height; });
that.model.set({
height: mainSize.height + 'px',
width: mainSize.width + 'px',
src: mainSize.url,
alt: (attachment.get('alt') !== "" && attachment.get('alt') !== undefined) ? attachment.get('alt') : attachment.get('title'),
});
// Rerender settings view due to changes from outside of settings view
that.render();
});
});
this._mediaManager.open();
}, },
onBeforeDestroy: function() {
if (typeof this._mediaManager === 'object') {
this._mediaManager.remove();
}
},
});
ImageWidgetView = base.WidgetView.extend({ mainEmbedToolbar: function(toolbar) {
getTemplate: function() { return templates.imageInsertion; }, toolbar.view = new wp.media.view.Toolbar.Embed({
behaviors: { controller: this,
DraggableBehavior: { text: 'Add images'
cloneOriginal: true, });
drop: function() { }
return new Module.ImageBlockModel();
},
onDrop: function(options) {
options.droppedView.triggerMethod('showSettings', { showImageManager: true });
},
}
},
});
Module.ImageWidgetView = ImageWidgetView;
App.on('before:start', function() { });
App.registerBlockType('image', {
blockModel: Module.ImageBlockModel, var theFrame = this._mediaManager = new MediaManager({
blockView: Module.ImageBlockView, id: 'mailpoet-media-manager',
frame: 'select',
title: 'Select image',
editing: false,
multiple: false,
library: {
type: 'image'
},
displaySettings: false,
button: {
text: 'Select',
},
}),
that = this;
this._mediaManager.on('insert', function() {
// Append media manager image selections to Images tab
var selection = theFrame.state().get('selection');
selection.each(function(attachment) {
var sizes = attachment.get('sizes'),
// Following advice from Becs, the target width should
// be a double of one column width to render well on
// retina screen devices
targetImageWidth = 1200,
// For main image use the size, that's closest to being 600px in width
sizeKeys = _.keys(sizes),
// Pick the width that is closest to target width
increasingByWidthDifference = _.sortBy(
_.keys(sizes),
function(size) { return Math.abs(targetImageWidth - sizes[size].width); }
),
bestWidth = sizes[_.first(increasingByWidthDifference)].width,
imagesOfBestWidth = _.filter(_.values(sizes), function(size) { return size.width === bestWidth; }),
// Maximize the height if there are multiple images with same width
mainSize = _.max(imagesOfBestWidth, function(size) { return size.height; });
that.model.set({
height: mainSize.height + 'px',
width: mainSize.width + 'px',
src: mainSize.url,
alt: (attachment.get('alt') !== "" && attachment.get('alt') !== undefined) ? attachment.get('alt') : attachment.get('title'),
});
// Rerender settings view due to changes from outside of settings view
that.render();
}); });
});
App.registerWidget({ this._mediaManager.open();
name: 'image', },
widgetView: Module.ImageWidgetView, onBeforeDestroy: function() {
priority: 91, if (typeof this._mediaManager === 'object') {
}); this._mediaManager.remove();
}
},
});
ImageWidgetView = base.WidgetView.extend({
getTemplate: function() { return templates.imageInsertion; },
behaviors: {
DraggableBehavior: {
cloneOriginal: true,
drop: function() {
return new Module.ImageBlockModel();
},
onDrop: function(options) {
options.droppedView.triggerMethod('showSettings', { showImageManager: true });
},
}
},
});
Module.ImageWidgetView = ImageWidgetView;
App.on('before:start', function() {
App.registerBlockType('image', {
blockModel: Module.ImageBlockModel,
blockView: Module.ImageBlockView,
}); });
App.registerWidget({
name: 'image',
widgetView: Module.ImageWidgetView,
priority: 91,
});
});
}); });
}); });

View File

@ -18,463 +18,462 @@ define('newsletter_editor/blocks/posts', [
], function(EditorApplication, Backbone, Marionette, MailPoet) { ], function(EditorApplication, Backbone, Marionette, MailPoet) {
EditorApplication.module("blocks.posts", function(Module, App, Backbone, Marionette, $, _) { EditorApplication.module("blocks.posts", function(Module, App, Backbone, Marionette, $, _) {
"use strict"; "use strict";
var base = App.module('blocks.base'); var base = App.module('blocks.base');
Module.PostsBlockModel = base.BlockModel.extend({ Module.PostsBlockModel = base.BlockModel.extend({
stale: ['_selectedPosts', '_availablePosts'], stale: ['_selectedPosts', '_availablePosts'],
defaults: function() { defaults: function() {
return this._getDefaults({ return this._getDefaults({
type: 'posts', type: 'posts',
amount: '10', amount: '10',
contentType: 'post', // 'post'|'page'|'mailpoet_page' contentType: 'post', // 'post'|'page'|'mailpoet_page'
postStatus: 'publish', // 'draft'|'pending'|'private'|'publish'|'future' postStatus: 'publish', // 'draft'|'pending'|'private'|'publish'|'future'
terms: [], // List of category and tag objects terms: [], // List of category and tag objects
search: '', // Search keyword term search: '', // Search keyword term
inclusionType: 'include', // 'include'|'exclude' inclusionType: 'include', // 'include'|'exclude'
displayType: 'excerpt', // 'excerpt'|'full'|'titleOnly' displayType: 'excerpt', // 'excerpt'|'full'|'titleOnly'
titleFormat: 'h1', // 'h1'|'h2'|'h3'|'ul' titleFormat: 'h1', // 'h1'|'h2'|'h3'|'ul'
titlePosition: 'inTextBlock', // 'inTextBlock'|'aboveBlock', titlePosition: 'inTextBlock', // 'inTextBlock'|'aboveBlock',
titleAlignment: 'left', // 'left'|'center'|'right' titleAlignment: 'left', // 'left'|'center'|'right'
titleIsLink: false, // false|true titleIsLink: false, // false|true
imagePadded: true, // true|false imagePadded: true, // true|false
//imageAlignment: 'centerPadded', // 'centerFull'|'centerPadded'|'left'|'right'|'alternate'|'none' //imageAlignment: 'centerPadded', // 'centerFull'|'centerPadded'|'left'|'right'|'alternate'|'none'
showAuthor: 'no', // 'no'|'aboveText'|'belowText' showAuthor: 'no', // 'no'|'aboveText'|'belowText'
authorPrecededBy: 'Author:', authorPrecededBy: 'Author:',
showCategories: 'no', // 'no'|'aboveText'|'belowText' showCategories: 'no', // 'no'|'aboveText'|'belowText'
categoriesPrecededBy: 'Categories:', categoriesPrecededBy: 'Categories:',
readMoreType: 'link', // 'link'|'button' readMoreType: 'link', // 'link'|'button'
readMoreText: 'Read more', // 'link'|'button' readMoreText: 'Read more', // 'link'|'button'
readMoreButton: { readMoreButton: {
text: 'Read more', text: 'Read more',
url: '[postLink]' url: '[postLink]'
},
sortBy: 'newest', // 'newest'|'oldest',
showDivider: true, // true|false
divider: {},
_selectedPosts: [],
_availablePosts: [],
}, EditorApplication.getConfig().get('blockDefaults.posts'));
}, },
relations: function() { sortBy: 'newest', // 'newest'|'oldest',
return { showDivider: true, // true|false
readMoreButton: App.getBlockTypeModel('button'), divider: {},
divider: App.getBlockTypeModel('divider'), _selectedPosts: [],
_selectedPosts: Backbone.Collection, _availablePosts: [],
_availablePosts: Backbone.Collection, }, EditorApplication.getConfig().get('blockDefaults.posts'));
}; },
}, relations: function() {
initialize: function() { return {
var that = this; readMoreButton: App.getBlockTypeModel('button'),
// Attach Radio.Requests API primarily for highlighting divider: App.getBlockTypeModel('divider'),
_.extend(this, Backbone.Radio.Requests); _selectedPosts: Backbone.Collection,
_availablePosts: Backbone.Collection,
};
},
initialize: function() {
var that = this;
// Attach Radio.Requests API primarily for highlighting
_.extend(this, Backbone.Radio.Requests);
this.fetchAvailablePosts(); this.fetchAvailablePosts();
this.on('change:amount change:contentType change:terms change:inclusionType change:postStatus change:search change:sortBy', this._scheduleFetchAvailablePosts, this); this.on('change:amount change:contentType change:terms change:inclusionType change:postStatus change:search change:sortBy', this._scheduleFetchAvailablePosts, this);
this.on('insertSelectedPosts', this._insertSelectedPosts, this); this.on('insertSelectedPosts', this._insertSelectedPosts, this);
}, },
fetchAvailablePosts: function() { fetchAvailablePosts: function() {
var that = this; var that = this;
// TODO: Move this logic to new AJAX query format // TODO: Move this logic to new AJAX query format
//mailpoet_post_wpi('posts.php', this.toJSON(), function(response) { //mailpoet_post_wpi('posts.php', this.toJSON(), function(response) {
//console.log('Posts fetched', arguments); //console.log('Posts fetched', arguments);
//that.get('_availablePosts').reset(response); //that.get('_availablePosts').reset(response);
//that.get('_selectedPosts').reset(); // Empty out the collection //that.get('_selectedPosts').reset(); // Empty out the collection
//that.trigger('change:_availablePosts'); //that.trigger('change:_availablePosts');
//}, function() { //}, function() {
//console.log('Posts fetchPosts error', arguments); //console.log('Posts fetchPosts error', arguments);
//}); //});
}, },
/** /**
* Batch more changes during a specific time, instead of fetching * Batch more changes during a specific time, instead of fetching
* ALC posts on each model change * ALC posts on each model change
*/ */
_scheduleFetchAvailablePosts: function() { _scheduleFetchAvailablePosts: function() {
var timeout = 500, var timeout = 500,
that = this; that = this;
if (this._fetchPostsTimer !== undefined) { if (this._fetchPostsTimer !== undefined) {
clearTimeout(this._fetchPostsTimer); clearTimeout(this._fetchPostsTimer);
} }
this._fetchPostsTimer = setTimeout(function() { this._fetchPostsTimer = setTimeout(function() {
that.fetchAvailablePosts(); that.fetchAvailablePosts();
that._fetchPostsTimer = undefined; that._fetchPostsTimer = undefined;
}, timeout); }, timeout);
}, },
_insertSelectedPosts: function() { _insertSelectedPosts: function() {
var that = this, var that = this,
data = this.toJSON(), data = this.toJSON(),
index = this.collection.indexOf(this), index = this.collection.indexOf(this),
collection = this.collection; collection = this.collection;
data.posts = this.get('_selectedPosts').pluck('ID'); data.posts = this.get('_selectedPosts').pluck('ID');
if (data.posts.length === 0) return; if (data.posts.length === 0) return;
// TODO: Move query logic to new AJAX format // TODO: Move query logic to new AJAX format
//mailpoet_post_wpi('automated_latest_content.php', data, function(response) { //mailpoet_post_wpi('automated_latest_content.php', data, function(response) {
//console.log('Available posts fetched', arguments); //console.log('Available posts fetched', arguments);
//collection.add(response, { at: index }); //collection.add(response, { at: index });
//}, function() { //}, function() {
//console.log('Posts fetchPosts error', arguments); //console.log('Posts fetchPosts error', arguments);
//}); //});
}, },
}); });
Module.PostsBlockView = base.BlockView.extend({ Module.PostsBlockView = base.BlockView.extend({
className: "mailpoet_block mailpoet_posts_block mailpoet_droppable_block", className: "mailpoet_block mailpoet_posts_block mailpoet_droppable_block",
getTemplate: function() { return templates.postsBlock; }, getTemplate: function() { return templates.postsBlock; },
modelEvents: {}, modelEvents: {},
onDragSubstituteBy: function() { return Module.PostsWidgetView; }, onDragSubstituteBy: function() { return Module.PostsWidgetView; },
initialize: function() { initialize: function() {
this.toolsView = new Module.PostsBlockToolsView({ model: this.model }); this.toolsView = new Module.PostsBlockToolsView({ model: this.model });
this.on('showSettings', this.showSettings); this.on('showSettings', this.showSettings);
this.model.reply('blockView', this.notifyAboutSelf, this); this.model.reply('blockView', this.notifyAboutSelf, this);
}, },
onRender: function() { onRender: function() {
if (!this.toolsRegion.hasView()) { if (!this.toolsRegion.hasView()) {
this.toolsRegion.show(this.toolsView); this.toolsRegion.show(this.toolsView);
} }
this.trigger('showSettings'); this.trigger('showSettings');
}, },
showSettings: function(options) { showSettings: function(options) {
this.toolsView.triggerMethod('showSettings', options); this.toolsView.triggerMethod('showSettings', options);
}, },
notifyAboutSelf: function() { notifyAboutSelf: function() {
return this; return this;
}, },
onBeforeDestroy: function() { onBeforeDestroy: function() {
this.model.stopReplying('blockView', this.notifyAboutSelf, this); this.model.stopReplying('blockView', this.notifyAboutSelf, this);
}, },
}); });
Module.PostsBlockToolsView = base.BlockToolsView.extend({ Module.PostsBlockToolsView = base.BlockToolsView.extend({
getSettingsView: function() { return Module.PostsBlockSettingsView; }, getSettingsView: function() { return Module.PostsBlockSettingsView; },
initialize: function() { initialize: function() {
base.BlockToolsView.prototype.initialize.apply(this, arguments); base.BlockToolsView.prototype.initialize.apply(this, arguments);
this.on('showSettings', this.changeSettings); this.on('showSettings', this.changeSettings);
this.settingsView = new Module.PostsBlockSettingsView({ model: this.model }); this.settingsView = new Module.PostsBlockSettingsView({ model: this.model });
}, },
changeSettings: function() { changeSettings: function() {
this.settingsView.render(); this.settingsView.render();
}, },
onBeforeDestroy: function() { onBeforeDestroy: function() {
this.settingsView.destroy(); this.settingsView.destroy();
this.off('showSettings'); this.off('showSettings');
MailPoet.Modal.close(); MailPoet.Modal.close();
}, },
}); });
Module.PostsBlockSettingsView = base.BlockSettingsView.extend({ Module.PostsBlockSettingsView = base.BlockSettingsView.extend({
getTemplate: function() { return templates.postsBlockSettings; }, getTemplate: function() { return templates.postsBlockSettings; },
regions: { regions: {
selectionRegion: '.mailpoet_settings_posts_selection', selectionRegion: '.mailpoet_settings_posts_selection',
displayOptionsRegion: '.mailpoet_settings_posts_display_options', displayOptionsRegion: '.mailpoet_settings_posts_display_options',
}, },
events: { events: {
'click .mailpoet_settings_posts_show_display_options': 'switchToDisplayOptions', 'click .mailpoet_settings_posts_show_display_options': 'switchToDisplayOptions',
'click .mailpoet_settings_posts_show_post_selection': 'switchToPostSelection', 'click .mailpoet_settings_posts_show_post_selection': 'switchToPostSelection',
'click .mailpoet_settings_posts_insert_selected': 'insertPosts', 'click .mailpoet_settings_posts_insert_selected': 'insertPosts',
}, },
templateHelpers: function() { templateHelpers: function() {
return { return {
model: this.model.toJSON(), model: this.model.toJSON(),
}; };
}, },
initialize: function() { initialize: function() {
this.selectionView = new PostSelectionSettingsView({ model: this.model }); this.selectionView = new PostSelectionSettingsView({ model: this.model });
this.displayOptionsView = new PostsDisplayOptionsSettingsView({ model: this.model }); this.displayOptionsView = new PostsDisplayOptionsSettingsView({ model: this.model });
}, },
onRender: function() { onRender: function() {
var that = this, var that = this,
blockView = this.model.request('blockView'); blockView = this.model.request('blockView');
this.selectionRegion.show(this.selectionView); this.selectionRegion.show(this.selectionView);
this.displayOptionsRegion.show(this.displayOptionsView); this.displayOptionsRegion.show(this.displayOptionsView);
MailPoet.Modal.panel({ MailPoet.Modal.panel({
element: this.$el, element: this.$el,
template: '', template: '',
position: 'right', position: 'right',
overlay: true, overlay: true,
highlight: blockView.$el, highlight: blockView.$el,
width: App.getConfig().get('sidepanelWidth'), width: App.getConfig().get('sidepanelWidth'),
onCancel: function() { onCancel: function() {
// Self destroy the block if the user closes settings modal // Self destroy the block if the user closes settings modal
that.model.destroy(); that.model.destroy();
}, },
});
},
switchToDisplayOptions: function() {
// Switch content view
this.$('.mailpoet_settings_posts_selection').addClass('mailpoet_hidden');
this.$('.mailpoet_settings_posts_display_options').removeClass('mailpoet_hidden');
// Switch controls
this.$('.mailpoet_settings_posts_show_display_options').addClass('mailpoet_hidden');
this.$('.mailpoet_settings_posts_show_post_selection').removeClass('mailpoet_hidden');
},
switchToPostSelection: function() {
// Switch content view
this.$('.mailpoet_settings_posts_display_options').addClass('mailpoet_hidden');
this.$('.mailpoet_settings_posts_selection').removeClass('mailpoet_hidden');
// Switch controls
this.$('.mailpoet_settings_posts_show_post_selection').addClass('mailpoet_hidden');
this.$('.mailpoet_settings_posts_show_display_options').removeClass('mailpoet_hidden');
},
insertPosts: function() {
this.model.trigger('insertSelectedPosts');
this.model.destroy();
},
});
var PostSelectionSettingsView = Marionette.CompositeView.extend({
getTemplate: function() { return templates.postSelectionPostsBlockSettings; },
getChildView: function() { return SinglePostSelectionSettingsView; },
childViewContainer: '.mailpoet_post_selection_container',
getEmptyView: function() { return EmptyPostSelectionSettingsView; },
childViewOptions: function() {
return {
blockModel: this.model,
};
},
events: function() {
return {
'change .mailpoet_settings_posts_content_type': _.partial(this.changeField, 'contentType'),
'change .mailpoet_posts_post_status': _.partial(this.changeField, 'postStatus'),
'keyup .mailpoet_posts_search_term': _.partial(this.changeField, 'search'),
};
},
constructor: function() {
// Set the block collection to be handled by this view as well
arguments[0].collection = arguments[0].model.get('_availablePosts');
Marionette.CompositeView.apply(this, arguments);
},
onRender: function() {
var that = this;
this.$('.mailpoet_posts_categories_and_tags').select2({
multiple: true,
allowClear: true,
ajax: {
url: App.getConfig().get('urls.termSearch'),
type: 'POST',
dataType: 'json',
delay: 250,
data: function(searchParameter, page) {
return JSON.stringify({
postType: that.model.get('contentType'),
search: searchParameter,
limit: 10, // TODO: Move this hardcoded limit to Config
page: page,
}); });
}, },
switchToDisplayOptions: function() { /**
// Switch content view * Parse results for select2.
this.$('.mailpoet_settings_posts_selection').addClass('mailpoet_hidden'); * Returns object, where `results` key holds a list of
this.$('.mailpoet_settings_posts_display_options').removeClass('mailpoet_hidden'); * select item objects
*/
// Switch controls results: function (data, page) {
this.$('.mailpoet_settings_posts_show_display_options').addClass('mailpoet_hidden');
this.$('.mailpoet_settings_posts_show_post_selection').removeClass('mailpoet_hidden');
},
switchToPostSelection: function() {
// Switch content view
this.$('.mailpoet_settings_posts_display_options').addClass('mailpoet_hidden');
this.$('.mailpoet_settings_posts_selection').removeClass('mailpoet_hidden');
// Switch controls
this.$('.mailpoet_settings_posts_show_post_selection').addClass('mailpoet_hidden');
this.$('.mailpoet_settings_posts_show_display_options').removeClass('mailpoet_hidden');
},
insertPosts: function() {
this.model.trigger('insertSelectedPosts');
this.model.destroy();
},
});
var PostSelectionSettingsView = Marionette.CompositeView.extend({
getTemplate: function() { return templates.postSelectionPostsBlockSettings; },
getChildView: function() { return SinglePostSelectionSettingsView; },
childViewContainer: '.mailpoet_post_selection_container',
getEmptyView: function() { return EmptyPostSelectionSettingsView; },
childViewOptions: function() {
return { return {
blockModel: this.model, results: _.map(
}; data.results,
}, function(item) {
events: function() { return _.defaults({
return { text: data.taxonomies[item.taxonomy].labels.singular_name + ': ' + item.name,
'change .mailpoet_settings_posts_content_type': _.partial(this.changeField, 'contentType'), id: item.term_id
'change .mailpoet_posts_post_status': _.partial(this.changeField, 'postStatus'), }, item);
'keyup .mailpoet_posts_search_term': _.partial(this.changeField, 'search'),
};
},
constructor: function() {
// Set the block collection to be handled by this view as well
arguments[0].collection = arguments[0].model.get('_availablePosts');
Marionette.CompositeView.apply(this, arguments);
},
onRender: function() {
var that = this;
this.$('.mailpoet_posts_categories_and_tags').select2({
multiple: true,
allowClear: true,
ajax: {
url: App.getConfig().get('urls.termSearch'),
type: 'POST',
dataType: 'json',
delay: 250,
data: function(searchParameter, page) {
return JSON.stringify({
postType: that.model.get('contentType'),
search: searchParameter,
limit: 10, // TODO: Move this hardcoded limit to Config
page: page,
});
},
/**
* Parse results for select2.
* Returns object, where `results` key holds a list of
* select item objects
*/
results: function (data, page) {
return {
results: _.map(
data.results,
function(item) {
return _.defaults({
text: data.taxonomies[item.taxonomy].labels.singular_name + ': ' + item.name,
id: item.term_id
}, item);
}
)
};
}
},
}).trigger( 'change' ).on({
'change': function(e){
var data = [];
if (typeof data === 'string') {
if (data === '') {
data = [];
} else {
data = JSON.parse(data);
}
}
if ( e.added ){
data.push(e.added);
}
// Update ALC model
that.model.set('terms', data);
$(this).data('selected', JSON.stringify(data));
} }
}); )
},
onBeforeDestroy: function() {
// Force close select2 if it hasn't closed yet
this.$('.mailpoet_posts_categories_and_tags').select2('close');
},
changeField: function(field, event) {
this.model.set(field, jQuery(event.target).val());
},
});
var EmptyPostSelectionSettingsView = Marionette.ItemView.extend({
getTemplate: function() { return templates.emptyPostPostsBlockSettings; },
});
var SinglePostSelectionSettingsView = Marionette.ItemView.extend({
getTemplate: function() { return templates.singlePostPostsBlockSettings; },
events: function() {
return {
'change .mailpoet_select_post_checkbox': 'postSelectionChange',
}; };
}
}, },
templateHelpers: function() { }).trigger( 'change' ).on({
return { 'change': function(e){
model: this.model.toJSON(), var data = [];
index: this._index,
}; if (typeof data === 'string') {
}, if (data === '') {
initialize: function(options) { data = [];
this.blockModel = options.blockModel;
},
postSelectionChange: function(event) {
var checkBox = jQuery(event.target),
selectedPostsCollection = this.blockModel.get('_selectedPosts');
if (checkBox.prop('checked')) {
selectedPostsCollection.add(this.model);
} else { } else {
selectedPostsCollection.remove(this.model); data = JSON.parse(data);
} }
}
if ( e.added ){
data.push(e.added);
}
// Update ALC model
that.model.set('terms', data);
$(this).data('selected', JSON.stringify(data));
}
});
},
onBeforeDestroy: function() {
// Force close select2 if it hasn't closed yet
this.$('.mailpoet_posts_categories_and_tags').select2('close');
},
changeField: function(field, event) {
this.model.set(field, jQuery(event.target).val());
},
});
var EmptyPostSelectionSettingsView = Marionette.ItemView.extend({
getTemplate: function() { return templates.emptyPostPostsBlockSettings; },
});
var SinglePostSelectionSettingsView = Marionette.ItemView.extend({
getTemplate: function() { return templates.singlePostPostsBlockSettings; },
events: function() {
return {
'change .mailpoet_select_post_checkbox': 'postSelectionChange',
};
},
templateHelpers: function() {
return {
model: this.model.toJSON(),
index: this._index,
};
},
initialize: function(options) {
this.blockModel = options.blockModel;
},
postSelectionChange: function(event) {
var checkBox = jQuery(event.target),
selectedPostsCollection = this.blockModel.get('_selectedPosts');
if (checkBox.prop('checked')) {
selectedPostsCollection.add(this.model);
} else {
selectedPostsCollection.remove(this.model);
}
},
});
var PostsDisplayOptionsSettingsView = base.BlockSettingsView.extend({
getTemplate: function() { return templates.displayOptionsPostsBlockSettings; },
events: function() {
return {
"click .mailpoet_posts_select_button": 'showButtonSettings',
"click .mailpoet_posts_select_divider": 'showDividerSettings',
"change .mailpoet_posts_read_more_type": 'changeReadMoreType',
"change .mailpoet_posts_display_type": 'changeDisplayType',
"change .mailpoet_posts_title_format": 'changeTitleFormat',
"change .mailpoet_posts_title_as_links": _.partial(this.changeBoolField, 'titleIsLink'),
"change .mailpoet_posts_show_divider": _.partial(this.changeBoolField, 'showDivider'),
"keyup .mailpoet_posts_show_amount": _.partial(this.changeField, "amount"),
"change .mailpoet_posts_content_type": _.partial(this.changeField, "contentType"),
"change .mailpoet_posts_include_or_exclude": _.partial(this.changeField, "inclusionType"),
"change .mailpoet_posts_title_position": _.partial(this.changeField, "titlePosition"),
"change .mailpoet_posts_title_alignment": _.partial(this.changeField, "titleAlignment"),
"change .mailpoet_posts_image_padded": _.partial(this.changeBoolField, "imagePadded"),
"change .mailpoet_posts_show_author": _.partial(this.changeField, "showAuthor"),
"keyup .mailpoet_posts_author_preceded_by": _.partial(this.changeField, "authorPrecededBy"),
"change .mailpoet_posts_show_categories": _.partial(this.changeField, "showCategories"),
"keyup .mailpoet_posts_categories": _.partial(this.changeField, "categoriesPrecededBy"),
"keyup .mailpoet_posts_read_more_text": _.partial(this.changeField, "readMoreText"),
"change .mailpoet_posts_sort_by": _.partial(this.changeField, "sortBy"),
};
},
behaviors: {
ColorPickerBehavior: {},
},
templateHelpers: function() {
return {
model: this.model.toJSON(),
};
},
showButtonSettings: function(event) {
var buttonModule = App.module('blocks.button');
(new buttonModule.ButtonBlockSettingsView({
model: this.model.get('readMoreButton'),
renderOptions: {
displayFormat: 'subpanel',
hideLink: true,
hideApplyToAll: true,
}, },
})).render();
},
showDividerSettings: function(event) {
var dividerModule = App.module('blocks.divider');
(new dividerModule.DividerBlockSettingsView({
model: this.model.get('divider'),
renderOptions: {
displayFormat: 'subpanel',
hideApplyToAll: true,
},
})).render();
},
changeReadMoreType: function(event) {
var value = jQuery(event.target).val();
if (value == 'link') {
this.$('.mailpoet_posts_read_more_text').removeClass('mailpoet_hidden');
this.$('.mailpoet_posts_select_button').addClass('mailpoet_hidden');
} else if (value == 'button') {
this.$('.mailpoet_posts_read_more_text').addClass('mailpoet_hidden');
this.$('.mailpoet_posts_select_button').removeClass('mailpoet_hidden');
}
this.changeField('readMoreType', event);
},
changeDisplayType: function(event) {
var value = jQuery(event.target).val();
if (value == 'titleOnly') {
this.$('.mailpoet_posts_title_position_container').addClass('mailpoet_hidden');
this.$('.mailpoet_posts_title_as_list').removeClass('mailpoet_hidden');
} else {
this.$('.mailpoet_posts_title_position_container').removeClass('mailpoet_hidden');
this.$('.mailpoet_posts_title_as_list').addClass('mailpoet_hidden');
// Reset titleFormat if it was set to List when switching away from displayType=titleOnly
if (this.model.get('titleFormat') === 'ul') {
this.model.set('titleFormat', 'h1');
this.$('.mailpoet_posts_title_format').val(['h1']);
this.$('.mailpoet_posts_title_as_link').removeClass('mailpoet_hidden');
}
}
this.changeField('displayType', event);
},
changeTitleFormat: function(event) {
var value = jQuery(event.target).val();
if (value == 'ul') {
this.$('.mailpoet_posts_non_title_list_options').addClass('mailpoet_hidden');
this.model.set('titleIsLink', true);
this.$('.mailpoet_posts_title_as_link').addClass('mailpoet_hidden');
this.$('.mailpoet_posts_title_as_links').val(['true']);
} else {
this.$('.mailpoet_posts_non_title_list_options').removeClass('mailpoet_hidden');
this.$('.mailpoet_posts_title_as_link').removeClass('mailpoet_hidden');
}
this.changeField('titleFormat', event);
},
});
Module.PostsWidgetView = base.WidgetView.extend({
getTemplate: function() { return templates.postsInsertion; },
behaviors: {
DraggableBehavior: {
cloneOriginal: true,
drop: function() {
return new Module.PostsBlockModel({}, { parse: true });
}
}
},
});
App.on('before:start', function() {
App.registerBlockType('posts', {
blockModel: Module.PostsBlockModel,
blockView: Module.PostsBlockView,
}); });
var PostsDisplayOptionsSettingsView = base.BlockSettingsView.extend({ App.registerWidget({
getTemplate: function() { return templates.displayOptionsPostsBlockSettings; }, name: 'posts',
events: function() { widgetView: Module.PostsWidgetView,
return { priority: 96,
"click .mailpoet_posts_select_button": 'showButtonSettings',
"click .mailpoet_posts_select_divider": 'showDividerSettings',
"change .mailpoet_posts_read_more_type": 'changeReadMoreType',
"change .mailpoet_posts_display_type": 'changeDisplayType',
"change .mailpoet_posts_title_format": 'changeTitleFormat',
"change .mailpoet_posts_title_as_links": _.partial(this.changeBoolField, 'titleIsLink'),
"change .mailpoet_posts_show_divider": _.partial(this.changeBoolField, 'showDivider'),
"keyup .mailpoet_posts_show_amount": _.partial(this.changeField, "amount"),
"change .mailpoet_posts_content_type": _.partial(this.changeField, "contentType"),
"change .mailpoet_posts_include_or_exclude": _.partial(this.changeField, "inclusionType"),
"change .mailpoet_posts_title_position": _.partial(this.changeField, "titlePosition"),
"change .mailpoet_posts_title_alignment": _.partial(this.changeField, "titleAlignment"),
"change .mailpoet_posts_image_padded": _.partial(this.changeBoolField, "imagePadded"),
"change .mailpoet_posts_show_author": _.partial(this.changeField, "showAuthor"),
"keyup .mailpoet_posts_author_preceded_by": _.partial(this.changeField, "authorPrecededBy"),
"change .mailpoet_posts_show_categories": _.partial(this.changeField, "showCategories"),
"keyup .mailpoet_posts_categories": _.partial(this.changeField, "categoriesPrecededBy"),
"keyup .mailpoet_posts_read_more_text": _.partial(this.changeField, "readMoreText"),
"change .mailpoet_posts_sort_by": _.partial(this.changeField, "sortBy"),
};
},
behaviors: {
ColorPickerBehavior: {},
},
templateHelpers: function() {
return {
model: this.model.toJSON(),
};
},
showButtonSettings: function(event) {
var buttonModule = App.module('blocks.button');
(new buttonModule.ButtonBlockSettingsView({
model: this.model.get('readMoreButton'),
renderOptions: {
displayFormat: 'subpanel',
hideLink: true,
hideApplyToAll: true,
},
})).render();
},
showDividerSettings: function(event) {
var dividerModule = App.module('blocks.divider');
(new dividerModule.DividerBlockSettingsView({
model: this.model.get('divider'),
renderOptions: {
displayFormat: 'subpanel',
hideApplyToAll: true,
},
})).render();
},
changeReadMoreType: function(event) {
var value = jQuery(event.target).val();
if (value == 'link') {
this.$('.mailpoet_posts_read_more_text').removeClass('mailpoet_hidden');
this.$('.mailpoet_posts_select_button').addClass('mailpoet_hidden');
} else if (value == 'button') {
this.$('.mailpoet_posts_read_more_text').addClass('mailpoet_hidden');
this.$('.mailpoet_posts_select_button').removeClass('mailpoet_hidden');
}
this.changeField('readMoreType', event);
},
changeDisplayType: function(event) {
var value = jQuery(event.target).val();
if (value == 'titleOnly') {
this.$('.mailpoet_posts_title_position_container').addClass('mailpoet_hidden');
this.$('.mailpoet_posts_title_as_list').removeClass('mailpoet_hidden');
} else {
this.$('.mailpoet_posts_title_position_container').removeClass('mailpoet_hidden');
this.$('.mailpoet_posts_title_as_list').addClass('mailpoet_hidden');
// Reset titleFormat if it was set to List when switching away from displayType=titleOnly
if (this.model.get('titleFormat') === 'ul') {
this.model.set('titleFormat', 'h1');
this.$('.mailpoet_posts_title_format').val(['h1']);
this.$('.mailpoet_posts_title_as_link').removeClass('mailpoet_hidden');
}
}
this.changeField('displayType', event);
},
changeTitleFormat: function(event) {
var value = jQuery(event.target).val();
if (value == 'ul') {
this.$('.mailpoet_posts_non_title_list_options').addClass('mailpoet_hidden');
this.model.set('titleIsLink', true);
this.$('.mailpoet_posts_title_as_link').addClass('mailpoet_hidden');
this.$('.mailpoet_posts_title_as_links').val(['true']);
} else {
this.$('.mailpoet_posts_non_title_list_options').removeClass('mailpoet_hidden');
this.$('.mailpoet_posts_title_as_link').removeClass('mailpoet_hidden');
}
this.changeField('titleFormat', event);
},
});
Module.PostsWidgetView = base.WidgetView.extend({
getTemplate: function() { return templates.postsInsertion; },
behaviors: {
DraggableBehavior: {
cloneOriginal: true,
drop: function() {
return new Module.PostsBlockModel({}, { parse: true });
}
}
},
});
App.on('before:start', function() {
App.registerBlockType('posts', {
blockModel: Module.PostsBlockModel,
blockView: Module.PostsBlockView,
});
App.registerWidget({
name: 'posts',
widgetView: Module.PostsWidgetView,
priority: 96,
});
}); });
});
}); });
}); });

View File

@ -9,366 +9,365 @@ define('newsletter_editor/blocks/social', [
], function(EditorApplication, Backbone, Marionette, MailPoet) { ], function(EditorApplication, Backbone, Marionette, MailPoet) {
EditorApplication.module("blocks.social", function(Module, App, Backbone, Marionette, $, _) { EditorApplication.module("blocks.social", function(Module, App, Backbone, Marionette, $, _) {
"use strict"; "use strict";
var base = App.module('blocks.base'), var base = App.module('blocks.base'),
SocialBlockSettingsIconSelectorView, SocialBlockSettingsIconView, SocialBlockSettingsStylesView; SocialBlockSettingsIconSelectorView, SocialBlockSettingsIconView, SocialBlockSettingsStylesView;
Module.SocialIconModel = Backbone.SuperModel.extend({ Module.SocialIconModel = Backbone.SuperModel.extend({
defaults: function() { defaults: function() {
var defaultValues = App.getConfig().get('socialIcons.custom'); var defaultValues = App.getConfig().get('socialIcons.custom');
return { return {
type: 'socialIcon',
iconType: 'custom',
link: defaultValues.get('defaultLink'),
image: App.getAvailableStyles().get('socialIconSets.default.custom'),
height: '32px',
width: '32px',
text: defaultValues.get('title'),
};
},
initialize: function(options) {
var that = this;
// Make model swap to default values for that type when iconType changes
this.on('change:iconType', function() {
var defaultValues = App.getConfig().get('socialIcons').get(that.get('iconType')),
iconSet = that.collection.iconBlockModel.getIconSet();
this.set({
link: defaultValues.get('defaultLink'),
image: iconSet.get(that.get('iconType')),
text: defaultValues.get('title'),
});
}, this);
this.on('change', function() { App.getChannel().trigger('autoSave'); });
},
});
Module.SocialIconCollectionModel = Backbone.Collection.extend({
model: Module.SocialIconModel
});
Module.SocialBlockModel = base.BlockModel.extend({
name: 'iconBlockModel',
defaults: function() {
return this._getDefaults({
type: 'social',
iconSet: 'default',
icons: new Module.SocialIconCollectionModel(),
}, EditorApplication.getConfig().get('blockDefaults.social'));
},
relations: {
icons: Module.SocialIconCollectionModel,
},
initialize: function() {
this.get('icons').on('add remove change', this._iconsChanged, this);
this.on('change:iconSet', this.changeIconSet, this);
},
getIconSet: function() {
return App.getAvailableStyles().get('socialIconSets').get(this.get('iconSet'));
},
changeIconSet: function() {
var iconSet = this.getIconSet();
_.each(this.get('icons').models, function(model) {
model.set('image', iconSet.get(model.get('iconType')));
});
},
_iconsChanged: function() {
App.getChannel().trigger('autoSave');
},
});
var SocialIconView = Marionette.ItemView.extend({
tagName: 'span',
getTemplate: function() { return templates.socialIconBlock; },
modelEvents: {
'change': 'render',
},
templateHelpers: function() {
var allIconSets = App.getAvailableStyles().get('socialIconSets');
return {
model: this.model.toJSON(),
allIconSets: allIconSets.toJSON(),
};
},
});
Module.SocialBlockView = Marionette.CompositeView.extend({
regionClass: Marionette.Region,
className: 'mailpoet_block mailpoet_social_block mailpoet_droppable_block',
getTemplate: function() { return templates.socialBlock; },
childViewContainer: '.mailpoet_social',
modelEvents: {
'change': 'render'
},
events: {
"mouseover": "showTools",
"mouseout": "hideTools",
},
regions: {
toolsRegion: '> .mailpoet_tools',
},
ui: {
tools: '> .mailpoet_tools'
},
behaviors: {
DraggableBehavior: {
cloneOriginal: true,
hideOriginal: true,
onDrop: function(options) {
// After a clone of model has been dropped, cleanup
// and destroy self
options.dragBehavior.view.model.destroy();
},
onDragSubstituteBy: function(behavior) {
var WidgetView, node;
// When block is being dragged, display the widget icon instead.
// This will create an instance of block's widget view and
// use it's rendered DOM element instead of the content block
if (_.isFunction(behavior.view.onDragSubstituteBy)) {
WidgetView = new (behavior.view.onDragSubstituteBy())();
WidgetView.render();
node = WidgetView.$el.get(0).cloneNode(true);
WidgetView.destroy();
return node;
}
},
},
},
onDragSubstituteBy: function() { return Module.SocialWidgetView; },
constructor: function() {
// Set the block collection to be handled by this view as well
arguments[0].collection = arguments[0].model.get('icons');
Marionette.CompositeView.apply(this, arguments);
},
// Determines which view type should be used for a child
childView: SocialIconView,
templateHelpers: function() {
return {
model: this.model.toJSON(),
viewCid: this.cid,
};
},
onRender: function() {
this._rebuildRegions();
this.toolsView = new Module.SocialBlockToolsView({ model: this.model });
this.toolsRegion.show(this.toolsView);
},
onBeforeDestroy: function() {
this.regionManager.destroy();
},
showTools: function(_event) {
this.$(this.ui.tools).show();
_event.stopPropagation();
},
hideTools: function(_event) {
this.$(this.ui.tools).hide();
_event.stopPropagation();
},
getDropFunc: function() {
var that = this;
return function() {
var newModel = that.model.clone();
//that.model.destroy();
return newModel;
};
},
_buildRegions: function(regions) {
var that = this;
var defaults = {
regionClass: this.getOption('regionClass'),
parentEl: function() { return that.$el; }
};
return this.regionManager.addRegions(regions, defaults);
},
_rebuildRegions: function() {
if (this.regionManager === undefined) {
this.regionManager = new Backbone.Marionette.RegionManager();
}
this.regionManager.destroy();
_.extend(this, this._buildRegions(this.regions));
},
});
Module.SocialBlockToolsView = base.BlockToolsView.extend({
getSettingsView: function() { return Module.SocialBlockSettingsView; },
});
// Sidebar view container
Module.SocialBlockSettingsView = base.BlockSettingsView.extend({
getTemplate: function() { return templates.socialBlockSettings; },
regions: {
iconRegion: '#mailpoet_social_icons_selection',
stylesRegion: '#mailpoet_social_icons_styles',
},
events: function() {
return {
"click .mailpoet_done_editing": "close",
};
},
initialize: function() {
base.BlockSettingsView.prototype.initialize.apply(this, arguments);
this._iconSelectorView = new SocialBlockSettingsIconSelectorView({ model: this.model });
this._stylesView = new SocialBlockSettingsStylesView({ model: this.model });
},
onRender: function() {
this.iconRegion.show(this._iconSelectorView);
this.stylesRegion.show(this._stylesView);
}
});
// Single icon settings view, used by the selector view
SocialBlockSettingsIconView = Marionette.ItemView.extend({
getTemplate: function() { return templates.socialSettingsIcon; },
events: function() {
return {
"click .mailpoet_delete_block": "deleteIcon",
"change .mailpoet_social_icon_field_type": _.partial(this.changeField, "iconType"),
"keyup .mailpoet_social_icon_field_image": _.partial(this.changeField, "image"),
"keyup .mailpoet_social_icon_field_link": this.changeLink,
"keyup .mailpoet_social_icon_field_text": _.partial(this.changeField, "text"),
};
},
modelEvents: {
'change:iconType': 'render',
'change:image': function() {
this.$('.mailpoet_social_icon_image').attr('src', this.model.get('image'));
},
'change:text': function() {
this.$('.mailpoet_social_icon_image').attr('alt', this.model.get('text'));
},
},
templateHelpers: function() {
var icons = App.getConfig().get('socialIcons'),
// Construct icon type list of format [{iconType: 'type', title: 'Title'}, ...]
availableIconTypes = _.map(_.keys(icons.attributes), function(key) { return { iconType: key, title: icons.get(key).get('title') }; }),
allIconSets = App.getAvailableStyles().get('socialIconSets');
return {
model: this.model.toJSON(),
iconTypes: availableIconTypes,
currentType: icons.get(this.model.get('iconType')).toJSON(),
allIconSets: allIconSets.toJSON(),
};
},
deleteIcon: function() {
this.model.destroy();
},
changeLink: function(event) {
if (this.model.get('iconType') === 'email') {
this.model.set('link', 'mailto:' + jQuery(event.target).val());
} else {
return this.changeField('link', event);
}
},
changeField: function(field, event) {
this.model.set(field, jQuery(event.target).val());
},
});
// Select icons section container view
SocialBlockSettingsIconSelectorView = Marionette.CompositeView.extend({
getTemplate: function() { return templates.socialSettingsIconSelector; },
childView: SocialBlockSettingsIconView,
childViewContainer: '#mailpoet_social_icon_selector_contents',
events: {
'click .mailpoet_add_social_icon': 'addSocialIcon',
},
modelEvents: {
'change:iconSet': 'render',
},
behaviors: {
SortableBehavior: {
items: '#mailpoet_social_icon_selector_contents > div',
},
},
constructor: function() {
// Set the icon collection to be handled by this view as well
arguments[0].collection = arguments[0].model.get('icons');
Marionette.CompositeView.apply(this, arguments);
},
addSocialIcon: function() {
// Add a social icon with default values
this.collection.add({});
}
});
SocialBlockSettingsStylesView = Marionette.ItemView.extend({
getTemplate: function() { return templates.socialSettingsStyles; },
modelEvents: {
'change': 'render',
},
events: {
'click .mailpoet_social_icon_set': 'changeSocialIconSet',
},
initialize: function() {
this.listenTo(this.model.get('icons'), 'add remove change', this.render);
},
templateHelpers: function() {
var allIconSets = App.getAvailableStyles().get('socialIconSets');
return {
activeSet: this.model.get('iconSet'),
socialIconSets: allIconSets.toJSON(),
availableSets: _.keys(allIconSets.toJSON()),
availableSocialIcons: this.model.get('icons').pluck('iconType'),
};
},
changeSocialIconSet: function(event) {
this.model.set('iconSet', jQuery(event.currentTarget).data('setname'));
},
onBeforeDestroy: function() {
this.model.get('icons').off('add remove', this.render, this);
},
});
Module.SocialWidgetView = base.WidgetView.extend({
getTemplate: function() { return templates.socialInsertion; },
behaviors: {
DraggableBehavior: {
cloneOriginal: true,
drop: function() {
return new Module.SocialBlockModel({
type: 'social',
iconSet: 'default',
icons: [
{
type: 'socialIcon', type: 'socialIcon',
iconType: 'custom', iconType: 'facebook',
link: defaultValues.get('defaultLink'), link: 'http://example.com',
image: App.getAvailableStyles().get('socialIconSets.default.custom'), image: App.getAvailableStyles().get('socialIconSets.default.facebook'),
height: '32px', height: '32px',
width: '32px', width: '32px',
text: defaultValues.get('title'), text: 'Facebook',
}; },
}, {
initialize: function(options) { type: 'socialIcon',
var that = this; iconType: 'twitter',
// Make model swap to default values for that type when iconType changes link: 'http://example.com',
this.on('change:iconType', function() { image: App.getAvailableStyles().get('socialIconSets.default.twitter'),
var defaultValues = App.getConfig().get('socialIcons').get(that.get('iconType')), height: '32px',
iconSet = that.collection.iconBlockModel.getIconSet(); width: '32px',
this.set({ text: 'Twitter',
link: defaultValues.get('defaultLink'), },
image: iconSet.get(that.get('iconType')), ],
text: defaultValues.get('title'), }, { parse: true });
});
}, this);
this.on('change', function() { App.getChannel().trigger('autoSave'); });
},
});
Module.SocialIconCollectionModel = Backbone.Collection.extend({
model: Module.SocialIconModel
});
Module.SocialBlockModel = base.BlockModel.extend({
name: 'iconBlockModel',
defaults: function() {
return this._getDefaults({
type: 'social',
iconSet: 'default',
icons: new Module.SocialIconCollectionModel(),
}, EditorApplication.getConfig().get('blockDefaults.social'));
},
relations: {
icons: Module.SocialIconCollectionModel,
},
initialize: function() {
this.get('icons').on('add remove change', this._iconsChanged, this);
this.on('change:iconSet', this.changeIconSet, this);
},
getIconSet: function() {
return App.getAvailableStyles().get('socialIconSets').get(this.get('iconSet'));
},
changeIconSet: function() {
var iconSet = this.getIconSet();
_.each(this.get('icons').models, function(model) {
model.set('image', iconSet.get(model.get('iconType')));
});
},
_iconsChanged: function() {
App.getChannel().trigger('autoSave');
},
});
var SocialIconView = Marionette.ItemView.extend({
tagName: 'span',
getTemplate: function() { return templates.socialIconBlock; },
modelEvents: {
'change': 'render',
},
templateHelpers: function() {
var allIconSets = App.getAvailableStyles().get('socialIconSets');
return {
model: this.model.toJSON(),
allIconSets: allIconSets.toJSON(),
};
},
});
Module.SocialBlockView = Marionette.CompositeView.extend({
regionClass: Marionette.Region,
className: 'mailpoet_block mailpoet_social_block mailpoet_droppable_block',
getTemplate: function() { return templates.socialBlock; },
childViewContainer: '.mailpoet_social',
modelEvents: {
'change': 'render'
},
events: {
"mouseover": "showTools",
"mouseout": "hideTools",
},
regions: {
toolsRegion: '> .mailpoet_tools',
},
ui: {
tools: '> .mailpoet_tools'
},
behaviors: {
DraggableBehavior: {
cloneOriginal: true,
hideOriginal: true,
onDrop: function(options) {
// After a clone of model has been dropped, cleanup
// and destroy self
options.dragBehavior.view.model.destroy();
},
onDragSubstituteBy: function(behavior) {
var WidgetView, node;
// When block is being dragged, display the widget icon instead.
// This will create an instance of block's widget view and
// use it's rendered DOM element instead of the content block
if (_.isFunction(behavior.view.onDragSubstituteBy)) {
WidgetView = new (behavior.view.onDragSubstituteBy())();
WidgetView.render();
node = WidgetView.$el.get(0).cloneNode(true);
WidgetView.destroy();
return node;
}
},
},
},
onDragSubstituteBy: function() { return Module.SocialWidgetView; },
constructor: function() {
// Set the block collection to be handled by this view as well
arguments[0].collection = arguments[0].model.get('icons');
Marionette.CompositeView.apply(this, arguments);
},
// Determines which view type should be used for a child
childView: SocialIconView,
templateHelpers: function() {
return {
model: this.model.toJSON(),
viewCid: this.cid,
};
},
onRender: function() {
this._rebuildRegions();
this.toolsView = new Module.SocialBlockToolsView({ model: this.model });
this.toolsRegion.show(this.toolsView);
},
onBeforeDestroy: function() {
this.regionManager.destroy();
},
showTools: function(_event) {
this.$(this.ui.tools).show();
_event.stopPropagation();
},
hideTools: function(_event) {
this.$(this.ui.tools).hide();
_event.stopPropagation();
},
getDropFunc: function() {
var that = this;
return function() {
var newModel = that.model.clone();
//that.model.destroy();
return newModel;
};
},
_buildRegions: function(regions) {
var that = this;
var defaults = {
regionClass: this.getOption('regionClass'),
parentEl: function() { return that.$el; }
};
return this.regionManager.addRegions(regions, defaults);
},
_rebuildRegions: function() {
if (this.regionManager === undefined) {
this.regionManager = new Backbone.Marionette.RegionManager();
}
this.regionManager.destroy();
_.extend(this, this._buildRegions(this.regions));
},
});
Module.SocialBlockToolsView = base.BlockToolsView.extend({
getSettingsView: function() { return Module.SocialBlockSettingsView; },
});
// Sidebar view container
Module.SocialBlockSettingsView = base.BlockSettingsView.extend({
getTemplate: function() { return templates.socialBlockSettings; },
regions: {
iconRegion: '#mailpoet_social_icons_selection',
stylesRegion: '#mailpoet_social_icons_styles',
},
events: function() {
return {
"click .mailpoet_done_editing": "close",
};
},
initialize: function() {
base.BlockSettingsView.prototype.initialize.apply(this, arguments);
this._iconSelectorView = new SocialBlockSettingsIconSelectorView({ model: this.model });
this._stylesView = new SocialBlockSettingsStylesView({ model: this.model });
},
onRender: function() {
this.iconRegion.show(this._iconSelectorView);
this.stylesRegion.show(this._stylesView);
} }
}
},
});
App.on('before:start', function() {
App.registerBlockType('social', {
blockModel: Module.SocialBlockModel,
blockView: Module.SocialBlockView,
}); });
// Single icon settings view, used by the selector view App.registerWidget({
SocialBlockSettingsIconView = Marionette.ItemView.extend({ name: 'social',
getTemplate: function() { return templates.socialSettingsIcon; }, widgetView: Module.SocialWidgetView,
events: function() { priority: 95,
return {
"click .mailpoet_delete_block": "deleteIcon",
"change .mailpoet_social_icon_field_type": _.partial(this.changeField, "iconType"),
"keyup .mailpoet_social_icon_field_image": _.partial(this.changeField, "image"),
"keyup .mailpoet_social_icon_field_link": this.changeLink,
"keyup .mailpoet_social_icon_field_text": _.partial(this.changeField, "text"),
};
},
modelEvents: {
'change:iconType': 'render',
'change:image': function() {
this.$('.mailpoet_social_icon_image').attr('src', this.model.get('image'));
},
'change:text': function() {
this.$('.mailpoet_social_icon_image').attr('alt', this.model.get('text'));
},
},
templateHelpers: function() {
var icons = App.getConfig().get('socialIcons'),
// Construct icon type list of format [{iconType: 'type', title: 'Title'}, ...]
availableIconTypes = _.map(_.keys(icons.attributes), function(key) { return { iconType: key, title: icons.get(key).get('title') }; }),
allIconSets = App.getAvailableStyles().get('socialIconSets');
return {
model: this.model.toJSON(),
iconTypes: availableIconTypes,
currentType: icons.get(this.model.get('iconType')).toJSON(),
allIconSets: allIconSets.toJSON(),
};
},
deleteIcon: function() {
this.model.destroy();
},
changeLink: function(event) {
if (this.model.get('iconType') === 'email') {
this.model.set('link', 'mailto:' + jQuery(event.target).val());
} else {
return this.changeField('link', event);
}
},
changeField: function(field, event) {
this.model.set(field, jQuery(event.target).val());
},
});
// Select icons section container view
SocialBlockSettingsIconSelectorView = Marionette.CompositeView.extend({
getTemplate: function() { return templates.socialSettingsIconSelector; },
childView: SocialBlockSettingsIconView,
childViewContainer: '#mailpoet_social_icon_selector_contents',
events: {
'click .mailpoet_add_social_icon': 'addSocialIcon',
},
modelEvents: {
'change:iconSet': 'render',
},
behaviors: {
SortableBehavior: {
items: '#mailpoet_social_icon_selector_contents > div',
},
},
constructor: function() {
// Set the icon collection to be handled by this view as well
arguments[0].collection = arguments[0].model.get('icons');
Marionette.CompositeView.apply(this, arguments);
},
addSocialIcon: function() {
// Add a social icon with default values
this.collection.add({});
}
});
SocialBlockSettingsStylesView = Marionette.ItemView.extend({
getTemplate: function() { return templates.socialSettingsStyles; },
modelEvents: {
'change': 'render',
},
events: {
'click .mailpoet_social_icon_set': 'changeSocialIconSet',
},
initialize: function() {
this.listenTo(this.model.get('icons'), 'add remove change', this.render);
},
templateHelpers: function() {
var allIconSets = App.getAvailableStyles().get('socialIconSets');
return {
activeSet: this.model.get('iconSet'),
socialIconSets: allIconSets.toJSON(),
availableSets: _.keys(allIconSets.toJSON()),
availableSocialIcons: this.model.get('icons').pluck('iconType'),
};
},
changeSocialIconSet: function(event) {
this.model.set('iconSet', jQuery(event.currentTarget).data('setname'));
},
onBeforeDestroy: function() {
this.model.get('icons').off('add remove', this.render, this);
},
});
Module.SocialWidgetView = base.WidgetView.extend({
getTemplate: function() { return templates.socialInsertion; },
behaviors: {
DraggableBehavior: {
cloneOriginal: true,
drop: function() {
return new Module.SocialBlockModel({
type: 'social',
iconSet: 'default',
icons: [
{
type: 'socialIcon',
iconType: 'facebook',
link: 'http://example.com',
image: App.getAvailableStyles().get('socialIconSets.default.facebook'),
height: '32px',
width: '32px',
text: 'Facebook',
},
{
type: 'socialIcon',
iconType: 'twitter',
link: 'http://example.com',
image: App.getAvailableStyles().get('socialIconSets.default.twitter'),
height: '32px',
width: '32px',
text: 'Twitter',
},
],
}, { parse: true });
}
}
},
});
App.on('before:start', function() {
App.registerBlockType('social', {
blockModel: Module.SocialBlockModel,
blockView: Module.SocialBlockView,
});
App.registerWidget({
name: 'social',
widgetView: Module.SocialWidgetView,
priority: 95,
});
}); });
});
}); });
}); });

View File

@ -9,97 +9,96 @@ define('newsletter_editor/blocks/spacer', [
], function(EditorApplication, Backbone, Marionette, MailPoet) { ], function(EditorApplication, Backbone, Marionette, MailPoet) {
EditorApplication.module("blocks.spacer", function(Module, App, Backbone, Marionette, $, _) { EditorApplication.module("blocks.spacer", function(Module, App, Backbone, Marionette, $, _) {
"use strict"; "use strict";
var base = App.module('blocks.base'); var base = App.module('blocks.base');
Module.SpacerBlockModel = base.BlockModel.extend({ Module.SpacerBlockModel = base.BlockModel.extend({
defaults: function() { defaults: function() {
return this._getDefaults({ return this._getDefaults({
type: 'spacer', type: 'spacer',
styles: { styles: {
block: { block: {
backgroundColor: 'transparent', backgroundColor: 'transparent',
height: '40px', height: '40px',
}, },
},
}, EditorApplication.getConfig().get('blockDefaults.spacer'));
}, },
}, EditorApplication.getConfig().get('blockDefaults.spacer'));
},
});
Module.SpacerBlockView = base.BlockView.extend({
className: "mailpoet_block mailpoet_spacer_block mailpoet_droppable_block",
getTemplate: function() { return templates.spacerBlock; },
behaviors: _.defaults({
ResizableBehavior: {
elementSelector: '.mailpoet_spacer',
resizeHandleSelector: '.mailpoet_resize_handle',
minLength: 20, // TODO: Move this number to editor configuration
modelField: 'styles.block.height',
},
}, base.BlockView.prototype.behaviors),
modelEvents: _.omit(base.BlockView.prototype.modelEvents, 'change'),
onDragSubstituteBy: function() { return Module.SpacerWidgetView; },
initialize: function() {
base.BlockView.prototype.initialize.apply(this, arguments);
this.listenTo(this.model, 'change:styles.block.backgroundColor', this.render);
this.listenTo(this.model, 'change:styles.block.height', this.changeHeight);
},
onRender: function() {
this.toolsView = new Module.SpacerBlockToolsView({ model: this.model });
this.toolsRegion.show(this.toolsView);
},
changeHeight: function() {
this.$('.mailpoet_spacer').css('height', this.model.get('styles.block.height'));
this.$('.mailpoet_resize_handle_text').text(this.model.get('styles.block.height'));
},
onBeforeDestroy: function() {
this.stopListening(this.model);
},
});
Module.SpacerBlockToolsView = base.BlockToolsView.extend({
getSettingsView: function() { return Module.SpacerBlockSettingsView; },
});
Module.SpacerBlockSettingsView = base.BlockSettingsView.extend({
getTemplate: function() { return templates.spacerBlockSettings; },
events: function() {
return {
"change .mailpoet_field_spacer_background_color": _.partial(this.changeColorField, "styles.block.backgroundColor"),
"click .mailpoet_done_editing": "close",
};
},
behaviors: {
ColorPickerBehavior: {},
},
});
Module.SpacerWidgetView = base.WidgetView.extend({
getTemplate: function() { return templates.spacerInsertion; },
behaviors: {
DraggableBehavior: {
cloneOriginal: true,
drop: function() {
return new Module.SpacerBlockModel();
},
}
},
});
App.on('before:start', function() {
App.registerBlockType('spacer', {
blockModel: Module.SpacerBlockModel,
blockView: Module.SpacerBlockView,
}); });
Module.SpacerBlockView = base.BlockView.extend({ App.registerWidget({
className: "mailpoet_block mailpoet_spacer_block mailpoet_droppable_block", name: 'spacer',
getTemplate: function() { return templates.spacerBlock; }, widgetView: Module.SpacerWidgetView,
behaviors: _.defaults({ priority: 94,
ResizableBehavior: {
elementSelector: '.mailpoet_spacer',
resizeHandleSelector: '.mailpoet_resize_handle',
minLength: 20, // TODO: Move this number to editor configuration
modelField: 'styles.block.height',
},
}, base.BlockView.prototype.behaviors),
modelEvents: _.omit(base.BlockView.prototype.modelEvents, 'change'),
onDragSubstituteBy: function() { return Module.SpacerWidgetView; },
initialize: function() {
base.BlockView.prototype.initialize.apply(this, arguments);
this.listenTo(this.model, 'change:styles.block.backgroundColor', this.render);
this.listenTo(this.model, 'change:styles.block.height', this.changeHeight);
},
onRender: function() {
this.toolsView = new Module.SpacerBlockToolsView({ model: this.model });
this.toolsRegion.show(this.toolsView);
},
changeHeight: function() {
this.$('.mailpoet_spacer').css('height', this.model.get('styles.block.height'));
this.$('.mailpoet_resize_handle_text').text(this.model.get('styles.block.height'));
},
onBeforeDestroy: function() {
this.stopListening(this.model);
},
});
Module.SpacerBlockToolsView = base.BlockToolsView.extend({
getSettingsView: function() { return Module.SpacerBlockSettingsView; },
});
Module.SpacerBlockSettingsView = base.BlockSettingsView.extend({
getTemplate: function() { return templates.spacerBlockSettings; },
events: function() {
return {
"change .mailpoet_field_spacer_background_color": _.partial(this.changeColorField, "styles.block.backgroundColor"),
"click .mailpoet_done_editing": "close",
};
},
behaviors: {
ColorPickerBehavior: {},
},
});
Module.SpacerWidgetView = base.WidgetView.extend({
getTemplate: function() { return templates.spacerInsertion; },
behaviors: {
DraggableBehavior: {
cloneOriginal: true,
drop: function() {
return new Module.SpacerBlockModel();
},
}
},
});
App.on('before:start', function() {
App.registerBlockType('spacer', {
blockModel: Module.SpacerBlockModel,
blockView: Module.SpacerBlockView,
});
App.registerWidget({
name: 'spacer',
widgetView: Module.SpacerWidgetView,
priority: 94,
});
}); });
});
}); });
}); });

View File

@ -10,117 +10,116 @@ define('newsletter_editor/blocks/text', [
], function(EditorApplication, Backbone, Marionette, MailPoet, jQuery) { ], function(EditorApplication, Backbone, Marionette, MailPoet, jQuery) {
EditorApplication.module("blocks.text", function(Module, App, Backbone, Marionette, $, _) { EditorApplication.module("blocks.text", function(Module, App, Backbone, Marionette, $, _) {
"use strict"; "use strict";
var base = App.module('blocks.base'); var base = App.module('blocks.base');
Module.TextBlockModel = base.BlockModel.extend({ Module.TextBlockModel = base.BlockModel.extend({
defaults: function() { defaults: function() {
return this._getDefaults({ return this._getDefaults({
type: 'text', type: 'text',
text: 'Edit this to insert text', text: 'Edit this to insert text',
}, EditorApplication.getConfig().get('blockDefaults.text')); }, EditorApplication.getConfig().get('blockDefaults.text'));
},
});
Module.TextBlockView = base.BlockView.extend({
className: "mailpoet_block mailpoet_text_block mailpoet_droppable_block",
getTemplate: function() { return templates.textBlock; },
modelEvents: _.omit(base.BlockView.prototype.modelEvents, 'change'), // Prevent rerendering on model change due to text editor redrawing
initialize: function(options) {
this.renderOptions = _.defaults(options.renderOptions || {}, {
disableTextEditor: false,
});
},
onDragSubstituteBy: function() { return Module.TextWidgetView; },
onRender: function() {
this.toolsView = new Module.TextBlockToolsView({
model: this.model,
tools: {
settings: false,
}, },
}); });
this.toolsRegion.show(this.toolsView);
},
onDomRefresh: function() {
this.attachTextEditor();
},
attachTextEditor: function() {
var that = this;
if (!this.renderOptions.disableTextEditor) {
this.$('.mailpoet_content').tinymce({
inline: true,
Module.TextBlockView = base.BlockView.extend({ menubar: false,
className: "mailpoet_block mailpoet_text_block mailpoet_droppable_block", toolbar1: "styleselect bold italic forecolor | link unlink",
getTemplate: function() { return templates.textBlock; }, toolbar2: "alignleft aligncenter alignright alignjustify | bullist numlist blockquote | code mailpoet_custom_fields",
modelEvents: _.omit(base.BlockView.prototype.modelEvents, 'change'), // Prevent rerendering on model change due to text editor redrawing
initialize: function(options) { //forced_root_block: 'p',
this.renderOptions = _.defaults(options.renderOptions || {}, { valid_elements: "p[class|style],span[class|style],a[href|class|title|target|style],h1[class|style],h2[class|style],h3[class|style],ol[class|style],ul[class|style],li[class|style],strong[class|style],em[class|style],strike,br,blockquote[class|style],table[class|style],tr[class|style],th[class|style],td[class|style]",
disableTextEditor: false, invalid_elements: "script",
style_formats: [
{title: 'Heading 1', block: 'h1'},
{title: 'Heading 2', block: 'h2'},
{title: 'Heading 3', block: 'h3'},
{title: 'Paragraph', block: 'p'},
],
plugins: "wplink code textcolor mailpoet_custom_fields",
setup: function(editor) {
editor.on('change', function(e) {
that.model.set('text', editor.getContent());
}); });
},
onDragSubstituteBy: function() { return Module.TextWidgetView; }, editor.on('focus', function(e) {
onRender: function() { that.disableShowingTools();
this.toolsView = new Module.TextBlockToolsView({
model: this.model,
tools: {
settings: false,
},
}); });
this.toolsRegion.show(this.toolsView);
},
onDomRefresh: function() {
this.attachTextEditor();
},
attachTextEditor: function() {
var that = this;
if (!this.renderOptions.disableTextEditor) {
this.$('.mailpoet_content').tinymce({
inline: true,
menubar: false, editor.on('blur', function(e) {
toolbar1: "styleselect bold italic forecolor | link unlink", that.enableShowingTools();
toolbar2: "alignleft aligncenter alignright alignjustify | bullist numlist blockquote | code mailpoet_custom_fields", });
},
//forced_root_block: 'p', mailpoet_custom_fields: App.getConfig().get('customFields').toJSON(),
valid_elements: "p[class|style],span[class|style],a[href|class|title|target|style],h1[class|style],h2[class|style],h3[class|style],ol[class|style],ul[class|style],li[class|style],strong[class|style],em[class|style],strike,br,blockquote[class|style],table[class|style],tr[class|style],th[class|style],td[class|style]", mailpoet_custom_fields_window_title: App.getConfig().get('translations.customFieldsWindowTitle'),
invalid_elements: "script",
style_formats: [
{title: 'Heading 1', block: 'h1'},
{title: 'Heading 2', block: 'h2'},
{title: 'Heading 3', block: 'h3'},
{title: 'Paragraph', block: 'p'},
],
plugins: "wplink code textcolor mailpoet_custom_fields",
setup: function(editor) {
editor.on('change', function(e) {
that.model.set('text', editor.getContent());
});
editor.on('focus', function(e) {
that.disableShowingTools();
});
editor.on('blur', function(e) {
that.enableShowingTools();
});
},
mailpoet_custom_fields: App.getConfig().get('customFields').toJSON(),
mailpoet_custom_fields_window_title: App.getConfig().get('translations.customFieldsWindowTitle'),
});
}
},
});
Module.TextBlockToolsView = base.BlockToolsView.extend({
getSettingsView: function() { return Module.TextBlockSettingsView; },
});
Module.TextBlockSettingsView = base.BlockSettingsView.extend({
getTemplate: function() { return templates.textBlockSettings; },
});
Module.TextWidgetView = base.WidgetView.extend({
getTemplate: function() { return templates.textInsertion; },
behaviors: {
DraggableBehavior: {
cloneOriginal: true,
drop: function() {
return new Module.TextBlockModel();
},
}
},
});
App.on('before:start', function() {
App.registerBlockType('text', {
blockModel: Module.TextBlockModel,
blockView: Module.TextBlockView,
}); });
}
},
});
App.registerWidget({ Module.TextBlockToolsView = base.BlockToolsView.extend({
name: 'text', getSettingsView: function() { return Module.TextBlockSettingsView; },
widgetView: Module.TextWidgetView, });
priority: 90,
}); Module.TextBlockSettingsView = base.BlockSettingsView.extend({
getTemplate: function() { return templates.textBlockSettings; },
});
Module.TextWidgetView = base.WidgetView.extend({
getTemplate: function() { return templates.textInsertion; },
behaviors: {
DraggableBehavior: {
cloneOriginal: true,
drop: function() {
return new Module.TextBlockModel();
},
}
},
});
App.on('before:start', function() {
App.registerBlockType('text', {
blockModel: Module.TextBlockModel,
blockView: Module.TextBlockView,
}); });
App.registerWidget({
name: 'text',
widgetView: Module.TextWidgetView,
priority: 90,
});
});
}); });
}); });

View File

@ -4,32 +4,34 @@ define('newsletter_editor/components/config', [
], function(EditorApplication, Backbone) { ], function(EditorApplication, Backbone) {
EditorApplication.module("components.config", function(Module, App, Backbone, Marionette, $, _) { EditorApplication.module("components.config", function(Module, App, Backbone, Marionette, $, _) {
"use strict"; "use strict";
Module.ConfigModel = Backbone.SuperModel.extend({ Module.ConfigModel = Backbone.SuperModel.extend({
defaults: { defaults: {
availableStyles: {}, availableStyles: {},
socialIcons: {}, socialIcons: {},
blockDefaults: {}, blockDefaults: {},
translations: {}, translations: {},
sidepanelWidth: '331px', sidepanelWidth: '331px',
validation: {}, validation: {},
urls: {}, urls: {},
}, },
}); });
// Global and available styles for access in blocks and their settings // Global and available styles for access in blocks and their settings
Module._config = {}; Module._config = {};
Module.getConfig = function() { return Module._config; }; Module.getConfig = function() { return Module._config; };
Module.setConfig = function(options) { Module._config = new Module.ConfigModel(options, { parse: true }); return Module._config; }; Module.setConfig = function(options) {
Module._config = new Module.ConfigModel(options, { parse: true });
return Module._config;
};
App.on('before:start', function(options) { App.on('before:start', function(options) {
// Expose config methods globally // Expose config methods globally
App.getConfig = Module.getConfig; App.getConfig = Module.getConfig;
App.setConfig = Module.setConfig; App.setConfig = Module.setConfig;
App.setConfig(options.config); App.setConfig(options.config);
}); });
}); });
}); });

View File

@ -5,76 +5,75 @@ define('newsletter_editor/components/content', [
], function(EditorApplication, Backbone, Marionette) { ], function(EditorApplication, Backbone, Marionette) {
EditorApplication.module("components.content", function(Module, App, Backbone, Marionette, $, _) { EditorApplication.module("components.content", function(Module, App, Backbone, Marionette, $, _) {
"use strict"; "use strict";
// Holds newsletter entry fields, such as subject or creation datetime. // Holds newsletter entry fields, such as subject or creation datetime.
// Does not hold newsletter content nor newsletter styles, those are // Does not hold newsletter content nor newsletter styles, those are
// handled by other components. // handled by other components.
Module.NewsletterModel = Backbone.SuperModel.extend({ Module.NewsletterModel = Backbone.SuperModel.extend({
stale: ['data', 'styles'], stale: ['data', 'styles'],
initialize: function(options) { initialize: function(options) {
this.on('change', function() { this.on('change', function() {
App.getChannel().trigger('autoSave'); App.getChannel().trigger('autoSave');
}); });
}, },
toJSON: function() { toJSON: function() {
// Remove stale attributes from resulting JSON object // Remove stale attributes from resulting JSON object
return _.omit(Backbone.SuperModel.prototype.toJSON.call(this), this.stale); return _.omit(Backbone.SuperModel.prototype.toJSON.call(this), this.stale);
}, },
});
// Content block view and model handlers for different content types
Module._blockTypes = {};
Module.registerBlockType = function(type, data) {
Module._blockTypes[type] = data;
};
Module.getBlockTypeModel = function(type) {
if (type in Module._blockTypes) {
return Module._blockTypes[type].blockModel;
} else {
throw "Block type not supported: " + type;
}
};
Module.getBlockTypeView = function(type) {
if (type in Module._blockTypes) {
return Module._blockTypes[type].blockView;
} else {
throw "Block type not supported: " + type;
}
};
Module.toJSON = function() {
return _.extend({
data: App._contentContainer.toJSON(),
styles: App.getGlobalStyles().toJSON(),
}, App.getNewsletter().toJSON());
};
Module.getNewsletter = function() {
return Module.newsletter;
};
App.on('before:start', function(options) {
// Expose block methods globally
App.registerBlockType = Module.registerBlockType;
App.getBlockTypeModel = Module.getBlockTypeModel;
App.getBlockTypeView = Module.getBlockTypeView;
App.toJSON = Module.toJSON;
App.getNewsletter = Module.getNewsletter;
Module.newsletter = new Module.NewsletterModel(_.omit(_.clone(options.newsletter), ['data', 'styles']));
});
App.on('start', function(options) {
// TODO: Other newsletter information will be needed as well.
App._contentContainer = new (this.getBlockTypeModel('container'))(options.newsletter.data, {parse: true});
App._contentContainerView = new (this.getBlockTypeView('container'))({
model: App._contentContainer,
renderOptions: { depth: 0 },
}); });
// Content block view and model handlers for different content types App._appView.contentRegion.show(App._contentContainerView);
Module._blockTypes = {}; });
Module.registerBlockType = function(type, data) {
Module._blockTypes[type] = data;
};
Module.getBlockTypeModel = function(type) {
if (type in Module._blockTypes) {
return Module._blockTypes[type].blockModel;
} else {
throw "Block type not supported: " + type;
}
};
Module.getBlockTypeView = function(type) {
if (type in Module._blockTypes) {
return Module._blockTypes[type].blockView;
} else {
throw "Block type not supported: " + type;
}
};
Module.toJSON = function() {
return _.extend({
data: App._contentContainer.toJSON(),
styles: App.getGlobalStyles().toJSON(),
}, App.getNewsletter().toJSON());
};
Module.getNewsletter = function() {
return Module.newsletter;
};
App.on('before:start', function(options) {
// Expose block methods globally
App.registerBlockType = Module.registerBlockType;
App.getBlockTypeModel = Module.getBlockTypeModel;
App.getBlockTypeView = Module.getBlockTypeView;
App.toJSON = Module.toJSON;
App.getNewsletter = Module.getNewsletter;
Module.newsletter = new Module.NewsletterModel(_.omit(_.clone(options.newsletter), ['data', 'styles']));
});
App.on('start', function(options) {
// TODO: Other newsletter information will be needed as well.
App._contentContainer = new (this.getBlockTypeModel('container'))(options.newsletter.data, {parse: true});
App._contentContainerView = new (this.getBlockTypeView('container'))({
model: App._contentContainer,
renderOptions: { depth: 0 },
});
App._appView.contentRegion.show(App._contentContainerView);
});
}); });
}); });

View File

@ -5,29 +5,28 @@ define('newsletter_editor/components/heading', [
], function(EditorApplication, Backbone, Marionette) { ], function(EditorApplication, Backbone, Marionette) {
EditorApplication.module("components.heading", function(Module, App, Backbone, Marionette, $, _) { EditorApplication.module("components.heading", function(Module, App, Backbone, Marionette, $, _) {
"use strict"; "use strict";
Module.HeadingView = Marionette.ItemView.extend({ Module.HeadingView = Marionette.ItemView.extend({
getTemplate: function() { return templates.heading; }, getTemplate: function() { return templates.heading; },
templateHelpers: function() { templateHelpers: function() {
return { return {
model: this.model.toJSON(), model: this.model.toJSON(),
}; };
}, },
events: function() { events: function() {
return { return {
'keyup .mailpoet_input_title': _.partial(this.changeField, "newsletter_subject"), 'keyup .mailpoet_input_title': _.partial(this.changeField, "newsletter_subject"),
'keyup .mailpoet_input_preheader': _.partial(this.changeField, "newsletter_preheader"), 'keyup .mailpoet_input_preheader': _.partial(this.changeField, "newsletter_preheader"),
}; };
}, },
changeField: function(field, event) { changeField: function(field, event) {
this.model.set(field, jQuery(event.target).val()); this.model.set(field, jQuery(event.target).val());
}, },
}); });
App.on('start', function(options) { App.on('start', function(options) {
App._appView.headingRegion.show(new Module.HeadingView({ model: App.getNewsletter() })); App._appView.headingRegion.show(new Module.HeadingView({ model: App.getNewsletter() }));
}); });
}); });
}); });

View File

@ -5,174 +5,173 @@ define('newsletter_editor/components/save', [
], function(EditorApplication, Backbone, Marionette) { ], function(EditorApplication, Backbone, Marionette) {
EditorApplication.module("components.save", function(Module, App, Backbone, Marionette, $, _) { EditorApplication.module("components.save", function(Module, App, Backbone, Marionette, $, _) {
"use strict"; "use strict";
var saveTimeout; var saveTimeout;
// Save editor contents to server // Save editor contents to server
Module.save = function() { Module.save = function() {
App.getChannel().trigger('beforeEditorSave'); App.getChannel().trigger('beforeEditorSave');
var json = App.toJSON(); var json = App.toJSON();
// save newsletter // save newsletter
// TODO: Migrate logic to new AJAX format // TODO: Migrate logic to new AJAX format
//mailpoet_post_wpi('newsletter_save.php', json, function(response) { //mailpoet_post_wpi('newsletter_save.php', json, function(response) {
//if(response.success !== undefined && response.success === true) { //if(response.success !== undefined && response.success === true) {
////MailPoet.Notice.success("<?php _e('Newsletter has been saved.'); ?>"); ////MailPoet.Notice.success("<?php _e('Newsletter has been saved.'); ?>");
//} else if(response.error !== undefined) { //} else if(response.error !== undefined) {
//if(response.error.length === 0) { //if(response.error.length === 0) {
//// TODO: Handle translations //// TODO: Handle translations
//MailPoet.Notice.error("<?php _e('An unknown error occurred, please check your settings.'); ?>"); //MailPoet.Notice.error("<?php _e('An unknown error occurred, please check your settings.'); ?>");
//} else { //} else {
//$(response.error).each(function(i, error) { //$(response.error).each(function(i, error) {
//MailPoet.Notice.error(error); //MailPoet.Notice.error(error);
//}); //});
//} //}
//} //}
//App.getChannel().trigger('afterEditorSave', json, response); //App.getChannel().trigger('afterEditorSave', json, response);
//}, function(error) { //}, function(error) {
//// TODO: Handle saving errors //// TODO: Handle saving errors
//App.getChannel().trigger('afterEditorSave', {}, error); //App.getChannel().trigger('afterEditorSave', {}, error);
//}); //});
}; };
Module.SaveView = Marionette.LayoutView.extend({ Module.SaveView = Marionette.LayoutView.extend({
getTemplate: function() { return templates.save; }, getTemplate: function() { return templates.save; },
events: { events: {
'click .mailpoet_save_button': 'save', 'click .mailpoet_save_button': 'save',
'click .mailpoet_save_show_options': 'toggleSaveOptions', 'click .mailpoet_save_show_options': 'toggleSaveOptions',
'click .mailpoet_save_next': 'next', 'click .mailpoet_save_next': 'next',
/* Save as template */ /* Save as template */
'click .mailpoet_save_template': 'toggleSaveAsTemplate', 'click .mailpoet_save_template': 'toggleSaveAsTemplate',
'click .mailpoet_save_as_template': 'saveAsTemplate', 'click .mailpoet_save_as_template': 'saveAsTemplate',
/* Export template */ /* Export template */
'click .mailpoet_save_export': 'exportTemplate', 'click .mailpoet_save_export': 'exportTemplate',
}, },
initialize: function(options) { initialize: function(options) {
App.getChannel().on('beforeEditorSave', this.beforeSave, this); App.getChannel().on('beforeEditorSave', this.beforeSave, this);
App.getChannel().on('afterEditorSave', this.afterSave, this); App.getChannel().on('afterEditorSave', this.afterSave, this);
this.validateNewsletter(App.toJSON()); this.validateNewsletter(App.toJSON());
}, },
save: function() { save: function() {
this.hideOptionContents(); this.hideOptionContents();
App.getChannel().trigger('save'); App.getChannel().trigger('save');
}, },
beforeSave: function() { beforeSave: function() {
// TODO: Add a loading animation instead // TODO: Add a loading animation instead
this.$('.mailpoet_autosaved_at').text('Saving...'); this.$('.mailpoet_autosaved_at').text('Saving...');
}, },
afterSave: function(json, response) { afterSave: function(json, response) {
this.validateNewsletter(json); this.validateNewsletter(json);
// Update 'Last saved timer' // Update 'Last saved timer'
this.$('.mailpoet_editor_last_saved').removeClass('mailpoet_hidden'); this.$('.mailpoet_editor_last_saved').removeClass('mailpoet_hidden');
this.$('.mailpoet_autosaved_at').text(response.time); this.$('.mailpoet_autosaved_at').text(response.time);
}, },
toggleSaveOptions: function() { toggleSaveOptions: function() {
this.$('.mailpoet_save_options').toggleClass('mailpoet_hidden'); this.$('.mailpoet_save_options').toggleClass('mailpoet_hidden');
this.$('.mailpoet_save_show_options').toggleClass('mailpoet_save_show_options_active'); this.$('.mailpoet_save_show_options').toggleClass('mailpoet_save_show_options_active');
}, },
toggleSaveAsTemplate: function() { toggleSaveAsTemplate: function() {
this.$('.mailpoet_save_as_template_container').toggleClass('mailpoet_hidden'); this.$('.mailpoet_save_as_template_container').toggleClass('mailpoet_hidden');
this.toggleSaveOptions(); this.toggleSaveOptions();
}, },
showSaveAsTemplate: function() { showSaveAsTemplate: function() {
this.$('.mailpoet_save_as_template_container').removeClass('mailpoet_hidden'); this.$('.mailpoet_save_as_template_container').removeClass('mailpoet_hidden');
this.toggleSaveOptions(); this.toggleSaveOptions();
}, },
hideSaveAsTemplate: function() { hideSaveAsTemplate: function() {
this.$('.mailpoet_save_as_template_container').addClass('mailpoet_hidden'); this.$('.mailpoet_save_as_template_container').addClass('mailpoet_hidden');
}, },
saveAsTemplate: function() { saveAsTemplate: function() {
var templateName = this.$('.mailpoet_save_as_template_name').val(), var templateName = this.$('.mailpoet_save_as_template_name').val(),
templateDescription = this.$('.mailpoet_save_as_template_description').val(); templateDescription = this.$('.mailpoet_save_as_template_description').val();
console.log('Saving template with ', templateName, templateDescription); console.log('Saving template with ', templateName, templateDescription);
this.hideOptionContents(); this.hideOptionContents();
}, },
exportTemplate: function() { exportTemplate: function() {
console.log('Exporting template'); console.log('Exporting template');
this.hideOptionContents(); this.hideOptionContents();
}, },
hideOptionContents: function() { hideOptionContents: function() {
this.hideSaveAsTemplate(); this.hideSaveAsTemplate();
this.$('.mailpoet_save_options').addClass('mailpoet_hidden'); this.$('.mailpoet_save_options').addClass('mailpoet_hidden');
}, },
next: function() { next: function() {
this.hideOptionContents(); this.hideOptionContents();
console.log('Next'); console.log('Next');
window.location.href = App.getConfig().get('urls.send'); window.location.href = App.getConfig().get('urls.send');
}, },
validateNewsletter: function(jsonObject) { validateNewsletter: function(jsonObject) {
if (!App._contentContainer.isValid()) { if (!App._contentContainer.isValid()) {
this.showValidationError(App._contentContainer.validationError); this.showValidationError(App._contentContainer.validationError);
return; return;
} }
if (App.getConfig().get('validation.validateUnsubscribeLinkPresent') && if (App.getConfig().get('validation.validateUnsubscribeLinkPresent') &&
JSON.stringify(jsonObject).indexOf("[unsubscribeUrl]") < 0) { JSON.stringify(jsonObject).indexOf("[unsubscribeUrl]") < 0) {
this.showValidationError(App.getConfig().get('translations.unsubscribeLinkMissing')); this.showValidationError(App.getConfig().get('translations.unsubscribeLinkMissing'));
return; return;
} }
this.hideValidationError(); this.hideValidationError();
}, },
showValidationError: function(message) { showValidationError: function(message) {
var $el = this.$('.mailpoet_save_error'); var $el = this.$('.mailpoet_save_error');
$el.text(message); $el.text(message);
$el.removeClass('mailpoet_hidden'); $el.removeClass('mailpoet_hidden');
this.$('.mailpoet_save_next').addClass('button-disabled'); this.$('.mailpoet_save_next').addClass('button-disabled');
}, },
hideValidationError: function() { hideValidationError: function() {
this.$('.mailpoet_save_error').addClass('mailpoet_hidden'); this.$('.mailpoet_save_error').addClass('mailpoet_hidden');
this.$('.mailpoet_save_next').removeClass('button-disabled'); this.$('.mailpoet_save_next').removeClass('button-disabled');
}, },
}); });
Module.autoSave = function() { Module.autoSave = function() {
// Delay in saving editor contents, during which a new autosave // Delay in saving editor contents, during which a new autosave
// may be requested // may be requested
var AUTOSAVE_DELAY_DURATION = 1000; var AUTOSAVE_DELAY_DURATION = 1000;
// Cancel save timer if another change happens before it completes // Cancel save timer if another change happens before it completes
if (saveTimeout) clearTimeout(saveTimeout); if (saveTimeout) clearTimeout(saveTimeout);
saveTimeout = setTimeout(function() { saveTimeout = setTimeout(function() {
App.getChannel().trigger('save'); App.getChannel().trigger('save');
clearTimeout(saveTimeout); clearTimeout(saveTimeout);
saveTimeout = undefined; saveTimeout = undefined;
}, AUTOSAVE_DELAY_DURATION); }, AUTOSAVE_DELAY_DURATION);
}; };
Module.beforeExitWithUnsavedChanges = function(e) { Module.beforeExitWithUnsavedChanges = function(e) {
if (saveTimeout) { if (saveTimeout) {
// TODO: Translate this message // TODO: Translate this message
var message = "There are unsaved changes which will be lost if you leave this page."; var message = "There are unsaved changes which will be lost if you leave this page.";
e = e || window.event; e = e || window.event;
if (e) { if (e) {
e.returnValue = message; e.returnValue = message;
} }
return message; return message;
} }
}; };
App.on('before:start', function(options) { App.on('before:start', function(options) {
App.save = Module.save; App.save = Module.save;
App.getChannel().on('autoSave', Module.autoSave); App.getChannel().on('autoSave', Module.autoSave);
window.onbeforeunload = Module.beforeExitWithUnsavedChanges; window.onbeforeunload = Module.beforeExitWithUnsavedChanges;
App.getChannel().on('save', function() { App.save(); }); App.getChannel().on('save', function() { App.save(); });
}); });
App.on('start', function(options) { App.on('start', function(options) {
var saveView = new Module.SaveView(); var saveView = new Module.SaveView();
App._appView.bottomRegion.show(saveView); App._appView.bottomRegion.show(saveView);
}); });
}); });
}); });

View File

@ -6,254 +6,253 @@ define('newsletter_editor/components/sidebar', [
], function(EditorApplication, Backbone, Marionette) { ], function(EditorApplication, Backbone, Marionette) {
EditorApplication.module("components.sidebar", function(Module, App, Backbone, Marionette, $, _) { EditorApplication.module("components.sidebar", function(Module, App, Backbone, Marionette, $, _) {
"use strict"; "use strict";
// Widget handlers for use to create new content blocks via drag&drop // Widget handlers for use to create new content blocks via drag&drop
Module._contentWidgets = new (Backbone.Collection.extend({ Module._contentWidgets = new (Backbone.Collection.extend({
model: Backbone.SuperModel.extend({ model: Backbone.SuperModel.extend({
defaults: { defaults: {
name: '', name: '',
priority: 100, priority: 100,
widgetView: undefined, widgetView: undefined,
}, },
}), }),
comparator: 'priority', comparator: 'priority',
}))(); }))();
Module.registerWidget = function(widget) { return Module._contentWidgets.add(widget); }; Module.registerWidget = function(widget) { return Module._contentWidgets.add(widget); };
Module.getWidgets = function() { return Module._contentWidgets; }; Module.getWidgets = function() { return Module._contentWidgets; };
// Layout widget handlers for use to create new layout blocks via drag&drop // Layout widget handlers for use to create new layout blocks via drag&drop
Module._layoutWidgets = new (Backbone.Collection.extend({ Module._layoutWidgets = new (Backbone.Collection.extend({
model: Backbone.SuperModel.extend({ model: Backbone.SuperModel.extend({
defaults: { defaults: {
name: '', name: '',
priority: 100, priority: 100,
widgetView: undefined, widgetView: undefined,
}, },
}), }),
comparator: 'priority', comparator: 'priority',
}))(); }))();
Module.registerLayoutWidget = function(widget) { return Module._layoutWidgets.add(widget); }; Module.registerLayoutWidget = function(widget) { return Module._layoutWidgets.add(widget); };
Module.getLayoutWidgets = function() { return Module._layoutWidgets; }; Module.getLayoutWidgets = function() { return Module._layoutWidgets; };
var SidebarView = Backbone.Marionette.LayoutView.extend({ var SidebarView = Backbone.Marionette.LayoutView.extend({
getTemplate: function() { return templates.sidebar; }, getTemplate: function() { return templates.sidebar; },
regions: { regions: {
contentRegion: '.mailpoet_content_region', contentRegion: '.mailpoet_content_region',
layoutRegion: '.mailpoet_layout_region', layoutRegion: '.mailpoet_layout_region',
stylesRegion: '.mailpoet_styles_region', stylesRegion: '.mailpoet_styles_region',
previewRegion: '.mailpoet_preview_region', previewRegion: '.mailpoet_preview_region',
}, },
events: { events: {
'click .mailpoet_sidebar_region h3, .mailpoet_sidebar_region .handlediv': function(event) { 'click .mailpoet_sidebar_region h3, .mailpoet_sidebar_region .handlediv': function(event) {
this.$el.find('.mailpoet_sidebar_region').addClass('closed'); this.$el.find('.mailpoet_sidebar_region').addClass('closed');
this.$el.find(event.target).parent().parent().removeClass('closed'); this.$el.find(event.target).parent().parent().removeClass('closed');
}, },
}, },
initialize: function(options) { initialize: function(options) {
$(window) $(window)
.on('resize', this.updateHorizontalScroll.bind(this)) .on('resize', this.updateHorizontalScroll.bind(this))
.on('scroll', this.updateHorizontalScroll.bind(this)); .on('scroll', this.updateHorizontalScroll.bind(this));
}, },
onRender: function() { onRender: function() {
this.contentRegion.show(new Module.SidebarWidgetsView({ this.contentRegion.show(new Module.SidebarWidgetsView({
collection: App.getWidgets(), collection: App.getWidgets(),
})); }));
this.layoutRegion.show(new Module.SidebarLayoutWidgetsView({ this.layoutRegion.show(new Module.SidebarLayoutWidgetsView({
collection: App.getLayoutWidgets(), collection: App.getLayoutWidgets(),
})); }));
this.stylesRegion.show(new Module.SidebarStylesView({ this.stylesRegion.show(new Module.SidebarStylesView({
model: App.getGlobalStyles(), model: App.getGlobalStyles(),
availableStyles: App.getAvailableStyles(), availableStyles: App.getAvailableStyles(),
})); }));
this.previewRegion.show(new Module.SidebarPreviewView()); this.previewRegion.show(new Module.SidebarPreviewView());
}, },
updateHorizontalScroll: function() { updateHorizontalScroll: function() {
// Fixes the sidebar so that on narrower screens the horizontal // Fixes the sidebar so that on narrower screens the horizontal
// position of the sidebar would be scrollable and not fixed // position of the sidebar would be scrollable and not fixed
// partially out of visible screen // partially out of visible screen
this.$el.parent().each(function () { this.$el.parent().each(function () {
var calculated_left, self; var calculated_left, self;
self = $(this); self = $(this);
if (self.css('position') === 'fixed') { if (self.css('position') === 'fixed') {
calculated_left = self.parent().offset().left - $(window).scrollLeft(); calculated_left = self.parent().offset().left - $(window).scrollLeft();
self.css('left', calculated_left + 'px'); self.css('left', calculated_left + 'px');
} else { } else {
self.css('left', ''); self.css('left', '');
} }
}); });
}, },
onDomRefresh: function() { onDomRefresh: function() {
var that = this; var that = this;
this.$el.parent().stick_in_parent({ this.$el.parent().stick_in_parent({
offset_top: 32, offset_top: 32,
}); });
this.$el.parent().on('sticky_kit:stick', this.updateHorizontalScroll.bind(this)); this.$el.parent().on('sticky_kit:stick', this.updateHorizontalScroll.bind(this));
this.$el.parent().on('sticky_kit:unstick', this.updateHorizontalScroll.bind(this)); this.$el.parent().on('sticky_kit:unstick', this.updateHorizontalScroll.bind(this));
this.$el.parent().on('sticky_kit:bottom', this.updateHorizontalScroll.bind(this)); this.$el.parent().on('sticky_kit:bottom', this.updateHorizontalScroll.bind(this));
this.$el.parent().on('sticky_kit:unbottom', this.updateHorizontalScroll.bind(this)); this.$el.parent().on('sticky_kit:unbottom', this.updateHorizontalScroll.bind(this));
}, },
}); });
/** /**
* Responsible for rendering draggable content widgets * Responsible for rendering draggable content widgets
*/ */
Module.SidebarWidgetsView = Backbone.Marionette.CompositeView.extend({ Module.SidebarWidgetsView = Backbone.Marionette.CompositeView.extend({
getTemplate: function() { return templates.sidebarContent; }, getTemplate: function() { return templates.sidebarContent; },
getChildView: function(model) { getChildView: function(model) {
return model.get('widgetView'); return model.get('widgetView');
}, },
childViewContainer: '.mailpoet_region_content', childViewContainer: '.mailpoet_region_content',
}); });
/** /**
* Responsible for rendering draggable layout widgets * Responsible for rendering draggable layout widgets
*/ */
Module.SidebarLayoutWidgetsView = Module.SidebarWidgetsView.extend({ Module.SidebarLayoutWidgetsView = Module.SidebarWidgetsView.extend({
getTemplate: function() { return templates.sidebarLayout; }, getTemplate: function() { return templates.sidebarLayout; },
}); });
/** /**
* Responsible for managing global styles * Responsible for managing global styles
*/ */
Module.SidebarStylesView = Backbone.Marionette.LayoutView.extend({ Module.SidebarStylesView = Backbone.Marionette.LayoutView.extend({
getTemplate: function() { return templates.sidebarStyles; }, getTemplate: function() { return templates.sidebarStyles; },
events: function() { events: function() {
return { return {
"change #mailpoet_text_font_color": _.partial(this.changeColorField, 'text.fontColor'), "change #mailpoet_text_font_color": _.partial(this.changeColorField, 'text.fontColor'),
"change #mailpoet_text_font_family": function(event) { "change #mailpoet_text_font_family": function(event) {
this.model.set('text.fontFamily', event.target.value); this.model.set('text.fontFamily', event.target.value);
},
"change #mailpoet_text_font_size": function(event) {
this.model.set('text.fontSize', event.target.value);
},
"change #mailpoet_h1_font_color": _.partial(this.changeColorField, 'h1.fontColor'),
"change #mailpoet_h1_font_family": function(event) {
this.model.set('h1.fontFamily', event.target.value);
},
"change #mailpoet_h1_font_size": function(event) {
this.model.set('h1.fontSize', event.target.value);
},
"change #mailpoet_h2_font_color": _.partial(this.changeColorField, 'h2.fontColor'),
"change #mailpoet_h2_font_family": function(event) {
this.model.set('h2.fontFamily', event.target.value);
},
"change #mailpoet_h2_font_size": function(event) {
this.model.set('h2.fontSize', event.target.value);
},
"change #mailpoet_h3_font_color": _.partial(this.changeColorField, 'h3.fontColor'),
"change #mailpoet_h3_font_family": function(event) {
this.model.set('h3.fontFamily', event.target.value);
},
"change #mailpoet_h3_font_size": function(event) {
this.model.set('h3.fontSize', event.target.value);
},
"change #mailpoet_a_font_color": _.partial(this.changeColorField, 'link.fontColor'),
"change #mailpoet_a_font_underline": function(event) {
this.model.set('link.textDecoration', (event.target.checked) ? event.target.value : 'none');
},
"change #mailpoet_newsletter_background_color": _.partial(this.changeColorField, 'newsletter.backgroundColor'),
"change #mailpoet_background_color": _.partial(this.changeColorField, 'background.backgroundColor'),
};
}, },
templateHelpers: function() { "change #mailpoet_text_font_size": function(event) {
return { this.model.set('text.fontSize', event.target.value);
model: this.model.toJSON(),
availableStyles: this.availableStyles.toJSON(),
};
}, },
initialize: function(options) { "change #mailpoet_h1_font_color": _.partial(this.changeColorField, 'h1.fontColor'),
this.availableStyles = options.availableStyles; "change #mailpoet_h1_font_family": function(event) {
var that = this; this.model.set('h1.fontFamily', event.target.value);
}, },
onRender: function() { "change #mailpoet_h1_font_size": function(event) {
var that = this; this.model.set('h1.fontSize', event.target.value);
this.$('.mailpoet_color').spectrum({
clickoutFiresChange: true,
showInput: true,
showInitial: true,
preferredFormat: "hex6",
allowEmpty: true,
});
}, },
changeField: function(field, event) { "change #mailpoet_h2_font_color": _.partial(this.changeColorField, 'h2.fontColor'),
this.model.set(field, jQuery(event.target).val()); "change #mailpoet_h2_font_family": function(event) {
this.model.set('h2.fontFamily', event.target.value);
}, },
changeColorField: function(field, event) { "change #mailpoet_h2_font_size": function(event) {
var value = jQuery(event.target).val(); this.model.set('h2.fontSize', event.target.value);
if (value === '') {
value = 'transparent';
}
this.model.set(field, value);
}, },
}); "change #mailpoet_h3_font_color": _.partial(this.changeColorField, 'h3.fontColor'),
"change #mailpoet_h3_font_family": function(event) {
this.model.set('h3.fontFamily', event.target.value);
},
"change #mailpoet_h3_font_size": function(event) {
this.model.set('h3.fontSize', event.target.value);
},
"change #mailpoet_a_font_color": _.partial(this.changeColorField, 'link.fontColor'),
"change #mailpoet_a_font_underline": function(event) {
this.model.set('link.textDecoration', (event.target.checked) ? event.target.value : 'none');
},
"change #mailpoet_newsletter_background_color": _.partial(this.changeColorField, 'newsletter.backgroundColor'),
"change #mailpoet_background_color": _.partial(this.changeColorField, 'background.backgroundColor'),
};
},
templateHelpers: function() {
return {
model: this.model.toJSON(),
availableStyles: this.availableStyles.toJSON(),
};
},
initialize: function(options) {
this.availableStyles = options.availableStyles;
var that = this;
},
onRender: function() {
var that = this;
this.$('.mailpoet_color').spectrum({
clickoutFiresChange: true,
showInput: true,
showInitial: true,
preferredFormat: "hex6",
allowEmpty: true,
});
},
changeField: function(field, event) {
this.model.set(field, jQuery(event.target).val());
},
changeColorField: function(field, event) {
var value = jQuery(event.target).val();
if (value === '') {
value = 'transparent';
}
this.model.set(field, value);
},
});
Module.SidebarPreviewView = Backbone.Marionette.LayoutView.extend({ Module.SidebarPreviewView = Backbone.Marionette.LayoutView.extend({
getTemplate: function() { return templates.sidebarPreview; }, getTemplate: function() { return templates.sidebarPreview; },
events: { events: {
'click .mailpoet_show_preview': 'showPreview', 'click .mailpoet_show_preview': 'showPreview',
'click #mailpoet_send_preview': 'sendPreview', 'click #mailpoet_send_preview': 'sendPreview',
}, },
showPreview: function() { showPreview: function() {
var json = App.toJSON(); var json = App.toJSON();
mailpoet_post_json('newsletter_render.php', { data: json }, function(response) { mailpoet_post_json('newsletter_render.php', { data: json }, function(response) {
console.log('Should open a new window'); console.log('Should open a new window');
window.open('data:text/html,' + encodeURIComponent(response), '_blank'); window.open('data:text/html,' + encodeURIComponent(response), '_blank');
}, function(error) { }, function(error) {
console.log('Preview error', json); console.log('Preview error', json);
alert('Something went wrong, check console'); alert('Something went wrong, check console');
}); });
}, },
sendPreview: function() { sendPreview: function() {
// testing sending method // testing sending method
console.log('trying to send a preview'); console.log('trying to send a preview');
// get form data // get form data
var data = { var data = {
from_name: this.$('#mailpoet_preview_from_name').val(), from_name: this.$('#mailpoet_preview_from_name').val(),
from_email: this.$('#mailpoet_preview_from_email').val(), from_email: this.$('#mailpoet_preview_from_email').val(),
to_email: this.$('#mailpoet_preview_to_email').val(), to_email: this.$('#mailpoet_preview_to_email').val(),
newsletter: App.newsletterId, newsletter: App.newsletterId,
}; };
// send test email // send test email
MailPoet.Modal.loading(true); MailPoet.Modal.loading(true);
// TODO: Migrate logic to new AJAX format // TODO: Migrate logic to new AJAX format
//mailpoet_post_wpi('newsletter_preview.php', data, function(response) { //mailpoet_post_wpi('newsletter_preview.php', data, function(response) {
//if(response.success !== undefined && response.success === true) { //if(response.success !== undefined && response.success === true) {
//MailPoet.Notice.success(App.getConfig().get('translations.testEmailSent')); //MailPoet.Notice.success(App.getConfig().get('translations.testEmailSent'));
//} else if(response.error !== undefined) { //} else if(response.error !== undefined) {
//if(response.error.length === 0) { //if(response.error.length === 0) {
//MailPoet.Notice.error(App.getConfig().get('translations.unknownErrorOccurred')); //MailPoet.Notice.error(App.getConfig().get('translations.unknownErrorOccurred'));
//} else { //} else {
//$(response.error).each(function(i, error) { //$(response.error).each(function(i, error) {
//MailPoet.Notice.error(error); //MailPoet.Notice.error(error);
//});
//}
//}
//MailPoet.Modal.loading(false);
//}, function(error) {
//// an error occurred
//MailPoet.Modal.loading(false);
//}); //});
}, //}
}); //}
//MailPoet.Modal.loading(false);
//}, function(error) {
//// an error occurred
//MailPoet.Modal.loading(false);
//});
},
});
App.on('before:start', function(options) { App.on('before:start', function(options) {
App.registerWidget = Module.registerWidget; App.registerWidget = Module.registerWidget;
App.getWidgets = Module.getWidgets; App.getWidgets = Module.getWidgets;
App.registerLayoutWidget = Module.registerLayoutWidget; App.registerLayoutWidget = Module.registerLayoutWidget;
App.getLayoutWidgets = Module.getLayoutWidgets; App.getLayoutWidgets = Module.getLayoutWidgets;
}); });
App.on('start', function(options) { App.on('start', function(options) {
var stylesModel = App.getGlobalStyles(), var stylesModel = App.getGlobalStyles(),
sidebarView = new SidebarView(); sidebarView = new SidebarView();
App._appView.sidebarRegion.show(sidebarView); App._appView.sidebarRegion.show(sidebarView);
}); });
}); });
}); });

View File

@ -5,79 +5,78 @@ define('newsletter_editor/components/styles', [
], function(EditorApplication, Backbone, Marionette) { ], function(EditorApplication, Backbone, Marionette) {
EditorApplication.module("components.styles", function(Module, App, Backbone, Marionette, $, _) { EditorApplication.module("components.styles", function(Module, App, Backbone, Marionette, $, _) {
"use strict"; "use strict";
Module.StylesModel = Backbone.SuperModel.extend({ Module.StylesModel = Backbone.SuperModel.extend({
defaults: { defaults: {
text: { text: {
fontColor: '#000000', fontColor: '#000000',
fontFamily: 'Arial', fontFamily: 'Arial',
fontSize: '16px', fontSize: '16px',
}, },
h1: { h1: {
fontColor: '#111111', fontColor: '#111111',
fontFamily: 'Arial Black', fontFamily: 'Arial Black',
fontSize: '40px' fontSize: '40px'
}, },
h2: { h2: {
fontColor: '#222222', fontColor: '#222222',
fontFamily: 'Tahoma', fontFamily: 'Tahoma',
fontSize: '32px', fontSize: '32px',
}, },
h3: { h3: {
fontColor: '#333333', fontColor: '#333333',
fontFamily: 'Verdana', fontFamily: 'Verdana',
fontSize: '24px', fontSize: '24px',
}, },
link: { link: {
fontColor: '#21759B', fontColor: '#21759B',
textDecoration: 'underline', textDecoration: 'underline',
}, },
newsletter: { newsletter: {
backgroundColor: '#ffffff', backgroundColor: '#ffffff',
}, },
background: { background: {
backgroundColor: '#cccccc', backgroundColor: '#cccccc',
}, },
}, },
initialize: function() { initialize: function() {
this.on('change', function() { App.getChannel().trigger('autoSave'); }); this.on('change', function() { App.getChannel().trigger('autoSave'); });
}, },
}); });
Module.StylesView = Marionette.ItemView.extend({ Module.StylesView = Marionette.ItemView.extend({
getTemplate: function() { return templates.styles; }, getTemplate: function() { return templates.styles; },
modelEvents: { modelEvents: {
'change': 'render', 'change': 'render',
}, },
}); });
Module._globalStyles = new Backbone.SuperModel(); Module._globalStyles = new Backbone.SuperModel();
Module.getGlobalStyles = function() { Module.getGlobalStyles = function() {
return Module._globalStyles; return Module._globalStyles;
}; };
Module.setGlobalStyles = function(options) { Module.setGlobalStyles = function(options) {
Module._globalStyles = new Module.StylesModel(options); Module._globalStyles = new Module.StylesModel(options);
return Module._globalStyles; return Module._globalStyles;
}; };
Module.getAvailableStyles = function() { Module.getAvailableStyles = function() {
return App.getConfig().get('availableStyles'); return App.getConfig().get('availableStyles');
}; };
App.on('before:start', function(options) { App.on('before:start', function(options) {
// Expose style methods to global application // Expose style methods to global application
App.getGlobalStyles = Module.getGlobalStyles; App.getGlobalStyles = Module.getGlobalStyles;
App.setGlobalStyles = Module.setGlobalStyles; App.setGlobalStyles = Module.setGlobalStyles;
App.getAvailableStyles = Module.getAvailableStyles; App.getAvailableStyles = Module.getAvailableStyles;
this.setGlobalStyles(options.newsletter.styles); this.setGlobalStyles(options.newsletter.styles);
}); });
App.on('start', function(options) { App.on('start', function(options) {
var stylesView = new Module.StylesView({ model: App.getGlobalStyles() }); var stylesView = new Module.StylesView({ model: App.getGlobalStyles() });
App._appView.stylesRegion.show(stylesView); App._appView.stylesRegion.show(stylesView);
}); });
}); });
}); });

View File

@ -11,48 +11,48 @@
/*jshint unused:false */ /*jshint unused:false */
/*global tinymce:true */ /*global tinymce:true */
tinymce.PluginManager.add('mailpoet_custom_fields', function(editor, url) { tinymce.PluginManager.add('mailpoet_custom_fields', function(editor, url) {
var appendLabelAndClose = function(text) { var appendLabelAndClose = function(text) {
editor.insertContent('[' + text + ']'); editor.insertContent('[' + text + ']');
editor.windowManager.close(); editor.windowManager.close();
}, },
generateOnClickFunc = function(id) { generateOnClickFunc = function(id) {
return function() { return function() {
appendLabelAndClose(id); appendLabelAndClose(id);
}; };
}; };
editor.addButton('mailpoet_custom_fields', { editor.addButton('mailpoet_custom_fields', {
icon: 'mailpoet_custom_fields', icon: 'mailpoet_custom_fields',
onclick: function() { onclick: function() {
var customFields = [], var customFields = [],
configCustomFields = editor.settings.mailpoet_custom_fields; configCustomFields = editor.settings.mailpoet_custom_fields;
for (var segment in configCustomFields) { for (var segment in configCustomFields) {
if (configCustomFields.hasOwnProperty(segment)) { if (configCustomFields.hasOwnProperty(segment)) {
customFields.push({ customFields.push({
type: 'label', type: 'label',
text: segment, text: segment,
}); });
for (var i = 0; i < configCustomFields[segment].length; i += 1) { for (var i = 0; i < configCustomFields[segment].length; i += 1) {
customFields.push({ customFields.push({
type: 'button', type: 'button',
text: configCustomFields[segment][i].text, text: configCustomFields[segment][i].text,
onClick: generateOnClickFunc(configCustomFields[segment][i].shortcode) onClick: generateOnClickFunc(configCustomFields[segment][i].shortcode)
});
}
}
}
// Open window
editor.windowManager.open({
height: parseInt(editor.getParam("plugin_mailpoet_custom_fields_height", 400)),
width: parseInt(editor.getParam("plugin_mailpoet_custom_fields_width", 450)),
autoScroll: true,
title: editor.settings.mailpoet_custom_fields_window_title,
body: customFields,
buttons: [],
}); });
}, }
}); }
}
// Open window
editor.windowManager.open({
height: parseInt(editor.getParam("plugin_mailpoet_custom_fields_height", 400)),
width: parseInt(editor.getParam("plugin_mailpoet_custom_fields_width", 450)),
autoScroll: true,
title: editor.settings.mailpoet_custom_fields_window_title,
body: customFields,
buttons: [],
});
},
});
}); });

View File

@ -3,25 +3,25 @@
* A draggable widget, on drop creates a container with (image|text) block. * A draggable widget, on drop creates a container with (image|text) block.
*/ */
ImageAndTextTemplateWidgetView = EditorApplication.module('blocks.base').WidgetView.extend({ ImageAndTextTemplateWidgetView = EditorApplication.module('blocks.base').WidgetView.extend({
getTemplate: function() { return templates.imageAndTextInsertion; }, getTemplate: function() { return templates.imageAndTextInsertion; },
className: 'mailpoet_droppable_block mailpoet_droppable_widget', className: 'mailpoet_droppable_block mailpoet_droppable_widget',
behaviors: { behaviors: {
DraggableBehavior: { DraggableBehavior: {
drop: function() { drop: function() {
return new (EditorApplication.getBlockTypeModel('container'))({ return new (EditorApplication.getBlockTypeModel('container'))({
type: 'container', type: 'container',
orientation: 'horizontal', orientation: 'horizontal',
blocks: [ blocks: [
{ {
type: 'image', type: 'image',
},
{
type: 'text',
text: 'Some random text',
},
],
}, {parse: true});
}, },
} {
}, type: 'text',
text: 'Some random text',
},
],
}, {parse: true});
},
}
},
}); });

View File

@ -1,28 +1,27 @@
var fs = require('fs'); var fs = require('fs');
module.exports = { module.exports = {
loadFileToContainer: function (path, window, containerTagName, options) { loadFileToContainer: function (path, window, containerTagName, options) {
var contents = fs.readFileSync(path), var contents = fs.readFileSync(path),
container = window.document.createElement(containerTagName); container = window.document.createElement(containerTagName);
options = options || {}; options = options || {};
container.innerHTML = contents; container.innerHTML = contents;
if (options.type) { if (options.type) {
container.type = options.type; container.type = options.type;
} }
if (options.id) { if (options.id) {
container.id = options.id; container.id = options.id;
} }
global.window.document.body.appendChild(container); global.window.document.body.appendChild(container);
}, },
loadScript: function (scriptPath, window, options) { loadScript: function (scriptPath, window, options) {
this.loadFileToContainer(scriptPath, window, 'script', options); this.loadFileToContainer(scriptPath, window, 'script', options);
}, },
loadTemplate: function (path, window, options) { loadTemplate: function (path, window, options) {
var w = window || global.window; var w = window || global.window;
options = options || {}; options = options || {};
options.type = "text/x-handlebars-template"; options.type = "text/x-handlebars-template";
this.loadScript("views/newsletter/templates/" + path, w, options); this.loadScript("views/newsletter/templates/" + path, w, options);
}, },
}; };

View File

@ -10,21 +10,21 @@ global.expect = chai.expect;
global.sinon = sinon; global.sinon = sinon;
if (!global.document || !global.window) { if (!global.document || !global.window) {
var jsdom = require('jsdom').jsdom; var jsdom = require('jsdom').jsdom;
global.document = jsdom('<html><head><script></script></head><body></body></html>', {}, { global.document = jsdom('<html><head><script></script></head><body></body></html>', {}, {
FetchExternalResources: ['script'], FetchExternalResources: ['script'],
ProcessExternalResources: ['script'], ProcessExternalResources: ['script'],
MutationEvents: '2.0', MutationEvents: '2.0',
QuerySelector: false QuerySelector: false
}); });
global.window = document.parentWindow; global.window = document.parentWindow;
global.navigator = global.window.navigator; global.navigator = global.window.navigator;
global.window.Node.prototype.contains = function (node) { global.window.Node.prototype.contains = function (node) {
return this.compareDocumentPosition(node) & 16; return this.compareDocumentPosition(node) & 16;
}; };
} }
global.testHelpers = require('./loadHelpers.js'); global.testHelpers = require('./loadHelpers.js');
@ -35,14 +35,14 @@ global.Handlebars = global.window.Handlebars;
// Stub out interact.js // Stub out interact.js
global.interact = function () { global.interact = function () {
return { return {
draggable: global.interact, draggable: global.interact,
restrict: global.interact, restrict: global.interact,
resizable: global.interact, resizable: global.interact,
on: global.interact, on: global.interact,
dropzone: global.interact, dropzone: global.interact,
preventDefault: global.interact, preventDefault: global.interact,
}; };
}; };
jQuery.fn.spectrum = global.spectrum = function() { return this; }; jQuery.fn.spectrum = global.spectrum = function() { return this; };
@ -51,20 +51,20 @@ jQuery.fn.stick_in_parent = function() { return this; };
// Add global stubs for convenience // Add global stubs for convenience
// TODO: Extract those to a separate file // TODO: Extract those to a separate file
global.stubChannel = function (EditorApplication, returnObject) { global.stubChannel = function (EditorApplication, returnObject) {
EditorApplication.getChannel = sinon.stub().returns(_.defaults(returnObject || {}, { EditorApplication.getChannel = sinon.stub().returns(_.defaults(returnObject || {}, {
trigger: function () { trigger: function () {
}, },
on: function () { on: function () {
}, },
})); }));
}; };
global.stubConfig = function (EditorApplication, config) { global.stubConfig = function (EditorApplication, config) {
config = config || {}; config = config || {};
EditorApplication.getConfig = sinon.stub().returns(new Backbone.SuperModel(config)); EditorApplication.getConfig = sinon.stub().returns(new Backbone.SuperModel(config));
}; };
global.stubAvailableStyles = function (EditorApplication, styles) { global.stubAvailableStyles = function (EditorApplication, styles) {
styles = styles || {}; styles = styles || {};
EditorApplication.getAvailableStyles = sinon.stub().returns(new Backbone.SuperModel(styles)); EditorApplication.getAvailableStyles = sinon.stub().returns(new Backbone.SuperModel(styles));
}; };
testHelpers.loadTemplate('blocks/base/toolsGeneric.hbs', window, {id: 'newsletter_editor_template_tools_generic'}); testHelpers.loadTemplate('blocks/base/toolsGeneric.hbs', window, {id: 'newsletter_editor_template_tools_generic'});

View File

@ -4,398 +4,397 @@ define('test/newsletter_editor/blocks/automatedLatestContent', [
], function(EditorApplication) { ], function(EditorApplication) {
describe('Automated latest content', function () { describe('Automated latest content', function () {
describe('model', function () { describe('model', function () {
var model; var model;
beforeEach(function () { beforeEach(function () {
global.stubChannel(EditorApplication); global.stubChannel(EditorApplication);
global.stubConfig(EditorApplication); global.stubConfig(EditorApplication);
EditorApplication.getBlockTypeModel = sinon.stub().returns(Backbone.SuperModel); EditorApplication.getBlockTypeModel = sinon.stub().returns(Backbone.SuperModel);
global.mailpoet_post_wpi = sinon.stub(); global.mailpoet_post_wpi = sinon.stub();
model = new (EditorApplication.module('blocks.automatedLatestContent').AutomatedLatestContentBlockModel)(); model = new (EditorApplication.module('blocks.automatedLatestContent').AutomatedLatestContentBlockModel)();
}); });
afterEach(function () { afterEach(function () {
delete EditorApplication.getChannel; delete EditorApplication.getChannel;
}); });
it('has automatedLatestContent type', function () { it('has automatedLatestContent type', function () {
expect(model.get('type')).to.equal('automatedLatestContent'); expect(model.get('type')).to.equal('automatedLatestContent');
}); });
it('has post amount limit', function () { it('has post amount limit', function () {
expect(model.get('amount')).to.match(/^\d+$/); expect(model.get('amount')).to.match(/^\d+$/);
}); });
it('has post type filter', function () { it('has post type filter', function () {
expect(model.get('contentType')).to.match(/^(post|page|mailpoet_page)$/); expect(model.get('contentType')).to.match(/^(post|page|mailpoet_page)$/);
}); });
it('has terms filter', function () { it('has terms filter', function () {
expect(model.get('terms')).to.have.length(0); expect(model.get('terms')).to.have.length(0);
}); });
it('has inclusion filter', function () { it('has inclusion filter', function () {
expect(model.get('inclusionType')).to.match(/^(include|exclude)$/); expect(model.get('inclusionType')).to.match(/^(include|exclude)$/);
}); });
it('has display type', function () { it('has display type', function () {
expect(model.get('displayType')).to.match(/^(excerpt|full|titleOnly)$/); expect(model.get('displayType')).to.match(/^(excerpt|full|titleOnly)$/);
}); });
it('has title heading format', function () { it('has title heading format', function () {
expect(model.get('titleFormat')).to.match(/^(h1|h2|h3|ul)$/); expect(model.get('titleFormat')).to.match(/^(h1|h2|h3|ul)$/);
}); });
it('has title position', function () { it('has title position', function () {
expect(model.get('titlePosition')).to.match(/^(inTextBlock|aboveBlock)$/); expect(model.get('titlePosition')).to.match(/^(inTextBlock|aboveBlock)$/);
}); });
it('has title alignment', function () { it('has title alignment', function () {
expect(model.get('titleAlignment')).to.match(/^(left|center|right)$/); expect(model.get('titleAlignment')).to.match(/^(left|center|right)$/);
}); });
it('optionally has title as link', function () { it('optionally has title as link', function () {
expect(model.get('titleIsLink')).to.be.a('boolean'); expect(model.get('titleIsLink')).to.be.a('boolean');
}); });
it('has image width', function () { it('has image width', function () {
expect(model.get('imagePadded')).to.be.a('boolean'); expect(model.get('imagePadded')).to.be.a('boolean');
}); });
it('has an option to display author', function () { it('has an option to display author', function () {
expect(model.get('showAuthor')).to.match(/^(no|aboveText|belowText)$/); expect(model.get('showAuthor')).to.match(/^(no|aboveText|belowText)$/);
}); });
it('has text preceding author', function () { it('has text preceding author', function () {
expect(model.get('authorPrecededBy')).to.be.a('string'); expect(model.get('authorPrecededBy')).to.be.a('string');
}); });
it('has an option to display categories', function () { it('has an option to display categories', function () {
expect(model.get('showCategories')).to.match(/^(no|aboveText|belowText)$/); expect(model.get('showCategories')).to.match(/^(no|aboveText|belowText)$/);
}); });
it('has text preceding categories', function () { it('has text preceding categories', function () {
expect(model.get('categoriesPrecededBy')).to.be.a('string'); expect(model.get('categoriesPrecededBy')).to.be.a('string');
}); });
it('has a link or a button type for read more', function () { it('has a link or a button type for read more', function () {
expect(model.get('readMoreType')).to.match(/^(link|button)$/); expect(model.get('readMoreType')).to.match(/^(link|button)$/);
}); });
it('has read more text', function () { it('has read more text', function () {
expect(model.get('readMoreText')).to.be.a('string'); expect(model.get('readMoreText')).to.be.a('string');
}); });
it('has a read more button', function () { it('has a read more button', function () {
expect(model.get('readMoreButton')).to.be.instanceof(Backbone.Model); expect(model.get('readMoreButton')).to.be.instanceof(Backbone.Model);
}); });
it('has sorting', function () { it('has sorting', function () {
expect(model.get('sortBy')).to.match(/^(newest|oldest)$/); expect(model.get('sortBy')).to.match(/^(newest|oldest)$/);
}); });
it('has an option to display divider', function () { it('has an option to display divider', function () {
expect(model.get('showDivider')).to.be.a('boolean'); expect(model.get('showDivider')).to.be.a('boolean');
}); });
it('has a divider', function () { it('has a divider', function () {
expect(model.get('divider')).to.be.instanceof(Backbone.Model); expect(model.get('divider')).to.be.instanceof(Backbone.Model);
}); });
it("uses defaults from config when they are set", function () { it("uses defaults from config when they are set", function () {
global.stubConfig(EditorApplication, { global.stubConfig(EditorApplication, {
blockDefaults: { blockDefaults: {
automatedLatestContent: { automatedLatestContent: {
amount: '17', amount: '17',
contentType: 'mailpoet_page', // 'post'|'page'|'mailpoet_page' contentType: 'mailpoet_page', // 'post'|'page'|'mailpoet_page'
inclusionType: 'exclude', // 'include'|'exclude' inclusionType: 'exclude', // 'include'|'exclude'
displayType: 'full', // 'excerpt'|'full'|'titleOnly' displayType: 'full', // 'excerpt'|'full'|'titleOnly'
titleFormat: 'h3', // 'h1'|'h2'|'h3'|'ul' titleFormat: 'h3', // 'h1'|'h2'|'h3'|'ul'
titlePosition: 'aboveBlock', // 'inTextBlock'|'aboveBlock', titlePosition: 'aboveBlock', // 'inTextBlock'|'aboveBlock',
titleAlignment: 'right', // 'left'|'center'|'right' titleAlignment: 'right', // 'left'|'center'|'right'
titleIsLink: true, // false|true titleIsLink: true, // false|true
imagePadded: false, // true|false imagePadded: false, // true|false
showAuthor: 'belowText', // 'no'|'aboveText'|'belowText' showAuthor: 'belowText', // 'no'|'aboveText'|'belowText'
authorPrecededBy: 'Custom config author preceded by', authorPrecededBy: 'Custom config author preceded by',
showCategories: 'belowText', // 'no'|'aboveText'|'belowText' showCategories: 'belowText', // 'no'|'aboveText'|'belowText'
categoriesPrecededBy: 'Custom config categories preceded by', categoriesPrecededBy: 'Custom config categories preceded by',
readMoreType: 'button', // 'link'|'button' readMoreType: 'button', // 'link'|'button'
readMoreText: 'Custom Config read more text', readMoreText: 'Custom Config read more text',
readMoreButton: { readMoreButton: {
text: 'Custom config read more', text: 'Custom config read more',
url: '[postLink]', url: '[postLink]',
styles: { styles: {
block: { block: {
backgroundColor: '#123456', backgroundColor: '#123456',
borderColor: '#234567', borderColor: '#234567',
},
link: {
fontColor: '#345678',
fontFamily: 'Tahoma',
fontSize: '37px',
},
},
},
sortBy: 'oldest', // 'newest'|'oldest',
showDivider: true, // true|false
divider: {
src: 'http://example.org/someConfigDividerImage.png',
styles: {
block: {
backgroundColor: '#456789',
padding: '38px',
},
},
},
},
}, },
}); link: {
var model = new (EditorApplication.module('blocks.automatedLatestContent').AutomatedLatestContentBlockModel)(); fontColor: '#345678',
fontFamily: 'Tahoma',
fontSize: '37px',
},
},
},
sortBy: 'oldest', // 'newest'|'oldest',
showDivider: true, // true|false
divider: {
src: 'http://example.org/someConfigDividerImage.png',
styles: {
block: {
backgroundColor: '#456789',
padding: '38px',
},
},
},
},
},
});
var model = new (EditorApplication.module('blocks.automatedLatestContent').AutomatedLatestContentBlockModel)();
expect(model.get('amount')).to.equal('17'); expect(model.get('amount')).to.equal('17');
expect(model.get('contentType')).to.equal('mailpoet_page'); expect(model.get('contentType')).to.equal('mailpoet_page');
expect(model.get('inclusionType')).to.equal('exclude'); expect(model.get('inclusionType')).to.equal('exclude');
expect(model.get('displayType')).to.equal('full'); expect(model.get('displayType')).to.equal('full');
expect(model.get('titleFormat')).to.equal('h3'); expect(model.get('titleFormat')).to.equal('h3');
expect(model.get('titlePosition')).to.equal('aboveBlock'); expect(model.get('titlePosition')).to.equal('aboveBlock');
expect(model.get('titleAlignment')).to.equal('right'); expect(model.get('titleAlignment')).to.equal('right');
expect(model.get('titleIsLink')).to.equal(true); expect(model.get('titleIsLink')).to.equal(true);
expect(model.get('imagePadded')).to.equal(false); expect(model.get('imagePadded')).to.equal(false);
expect(model.get('showAuthor')).to.equal('belowText'); expect(model.get('showAuthor')).to.equal('belowText');
expect(model.get('authorPrecededBy')).to.equal('Custom config author preceded by'); expect(model.get('authorPrecededBy')).to.equal('Custom config author preceded by');
expect(model.get('showCategories')).to.equal('belowText'); expect(model.get('showCategories')).to.equal('belowText');
expect(model.get('categoriesPrecededBy')).to.equal('Custom config categories preceded by'); expect(model.get('categoriesPrecededBy')).to.equal('Custom config categories preceded by');
expect(model.get('readMoreType')).to.equal('button'); expect(model.get('readMoreType')).to.equal('button');
expect(model.get('readMoreText')).to.equal('Custom Config read more text'); expect(model.get('readMoreText')).to.equal('Custom Config read more text');
expect(model.get('readMoreButton.text')).to.equal('Custom config read more'); expect(model.get('readMoreButton.text')).to.equal('Custom config read more');
expect(model.get('readMoreButton.url')).to.equal('[postLink]'); expect(model.get('readMoreButton.url')).to.equal('[postLink]');
expect(model.get('readMoreButton.styles.block.backgroundColor')).to.equal('#123456'); expect(model.get('readMoreButton.styles.block.backgroundColor')).to.equal('#123456');
expect(model.get('readMoreButton.styles.block.borderColor')).to.equal('#234567'); expect(model.get('readMoreButton.styles.block.borderColor')).to.equal('#234567');
expect(model.get('readMoreButton.styles.link.fontColor')).to.equal('#345678'); expect(model.get('readMoreButton.styles.link.fontColor')).to.equal('#345678');
expect(model.get('readMoreButton.styles.link.fontFamily')).to.equal('Tahoma'); expect(model.get('readMoreButton.styles.link.fontFamily')).to.equal('Tahoma');
expect(model.get('readMoreButton.styles.link.fontSize')).to.equal('37px'); expect(model.get('readMoreButton.styles.link.fontSize')).to.equal('37px');
expect(model.get('sortBy')).to.equal('oldest'); expect(model.get('sortBy')).to.equal('oldest');
expect(model.get('showDivider')).to.equal(true); expect(model.get('showDivider')).to.equal(true);
expect(model.get('divider.src')).to.equal('http://example.org/someConfigDividerImage.png'); expect(model.get('divider.src')).to.equal('http://example.org/someConfigDividerImage.png');
expect(model.get('divider.styles.block.backgroundColor')).to.equal('#456789'); expect(model.get('divider.styles.block.backgroundColor')).to.equal('#456789');
expect(model.get('divider.styles.block.padding')).to.equal('38px'); expect(model.get('divider.styles.block.padding')).to.equal('38px');
}); });
});
describe('block view', function () {
var model, view;
beforeEach(function () {
global.stubChannel(EditorApplication);
global.stubConfig(EditorApplication);
EditorApplication.getBlockTypeModel = sinon.stub().returns(Backbone.Model);
EditorApplication.getBlockTypeView = sinon.stub().returns(Backbone.View);
model = new (EditorApplication.module('blocks.automatedLatestContent').AutomatedLatestContentBlockModel)();
view = new (EditorApplication.module('blocks.automatedLatestContent').AutomatedLatestContentBlockView)({model: model});
}); });
describe('block view', function () { afterEach(function () {
var model, view; delete EditorApplication.getChannel;
beforeEach(function () {
global.stubChannel(EditorApplication);
global.stubConfig(EditorApplication);
EditorApplication.getBlockTypeModel = sinon.stub().returns(Backbone.Model);
EditorApplication.getBlockTypeView = sinon.stub().returns(Backbone.View);
model = new (EditorApplication.module('blocks.automatedLatestContent').AutomatedLatestContentBlockModel)();
view = new (EditorApplication.module('blocks.automatedLatestContent').AutomatedLatestContentBlockView)({model: model});
});
afterEach(function () {
delete EditorApplication.getChannel;
});
it('renders', function () {
expect(view.render).to.not.throw();
expect(view.$('.mailpoet_content')).to.have.length(1);
});
}); });
describe('block settings view', function () { it('renders', function () {
expect(view.render).to.not.throw();
expect(view.$('.mailpoet_content')).to.have.length(1);
});
});
describe('block settings view', function () {
var model, view;
before(function () {
global.stubChannel(EditorApplication);
global.stubConfig(EditorApplication, {
blockDefaults: {},
});
EditorApplication.getBlockTypeModel = sinon.stub().returns(Backbone.Model);
EditorApplication.getBlockTypeView = sinon.stub().returns(Backbone.View);
});
beforeEach(function() {
model = new (EditorApplication.module('blocks.automatedLatestContent').AutomatedLatestContentBlockModel)();
view = new (EditorApplication.module('blocks.automatedLatestContent').AutomatedLatestContentBlockSettingsView)({model: model});
});
after(function () {
delete EditorApplication.getChannel;
});
it('renders', function () {
expect(view.render).to.not.throw();
});
describe('once rendered', function () {
beforeEach(function() {
model = new (EditorApplication.module('blocks.automatedLatestContent').AutomatedLatestContentBlockModel)();
view = new (EditorApplication.module('blocks.automatedLatestContent').AutomatedLatestContentBlockSettingsView)({model: model});
view.render();
});
it('changes the model if post amount changes', function () {
var newValue = '11';
view.$('.mailpoet_automated_latest_content_show_amount').val(newValue).keyup();
expect(model.get('amount')).to.equal(newValue);
});
it('changes the model if post type changes', function () {
var newValue = 'mailpoet_page';
view.$('.mailpoet_automated_latest_content_content_type').val(newValue).change();
expect(model.get('contentType')).to.equal(newValue);
});
it('changes the model if inclusion type changes', function () {
var newValue = 'exclude';
view.$('.mailpoet_automated_latest_content_include_or_exclude').val(newValue).change();
expect(model.get('inclusionType')).to.equal(newValue);
});
it('changes the model if display type changes', function () {
var newValue = 'full';
view.$('.mailpoet_automated_latest_content_display_type').val(newValue).change();
expect(model.get('displayType')).to.equal(newValue);
});
it('changes the model if title format changes', function () {
var newValue = 'h3';
view.$('.mailpoet_automated_latest_content_title_format').val(newValue).change();
expect(model.get('titleFormat')).to.equal(newValue);
});
it('changes the model if title position changes', function () {
var newValue = 'aboveBlock';
view.$('.mailpoet_automated_latest_content_title_position').val(newValue).change();
expect(model.get('titlePosition')).to.equal(newValue);
});
it('changes the model if title alignment changes', function () {
var newValue = 'right';
view.$('.mailpoet_automated_latest_content_title_alignment').val(newValue).change();
expect(model.get('titleAlignment')).to.equal(newValue);
});
it('changes the model if title link changes', function () {
var newValue = true;
view.$('.mailpoet_automated_latest_content_title_as_links').val(newValue).change();
expect(model.get('titleIsLink')).to.equal(newValue);
});
it('changes the model if image alignment changes', function () {
var newValue = false;
view.$('.mailpoet_automated_latest_content_image_padded').val(newValue).change();
expect(model.get('imagePadded')).to.equal(newValue);
});
it('changes the model if show author changes', function () {
var newValue = 'belowText';
view.$('.mailpoet_automated_latest_content_show_author').val(newValue).change();
expect(model.get('showAuthor')).to.equal(newValue);
});
it('changes the model if author preceded by changes', function () {
var newValue = 'New author preceded by test';
view.$('.mailpoet_automated_latest_content_author_preceded_by').val(newValue).keyup();
expect(model.get('authorPrecededBy')).to.equal(newValue);
});
it('changes the model if show categories changes', function () {
var newValue = 'belowText';
view.$('.mailpoet_automated_latest_content_show_categories').val(newValue).change();
expect(model.get('showCategories')).to.equal(newValue);
});
it('changes the model if categories preceded by changes', function () {
var newValue = 'New categories preceded by test';
view.$('.mailpoet_automated_latest_content_categories').val(newValue).keyup();
expect(model.get('categoriesPrecededBy')).to.equal(newValue);
});
it('changes the model if read more button type changes', function () {
var newValue = 'link';
view.$('.mailpoet_automated_latest_content_read_more_type').val(newValue).change();
expect(model.get('readMoreType')).to.equal(newValue);
});
it('changes the model if read more text changes', function () {
var newValue = 'New read more text';
view.$('.mailpoet_automated_latest_content_read_more_text').val(newValue).keyup();
expect(model.get('readMoreText')).to.equal(newValue);
});
it('changes the model if sort by changes', function () {
var newValue = 'oldest';
view.$('.mailpoet_automated_latest_content_sort_by').val(newValue).change();
expect(model.get('sortBy')).to.equal(newValue);
});
it('changes the model if show divider changes', function () {
var newValue = true;
view.$('.mailpoet_automated_latest_content_show_divider').val(newValue).change();
expect(model.get('showDivider')).to.equal(newValue);
});
describe('when "title only" display type is selected', function() {
var model, view; var model, view;
before(function () {
global.stubChannel(EditorApplication);
global.stubConfig(EditorApplication, {
blockDefaults: {},
});
EditorApplication.getBlockTypeModel = sinon.stub().returns(Backbone.Model);
EditorApplication.getBlockTypeView = sinon.stub().returns(Backbone.View);
});
beforeEach(function() { beforeEach(function() {
model = new (EditorApplication.module('blocks.automatedLatestContent').AutomatedLatestContentBlockModel)();
view = new (EditorApplication.module('blocks.automatedLatestContent').AutomatedLatestContentBlockSettingsView)({model: model});
view.render();
view.$('.mailpoet_automated_latest_content_display_type').val('titleOnly').change();
});
it('shows "title as list" option', function () {
expect(view.$('.mailpoet_automated_latest_content_title_as_list')).to.not.have.$class('mailpoet_hidden');
});
describe('when "title as list" is selected', function() {
var model, view;
beforeEach(function() {
model = new (EditorApplication.module('blocks.automatedLatestContent').AutomatedLatestContentBlockModel)(); model = new (EditorApplication.module('blocks.automatedLatestContent').AutomatedLatestContentBlockModel)();
view = new (EditorApplication.module('blocks.automatedLatestContent').AutomatedLatestContentBlockSettingsView)({model: model}); view = new (EditorApplication.module('blocks.automatedLatestContent').AutomatedLatestContentBlockSettingsView)({model: model});
view.render();
view.$('.mailpoet_automated_latest_content_display_type').val('titleOnly').change();
view.$('.mailpoet_automated_latest_content_title_format').val('ul').change();
});
describe('"title is link" option', function () {
it('is hidden', function () {
expect(view.$('.mailpoet_automated_latest_content_title_as_link')).to.have.$class('mailpoet_hidden');
});
it('is set to "yes"', function() {
expect(model.get('titleIsLink')).to.equal(true);
});
});
}); });
after(function () { describe('when "title as list" is deselected', function() {
delete EditorApplication.getChannel; before(function() {
view.$('.mailpoet_automated_latest_content_title_format').val('ul').change();
view.$('.mailpoet_automated_latest_content_title_format').val('h3').change();
});
describe('"title is link" option', function () {
it('is visible', function () {
expect(view.$('.mailpoet_automated_latest_content_title_as_link')).to.not.have.$class('mailpoet_hidden');
});
});
}); });
});
it('renders', function () { it.skip('closes the sidepanel after "Done" is clicked', function () {
expect(view.render).to.not.throw(); var mock = sinon.mock().once();
}); global.MailPoet.Modal.cancel = mock;
view.$('.mailpoet_done_editing').click();
describe('once rendered', function () { mock.verify();
beforeEach(function() { delete(global.MailPoet.Modal.cancel);
model = new (EditorApplication.module('blocks.automatedLatestContent').AutomatedLatestContentBlockModel)(); });
view = new (EditorApplication.module('blocks.automatedLatestContent').AutomatedLatestContentBlockSettingsView)({model: model});
view.render();
});
it('changes the model if post amount changes', function () {
var newValue = '11';
view.$('.mailpoet_automated_latest_content_show_amount').val(newValue).keyup();
expect(model.get('amount')).to.equal(newValue);
});
it('changes the model if post type changes', function () {
var newValue = 'mailpoet_page';
view.$('.mailpoet_automated_latest_content_content_type').val(newValue).change();
expect(model.get('contentType')).to.equal(newValue);
});
it('changes the model if inclusion type changes', function () {
var newValue = 'exclude';
view.$('.mailpoet_automated_latest_content_include_or_exclude').val(newValue).change();
expect(model.get('inclusionType')).to.equal(newValue);
});
it('changes the model if display type changes', function () {
var newValue = 'full';
view.$('.mailpoet_automated_latest_content_display_type').val(newValue).change();
expect(model.get('displayType')).to.equal(newValue);
});
it('changes the model if title format changes', function () {
var newValue = 'h3';
view.$('.mailpoet_automated_latest_content_title_format').val(newValue).change();
expect(model.get('titleFormat')).to.equal(newValue);
});
it('changes the model if title position changes', function () {
var newValue = 'aboveBlock';
view.$('.mailpoet_automated_latest_content_title_position').val(newValue).change();
expect(model.get('titlePosition')).to.equal(newValue);
});
it('changes the model if title alignment changes', function () {
var newValue = 'right';
view.$('.mailpoet_automated_latest_content_title_alignment').val(newValue).change();
expect(model.get('titleAlignment')).to.equal(newValue);
});
it('changes the model if title link changes', function () {
var newValue = true;
view.$('.mailpoet_automated_latest_content_title_as_links').val(newValue).change();
expect(model.get('titleIsLink')).to.equal(newValue);
});
it('changes the model if image alignment changes', function () {
var newValue = false;
view.$('.mailpoet_automated_latest_content_image_padded').val(newValue).change();
expect(model.get('imagePadded')).to.equal(newValue);
});
it('changes the model if show author changes', function () {
var newValue = 'belowText';
view.$('.mailpoet_automated_latest_content_show_author').val(newValue).change();
expect(model.get('showAuthor')).to.equal(newValue);
});
it('changes the model if author preceded by changes', function () {
var newValue = 'New author preceded by test';
view.$('.mailpoet_automated_latest_content_author_preceded_by').val(newValue).keyup();
expect(model.get('authorPrecededBy')).to.equal(newValue);
});
it('changes the model if show categories changes', function () {
var newValue = 'belowText';
view.$('.mailpoet_automated_latest_content_show_categories').val(newValue).change();
expect(model.get('showCategories')).to.equal(newValue);
});
it('changes the model if categories preceded by changes', function () {
var newValue = 'New categories preceded by test';
view.$('.mailpoet_automated_latest_content_categories').val(newValue).keyup();
expect(model.get('categoriesPrecededBy')).to.equal(newValue);
});
it('changes the model if read more button type changes', function () {
var newValue = 'link';
view.$('.mailpoet_automated_latest_content_read_more_type').val(newValue).change();
expect(model.get('readMoreType')).to.equal(newValue);
});
it('changes the model if read more text changes', function () {
var newValue = 'New read more text';
view.$('.mailpoet_automated_latest_content_read_more_text').val(newValue).keyup();
expect(model.get('readMoreText')).to.equal(newValue);
});
it('changes the model if sort by changes', function () {
var newValue = 'oldest';
view.$('.mailpoet_automated_latest_content_sort_by').val(newValue).change();
expect(model.get('sortBy')).to.equal(newValue);
});
it('changes the model if show divider changes', function () {
var newValue = true;
view.$('.mailpoet_automated_latest_content_show_divider').val(newValue).change();
expect(model.get('showDivider')).to.equal(newValue);
});
describe('when "title only" display type is selected', function() {
var model, view;
beforeEach(function() {
model = new (EditorApplication.module('blocks.automatedLatestContent').AutomatedLatestContentBlockModel)();
view = new (EditorApplication.module('blocks.automatedLatestContent').AutomatedLatestContentBlockSettingsView)({model: model});
view.render();
view.$('.mailpoet_automated_latest_content_display_type').val('titleOnly').change();
});
it('shows "title as list" option', function () {
expect(view.$('.mailpoet_automated_latest_content_title_as_list')).to.not.have.$class('mailpoet_hidden');
});
describe('when "title as list" is selected', function() {
var model, view;
beforeEach(function() {
model = new (EditorApplication.module('blocks.automatedLatestContent').AutomatedLatestContentBlockModel)();
view = new (EditorApplication.module('blocks.automatedLatestContent').AutomatedLatestContentBlockSettingsView)({model: model});
view.render();
view.$('.mailpoet_automated_latest_content_display_type').val('titleOnly').change();
view.$('.mailpoet_automated_latest_content_title_format').val('ul').change();
});
describe('"title is link" option', function () {
it('is hidden', function () {
expect(view.$('.mailpoet_automated_latest_content_title_as_link')).to.have.$class('mailpoet_hidden');
});
it('is set to "yes"', function() {
expect(model.get('titleIsLink')).to.equal(true);
});
});
});
describe('when "title as list" is deselected', function() {
before(function() {
view.$('.mailpoet_automated_latest_content_title_format').val('ul').change();
view.$('.mailpoet_automated_latest_content_title_format').val('h3').change();
});
describe('"title is link" option', function () {
it('is visible', function () {
expect(view.$('.mailpoet_automated_latest_content_title_as_link')).to.not.have.$class('mailpoet_hidden');
});
});
});
});
it.skip('closes the sidepanel after "Done" is clicked', function () {
var mock = sinon.mock().once();
global.MailPoet.Modal.cancel = mock;
view.$('.mailpoet_done_editing').click();
mock.verify();
delete(global.MailPoet.Modal.cancel);
});
});
}); });
});
}); });
}); });

View File

@ -4,419 +4,418 @@ define('test/newsletter_editor/blocks/button', [
], function(EditorApplication) { ], function(EditorApplication) {
describe("Button", function () { describe("Button", function () {
describe("model", function () { describe("model", function () {
var model; var model;
beforeEach(function () { beforeEach(function () {
global.stubChannel(EditorApplication); global.stubChannel(EditorApplication);
global.stubConfig(EditorApplication, { global.stubConfig(EditorApplication, {
blockDefaults: {}, blockDefaults: {},
}); });
model = new (EditorApplication.module('blocks.button').ButtonBlockModel)(); model = new (EditorApplication.module('blocks.button').ButtonBlockModel)();
});
afterEach(function () {
delete EditorApplication.getChannel;
});
it("has a button type", function () {
expect(model.get('type')).to.equal('button');
});
it("has a label", function () {
expect(model.get('text')).to.be.a('string');
});
it("has a url", function () {
expect(model.get('url')).to.be.a('string');
});
it("has a block background color", function () {
expect(model.get('styles.block.backgroundColor')).to.match(/^(#[abcdef0-9]{6})|transparent$/);
});
it("has a block border color", function () {
expect(model.get('styles.block.borderColor')).to.match(/^(#[abcdef0-9]{6})|transparent$/);
});
it("has a block border width", function () {
expect(model.get('styles.block.borderWidth')).to.match(/^\d+px$/);
});
it("has block border radius", function () {
expect(model.get('styles.block.borderRadius')).to.match(/^\d+px$/);
});
it("has block border style", function () {
expect(model.get('styles.block.borderStyle')).to.equal('solid');
});
it("has a text color", function () {
expect(model.get('styles.block.fontColor')).to.match(/^(#[abcdef0-9]{6})|transparent$/);
});
it("has a text font family", function () {
expect(model.get('styles.block.fontFamily')).to.be.a('string');
});
it("has a text size", function () {
expect(model.get('styles.block.fontSize')).to.match(/^\d+px$/);
});
it("has width", function () {
expect(model.get('styles.block.width')).to.match(/^\d+px$/);
});
it("has line height", function () {
expect(model.get('styles.block.lineHeight')).to.match(/^\d+px$/);
});
it("changes attributes with set", function () {
var newText = 'Some new text';
model.set('text', newText);
expect(model.get('text')).to.equal(newText);
});
it("triggers autosave if any attribute changes", function () {
var mock = sinon.mock().exactly(11).withArgs('autoSave');
EditorApplication.getChannel = sinon.stub().returns({
trigger: mock,
});
model.set('text', 'some other text');
model.set('url', 'some url');
model.set('styles.block.backgroundColor', '#123456');
model.set('styles.block.borderColor', '#234567');
model.set('styles.block.borderWidth', '3px');
model.set('styles.block.borderRadius', '8px');
model.set('styles.block.width', '400px');
model.set('styles.block.lineHeight', '100px');
model.set('styles.block.fontColor', '#345678');
model.set('styles.block.fontFamily', 'Some other style');
model.set('styles.block.fontSize', '10px');
mock.verify();
});
it("uses defaults from config when they are set", function () {
global.stubConfig(EditorApplication, {
blockDefaults: {
button: {
text: 'Some new text',
url: 'http://somenewurl.com',
styles: {
block: {
backgroundColor: '#123456',
borderColor: '#234567',
borderWidth: '11px',
borderRadius: '13px',
borderStyle: 'solid',
width: '371px',
lineHeight: '107px',
fontColor: '#345678',
fontFamily: 'Tahoma',
fontSize: '30px',
},
},
},
},
});
var model = new (EditorApplication.module('blocks.button').ButtonBlockModel)();
expect(model.get('text')).to.equal('Some new text');
expect(model.get('url')).to.equal('http://somenewurl.com');
expect(model.get('styles.block.backgroundColor')).to.equal('#123456');
expect(model.get('styles.block.borderColor')).to.equal('#234567');
expect(model.get('styles.block.borderWidth')).to.equal('11px');
expect(model.get('styles.block.borderRadius')).to.equal('13px');
expect(model.get('styles.block.borderStyle')).to.equal('solid');
expect(model.get('styles.block.width')).to.equal('371px');
expect(model.get('styles.block.lineHeight')).to.equal('107px');
expect(model.get('styles.block.fontColor')).to.equal('#345678');
expect(model.get('styles.block.fontFamily')).to.equal('Tahoma');
expect(model.get('styles.block.fontSize')).to.equal('30px');
});
}); });
describe('block view', function () { afterEach(function () {
var model; delete EditorApplication.getChannel;
beforeEach(function () {
global.stubChannel(EditorApplication);
model = new (EditorApplication.module('blocks.button').ButtonBlockModel)();
});
it('renders', function () {
var view = new (EditorApplication.module('blocks.button').ButtonBlockView)({model: model});
expect(view.render).to.not.throw();
expect(view.$('.mailpoet_editor_button')).to.have.length(1);
});
it('rerenders when attributes change', function () {
var view = new (EditorApplication.module('blocks.button').ButtonBlockView)({model: model});
view.render();
model.set('text', 'Some new text');
expect(view.$('.mailpoet_editor_button').text()).to.equal('Some new text');
});
describe('once rendered', function () {
var model, view;
before(function () {
global.stubChannel(EditorApplication);
model = new (EditorApplication.module('blocks.button').ButtonBlockModel)({
text: 'Some button',
url: 'http://example.org',
styles: {
block: {
backgroundColor: '#123456',
borderColor: '#234567',
borderWidth: '7px',
borderRadius: '8px',
borderStyle: 'solid',
width: '123px',
lineHeight: '45px',
fontColor: '#345678',
fontFamily: 'Arial',
fontSize: '12px',
},
},
});
view = new (EditorApplication.module('blocks.button').ButtonBlockView)({model: model});
view.render();
});
it('has a specified text', function () {
expect(view.$('.mailpoet_editor_button').text()).to.equal(model.get('text'));
});
it('has a specified button url', function () {
expect(view.$('.mailpoet_editor_button').attr('href')).to.equal(model.get('url'));
});
it('has a specified background color', function () {
// jQuery colors appear in rgb format, not hex6
expect(view.$('.mailpoet_editor_button').css('background-color')).to.equal('rgb(18, 52, 86)');
});
it('has a specified border color', function () {
expect(view.$('.mailpoet_editor_button').css('border-color')).to.equal(model.get('styles.block.borderColor'));
});
it('has a specified border width', function () {
expect(view.$('.mailpoet_editor_button').css('border-width')).to.equal(model.get('styles.block.borderWidth'));
});
it('has a specified border radius', function () {
expect(view.$('.mailpoet_editor_button').css('border-radius')).to.equal(model.get('styles.block.borderRadius'));
});
it('has a specified border style', function () {
expect(view.$('.mailpoet_editor_button').css('border-style')).to.equal(model.get('styles.block.borderStyle'));
});
it('has a specified width', function () {
expect(view.$('.mailpoet_editor_button').css('width')).to.equal(model.get('styles.block.width'));
});
it('has a specified line height', function () {
expect(view.$('.mailpoet_editor_button').css('lineHeight')).to.equal(model.get('styles.block.lineHeight'));
});
it('has a specified font color', function () {
// jQuery colors appear in rgb format, not hex6
expect(view.$('.mailpoet_editor_button').css('color')).to.equal('rgb(52, 86, 120)');
});
it('has a specified font family', function () {
expect(view.$('.mailpoet_editor_button').css('font-family')).to.equal(model.get('styles.block.fontFamily'));
});
it('has a specified font size', function () {
expect(view.$('.mailpoet_editor_button').css('font-size')).to.equal(model.get('styles.block.fontSize'));
});
});
}); });
describe('block settings view', function () { it("has a button type", function () {
var model; expect(model.get('type')).to.equal('button');
beforeEach(function () {
global.stubChannel(EditorApplication);
global.stubAvailableStyles(EditorApplication, {
fonts: ['Arial', 'Tahoma'],
headingSizes: ['16px', '20px'],
});
model = new (EditorApplication.module('blocks.button').ButtonBlockModel)({
type: 'button',
text: 'Some random text',
});
});
it('renders', function () {
var view = new (EditorApplication.module('blocks.button').ButtonBlockSettingsView)({model: model});
expect(view.render).to.not.throw();
});
describe('once rendered', function () {
var model, view;
before(function() {
global.stubChannel(EditorApplication);
global.stubConfig(EditorApplication);
global.stubAvailableStyles(EditorApplication, {
fonts: ['Arial', 'Tahoma'],
headingSizes: ['16px', '20px'],
});
});
beforeEach(function() {
model = new (EditorApplication.module('blocks.button').ButtonBlockModel)({
type: 'button',
text: 'Some random text',
});
view = new (EditorApplication.module('blocks.button').ButtonBlockSettingsView)({model: model});
view.render();
});
it('updates the model when text is changed', function () {
var newValue = 'something else';
view.$('.mailpoet_field_button_text').val(newValue).keyup();
expect(model.get('text')).to.equal(newValue);
});
it('updates the model when link is changed', function () {
var newValue = 'http://google.com/?q=123456';
view.$('.mailpoet_field_button_url').val(newValue).keyup();
expect(model.get('url')).to.equal(newValue);
});
it('updates the model when font color changes', function () {
var newValue = '#cccccc';
view.$('.mailpoet_field_button_font_color').val(newValue).change();
expect(model.get('styles.block.fontColor')).to.equal(newValue);
});
it('updates the model when font family changes', function () {
var newValue = 'Tahoma';
view.$('.mailpoet_field_button_font_family').val(newValue).change();
expect(model.get('styles.block.fontFamily')).to.equal(newValue);
});
it('updates the model when font size changes', function () {
var newValue = '20px';
view.$('.mailpoet_field_button_font_size').val(newValue).change();
expect(model.get('styles.block.fontSize')).to.equal(newValue);
});
it('updates the model when background color changes', function () {
var newValue = '#cccccc';
view.$('.mailpoet_field_button_background_color').val(newValue).change();
expect(model.get('styles.block.backgroundColor')).to.equal(newValue);
});
it('updates the model when border color changes', function () {
var newValue = '#cccccc';
view.$('.mailpoet_field_button_border_color').val(newValue).change();
expect(model.get('styles.block.borderColor')).to.equal(newValue);
});
it('updates the model when border width changes', function () {
view.$('.mailpoet_field_button_border_width').val('3').change();
expect(model.get('styles.block.borderWidth')).to.equal('3px');
});
it('updates the range slider when border width input changes', function () {
view.$('.mailpoet_field_button_border_width_input').val('5').keyup();
expect(view.$('.mailpoet_field_button_border_width').val()).to.equal('5');
});
it('updates the input when border width range slider changes', function () {
view.$('.mailpoet_field_button_border_width').val('4').change();
expect(view.$('.mailpoet_field_button_border_width_input').val()).to.equal('4');
});
it('updates the model when border radius changes', function () {
view.$('.mailpoet_field_button_border_radius').val('7').change();
expect(model.get('styles.block.borderRadius')).to.equal('7px');
});
it('updates the range slider when border radius input changes', function () {
view.$('.mailpoet_field_button_border_radius_input').val('7').keyup();
expect(view.$('.mailpoet_field_button_border_radius').val()).to.equal('7');
});
it('updates the input when border radius range slider changes', function () {
view.$('.mailpoet_field_button_border_radius').val('7').change();
expect(view.$('.mailpoet_field_button_border_radius_input').val()).to.equal('7');
});
it('updates the model when width changes', function () {
view.$('.mailpoet_field_button_width').val('127').change();
expect(model.get('styles.block.width')).to.equal('127px');
});
it('updates the range slider when width input changes', function () {
view.$('.mailpoet_field_button_width_input').val('127').keyup();
expect(view.$('.mailpoet_field_button_width').val()).to.equal('127');
});
it('updates the input when width range slider changes', function () {
view.$('.mailpoet_field_button_width').val('127').change();
expect(view.$('.mailpoet_field_button_width_input').val()).to.equal('127');
});
it('updates the model when line height changes', function () {
view.$('.mailpoet_field_button_line_height').val('37').change();
expect(model.get('styles.block.lineHeight')).to.equal('37px');
});
it('updates the range slider when line height input changes', function () {
view.$('.mailpoet_field_button_line_height_input').val('37').keyup();
expect(view.$('.mailpoet_field_button_line_height').val()).to.equal('37');
});
it('updates the input when line height range slider changes', function () {
view.$('.mailpoet_field_button_line_height').val('37').change();
expect(view.$('.mailpoet_field_button_line_height_input').val()).to.equal('37');
});
it('does not display link option when `hideLink` option is active', function() {
view = new (EditorApplication.module('blocks.button').ButtonBlockSettingsView)({
model: model,
renderOptions: {
hideLink: true,
},
});
view.render();
expect(view.$('.mailpoet_field_button_url').length).to.equal(0);
});
it('does not display "Apply to all" option when `hideApplyToAll` option is active', function() {
view = new (EditorApplication.module('blocks.button').ButtonBlockSettingsView)({
model: model,
renderOptions: {
hideApplyToAll: true,
},
});
view.render();
expect(view.$('.mailpoet_field_button_replace_all_styles').length).to.equal(0);
});
it.skip('closes the sidepanel after "Done" is clicked', function () {
var mock = sinon.mock().once();
global.MailPoet.Modal.cancel = mock;
view.$('.mailpoet_done_editing').click();
mock.verify();
delete(global.MailPoet.Modal.cancel);
});
});
}); });
it("has a label", function () {
expect(model.get('text')).to.be.a('string');
});
it("has a url", function () {
expect(model.get('url')).to.be.a('string');
});
it("has a block background color", function () {
expect(model.get('styles.block.backgroundColor')).to.match(/^(#[abcdef0-9]{6})|transparent$/);
});
it("has a block border color", function () {
expect(model.get('styles.block.borderColor')).to.match(/^(#[abcdef0-9]{6})|transparent$/);
});
it("has a block border width", function () {
expect(model.get('styles.block.borderWidth')).to.match(/^\d+px$/);
});
it("has block border radius", function () {
expect(model.get('styles.block.borderRadius')).to.match(/^\d+px$/);
});
it("has block border style", function () {
expect(model.get('styles.block.borderStyle')).to.equal('solid');
});
it("has a text color", function () {
expect(model.get('styles.block.fontColor')).to.match(/^(#[abcdef0-9]{6})|transparent$/);
});
it("has a text font family", function () {
expect(model.get('styles.block.fontFamily')).to.be.a('string');
});
it("has a text size", function () {
expect(model.get('styles.block.fontSize')).to.match(/^\d+px$/);
});
it("has width", function () {
expect(model.get('styles.block.width')).to.match(/^\d+px$/);
});
it("has line height", function () {
expect(model.get('styles.block.lineHeight')).to.match(/^\d+px$/);
});
it("changes attributes with set", function () {
var newText = 'Some new text';
model.set('text', newText);
expect(model.get('text')).to.equal(newText);
});
it("triggers autosave if any attribute changes", function () {
var mock = sinon.mock().exactly(11).withArgs('autoSave');
EditorApplication.getChannel = sinon.stub().returns({
trigger: mock,
});
model.set('text', 'some other text');
model.set('url', 'some url');
model.set('styles.block.backgroundColor', '#123456');
model.set('styles.block.borderColor', '#234567');
model.set('styles.block.borderWidth', '3px');
model.set('styles.block.borderRadius', '8px');
model.set('styles.block.width', '400px');
model.set('styles.block.lineHeight', '100px');
model.set('styles.block.fontColor', '#345678');
model.set('styles.block.fontFamily', 'Some other style');
model.set('styles.block.fontSize', '10px');
mock.verify();
});
it("uses defaults from config when they are set", function () {
global.stubConfig(EditorApplication, {
blockDefaults: {
button: {
text: 'Some new text',
url: 'http://somenewurl.com',
styles: {
block: {
backgroundColor: '#123456',
borderColor: '#234567',
borderWidth: '11px',
borderRadius: '13px',
borderStyle: 'solid',
width: '371px',
lineHeight: '107px',
fontColor: '#345678',
fontFamily: 'Tahoma',
fontSize: '30px',
},
},
},
},
});
var model = new (EditorApplication.module('blocks.button').ButtonBlockModel)();
expect(model.get('text')).to.equal('Some new text');
expect(model.get('url')).to.equal('http://somenewurl.com');
expect(model.get('styles.block.backgroundColor')).to.equal('#123456');
expect(model.get('styles.block.borderColor')).to.equal('#234567');
expect(model.get('styles.block.borderWidth')).to.equal('11px');
expect(model.get('styles.block.borderRadius')).to.equal('13px');
expect(model.get('styles.block.borderStyle')).to.equal('solid');
expect(model.get('styles.block.width')).to.equal('371px');
expect(model.get('styles.block.lineHeight')).to.equal('107px');
expect(model.get('styles.block.fontColor')).to.equal('#345678');
expect(model.get('styles.block.fontFamily')).to.equal('Tahoma');
expect(model.get('styles.block.fontSize')).to.equal('30px');
});
});
describe('block view', function () {
var model;
beforeEach(function () {
global.stubChannel(EditorApplication);
model = new (EditorApplication.module('blocks.button').ButtonBlockModel)();
});
it('renders', function () {
var view = new (EditorApplication.module('blocks.button').ButtonBlockView)({model: model});
expect(view.render).to.not.throw();
expect(view.$('.mailpoet_editor_button')).to.have.length(1);
});
it('rerenders when attributes change', function () {
var view = new (EditorApplication.module('blocks.button').ButtonBlockView)({model: model});
view.render();
model.set('text', 'Some new text');
expect(view.$('.mailpoet_editor_button').text()).to.equal('Some new text');
});
describe('once rendered', function () {
var model, view;
before(function () {
global.stubChannel(EditorApplication);
model = new (EditorApplication.module('blocks.button').ButtonBlockModel)({
text: 'Some button',
url: 'http://example.org',
styles: {
block: {
backgroundColor: '#123456',
borderColor: '#234567',
borderWidth: '7px',
borderRadius: '8px',
borderStyle: 'solid',
width: '123px',
lineHeight: '45px',
fontColor: '#345678',
fontFamily: 'Arial',
fontSize: '12px',
},
},
});
view = new (EditorApplication.module('blocks.button').ButtonBlockView)({model: model});
view.render();
});
it('has a specified text', function () {
expect(view.$('.mailpoet_editor_button').text()).to.equal(model.get('text'));
});
it('has a specified button url', function () {
expect(view.$('.mailpoet_editor_button').attr('href')).to.equal(model.get('url'));
});
it('has a specified background color', function () {
// jQuery colors appear in rgb format, not hex6
expect(view.$('.mailpoet_editor_button').css('background-color')).to.equal('rgb(18, 52, 86)');
});
it('has a specified border color', function () {
expect(view.$('.mailpoet_editor_button').css('border-color')).to.equal(model.get('styles.block.borderColor'));
});
it('has a specified border width', function () {
expect(view.$('.mailpoet_editor_button').css('border-width')).to.equal(model.get('styles.block.borderWidth'));
});
it('has a specified border radius', function () {
expect(view.$('.mailpoet_editor_button').css('border-radius')).to.equal(model.get('styles.block.borderRadius'));
});
it('has a specified border style', function () {
expect(view.$('.mailpoet_editor_button').css('border-style')).to.equal(model.get('styles.block.borderStyle'));
});
it('has a specified width', function () {
expect(view.$('.mailpoet_editor_button').css('width')).to.equal(model.get('styles.block.width'));
});
it('has a specified line height', function () {
expect(view.$('.mailpoet_editor_button').css('lineHeight')).to.equal(model.get('styles.block.lineHeight'));
});
it('has a specified font color', function () {
// jQuery colors appear in rgb format, not hex6
expect(view.$('.mailpoet_editor_button').css('color')).to.equal('rgb(52, 86, 120)');
});
it('has a specified font family', function () {
expect(view.$('.mailpoet_editor_button').css('font-family')).to.equal(model.get('styles.block.fontFamily'));
});
it('has a specified font size', function () {
expect(view.$('.mailpoet_editor_button').css('font-size')).to.equal(model.get('styles.block.fontSize'));
});
});
});
describe('block settings view', function () {
var model;
beforeEach(function () {
global.stubChannel(EditorApplication);
global.stubAvailableStyles(EditorApplication, {
fonts: ['Arial', 'Tahoma'],
headingSizes: ['16px', '20px'],
});
model = new (EditorApplication.module('blocks.button').ButtonBlockModel)({
type: 'button',
text: 'Some random text',
});
});
it('renders', function () {
var view = new (EditorApplication.module('blocks.button').ButtonBlockSettingsView)({model: model});
expect(view.render).to.not.throw();
});
describe('once rendered', function () {
var model, view;
before(function() {
global.stubChannel(EditorApplication);
global.stubConfig(EditorApplication);
global.stubAvailableStyles(EditorApplication, {
fonts: ['Arial', 'Tahoma'],
headingSizes: ['16px', '20px'],
});
});
beforeEach(function() {
model = new (EditorApplication.module('blocks.button').ButtonBlockModel)({
type: 'button',
text: 'Some random text',
});
view = new (EditorApplication.module('blocks.button').ButtonBlockSettingsView)({model: model});
view.render();
});
it('updates the model when text is changed', function () {
var newValue = 'something else';
view.$('.mailpoet_field_button_text').val(newValue).keyup();
expect(model.get('text')).to.equal(newValue);
});
it('updates the model when link is changed', function () {
var newValue = 'http://google.com/?q=123456';
view.$('.mailpoet_field_button_url').val(newValue).keyup();
expect(model.get('url')).to.equal(newValue);
});
it('updates the model when font color changes', function () {
var newValue = '#cccccc';
view.$('.mailpoet_field_button_font_color').val(newValue).change();
expect(model.get('styles.block.fontColor')).to.equal(newValue);
});
it('updates the model when font family changes', function () {
var newValue = 'Tahoma';
view.$('.mailpoet_field_button_font_family').val(newValue).change();
expect(model.get('styles.block.fontFamily')).to.equal(newValue);
});
it('updates the model when font size changes', function () {
var newValue = '20px';
view.$('.mailpoet_field_button_font_size').val(newValue).change();
expect(model.get('styles.block.fontSize')).to.equal(newValue);
});
it('updates the model when background color changes', function () {
var newValue = '#cccccc';
view.$('.mailpoet_field_button_background_color').val(newValue).change();
expect(model.get('styles.block.backgroundColor')).to.equal(newValue);
});
it('updates the model when border color changes', function () {
var newValue = '#cccccc';
view.$('.mailpoet_field_button_border_color').val(newValue).change();
expect(model.get('styles.block.borderColor')).to.equal(newValue);
});
it('updates the model when border width changes', function () {
view.$('.mailpoet_field_button_border_width').val('3').change();
expect(model.get('styles.block.borderWidth')).to.equal('3px');
});
it('updates the range slider when border width input changes', function () {
view.$('.mailpoet_field_button_border_width_input').val('5').keyup();
expect(view.$('.mailpoet_field_button_border_width').val()).to.equal('5');
});
it('updates the input when border width range slider changes', function () {
view.$('.mailpoet_field_button_border_width').val('4').change();
expect(view.$('.mailpoet_field_button_border_width_input').val()).to.equal('4');
});
it('updates the model when border radius changes', function () {
view.$('.mailpoet_field_button_border_radius').val('7').change();
expect(model.get('styles.block.borderRadius')).to.equal('7px');
});
it('updates the range slider when border radius input changes', function () {
view.$('.mailpoet_field_button_border_radius_input').val('7').keyup();
expect(view.$('.mailpoet_field_button_border_radius').val()).to.equal('7');
});
it('updates the input when border radius range slider changes', function () {
view.$('.mailpoet_field_button_border_radius').val('7').change();
expect(view.$('.mailpoet_field_button_border_radius_input').val()).to.equal('7');
});
it('updates the model when width changes', function () {
view.$('.mailpoet_field_button_width').val('127').change();
expect(model.get('styles.block.width')).to.equal('127px');
});
it('updates the range slider when width input changes', function () {
view.$('.mailpoet_field_button_width_input').val('127').keyup();
expect(view.$('.mailpoet_field_button_width').val()).to.equal('127');
});
it('updates the input when width range slider changes', function () {
view.$('.mailpoet_field_button_width').val('127').change();
expect(view.$('.mailpoet_field_button_width_input').val()).to.equal('127');
});
it('updates the model when line height changes', function () {
view.$('.mailpoet_field_button_line_height').val('37').change();
expect(model.get('styles.block.lineHeight')).to.equal('37px');
});
it('updates the range slider when line height input changes', function () {
view.$('.mailpoet_field_button_line_height_input').val('37').keyup();
expect(view.$('.mailpoet_field_button_line_height').val()).to.equal('37');
});
it('updates the input when line height range slider changes', function () {
view.$('.mailpoet_field_button_line_height').val('37').change();
expect(view.$('.mailpoet_field_button_line_height_input').val()).to.equal('37');
});
it('does not display link option when `hideLink` option is active', function() {
view = new (EditorApplication.module('blocks.button').ButtonBlockSettingsView)({
model: model,
renderOptions: {
hideLink: true,
},
});
view.render();
expect(view.$('.mailpoet_field_button_url').length).to.equal(0);
});
it('does not display "Apply to all" option when `hideApplyToAll` option is active', function() {
view = new (EditorApplication.module('blocks.button').ButtonBlockSettingsView)({
model: model,
renderOptions: {
hideApplyToAll: true,
},
});
view.render();
expect(view.$('.mailpoet_field_button_replace_all_styles').length).to.equal(0);
});
it.skip('closes the sidepanel after "Done" is clicked', function () {
var mock = sinon.mock().once();
global.MailPoet.Modal.cancel = mock;
view.$('.mailpoet_done_editing').click();
mock.verify();
delete(global.MailPoet.Modal.cancel);
});
});
});
}); });
}); });

View File

@ -4,204 +4,203 @@ define('test/newsletter_editor/blocks/container', [
], function(EditorApplication) { ], function(EditorApplication) {
describe('Container', function () { describe('Container', function () {
var ModelClass = EditorApplication.module('blocks.container').ContainerBlockModel; var ModelClass = EditorApplication.module('blocks.container').ContainerBlockModel;
describe('model', function () { describe('model', function () {
describe('by default', function () { describe('by default', function () {
global.stubConfig(EditorApplication); global.stubConfig(EditorApplication);
var model = new ModelClass(); var model = new ModelClass();
it('has container type', function () { it('has container type', function () {
expect(model.get('type')).to.equal('container'); expect(model.get('type')).to.equal('container');
}); });
it('has orientation', function () { it('has orientation', function () {
expect(model.get('orientation')).to.equal('vertical'); expect(model.get('orientation')).to.equal('vertical');
}); });
it('has a background color', function () { it('has a background color', function () {
expect(model.get('styles.block.backgroundColor')).to.match(/^(#[abcdef0-9]{6})|transparent$/); expect(model.get('styles.block.backgroundColor')).to.match(/^(#[abcdef0-9]{6})|transparent$/);
}); });
it('has a collection of blocks', function () { it('has a collection of blocks', function () {
expect(model.get('blocks')).to.be.instanceof(Backbone.Collection); expect(model.get('blocks')).to.be.instanceof(Backbone.Collection);
}); });
it("uses defaults from config when they are set", function () { it("uses defaults from config when they are set", function () {
global.stubConfig(EditorApplication, { global.stubConfig(EditorApplication, {
blockDefaults: { blockDefaults: {
container: { container: {
styles: { styles: {
block: { block: {
backgroundColor: '#123456', backgroundColor: '#123456',
},
},
},
},
});
var model = new (EditorApplication.module('blocks.container').ContainerBlockModel)();
expect(model.get('styles.block.backgroundColor')).to.equal('#123456');
});
});
describe('when creating with children', function () {
var testModel = {
type: 'sampleType',
someField: 'Some Content',
}, },
model; },
},
it('will recursively create children', function () { },
EditorApplication.getBlockTypeModel = sinon.stub().returns(Backbone.Model);
model = new (EditorApplication.module('blocks.container').ContainerBlockModel)({
type: 'container',
blocks: [testModel],
}, {parse: true});
expect(model.get('blocks')).to.have.length(1);
expect(model.get('blocks').at(0).get('type')).to.equal(testModel.type);
expect(model.get('blocks').at(0).get('someField')).to.equal(testModel.someField);
});
it('will create nested containers and their children', function () {
var stub = sinon.stub();
stub.withArgs('container').returns(ModelClass);
stub.withArgs('someType').returns(Backbone.Model);
EditorApplication.getBlockTypeModel = stub;
model = new ModelClass({
type: 'container',
blocks: [
{
type: 'container',
blocks: [
{
type: 'someType',
someField: 'some text',
},
{
type: 'someType',
someField: 'some text 2',
},
],
}
],
}, {parse: true});
expect(model.get('blocks')).to.have.length(1);
expect(model.get('blocks').at(0).get('blocks')).to.have.length(2);
expect(model.get('blocks').at(0).get('blocks').at(1).get('someField')).to.equal('some text 2');
});
}); });
var model = new (EditorApplication.module('blocks.container').ContainerBlockModel)();
expect(model.get('styles.block.backgroundColor')).to.equal('#123456');
});
}); });
describe('block view', function () { describe('when creating with children', function () {
global.stubChannel(EditorApplication); var testModel = {
global.stubAvailableStyles(EditorApplication); type: 'sampleType',
var model = new (EditorApplication.module('blocks.container').ContainerBlockModel)(), someField: 'Some Content',
view = new (EditorApplication.module('blocks.container').ContainerBlockView)({model: model}); },
model;
it('renders', function () { it('will recursively create children', function () {
expect(view.render).to.not.throw(); EditorApplication.getBlockTypeModel = sinon.stub().returns(Backbone.Model);
});
describe('once rendered', function () { model = new (EditorApplication.module('blocks.container').ContainerBlockModel)({
type: 'container',
blocks: [testModel],
}, {parse: true});
describe('on root level', function () { expect(model.get('blocks')).to.have.length(1);
var model = new (EditorApplication.module('blocks.container').ContainerBlockModel)(), expect(model.get('blocks').at(0).get('type')).to.equal(testModel.type);
view; expect(model.get('blocks').at(0).get('someField')).to.equal(testModel.someField);
});
beforeEach(function () { it('will create nested containers and their children', function () {
global.stubChannel(EditorApplication); var stub = sinon.stub();
global.stubAvailableStyles(EditorApplication); stub.withArgs('container').returns(ModelClass);
view = new (EditorApplication.module('blocks.container').ContainerBlockView)({ stub.withArgs('someType').returns(Backbone.Model);
model: model, EditorApplication.getBlockTypeModel = stub;
renderOptions: {
depth: 0,
},
});
view.render();
});
it('does not have a deletion tool', function () {
expect(view.$('.mailpoet_delete_block')).to.have.length(0);
});
it('does not have a move tool', function () { model = new ModelClass({
expect(view.$('.mailpoet_move_block')).to.have.length(0); type: 'container',
}); blocks: [
{
type: 'container',
blocks: [
{
type: 'someType',
someField: 'some text',
},
{
type: 'someType',
someField: 'some text 2',
},
],
}
],
}, {parse: true});
it('does not have a settings tool', function () { expect(model.get('blocks')).to.have.length(1);
expect(view.$('.mailpoet_edit_block')).to.have.length(0); expect(model.get('blocks').at(0).get('blocks')).to.have.length(2);
}); expect(model.get('blocks').at(0).get('blocks').at(1).get('someField')).to.equal('some text 2');
}); });
});
});
describe.skip('on non-root levels', function () { describe('block view', function () {
var model = new (EditorApplication.module('blocks.container').ContainerBlockModel)(), global.stubChannel(EditorApplication);
view; global.stubAvailableStyles(EditorApplication);
var model = new (EditorApplication.module('blocks.container').ContainerBlockModel)(),
view = new (EditorApplication.module('blocks.container').ContainerBlockView)({model: model});
beforeEach(function () { it('renders', function () {
global.stubChannel(EditorApplication); expect(view.render).to.not.throw();
global.stubAvailableStyles(EditorApplication);
view = new (EditorApplication.module('blocks.container').ContainerBlockView)({
model: model,
renderOptions: {
depth: 1,
},
});
view.render();
});
it('has a deletion tool', function () {
expect(view.$('.mailpoet_delete_block')).to.have.length(1);
});
it('has a move tool', function () {
expect(view.$('.mailpoet_move_block')).to.have.length(0);
});
it('has a settings tool', function () {
expect(view.$('.mailpoet_edit_block')).to.have.length(1);
});
});
});
}); });
describe('settings view', function () { describe('once rendered', function () {
global.stubChannel(EditorApplication);
global.stubAvailableStyles(EditorApplication); describe('on root level', function () {
var model = new (EditorApplication.module('blocks.container').ContainerBlockModel)(), var model = new (EditorApplication.module('blocks.container').ContainerBlockModel)(),
view = new (EditorApplication.module('blocks.container').ContainerBlockSettingsView)({model: model}); view;
it('renders', function () { beforeEach(function () {
expect(view.render).to.not.throw(); global.stubChannel(EditorApplication);
}); global.stubAvailableStyles(EditorApplication);
view = new (EditorApplication.module('blocks.container').ContainerBlockView)({
describe('once rendered', function () { model: model,
var model, view; renderOptions: {
beforeEach(function() { depth: 0,
global.stubChannel(EditorApplication); },
global.stubAvailableStyles(EditorApplication);
model = new (EditorApplication.module('blocks.container').ContainerBlockModel)();
view = new (EditorApplication.module('blocks.container').ContainerBlockSettingsView)({model: model});
}); });
view.render();
it('updates the model when background color changes', function () { });
view.$('.mailpoet_field_container_background_color').val('#123456').change(); it('does not have a deletion tool', function () {
expect(model.get('styles.block.backgroundColor')).to.equal('#123456'); expect(view.$('.mailpoet_delete_block')).to.have.length(0);
});
it.skip('closes the sidepanel after "Done" is clicked', function () {
var mock = sinon.mock().once();
global.MailPoet.Modal.cancel = mock;
view.$('.mailpoet_done_editing').click();
mock.verify();
delete(global.MailPoet.Modal.cancel);
});
}); });
});
});
it('does not have a move tool', function () {
expect(view.$('.mailpoet_move_block')).to.have.length(0);
});
it('does not have a settings tool', function () {
expect(view.$('.mailpoet_edit_block')).to.have.length(0);
});
});
describe.skip('on non-root levels', function () {
var model = new (EditorApplication.module('blocks.container').ContainerBlockModel)(),
view;
beforeEach(function () {
global.stubChannel(EditorApplication);
global.stubAvailableStyles(EditorApplication);
view = new (EditorApplication.module('blocks.container').ContainerBlockView)({
model: model,
renderOptions: {
depth: 1,
},
});
view.render();
});
it('has a deletion tool', function () {
expect(view.$('.mailpoet_delete_block')).to.have.length(1);
});
it('has a move tool', function () {
expect(view.$('.mailpoet_move_block')).to.have.length(0);
});
it('has a settings tool', function () {
expect(view.$('.mailpoet_edit_block')).to.have.length(1);
});
});
});
});
describe('settings view', function () {
global.stubChannel(EditorApplication);
global.stubAvailableStyles(EditorApplication);
var model = new (EditorApplication.module('blocks.container').ContainerBlockModel)(),
view = new (EditorApplication.module('blocks.container').ContainerBlockSettingsView)({model: model});
it('renders', function () {
expect(view.render).to.not.throw();
});
describe('once rendered', function () {
var model, view;
beforeEach(function() {
global.stubChannel(EditorApplication);
global.stubAvailableStyles(EditorApplication);
model = new (EditorApplication.module('blocks.container').ContainerBlockModel)();
view = new (EditorApplication.module('blocks.container').ContainerBlockSettingsView)({model: model});
});
it('updates the model when background color changes', function () {
view.$('.mailpoet_field_container_background_color').val('#123456').change();
expect(model.get('styles.block.backgroundColor')).to.equal('#123456');
});
it.skip('closes the sidepanel after "Done" is clicked', function () {
var mock = sinon.mock().once();
global.MailPoet.Modal.cancel = mock;
view.$('.mailpoet_done_editing').click();
mock.verify();
delete(global.MailPoet.Modal.cancel);
});
});
});
});
}); });

View File

@ -4,203 +4,202 @@ define('test/newsletter_editor/blocks/divider', [
], function(EditorApplication) { ], function(EditorApplication) {
describe("Divider", function () { describe("Divider", function () {
describe("model", function () { describe("model", function () {
var model; var model;
beforeEach(function () { beforeEach(function () {
global.stubChannel(EditorApplication); global.stubChannel(EditorApplication);
global.stubConfig(EditorApplication, { global.stubConfig(EditorApplication, {
blockDefaults: {}, blockDefaults: {},
}); });
global.stubAvailableStyles(EditorApplication); global.stubAvailableStyles(EditorApplication);
model = new (EditorApplication.module('blocks.divider').DividerBlockModel)(); model = new (EditorApplication.module('blocks.divider').DividerBlockModel)();
});
afterEach(function () {
delete EditorApplication.getChannel;
});
it("has a divider type", function () {
expect(model.get('type')).to.equal('divider');
});
it("has a background color", function () {
expect(model.get('styles.block.backgroundColor')).to.match(/^(#[abcdef0-9]{6})|transparent$/);
});
it("has padding", function () {
expect(model.get('styles.block.padding')).to.match(/^\d+px$/);
});
it('has border style', function () {
expect(model.get('styles.block.borderStyle')).to.match(/^(none|dotted|dashed|solid|double|groove|ridge|inset|outset)$/);
});
it('has border width', function () {
expect(model.get('styles.block.borderWidth')).to.match(/^\d+px$/);
});
it('has border color', function () {
expect(model.get('styles.block.borderColor')).to.match(/^(#[abcdef0-9]{6})|transparent$/);
});
it("changes attributes with set", function () {
var newValue = 'outset';
model.set('styles.block.borderStyle', newValue);
expect(model.get('styles.block.borderStyle')).to.equal(newValue);
});
it("triggers autosave if any attribute changes", function () {
var mock = sinon.mock().exactly(5).withArgs('autoSave');
EditorApplication.getChannel = sinon.stub().returns({
trigger: mock,
});
model.set('styles.block.backgroundColor', '#000000');
model.set('styles.block.padding', '19px');
model.set('styles.block.borderStyle', 'double');
model.set('styles.block.borderWidth', '17px');
model.set('styles.block.borderColor', '#123456');
mock.verify();
});
it("uses defaults from config when they are set", function () {
global.stubConfig(EditorApplication, {
blockDefaults: {
divider: {
styles: {
block: {
backgroundColor: '#123456',
padding: '37px',
borderStyle: 'inset',
borderWidth: '7px',
borderColor: '#345678',
},
},
},
},
});
var model = new (EditorApplication.module('blocks.divider').DividerBlockModel)();
expect(model.get('styles.block.backgroundColor')).to.equal('#123456');
expect(model.get('styles.block.padding')).to.equal('37px');
expect(model.get('styles.block.borderStyle')).to.equal('inset');
expect(model.get('styles.block.borderWidth')).to.equal('7px');
expect(model.get('styles.block.borderColor')).to.equal('#345678');
});
}); });
describe('block view', function () { afterEach(function () {
global.stubChannel(EditorApplication); delete EditorApplication.getChannel;
global.stubConfig(EditorApplication);
var model = new (EditorApplication.module('blocks.divider').DividerBlockModel)(),
view;
beforeEach(function () {
global.stubChannel(EditorApplication);
view = new (EditorApplication.module('blocks.divider').DividerBlockView)({model: model});
});
it('renders', function () {
expect(view.render).to.not.throw();
expect(view.$('.mailpoet_divider')).to.have.length(1);
});
it('rerenders if model attributes change', function () {
view.render();
model.set('styles.block.borderStyle', 'inset');
expect(view.$('.mailpoet_divider').css('border-top-style')).to.equal('inset');
});
}); });
describe('settings view', function () { it("has a divider type", function () {
expect(model.get('type')).to.equal('divider');
});
it("has a background color", function () {
expect(model.get('styles.block.backgroundColor')).to.match(/^(#[abcdef0-9]{6})|transparent$/);
});
it("has padding", function () {
expect(model.get('styles.block.padding')).to.match(/^\d+px$/);
});
it('has border style', function () {
expect(model.get('styles.block.borderStyle')).to.match(/^(none|dotted|dashed|solid|double|groove|ridge|inset|outset)$/);
});
it('has border width', function () {
expect(model.get('styles.block.borderWidth')).to.match(/^\d+px$/);
});
it('has border color', function () {
expect(model.get('styles.block.borderColor')).to.match(/^(#[abcdef0-9]{6})|transparent$/);
});
it("changes attributes with set", function () {
var newValue = 'outset';
model.set('styles.block.borderStyle', newValue);
expect(model.get('styles.block.borderStyle')).to.equal(newValue);
});
it("triggers autosave if any attribute changes", function () {
var mock = sinon.mock().exactly(5).withArgs('autoSave');
EditorApplication.getChannel = sinon.stub().returns({
trigger: mock,
});
model.set('styles.block.backgroundColor', '#000000');
model.set('styles.block.padding', '19px');
model.set('styles.block.borderStyle', 'double');
model.set('styles.block.borderWidth', '17px');
model.set('styles.block.borderColor', '#123456');
mock.verify();
});
it("uses defaults from config when they are set", function () {
global.stubConfig(EditorApplication, {
blockDefaults: {
divider: {
styles: {
block: {
backgroundColor: '#123456',
padding: '37px',
borderStyle: 'inset',
borderWidth: '7px',
borderColor: '#345678',
},
},
},
},
});
var model = new (EditorApplication.module('blocks.divider').DividerBlockModel)();
expect(model.get('styles.block.backgroundColor')).to.equal('#123456');
expect(model.get('styles.block.padding')).to.equal('37px');
expect(model.get('styles.block.borderStyle')).to.equal('inset');
expect(model.get('styles.block.borderWidth')).to.equal('7px');
expect(model.get('styles.block.borderColor')).to.equal('#345678');
});
});
describe('block view', function () {
global.stubChannel(EditorApplication);
global.stubConfig(EditorApplication);
var model = new (EditorApplication.module('blocks.divider').DividerBlockModel)(),
view;
beforeEach(function () {
global.stubChannel(EditorApplication);
view = new (EditorApplication.module('blocks.divider').DividerBlockView)({model: model});
});
it('renders', function () {
expect(view.render).to.not.throw();
expect(view.$('.mailpoet_divider')).to.have.length(1);
});
it('rerenders if model attributes change', function () {
view.render();
model.set('styles.block.borderStyle', 'inset');
expect(view.$('.mailpoet_divider').css('border-top-style')).to.equal('inset');
});
});
describe('settings view', function () {
global.stubChannel(EditorApplication);
global.stubAvailableStyles(EditorApplication, {
dividers: ['solid', 'inset'],
});
var model = new (EditorApplication.module('blocks.divider').DividerBlockModel)(),
view = new (EditorApplication.module('blocks.divider').DividerBlockSettingsView)({model: model});
it('renders', function () {
expect(view.render).to.not.throw();
expect(view.$('.mailpoet_divider_selector')).to.have.length(1);
});
describe('once rendered', function () {
var model, view;
before(function() {
global.stubChannel(EditorApplication); global.stubChannel(EditorApplication);
global.stubAvailableStyles(EditorApplication, { global.stubAvailableStyles(EditorApplication, {
dividers: ['solid', 'inset'], dividers: ['solid', 'inset'],
}); });
var model = new (EditorApplication.module('blocks.divider').DividerBlockModel)(), });
view = new (EditorApplication.module('blocks.divider').DividerBlockSettingsView)({model: model});
it('renders', function () { beforeEach(function () {
expect(view.render).to.not.throw(); model = new (EditorApplication.module('blocks.divider').DividerBlockModel)();
expect(view.$('.mailpoet_divider_selector')).to.have.length(1); view = new (EditorApplication.module('blocks.divider').DividerBlockSettingsView)({model: model});
view.render();
});
it('updates the model when divider style changes', function () {
view.$('.mailpoet_field_divider_style').last().click();
expect(model.get('styles.block.borderStyle')).to.equal('inset');
});
it('updates the model when divider width changes', function () {
view.$('.mailpoet_field_divider_border_width').val('17').change();
expect(model.get('styles.block.borderWidth')).to.equal('17px');
});
it('updates the range slider when divider width input changes', function () {
view.$('.mailpoet_field_divider_border_width_input').val('19').keyup();
expect(view.$('.mailpoet_field_divider_border_width').val()).to.equal('19');
});
it('updates the input when divider width range slider changes', function () {
view.$('.mailpoet_field_divider_border_width').val('19').change();
expect(view.$('.mailpoet_field_divider_border_width_input').val()).to.equal('19');
});
it('updates the model when divider color changes', function () {
view.$('.mailpoet_field_divider_border_color').val('#123457').change();
expect(model.get('styles.block.borderColor')).to.equal('#123457');
});
it('updates the model when divider background color changes', function () {
view.$('.mailpoet_field_divider_background_color').val('#cccccc').change();
expect(model.get('styles.block.backgroundColor')).to.equal('#cccccc');
});
it ('changes color of available divider styles when actual divider color changes', function() {
var newColor = '#889912';
view.$('.mailpoet_field_divider_border_color').val(newColor).change();
expect(view.$('.mailpoet_field_divider_style div')).to.have.$css('border-top-color', newColor);
});
it('does not display "Apply to all" option when `hideApplyToAll` option is active', function() {
view = new (EditorApplication.module('blocks.divider').DividerBlockSettingsView)({
model: model,
renderOptions: {
hideApplyToAll: true,
},
}); });
view.render();
expect(view.$('.mailpoet_button_divider_apply_to_all').length).to.equal(0);
});
describe('once rendered', function () { it.skip('closes the sidepanel after "Done" is clicked', function () {
var model, view; var mock = sinon.mock().once();
global.MailPoet.Modal.cancel = mock;
before(function() { view.$('.mailpoet_done_editing').click();
global.stubChannel(EditorApplication); mock.verify();
global.stubAvailableStyles(EditorApplication, { delete(global.MailPoet.Modal.cancel);
dividers: ['solid', 'inset'], });
});
});
beforeEach(function () {
model = new (EditorApplication.module('blocks.divider').DividerBlockModel)();
view = new (EditorApplication.module('blocks.divider').DividerBlockSettingsView)({model: model});
view.render();
});
it('updates the model when divider style changes', function () {
view.$('.mailpoet_field_divider_style').last().click();
expect(model.get('styles.block.borderStyle')).to.equal('inset');
});
it('updates the model when divider width changes', function () {
view.$('.mailpoet_field_divider_border_width').val('17').change();
expect(model.get('styles.block.borderWidth')).to.equal('17px');
});
it('updates the range slider when divider width input changes', function () {
view.$('.mailpoet_field_divider_border_width_input').val('19').keyup();
expect(view.$('.mailpoet_field_divider_border_width').val()).to.equal('19');
});
it('updates the input when divider width range slider changes', function () {
view.$('.mailpoet_field_divider_border_width').val('19').change();
expect(view.$('.mailpoet_field_divider_border_width_input').val()).to.equal('19');
});
it('updates the model when divider color changes', function () {
view.$('.mailpoet_field_divider_border_color').val('#123457').change();
expect(model.get('styles.block.borderColor')).to.equal('#123457');
});
it('updates the model when divider background color changes', function () {
view.$('.mailpoet_field_divider_background_color').val('#cccccc').change();
expect(model.get('styles.block.backgroundColor')).to.equal('#cccccc');
});
it ('changes color of available divider styles when actual divider color changes', function() {
var newColor = '#889912';
view.$('.mailpoet_field_divider_border_color').val(newColor).change();
expect(view.$('.mailpoet_field_divider_style div')).to.have.$css('border-top-color', newColor);
});
it('does not display "Apply to all" option when `hideApplyToAll` option is active', function() {
view = new (EditorApplication.module('blocks.divider').DividerBlockSettingsView)({
model: model,
renderOptions: {
hideApplyToAll: true,
},
});
view.render();
expect(view.$('.mailpoet_button_divider_apply_to_all').length).to.equal(0);
});
it.skip('closes the sidepanel after "Done" is clicked', function () {
var mock = sinon.mock().once();
global.MailPoet.Modal.cancel = mock;
view.$('.mailpoet_done_editing').click();
mock.verify();
delete(global.MailPoet.Modal.cancel);
});
});
}); });
});
}); });
}); });

View File

@ -4,197 +4,196 @@ define('test/newsletter_editor/blocks/footer', [
], function(EditorApplication) { ], function(EditorApplication) {
describe('Footer', function () { describe('Footer', function () {
describe('model', function () { describe('model', function () {
var model; var model;
beforeEach(function () { beforeEach(function () {
global.stubChannel(EditorApplication); global.stubChannel(EditorApplication);
model = new (EditorApplication.module('blocks.footer').FooterBlockModel)(); model = new (EditorApplication.module('blocks.footer').FooterBlockModel)();
});
it('has a footer type', function () {
expect(model.get('type')).to.equal('footer');
});
it('has text', function () {
expect(model.get('text')).to.be.a('string');
});
it('has a background color', function () {
expect(model.get('styles.block.backgroundColor')).to.match(/^(#[abcdef0-9]{6})|transparent$/);
});
it('has a text color', function () {
expect(model.get('styles.text.fontColor')).to.match(/^(#[abcdef0-9]{6})|transparent$/);
});
it('has a font family', function () {
expect(model.get('styles.text.fontFamily')).to.equal('Arial');
});
it('has a font size', function () {
expect(model.get('styles.text.fontSize')).to.match(/^\d+px$/);
});
it('has text alignment', function () {
expect(model.get('styles.text.textAlign')).to.match(/^(left|center|right|justify)$/);
});
it('has a link color', function () {
expect(model.get('styles.link.fontColor')).to.match(/^(#[abcdef0-9]{6})|transparent$/);
});
it('has link decoration', function () {
expect(model.get('styles.link.textDecoration')).to.match(/^(underline|none)$/);
});
it('changes attributes with set', function () {
var newValue = 'Some New Text';
model.set('text', newValue);
expect(model.get('text')).to.equal(newValue);
});
it('triggers autosave when any of the attributes change', function () {
var mock = sinon.mock().exactly(8).withArgs('autoSave');
EditorApplication.getChannel = sinon.stub().returns({
trigger: mock,
});
model.set('text', 'Some new text');
model.set('styles.block.backgroundColor', '#123456');
model.set('styles.text.fontColor', '#123456');
model.set('styles.text.fontFamily', 'SomeFontCT');
model.set('styles.text.fontSize', '23px');
model.set('styles.text.textAlign', 'justify');
model.set('styles.link.fontColor', '#123456');
model.set('styles.link.textDecoration', 'underline');
mock.verify();
});
it("uses defaults from config when they are set", function () {
global.stubConfig(EditorApplication, {
blockDefaults: {
footer: {
text: 'some custom config text',
styles: {
block: {
backgroundColor: '#123456',
},
text: {
fontColor: '#234567',
fontFamily: 'Tahoma',
fontSize: '37px',
textAlign: 'right',
},
link: {
fontColor: '#345678',
textDecoration: 'underline',
},
},
}
},
});
var model = new (EditorApplication.module('blocks.footer').FooterBlockModel)();
expect(model.get('text')).to.equal('some custom config text');
expect(model.get('styles.block.backgroundColor')).to.equal('#123456');
expect(model.get('styles.text.fontColor')).to.equal('#234567');
expect(model.get('styles.text.fontFamily')).to.equal('Tahoma');
expect(model.get('styles.text.fontSize')).to.equal('37px');
expect(model.get('styles.text.textAlign')).to.equal('right');
expect(model.get('styles.link.fontColor')).to.equal('#345678');
expect(model.get('styles.link.textDecoration')).to.equal('underline');
});
}); });
describe('block view', function () { it('has a footer type', function () {
global.stubChannel(EditorApplication); expect(model.get('type')).to.equal('footer');
global.stubConfig(EditorApplication);
global.stubAvailableStyles(EditorApplication);
var model = new (EditorApplication.module('blocks.footer').FooterBlockModel)(),
view;
beforeEach(function () {
global.stubChannel(EditorApplication);
view = new (EditorApplication.module('blocks.footer').FooterBlockView)({model: model});
});
it('renders', function () {
expect(view.render).to.not.throw();
expect(view.$('.mailpoet_content')).to.have.length(1);
});
}); });
describe('settings view', function () { it('has text', function () {
global.stubChannel(EditorApplication); expect(model.get('text')).to.be.a('string');
global.stubAvailableStyles(EditorApplication, {
fonts: ['Arial', 'Tahoma'],
textSizes: ['16px', '20px'],
});
var model = new (EditorApplication.module('blocks.footer').FooterBlockModel)(),
view = new (EditorApplication.module('blocks.footer').FooterBlockSettingsView)({model: model});
it('renders', function () {
expect(view.render).to.not.throw();
expect(view.$('.mailpoet_field_footer_text_color')).to.have.length(1);
});
describe('once rendered', function () {
var model, view;
beforeEach(function() {
global.stubChannel(EditorApplication);
global.stubAvailableStyles(EditorApplication, {
fonts: ['Arial', 'Tahoma'],
textSizes: ['16px', '20px'],
});
model = new (EditorApplication.module('blocks.footer').FooterBlockModel)({});
view = new (EditorApplication.module('blocks.footer').FooterBlockSettingsView)({model: model});
view.render();
});
it('updates the model when text font color changes', function () {
view.$('.mailpoet_field_footer_text_color').val('#123456').change();
expect(model.get('styles.text.fontColor')).to.equal('#123456');
});
it('updates the model when text font family changes', function () {
var value = 'Tahoma';
view.$('.mailpoet_field_footer_text_font_family').val(value).change();
expect(model.get('styles.text.fontFamily')).to.equal(value);
});
it('updates the model when text font size changes', function () {
var value = '20px';
view.$('.mailpoet_field_footer_text_size').val(value).change();
expect(model.get('styles.text.fontSize')).to.equal(value);
});
it('updates the model when link font color changes', function () {
view.$('#mailpoet_field_footer_link_color').val('#123456').change();
expect(model.get('styles.link.fontColor')).to.equal('#123456');
});
it('updates the model when link text decoration changes', function () {
view.$('#mailpoet_field_footer_link_underline').prop('checked', true).change();
expect(model.get('styles.link.textDecoration')).to.equal('underline');
});
it('updates the model when background color changes', function () {
view.$('.mailpoet_field_footer_alignment').last().prop('checked', true).change();
expect(model.get('styles.text.textAlign')).to.equal('right');
});
it.skip('closes the sidepanel after "Done" is clicked', function () {
var mock = sinon.mock().once();
global.MailPoet.Modal.cancel = mock;
view.$('.mailpoet_done_editing').click();
mock.verify();
delete(global.MailPoet.Modal.cancel);
});
});
}); });
it('has a background color', function () {
expect(model.get('styles.block.backgroundColor')).to.match(/^(#[abcdef0-9]{6})|transparent$/);
});
it('has a text color', function () {
expect(model.get('styles.text.fontColor')).to.match(/^(#[abcdef0-9]{6})|transparent$/);
});
it('has a font family', function () {
expect(model.get('styles.text.fontFamily')).to.equal('Arial');
});
it('has a font size', function () {
expect(model.get('styles.text.fontSize')).to.match(/^\d+px$/);
});
it('has text alignment', function () {
expect(model.get('styles.text.textAlign')).to.match(/^(left|center|right|justify)$/);
});
it('has a link color', function () {
expect(model.get('styles.link.fontColor')).to.match(/^(#[abcdef0-9]{6})|transparent$/);
});
it('has link decoration', function () {
expect(model.get('styles.link.textDecoration')).to.match(/^(underline|none)$/);
});
it('changes attributes with set', function () {
var newValue = 'Some New Text';
model.set('text', newValue);
expect(model.get('text')).to.equal(newValue);
});
it('triggers autosave when any of the attributes change', function () {
var mock = sinon.mock().exactly(8).withArgs('autoSave');
EditorApplication.getChannel = sinon.stub().returns({
trigger: mock,
});
model.set('text', 'Some new text');
model.set('styles.block.backgroundColor', '#123456');
model.set('styles.text.fontColor', '#123456');
model.set('styles.text.fontFamily', 'SomeFontCT');
model.set('styles.text.fontSize', '23px');
model.set('styles.text.textAlign', 'justify');
model.set('styles.link.fontColor', '#123456');
model.set('styles.link.textDecoration', 'underline');
mock.verify();
});
it("uses defaults from config when they are set", function () {
global.stubConfig(EditorApplication, {
blockDefaults: {
footer: {
text: 'some custom config text',
styles: {
block: {
backgroundColor: '#123456',
},
text: {
fontColor: '#234567',
fontFamily: 'Tahoma',
fontSize: '37px',
textAlign: 'right',
},
link: {
fontColor: '#345678',
textDecoration: 'underline',
},
},
}
},
});
var model = new (EditorApplication.module('blocks.footer').FooterBlockModel)();
expect(model.get('text')).to.equal('some custom config text');
expect(model.get('styles.block.backgroundColor')).to.equal('#123456');
expect(model.get('styles.text.fontColor')).to.equal('#234567');
expect(model.get('styles.text.fontFamily')).to.equal('Tahoma');
expect(model.get('styles.text.fontSize')).to.equal('37px');
expect(model.get('styles.text.textAlign')).to.equal('right');
expect(model.get('styles.link.fontColor')).to.equal('#345678');
expect(model.get('styles.link.textDecoration')).to.equal('underline');
});
});
describe('block view', function () {
global.stubChannel(EditorApplication);
global.stubConfig(EditorApplication);
global.stubAvailableStyles(EditorApplication);
var model = new (EditorApplication.module('blocks.footer').FooterBlockModel)(),
view;
beforeEach(function () {
global.stubChannel(EditorApplication);
view = new (EditorApplication.module('blocks.footer').FooterBlockView)({model: model});
});
it('renders', function () {
expect(view.render).to.not.throw();
expect(view.$('.mailpoet_content')).to.have.length(1);
});
});
describe('settings view', function () {
global.stubChannel(EditorApplication);
global.stubAvailableStyles(EditorApplication, {
fonts: ['Arial', 'Tahoma'],
textSizes: ['16px', '20px'],
});
var model = new (EditorApplication.module('blocks.footer').FooterBlockModel)(),
view = new (EditorApplication.module('blocks.footer').FooterBlockSettingsView)({model: model});
it('renders', function () {
expect(view.render).to.not.throw();
expect(view.$('.mailpoet_field_footer_text_color')).to.have.length(1);
});
describe('once rendered', function () {
var model, view;
beforeEach(function() {
global.stubChannel(EditorApplication);
global.stubAvailableStyles(EditorApplication, {
fonts: ['Arial', 'Tahoma'],
textSizes: ['16px', '20px'],
});
model = new (EditorApplication.module('blocks.footer').FooterBlockModel)({});
view = new (EditorApplication.module('blocks.footer').FooterBlockSettingsView)({model: model});
view.render();
});
it('updates the model when text font color changes', function () {
view.$('.mailpoet_field_footer_text_color').val('#123456').change();
expect(model.get('styles.text.fontColor')).to.equal('#123456');
});
it('updates the model when text font family changes', function () {
var value = 'Tahoma';
view.$('.mailpoet_field_footer_text_font_family').val(value).change();
expect(model.get('styles.text.fontFamily')).to.equal(value);
});
it('updates the model when text font size changes', function () {
var value = '20px';
view.$('.mailpoet_field_footer_text_size').val(value).change();
expect(model.get('styles.text.fontSize')).to.equal(value);
});
it('updates the model when link font color changes', function () {
view.$('#mailpoet_field_footer_link_color').val('#123456').change();
expect(model.get('styles.link.fontColor')).to.equal('#123456');
});
it('updates the model when link text decoration changes', function () {
view.$('#mailpoet_field_footer_link_underline').prop('checked', true).change();
expect(model.get('styles.link.textDecoration')).to.equal('underline');
});
it('updates the model when background color changes', function () {
view.$('.mailpoet_field_footer_alignment').last().prop('checked', true).change();
expect(model.get('styles.text.textAlign')).to.equal('right');
});
it.skip('closes the sidepanel after "Done" is clicked', function () {
var mock = sinon.mock().once();
global.MailPoet.Modal.cancel = mock;
view.$('.mailpoet_done_editing').click();
mock.verify();
delete(global.MailPoet.Modal.cancel);
});
});
});
}); });
}); });

View File

@ -4,200 +4,199 @@ define('test/newsletter_editor/blocks/header', [
], function(EditorApplication) { ], function(EditorApplication) {
describe('Header', function () { describe('Header', function () {
describe('model', function () { describe('model', function () {
var model; var model;
beforeEach(function () { beforeEach(function () {
global.stubChannel(EditorApplication); global.stubChannel(EditorApplication);
global. stubConfig(EditorApplication, { global. stubConfig(EditorApplication, {
blockDefaults: {}, blockDefaults: {},
}); });
model = new (EditorApplication.module('blocks.header').HeaderBlockModel)(); model = new (EditorApplication.module('blocks.header').HeaderBlockModel)();
});
it('has a header type', function () {
expect(model.get('type')).to.equal('header');
});
it('has text', function () {
expect(model.get('text')).to.be.a('string');
});
it('has background color', function () {
expect(model.get('styles.block.backgroundColor')).to.match(/^(#[abcdef0-9]{6})|transparent$/);
});
it('has a text color', function () {
expect(model.get('styles.text.fontColor')).to.match(/^(#[abcdef0-9]{6})|transparent$/);
});
it('has a text font family', function () {
expect(model.get('styles.text.fontFamily')).to.equal('Arial');
});
it('has a text font size', function () {
expect(model.get('styles.text.fontSize')).to.match(/^\d+px$/);
});
it('has text align', function () {
expect(model.get('styles.text.textAlign')).to.match(/^(left|center|right|justify)$/);
});
it('has link color', function () {
expect(model.get('styles.link.fontColor')).to.match(/^(#[abcdef0-9]{6})|transparent$/);
});
it('has link text decoration', function () {
expect(model.get('styles.link.textDecoration')).to.match(/^(underline|none)$/);
});
it("changes attributes with set", function () {
var newValue = 'Some random teeeext';
model.set('text', newValue);
expect(model.get('text')).to.equal(newValue);
});
it("triggers autosave if any attribute changes", function () {
var mock = sinon.mock().exactly(8).withArgs('autoSave');
EditorApplication.getChannel = sinon.stub().returns({
trigger: mock,
});
model.set('text', 'Some new text');
model.set('styles.block.backgroundColor', '#123456');
model.set('styles.text.fontColor', '#123456');
model.set('styles.text.fontFamily', 'SomeFontCT');
model.set('styles.text.fontSize', '23px');
model.set('styles.text.textAlign', 'justify');
model.set('styles.link.fontColor', '#123456');
model.set('styles.link.textDecoration', 'none');
mock.verify();
});
it("uses defaults from config when they are set", function () {
global.stubConfig(EditorApplication, {
blockDefaults: {
header: {
text: 'some custom config text',
styles: {
block: {
backgroundColor: '#123456',
},
text: {
fontColor: '#234567',
fontFamily: 'Tahoma',
fontSize: '37px',
textAlign: 'right',
},
link: {
fontColor: '#345678',
textDecoration: 'underline',
},
},
},
},
});
var model = new (EditorApplication.module('blocks.header').HeaderBlockModel)();
expect(model.get('text')).to.equal('some custom config text');
expect(model.get('styles.block.backgroundColor')).to.equal('#123456');
expect(model.get('styles.text.fontColor')).to.equal('#234567');
expect(model.get('styles.text.fontFamily')).to.equal('Tahoma');
expect(model.get('styles.text.fontSize')).to.equal('37px');
expect(model.get('styles.text.textAlign')).to.equal('right');
expect(model.get('styles.link.fontColor')).to.equal('#345678');
expect(model.get('styles.link.textDecoration')).to.equal('underline');
});
}); });
describe('block view', function () { it('has a header type', function () {
global.stubChannel(EditorApplication); expect(model.get('type')).to.equal('header');
global.stubConfig(EditorApplication);
global.stubAvailableStyles(EditorApplication);
var model = new (EditorApplication.module('blocks.header').HeaderBlockModel)(),
view;
beforeEach(function () {
global.stubChannel(EditorApplication);
view = new (EditorApplication.module('blocks.header').HeaderBlockView)({model: model});
});
it('renders', function () {
expect(view.render).to.not.throw();
expect(view.$('.mailpoet_content')).to.have.length(1);
});
}); });
describe('settings view', function () { it('has text', function () {
global.stubChannel(EditorApplication); expect(model.get('text')).to.be.a('string');
global.stubConfig(EditorApplication);
global.stubAvailableStyles(EditorApplication, {
fonts: ['Arial', 'Tahoma'],
textSizes: ['16px', '20px'],
});
var model = new (EditorApplication.module('blocks.header').HeaderBlockModel)(),
view = new (EditorApplication.module('blocks.header').HeaderBlockSettingsView)({model: model});
it('renders', function () {
expect(view.render).to.not.throw();
expect(view.$('.mailpoet_field_header_text_color')).to.have.length(1);
});
describe('once rendered', function () {
var model, view;
beforeEach(function() {
global.stubChannel(EditorApplication);
global.stubAvailableStyles(EditorApplication, {
fonts: ['Arial', 'Tahoma'],
textSizes: ['16px', '20px'],
});
model = new (EditorApplication.module('blocks.header').HeaderBlockModel)({});
view = new (EditorApplication.module('blocks.header').HeaderBlockSettingsView)({model: model});
view.render();
});
it('updates the model when text font color changes', function () {
view.$('.mailpoet_field_header_text_color').val('#123456').change();
expect(model.get('styles.text.fontColor')).to.equal('#123456');
});
it('updates the model when text font family changes', function () {
var value = 'Tahoma';
view.$('.mailpoet_field_header_text_font_family').val(value).change();
expect(model.get('styles.text.fontFamily')).to.equal(value);
});
it('updates the model when text font size changes', function () {
var value = '20px';
view.$('.mailpoet_field_header_text_size').val(value).change();
expect(model.get('styles.text.fontSize')).to.equal(value);
});
it('updates the model when link font color changes', function () {
view.$('#mailpoet_field_header_link_color').val('#123456').change();
expect(model.get('styles.link.fontColor')).to.equal('#123456');
});
it('updates the model when link text decoration changes', function () {
view.$('#mailpoet_field_header_link_underline').prop('checked', true).change();
expect(model.get('styles.link.textDecoration')).to.equal('underline');
});
it('updates the model when text alignment changes', function () {
view.$('.mailpoet_field_header_alignment').last().prop('checked', true).change();
expect(model.get('styles.text.textAlign')).to.equal('right');
});
it.skip('closes the sidepanel after "Done" is clicked', function () {
var mock = sinon.mock().once();
global.MailPoet.Modal.cancel = mock;
view.$('.mailpoet_done_editing').click();
mock.verify();
delete(global.MailPoet.Modal.cancel);
});
});
}); });
it('has background color', function () {
expect(model.get('styles.block.backgroundColor')).to.match(/^(#[abcdef0-9]{6})|transparent$/);
});
it('has a text color', function () {
expect(model.get('styles.text.fontColor')).to.match(/^(#[abcdef0-9]{6})|transparent$/);
});
it('has a text font family', function () {
expect(model.get('styles.text.fontFamily')).to.equal('Arial');
});
it('has a text font size', function () {
expect(model.get('styles.text.fontSize')).to.match(/^\d+px$/);
});
it('has text align', function () {
expect(model.get('styles.text.textAlign')).to.match(/^(left|center|right|justify)$/);
});
it('has link color', function () {
expect(model.get('styles.link.fontColor')).to.match(/^(#[abcdef0-9]{6})|transparent$/);
});
it('has link text decoration', function () {
expect(model.get('styles.link.textDecoration')).to.match(/^(underline|none)$/);
});
it("changes attributes with set", function () {
var newValue = 'Some random teeeext';
model.set('text', newValue);
expect(model.get('text')).to.equal(newValue);
});
it("triggers autosave if any attribute changes", function () {
var mock = sinon.mock().exactly(8).withArgs('autoSave');
EditorApplication.getChannel = sinon.stub().returns({
trigger: mock,
});
model.set('text', 'Some new text');
model.set('styles.block.backgroundColor', '#123456');
model.set('styles.text.fontColor', '#123456');
model.set('styles.text.fontFamily', 'SomeFontCT');
model.set('styles.text.fontSize', '23px');
model.set('styles.text.textAlign', 'justify');
model.set('styles.link.fontColor', '#123456');
model.set('styles.link.textDecoration', 'none');
mock.verify();
});
it("uses defaults from config when they are set", function () {
global.stubConfig(EditorApplication, {
blockDefaults: {
header: {
text: 'some custom config text',
styles: {
block: {
backgroundColor: '#123456',
},
text: {
fontColor: '#234567',
fontFamily: 'Tahoma',
fontSize: '37px',
textAlign: 'right',
},
link: {
fontColor: '#345678',
textDecoration: 'underline',
},
},
},
},
});
var model = new (EditorApplication.module('blocks.header').HeaderBlockModel)();
expect(model.get('text')).to.equal('some custom config text');
expect(model.get('styles.block.backgroundColor')).to.equal('#123456');
expect(model.get('styles.text.fontColor')).to.equal('#234567');
expect(model.get('styles.text.fontFamily')).to.equal('Tahoma');
expect(model.get('styles.text.fontSize')).to.equal('37px');
expect(model.get('styles.text.textAlign')).to.equal('right');
expect(model.get('styles.link.fontColor')).to.equal('#345678');
expect(model.get('styles.link.textDecoration')).to.equal('underline');
});
});
describe('block view', function () {
global.stubChannel(EditorApplication);
global.stubConfig(EditorApplication);
global.stubAvailableStyles(EditorApplication);
var model = new (EditorApplication.module('blocks.header').HeaderBlockModel)(),
view;
beforeEach(function () {
global.stubChannel(EditorApplication);
view = new (EditorApplication.module('blocks.header').HeaderBlockView)({model: model});
});
it('renders', function () {
expect(view.render).to.not.throw();
expect(view.$('.mailpoet_content')).to.have.length(1);
});
});
describe('settings view', function () {
global.stubChannel(EditorApplication);
global.stubConfig(EditorApplication);
global.stubAvailableStyles(EditorApplication, {
fonts: ['Arial', 'Tahoma'],
textSizes: ['16px', '20px'],
});
var model = new (EditorApplication.module('blocks.header').HeaderBlockModel)(),
view = new (EditorApplication.module('blocks.header').HeaderBlockSettingsView)({model: model});
it('renders', function () {
expect(view.render).to.not.throw();
expect(view.$('.mailpoet_field_header_text_color')).to.have.length(1);
});
describe('once rendered', function () {
var model, view;
beforeEach(function() {
global.stubChannel(EditorApplication);
global.stubAvailableStyles(EditorApplication, {
fonts: ['Arial', 'Tahoma'],
textSizes: ['16px', '20px'],
});
model = new (EditorApplication.module('blocks.header').HeaderBlockModel)({});
view = new (EditorApplication.module('blocks.header').HeaderBlockSettingsView)({model: model});
view.render();
});
it('updates the model when text font color changes', function () {
view.$('.mailpoet_field_header_text_color').val('#123456').change();
expect(model.get('styles.text.fontColor')).to.equal('#123456');
});
it('updates the model when text font family changes', function () {
var value = 'Tahoma';
view.$('.mailpoet_field_header_text_font_family').val(value).change();
expect(model.get('styles.text.fontFamily')).to.equal(value);
});
it('updates the model when text font size changes', function () {
var value = '20px';
view.$('.mailpoet_field_header_text_size').val(value).change();
expect(model.get('styles.text.fontSize')).to.equal(value);
});
it('updates the model when link font color changes', function () {
view.$('#mailpoet_field_header_link_color').val('#123456').change();
expect(model.get('styles.link.fontColor')).to.equal('#123456');
});
it('updates the model when link text decoration changes', function () {
view.$('#mailpoet_field_header_link_underline').prop('checked', true).change();
expect(model.get('styles.link.textDecoration')).to.equal('underline');
});
it('updates the model when text alignment changes', function () {
view.$('.mailpoet_field_header_alignment').last().prop('checked', true).change();
expect(model.get('styles.text.textAlign')).to.equal('right');
});
it.skip('closes the sidepanel after "Done" is clicked', function () {
var mock = sinon.mock().once();
global.MailPoet.Modal.cancel = mock;
view.$('.mailpoet_done_editing').click();
mock.verify();
delete(global.MailPoet.Modal.cancel);
});
});
});
}); });
}); });

View File

@ -4,197 +4,196 @@ define('test/newsletter_editor/blocks/image', [
], function(EditorApplication) { ], function(EditorApplication) {
describe('Image', function () { describe('Image', function () {
describe('model', function () { describe('model', function () {
var model; var model;
beforeEach(function () { beforeEach(function () {
global.stubChannel(EditorApplication); global.stubChannel(EditorApplication);
global.stubConfig(EditorApplication, { global.stubConfig(EditorApplication, {
blockDefaults: {}, blockDefaults: {},
}); });
model = new (EditorApplication.module('blocks.image').ImageBlockModel)(); model = new (EditorApplication.module('blocks.image').ImageBlockModel)();
});
it('has an image type', function () {
expect(model.get('type')).to.equal('image');
});
it('has a link', function () {
expect(model.get('link')).to.be.a('string');
});
it('has an image src', function () {
expect(model.get('src')).to.be.a('string');
});
it('has alt text', function () {
expect(model.get('alt')).to.be.a('string');
});
it('can be padded', function () {
expect(model.get('padded')).to.be.a('boolean');
});
it('has a width', function () {
expect(model.get('width')).to.match(/^\d+px$/);
});
it('has a height', function () {
expect(model.get('height')).to.match(/^\d+px$/);
});
it('has alignment', function () {
expect(model.get('styles.block.textAlign')).to.match(/^(left|center|right)$/);
});
it('changes attributes with set', function () {
var newValue = 'someImage.png';
model.set('src', newValue);
expect(model.get('src')).to.equal(newValue);
});
it('triggers autosave when any of the attributes change', function () {
var mock = sinon.mock().exactly(7).withArgs('autoSave');
EditorApplication.getChannel = sinon.stub().returns({
trigger: mock,
});
model.set('link', 'http://example.net');
model.set('src', 'someNewImage.png');
model.set('alt', 'Some alt text');
model.set('padded', false);
model.set('width', '63px');
model.set('height', '61px');
model.set('styles.block.textAlign', 'right');
mock.verify();
});
it("uses defaults from config when they are set", function () {
global.stubConfig(EditorApplication, {
blockDefaults: {
image: {
link: 'http://example.org/customConfigPage',
src: 'http://example.org/someCustomConfigImage.png',
alt: 'Custom config alt',
padded: false,
width: '1234px',
height: '2345px',
styles: {
block: {
textAlign: 'right',
},
},
}
},
});
var model = new (EditorApplication.module('blocks.image').ImageBlockModel)();
expect(model.get('link')).to.equal('http://example.org/customConfigPage');
expect(model.get('src')).to.equal('http://example.org/someCustomConfigImage.png');
expect(model.get('alt')).to.equal('Custom config alt');
expect(model.get('padded')).to.equal(false);
expect(model.get('width')).to.equal('1234px');
expect(model.get('height')).to.equal('2345px');
expect(model.get('styles.block.textAlign')).to.equal('right');
});
}); });
describe('block view', function () { it('has an image type', function () {
expect(model.get('type')).to.equal('image');
});
it('has a link', function () {
expect(model.get('link')).to.be.a('string');
});
it('has an image src', function () {
expect(model.get('src')).to.be.a('string');
});
it('has alt text', function () {
expect(model.get('alt')).to.be.a('string');
});
it('can be padded', function () {
expect(model.get('padded')).to.be.a('boolean');
});
it('has a width', function () {
expect(model.get('width')).to.match(/^\d+px$/);
});
it('has a height', function () {
expect(model.get('height')).to.match(/^\d+px$/);
});
it('has alignment', function () {
expect(model.get('styles.block.textAlign')).to.match(/^(left|center|right)$/);
});
it('changes attributes with set', function () {
var newValue = 'someImage.png';
model.set('src', newValue);
expect(model.get('src')).to.equal(newValue);
});
it('triggers autosave when any of the attributes change', function () {
var mock = sinon.mock().exactly(7).withArgs('autoSave');
EditorApplication.getChannel = sinon.stub().returns({
trigger: mock,
});
model.set('link', 'http://example.net');
model.set('src', 'someNewImage.png');
model.set('alt', 'Some alt text');
model.set('padded', false);
model.set('width', '63px');
model.set('height', '61px');
model.set('styles.block.textAlign', 'right');
mock.verify();
});
it("uses defaults from config when they are set", function () {
global.stubConfig(EditorApplication, {
blockDefaults: {
image: {
link: 'http://example.org/customConfigPage',
src: 'http://example.org/someCustomConfigImage.png',
alt: 'Custom config alt',
padded: false,
width: '1234px',
height: '2345px',
styles: {
block: {
textAlign: 'right',
},
},
}
},
});
var model = new (EditorApplication.module('blocks.image').ImageBlockModel)();
expect(model.get('link')).to.equal('http://example.org/customConfigPage');
expect(model.get('src')).to.equal('http://example.org/someCustomConfigImage.png');
expect(model.get('alt')).to.equal('Custom config alt');
expect(model.get('padded')).to.equal(false);
expect(model.get('width')).to.equal('1234px');
expect(model.get('height')).to.equal('2345px');
expect(model.get('styles.block.textAlign')).to.equal('right');
});
});
describe('block view', function () {
global.stubChannel(EditorApplication);
global.stubConfig(EditorApplication);
global.stubAvailableStyles(EditorApplication);
var model = new (EditorApplication.module('blocks.image').ImageBlockModel)(),
view;
beforeEach(function () {
view = new (EditorApplication.module('blocks.image').ImageBlockView)({model: model});
});
it('renders', function () {
expect(view.render).to.not.throw();
expect(view.$('.mailpoet_content')).to.have.length(1);
});
describe('once rendered', function () {
var model = new (EditorApplication.module('blocks.image').ImageBlockModel)({
link: 'http://example.org/somepath',
src: 'http://example.org/someimage.png',
alt: 'some alt',
}),
view;
beforeEach(function () {
global.stubChannel(EditorApplication); global.stubChannel(EditorApplication);
global.stubConfig(EditorApplication);
global.stubAvailableStyles(EditorApplication); global.stubAvailableStyles(EditorApplication);
var model = new (EditorApplication.module('blocks.image').ImageBlockModel)(), view = new (EditorApplication.module('blocks.image').ImageBlockView)({model: model});
view; view.render();
});
beforeEach(function () { it('displays the image', function () {
view = new (EditorApplication.module('blocks.image').ImageBlockView)({model: model}); expect(view.$('.mailpoet_content a').attr('href')).to.equal('http://example.org/somepath');
}); expect(view.$('.mailpoet_content img').attr('src')).to.equal('http://example.org/someimage.png');
expect(view.$('.mailpoet_content img').attr('alt')).to.equal('some alt');
});
it('renders', function () { it('rerenders if attribute changes', function () {
expect(view.render).to.not.throw(); var newValue = 'http://example.org/someNEWimage.png';
expect(view.$('.mailpoet_content')).to.have.length(1); expect(view.$('.mailpoet_content img').attr('src')).to.not.equal(newValue);
}); model.set('src', newValue);
expect(view.$('.mailpoet_content img').attr('src')).to.equal(newValue);
});
});
});
describe('once rendered', function () { describe('block settings view', function () {
var model = new (EditorApplication.module('blocks.image').ImageBlockModel)({ var model, view;
link: 'http://example.org/somepath',
src: 'http://example.org/someimage.png',
alt: 'some alt',
}),
view;
beforeEach(function () { before(function () {
global.stubChannel(EditorApplication); global.stubChannel(EditorApplication);
global.stubAvailableStyles(EditorApplication); global.stubConfig(EditorApplication, {
view = new (EditorApplication.module('blocks.image').ImageBlockView)({model: model}); blockDefaults: {},
view.render(); });
}); model = new (EditorApplication.module('blocks.image').ImageBlockModel)();
view = new (EditorApplication.module('blocks.image').ImageBlockSettingsView)({model: model});
it('displays the image', function () {
expect(view.$('.mailpoet_content a').attr('href')).to.equal('http://example.org/somepath');
expect(view.$('.mailpoet_content img').attr('src')).to.equal('http://example.org/someimage.png');
expect(view.$('.mailpoet_content img').attr('alt')).to.equal('some alt');
});
it('rerenders if attribute changes', function () {
var newValue = 'http://example.org/someNEWimage.png';
expect(view.$('.mailpoet_content img').attr('src')).to.not.equal(newValue);
model.set('src', newValue);
expect(view.$('.mailpoet_content img').attr('src')).to.equal(newValue);
});
});
}); });
describe('block settings view', function () { it('renders', function () {
var model, view; expect(view.render).to.not.throw();
before(function () {
global.stubChannel(EditorApplication);
global.stubConfig(EditorApplication, {
blockDefaults: {},
});
model = new (EditorApplication.module('blocks.image').ImageBlockModel)();
view = new (EditorApplication.module('blocks.image').ImageBlockSettingsView)({model: model});
});
it('renders', function () {
expect(view.render).to.not.throw();
});
describe('once rendered', function () {
it('updates the model when link changes', function () {
var newValue = 'http://example.org/someNewLink';
view.$('.mailpoet_field_image_link').val(newValue).keyup();
expect(model.get('link')).to.equal(newValue);
});
it('updates the model when src changes', function () {
var newValue = 'http://example.org/someNewImage.png';
view.$('.mailpoet_field_image_address').val(newValue).keyup();
expect(model.get('src')).to.equal(newValue);
});
it('updates the model when alt changes', function () {
var newValue = 'Some new alt text';
view.$('.mailpoet_field_image_alt_text').val(newValue).keyup();
expect(model.get('alt')).to.equal(newValue);
});
it('updates the model when padding changes', function () {
var newValue = 'false';
view.$('.mailpoet_field_image_padded').val(newValue).change();
expect(model.get('padded')).to.equal(false);
});
it.skip('closes the sidepanel after "Done" is clicked', function() {
var mock = sinon.mock().once();
global.MailPoet.Modal.cancel = mock;
view.$('.mailpoet_done_editing').click();
mock.verify();
delete(global.MailPoet.Modal.cancel);
});
});
}); });
describe('once rendered', function () {
it('updates the model when link changes', function () {
var newValue = 'http://example.org/someNewLink';
view.$('.mailpoet_field_image_link').val(newValue).keyup();
expect(model.get('link')).to.equal(newValue);
});
it('updates the model when src changes', function () {
var newValue = 'http://example.org/someNewImage.png';
view.$('.mailpoet_field_image_address').val(newValue).keyup();
expect(model.get('src')).to.equal(newValue);
});
it('updates the model when alt changes', function () {
var newValue = 'Some new alt text';
view.$('.mailpoet_field_image_alt_text').val(newValue).keyup();
expect(model.get('alt')).to.equal(newValue);
});
it('updates the model when padding changes', function () {
var newValue = 'false';
view.$('.mailpoet_field_image_padded').val(newValue).change();
expect(model.get('padded')).to.equal(false);
});
it.skip('closes the sidepanel after "Done" is clicked', function() {
var mock = sinon.mock().once();
global.MailPoet.Modal.cancel = mock;
view.$('.mailpoet_done_editing').click();
mock.verify();
delete(global.MailPoet.Modal.cancel);
});
});
});
}); });
}); });

View File

@ -4,385 +4,384 @@ define('test/newsletter_editor/blocks/posts', [
], function(EditorApplication) { ], function(EditorApplication) {
describe('Posts', function () { describe('Posts', function () {
Backbone.Radio = { Backbone.Radio = {
Requests: { Requests: {
request: function () { request: function () {
}, reply: function () { }, reply: function () {
}, },
}, },
}; };
describe('model', function () { describe('model', function () {
var model; var model;
beforeEach(function () { beforeEach(function () {
global.stubChannel(EditorApplication); global.stubChannel(EditorApplication);
global.stubConfig(EditorApplication); global.stubConfig(EditorApplication);
global.mailpoet_post_wpi = sinon.stub(); global.mailpoet_post_wpi = sinon.stub();
EditorApplication.getBlockTypeModel = sinon.stub().returns(Backbone.SuperModel); EditorApplication.getBlockTypeModel = sinon.stub().returns(Backbone.SuperModel);
model = new (EditorApplication.module('blocks.posts').PostsBlockModel)(); model = new (EditorApplication.module('blocks.posts').PostsBlockModel)();
}); });
afterEach(function () { afterEach(function () {
delete EditorApplication.getChannel; delete EditorApplication.getChannel;
}); });
it('has posts type', function () { it('has posts type', function () {
expect(model.get('type')).to.equal('posts'); expect(model.get('type')).to.equal('posts');
}); });
it('has post amount limit', function () { it('has post amount limit', function () {
expect(model.get('amount')).to.match(/^\d+$/); expect(model.get('amount')).to.match(/^\d+$/);
}); });
it('has post type filter', function () { it('has post type filter', function () {
expect(model.get('contentType')).to.match(/^(post|page|mailpoet_page)$/); expect(model.get('contentType')).to.match(/^(post|page|mailpoet_page)$/);
}); });
it('has terms filter', function () { it('has terms filter', function () {
expect(model.get('terms')).to.have.length(0); expect(model.get('terms')).to.have.length(0);
}); });
it('has inclusion filter', function () { it('has inclusion filter', function () {
expect(model.get('inclusionType')).to.match(/^(include|exclude)$/); expect(model.get('inclusionType')).to.match(/^(include|exclude)$/);
}); });
it('has display type', function () { it('has display type', function () {
expect(model.get('displayType')).to.match(/^(excerpt|full|titleOnly)$/); expect(model.get('displayType')).to.match(/^(excerpt|full|titleOnly)$/);
}); });
it('has title heading format', function () { it('has title heading format', function () {
expect(model.get('titleFormat')).to.match(/^(h1|h2|h3|ul)$/); expect(model.get('titleFormat')).to.match(/^(h1|h2|h3|ul)$/);
}); });
it('has title position', function () { it('has title position', function () {
expect(model.get('titlePosition')).to.match(/^(inTextBlock|aboveBlock)$/); expect(model.get('titlePosition')).to.match(/^(inTextBlock|aboveBlock)$/);
}); });
it('has title alignment', function () { it('has title alignment', function () {
expect(model.get('titleAlignment')).to.match(/^(left|center|right)$/); expect(model.get('titleAlignment')).to.match(/^(left|center|right)$/);
}); });
it('optionally has title as link', function () { it('optionally has title as link', function () {
expect(model.get('titleIsLink')).to.be.a('boolean'); expect(model.get('titleIsLink')).to.be.a('boolean');
}); });
it('has image specific alignment', function () { it('has image specific alignment', function () {
expect(model.get('imagePadded')).to.be.a('boolean'); expect(model.get('imagePadded')).to.be.a('boolean');
}); });
it('has an option to display author', function () { it('has an option to display author', function () {
expect(model.get('showAuthor')).to.match(/^(no|aboveText|belowText)$/); expect(model.get('showAuthor')).to.match(/^(no|aboveText|belowText)$/);
}); });
it('has text preceding author', function () { it('has text preceding author', function () {
expect(model.get('authorPrecededBy')).to.be.a('string'); expect(model.get('authorPrecededBy')).to.be.a('string');
}); });
it('has an option to display categories', function () { it('has an option to display categories', function () {
expect(model.get('showCategories')).to.match(/^(no|aboveText|belowText)$/); expect(model.get('showCategories')).to.match(/^(no|aboveText|belowText)$/);
}); });
it('has text preceding categories', function () { it('has text preceding categories', function () {
expect(model.get('categoriesPrecededBy')).to.be.a('string'); expect(model.get('categoriesPrecededBy')).to.be.a('string');
}); });
it('has a link or a button type for read more', function () { it('has a link or a button type for read more', function () {
expect(model.get('readMoreType')).to.match(/^(link|button)$/); expect(model.get('readMoreType')).to.match(/^(link|button)$/);
}); });
it('has read more text', function () { it('has read more text', function () {
expect(model.get('readMoreText')).to.be.a('string'); expect(model.get('readMoreText')).to.be.a('string');
}); });
it('has a read more button', function () { it('has a read more button', function () {
expect(model.get('readMoreButton')).to.be.instanceof(Backbone.Model); expect(model.get('readMoreButton')).to.be.instanceof(Backbone.Model);
}); });
it('has sorting', function () { it('has sorting', function () {
expect(model.get('sortBy')).to.match(/^(newest|oldest)$/); expect(model.get('sortBy')).to.match(/^(newest|oldest)$/);
}); });
it('has an option to display divider', function () { it('has an option to display divider', function () {
expect(model.get('showDivider')).to.be.a('boolean'); expect(model.get('showDivider')).to.be.a('boolean');
}); });
it('has a divider', function () { it('has a divider', function () {
expect(model.get('divider')).to.be.instanceof(Backbone.Model); expect(model.get('divider')).to.be.instanceof(Backbone.Model);
}); });
it("uses defaults from config when they are set", function () { it("uses defaults from config when they are set", function () {
global.stubConfig(EditorApplication, { global.stubConfig(EditorApplication, {
blockDefaults: { blockDefaults: {
posts: { posts: {
amount: '17', amount: '17',
contentType: 'mailpoet_page', // 'post'|'page'|'mailpoet_page' contentType: 'mailpoet_page', // 'post'|'page'|'mailpoet_page'
inclusionType: 'exclude', // 'include'|'exclude' inclusionType: 'exclude', // 'include'|'exclude'
displayType: 'full', // 'excerpt'|'full'|'titleOnly' displayType: 'full', // 'excerpt'|'full'|'titleOnly'
titleFormat: 'h3', // 'h1'|'h2'|'h3'|'ul' titleFormat: 'h3', // 'h1'|'h2'|'h3'|'ul'
titlePosition: 'aboveBlock', // 'inTextBlock'|'aboveBlock', titlePosition: 'aboveBlock', // 'inTextBlock'|'aboveBlock',
titleAlignment: 'right', // 'left'|'center'|'right' titleAlignment: 'right', // 'left'|'center'|'right'
titleIsLink: true, // false|true titleIsLink: true, // false|true
imagePadded: false, // true|false imagePadded: false, // true|false
//imageAlignment: 'right', // 'centerFull'|'centerPadded'|'left'|'right'|'alternate'|'none' //imageAlignment: 'right', // 'centerFull'|'centerPadded'|'left'|'right'|'alternate'|'none'
showAuthor: 'belowText', // 'no'|'aboveText'|'belowText' showAuthor: 'belowText', // 'no'|'aboveText'|'belowText'
authorPrecededBy: 'Custom config author preceded by', authorPrecededBy: 'Custom config author preceded by',
showCategories: 'belowText', // 'no'|'aboveText'|'belowText' showCategories: 'belowText', // 'no'|'aboveText'|'belowText'
categoriesPrecededBy: 'Custom config categories preceded by', categoriesPrecededBy: 'Custom config categories preceded by',
readMoreType: 'button', // 'link'|'button' readMoreType: 'button', // 'link'|'button'
readMoreText: 'Custom Config read more text', readMoreText: 'Custom Config read more text',
readMoreButton: { readMoreButton: {
text: 'Custom config read more', text: 'Custom config read more',
url: '[postLink]', url: '[postLink]',
styles: { styles: {
block: { block: {
backgroundColor: '#123456', backgroundColor: '#123456',
borderColor: '#234567', borderColor: '#234567',
},
link: {
fontColor: '#345678',
fontFamily: 'Tahoma',
fontSize: '37px',
},
},
},
sortBy: 'oldest', // 'newest'|'oldest',
showDivider: true, // true|false
divider: {
src: 'http://example.org/someConfigDividerImage.png',
styles: {
block: {
backgroundColor: '#456789',
padding: '38px',
},
},
},
},
}, },
}); link: {
var model = new (EditorApplication.module('blocks.posts').PostsBlockModel)(); fontColor: '#345678',
fontFamily: 'Tahoma',
fontSize: '37px',
},
},
},
sortBy: 'oldest', // 'newest'|'oldest',
showDivider: true, // true|false
divider: {
src: 'http://example.org/someConfigDividerImage.png',
styles: {
block: {
backgroundColor: '#456789',
padding: '38px',
},
},
},
},
},
});
var model = new (EditorApplication.module('blocks.posts').PostsBlockModel)();
expect(model.get('amount')).to.equal('17'); expect(model.get('amount')).to.equal('17');
expect(model.get('contentType')).to.equal('mailpoet_page'); expect(model.get('contentType')).to.equal('mailpoet_page');
expect(model.get('inclusionType')).to.equal('exclude'); expect(model.get('inclusionType')).to.equal('exclude');
expect(model.get('displayType')).to.equal('full'); expect(model.get('displayType')).to.equal('full');
expect(model.get('titleFormat')).to.equal('h3'); expect(model.get('titleFormat')).to.equal('h3');
expect(model.get('titlePosition')).to.equal('aboveBlock'); expect(model.get('titlePosition')).to.equal('aboveBlock');
expect(model.get('titleAlignment')).to.equal('right'); expect(model.get('titleAlignment')).to.equal('right');
expect(model.get('titleIsLink')).to.equal(true); expect(model.get('titleIsLink')).to.equal(true);
expect(model.get('imagePadded')).to.equal(false); expect(model.get('imagePadded')).to.equal(false);
expect(model.get('showAuthor')).to.equal('belowText'); expect(model.get('showAuthor')).to.equal('belowText');
expect(model.get('authorPrecededBy')).to.equal('Custom config author preceded by'); expect(model.get('authorPrecededBy')).to.equal('Custom config author preceded by');
expect(model.get('showCategories')).to.equal('belowText'); expect(model.get('showCategories')).to.equal('belowText');
expect(model.get('categoriesPrecededBy')).to.equal('Custom config categories preceded by'); expect(model.get('categoriesPrecededBy')).to.equal('Custom config categories preceded by');
expect(model.get('readMoreType')).to.equal('button'); expect(model.get('readMoreType')).to.equal('button');
expect(model.get('readMoreText')).to.equal('Custom Config read more text'); expect(model.get('readMoreText')).to.equal('Custom Config read more text');
expect(model.get('readMoreButton.text')).to.equal('Custom config read more'); expect(model.get('readMoreButton.text')).to.equal('Custom config read more');
expect(model.get('readMoreButton.url')).to.equal('[postLink]'); expect(model.get('readMoreButton.url')).to.equal('[postLink]');
expect(model.get('readMoreButton.styles.block.backgroundColor')).to.equal('#123456'); expect(model.get('readMoreButton.styles.block.backgroundColor')).to.equal('#123456');
expect(model.get('readMoreButton.styles.block.borderColor')).to.equal('#234567'); expect(model.get('readMoreButton.styles.block.borderColor')).to.equal('#234567');
expect(model.get('readMoreButton.styles.link.fontColor')).to.equal('#345678'); expect(model.get('readMoreButton.styles.link.fontColor')).to.equal('#345678');
expect(model.get('readMoreButton.styles.link.fontFamily')).to.equal('Tahoma'); expect(model.get('readMoreButton.styles.link.fontFamily')).to.equal('Tahoma');
expect(model.get('readMoreButton.styles.link.fontSize')).to.equal('37px'); expect(model.get('readMoreButton.styles.link.fontSize')).to.equal('37px');
expect(model.get('sortBy')).to.equal('oldest'); expect(model.get('sortBy')).to.equal('oldest');
expect(model.get('showDivider')).to.equal(true); expect(model.get('showDivider')).to.equal(true);
expect(model.get('divider.src')).to.equal('http://example.org/someConfigDividerImage.png'); expect(model.get('divider.src')).to.equal('http://example.org/someConfigDividerImage.png');
expect(model.get('divider.styles.block.backgroundColor')).to.equal('#456789'); expect(model.get('divider.styles.block.backgroundColor')).to.equal('#456789');
expect(model.get('divider.styles.block.padding')).to.equal('38px'); expect(model.get('divider.styles.block.padding')).to.equal('38px');
}); });
});
describe('block view', function () {
var model, view;
beforeEach(function () {
global.stubChannel(EditorApplication);
global.stubConfig(EditorApplication);
EditorApplication.getBlockTypeModel = sinon.stub().returns(Backbone.Model);
model = new (EditorApplication.module('blocks.posts').PostsBlockModel)();
view = new (EditorApplication.module('blocks.posts').PostsBlockView)({model: model});
// Disable auto-opening of settings view
view.off('showSettings');
}); });
describe('block view', function () { afterEach(function () {
var model, view; delete EditorApplication.getChannel;
beforeEach(function () {
global.stubChannel(EditorApplication);
global.stubConfig(EditorApplication);
EditorApplication.getBlockTypeModel = sinon.stub().returns(Backbone.Model);
model = new (EditorApplication.module('blocks.posts').PostsBlockModel)();
view = new (EditorApplication.module('blocks.posts').PostsBlockView)({model: model});
// Disable auto-opening of settings view
view.off('showSettings');
});
afterEach(function () {
delete EditorApplication.getChannel;
});
it('renders', function () {
expect(view.render).to.not.throw();
expect(view.$('.mailpoet_content')).to.have.length(1);
});
}); });
describe('block settings view', function () { it('renders', function () {
var model, view; expect(view.render).to.not.throw();
expect(view.$('.mailpoet_content')).to.have.length(1);
});
});
before(function () { describe('block settings view', function () {
global.stubChannel(EditorApplication); var model, view;
global.stubConfig(EditorApplication, {
blockDefaults: {}, before(function () {
}); global.stubChannel(EditorApplication);
EditorApplication.getBlockTypeModel = sinon.stub().returns(Backbone.Model); global.stubConfig(EditorApplication, {
model = new (EditorApplication.module('blocks.posts').PostsBlockModel)(); blockDefaults: {},
view = new (EditorApplication.module('blocks.posts').PostsBlockSettingsView)({model: model}); });
EditorApplication.getBlockTypeModel = sinon.stub().returns(Backbone.Model);
model = new (EditorApplication.module('blocks.posts').PostsBlockModel)();
view = new (EditorApplication.module('blocks.posts').PostsBlockSettingsView)({model: model});
});
it('renders', function () {
// Stub out block view requests
model.request = sinon.stub().returns({$el: {}});
expect(view.render).to.not.throw();
});
describe('once rendered', function () {
it('changes the model if post type changes', function () {
var newValue = 'mailpoet_page';
view.$('.mailpoet_settings_posts_content_type').val(newValue).change();
expect(model.get('contentType')).to.equal(newValue);
});
it('changes the model if post status changes', function () {
var newValue = 'pending';
view.$('.mailpoet_posts_post_status').val(newValue).change();
expect(model.get('postStatus')).to.equal(newValue);
});
it('changes the model if search term changes', function () {
var newValue = 'some New search term';
view.$('.mailpoet_posts_search_term').val(newValue).keyup();
expect(model.get('search')).to.equal(newValue);
});
it('changes the model if display type changes', function () {
var newValue = 'full';
view.$('.mailpoet_posts_display_type').val(newValue).change();
expect(model.get('displayType')).to.equal(newValue);
});
it('changes the model if title format changes', function () {
var newValue = 'h3';
view.$('.mailpoet_posts_title_format').val(newValue).change();
expect(model.get('titleFormat')).to.equal(newValue);
});
it('changes the model if title position changes', function () {
var newValue = 'aboveBlock';
view.$('.mailpoet_posts_title_position').val(newValue).change();
expect(model.get('titlePosition')).to.equal(newValue);
});
it('changes the model if title alignment changes', function () {
var newValue = 'right';
view.$('.mailpoet_posts_title_alignment').val(newValue).change();
expect(model.get('titleAlignment')).to.equal(newValue);
});
it('changes the model if title link changes', function () {
var newValue = true;
view.$('.mailpoet_posts_title_as_links').val(newValue).change();
expect(model.get('titleIsLink')).to.equal(newValue);
});
it('changes the model if image alignment changes', function () {
var newValue = false;
view.$('.mailpoet_posts_image_padded').val(newValue).change();
expect(model.get('imagePadded')).to.equal(newValue);
});
it('changes the model if show author changes', function () {
var newValue = 'belowText';
view.$('.mailpoet_posts_show_author').val(newValue).change();
expect(model.get('showAuthor')).to.equal(newValue);
});
it('changes the model if author preceded by changes', function () {
var newValue = 'New author preceded by test';
view.$('.mailpoet_posts_author_preceded_by').val(newValue).keyup();
expect(model.get('authorPrecededBy')).to.equal(newValue);
});
it('changes the model if show categories changes', function () {
var newValue = 'belowText';
view.$('.mailpoet_posts_show_categories').val(newValue).change();
expect(model.get('showCategories')).to.equal(newValue);
});
it('changes the model if categories preceded by changes', function () {
var newValue = 'New categories preceded by test';
view.$('.mailpoet_posts_categories').val(newValue).keyup();
expect(model.get('categoriesPrecededBy')).to.equal(newValue);
});
it('changes the model if read more button type changes', function () {
var newValue = 'link';
view.$('.mailpoet_posts_read_more_type').val(newValue).change();
expect(model.get('readMoreType')).to.equal(newValue);
});
it('changes the model if read more text changes', function () {
var newValue = 'New read more text';
view.$('.mailpoet_posts_read_more_text').val(newValue).keyup();
expect(model.get('readMoreText')).to.equal(newValue);
});
describe('when "title only" display type is selected', function() {
var model, view;
beforeEach(function() {
model = new (EditorApplication.module('blocks.posts').PostsBlockModel)();
model.request = sinon.stub().returns({$el: {}});
view = new (EditorApplication.module('blocks.posts').PostsBlockSettingsView)({model: model});
view.render();
view.$('.mailpoet_posts_display_type').val('titleOnly').change();
}); });
it('renders', function () { it('shows "title as list" option', function () {
// Stub out block view requests expect(view.$('.mailpoet_posts_title_as_list')).to.not.have.$class('mailpoet_hidden');
});
describe('when "title as list" is selected', function() {
var model, view;
beforeEach(function() {
model = new (EditorApplication.module('blocks.posts').PostsBlockModel)();
model.request = sinon.stub().returns({$el: {}}); model.request = sinon.stub().returns({$el: {}});
view = new (EditorApplication.module('blocks.posts').PostsBlockSettingsView)({model: model});
view.render();
view.$('.mailpoet_posts_display_type').val('titleOnly').change();
view.$('.mailpoet_posts_title_format').val('ul').change();
});
expect(view.render).to.not.throw(); describe('"title is link" option', function () {
it('is hidden', function () {
expect(view.$('.mailpoet_posts_title_as_link')).to.have.$class('mailpoet_hidden');
});
it('is set to "yes"', function() {
expect(model.get('titleIsLink')).to.equal(true);
});
});
}); });
describe('once rendered', function () { describe('when "title as list" is deselected', function() {
it('changes the model if post type changes', function () { before(function() {
var newValue = 'mailpoet_page'; view.$('.mailpoet_posts_title_format').val('ul').change();
view.$('.mailpoet_settings_posts_content_type').val(newValue).change(); view.$('.mailpoet_posts_title_format').val('h3').change();
expect(model.get('contentType')).to.equal(newValue); });
});
describe('"title is link" option', function () {
it('changes the model if post status changes', function () { it('is visible', function () {
var newValue = 'pending'; expect(view.$('.mailpoet_posts_title_as_link')).to.not.have.$class('mailpoet_hidden');
view.$('.mailpoet_posts_post_status').val(newValue).change();
expect(model.get('postStatus')).to.equal(newValue);
});
it('changes the model if search term changes', function () {
var newValue = 'some New search term';
view.$('.mailpoet_posts_search_term').val(newValue).keyup();
expect(model.get('search')).to.equal(newValue);
});
it('changes the model if display type changes', function () {
var newValue = 'full';
view.$('.mailpoet_posts_display_type').val(newValue).change();
expect(model.get('displayType')).to.equal(newValue);
});
it('changes the model if title format changes', function () {
var newValue = 'h3';
view.$('.mailpoet_posts_title_format').val(newValue).change();
expect(model.get('titleFormat')).to.equal(newValue);
});
it('changes the model if title position changes', function () {
var newValue = 'aboveBlock';
view.$('.mailpoet_posts_title_position').val(newValue).change();
expect(model.get('titlePosition')).to.equal(newValue);
});
it('changes the model if title alignment changes', function () {
var newValue = 'right';
view.$('.mailpoet_posts_title_alignment').val(newValue).change();
expect(model.get('titleAlignment')).to.equal(newValue);
});
it('changes the model if title link changes', function () {
var newValue = true;
view.$('.mailpoet_posts_title_as_links').val(newValue).change();
expect(model.get('titleIsLink')).to.equal(newValue);
});
it('changes the model if image alignment changes', function () {
var newValue = false;
view.$('.mailpoet_posts_image_padded').val(newValue).change();
expect(model.get('imagePadded')).to.equal(newValue);
});
it('changes the model if show author changes', function () {
var newValue = 'belowText';
view.$('.mailpoet_posts_show_author').val(newValue).change();
expect(model.get('showAuthor')).to.equal(newValue);
});
it('changes the model if author preceded by changes', function () {
var newValue = 'New author preceded by test';
view.$('.mailpoet_posts_author_preceded_by').val(newValue).keyup();
expect(model.get('authorPrecededBy')).to.equal(newValue);
});
it('changes the model if show categories changes', function () {
var newValue = 'belowText';
view.$('.mailpoet_posts_show_categories').val(newValue).change();
expect(model.get('showCategories')).to.equal(newValue);
});
it('changes the model if categories preceded by changes', function () {
var newValue = 'New categories preceded by test';
view.$('.mailpoet_posts_categories').val(newValue).keyup();
expect(model.get('categoriesPrecededBy')).to.equal(newValue);
});
it('changes the model if read more button type changes', function () {
var newValue = 'link';
view.$('.mailpoet_posts_read_more_type').val(newValue).change();
expect(model.get('readMoreType')).to.equal(newValue);
});
it('changes the model if read more text changes', function () {
var newValue = 'New read more text';
view.$('.mailpoet_posts_read_more_text').val(newValue).keyup();
expect(model.get('readMoreText')).to.equal(newValue);
});
describe('when "title only" display type is selected', function() {
var model, view;
beforeEach(function() {
model = new (EditorApplication.module('blocks.posts').PostsBlockModel)();
model.request = sinon.stub().returns({$el: {}});
view = new (EditorApplication.module('blocks.posts').PostsBlockSettingsView)({model: model});
view.render();
view.$('.mailpoet_posts_display_type').val('titleOnly').change();
});
it('shows "title as list" option', function () {
expect(view.$('.mailpoet_posts_title_as_list')).to.not.have.$class('mailpoet_hidden');
});
describe('when "title as list" is selected', function() {
var model, view;
beforeEach(function() {
model = new (EditorApplication.module('blocks.posts').PostsBlockModel)();
model.request = sinon.stub().returns({$el: {}});
view = new (EditorApplication.module('blocks.posts').PostsBlockSettingsView)({model: model});
view.render();
view.$('.mailpoet_posts_display_type').val('titleOnly').change();
view.$('.mailpoet_posts_title_format').val('ul').change();
});
describe('"title is link" option', function () {
it('is hidden', function () {
expect(view.$('.mailpoet_posts_title_as_link')).to.have.$class('mailpoet_hidden');
});
it('is set to "yes"', function() {
expect(model.get('titleIsLink')).to.equal(true);
});
});
});
describe('when "title as list" is deselected', function() {
before(function() {
view.$('.mailpoet_posts_title_format').val('ul').change();
view.$('.mailpoet_posts_title_format').val('h3').change();
});
describe('"title is link" option', function () {
it('is visible', function () {
expect(view.$('.mailpoet_posts_title_as_link')).to.not.have.$class('mailpoet_hidden');
});
});
});
});
it('changes the model if show divider changes', function () {
var newValue = true;
view.$('.mailpoet_posts_show_divider').val(newValue).change();
expect(model.get('showDivider')).to.equal(newValue);
}); });
});
}); });
});
it('changes the model if show divider changes', function () {
var newValue = true;
view.$('.mailpoet_posts_show_divider').val(newValue).change();
expect(model.get('showDivider')).to.equal(newValue);
});
}); });
});
}); });
}); });

View File

@ -4,277 +4,276 @@ define('test/newsletter_editor/blocks/social', [
], function(EditorApplication) { ], function(EditorApplication) {
describe('Social', function () { describe('Social', function () {
describe('block model', function () { describe('block model', function () {
var model; var model;
beforeEach(function () { beforeEach(function () {
global.stubChannel(EditorApplication); global.stubChannel(EditorApplication);
global.stubConfig(EditorApplication); global.stubConfig(EditorApplication);
model = new (EditorApplication.module('blocks.social').SocialBlockModel)(); model = new (EditorApplication.module('blocks.social').SocialBlockModel)();
});
it('has a social type', function () {
expect(model.get('type')).to.equal('social');
});
it('has an icon set it uses', function () {
expect(model.get('iconSet')).to.be.a('string');
});
it('has icons', function () {
expect(model.get('icons')).to.be.an.instanceof(Backbone.Collection);
});
it("uses defaults from config when they are set", function () {
global.stubConfig(EditorApplication, {
blockDefaults: {
social: {
iconSet: 'customConfigIconSet',
},
},
});
var model = new (EditorApplication.module('blocks.social').SocialBlockModel)();
expect(model.get('iconSet')).to.equal('customConfigIconSet');
});
}); });
describe('icon model', function () { it('has a social type', function () {
var model; expect(model.get('type')).to.equal('social');
before(function () {
global.stubChannel(EditorApplication);
global.stubAvailableStyles(EditorApplication, {
'socialIconSets.default.custom': 'someimage.jpg',
});
global.stubConfig(EditorApplication, {
socialIcons: {
custom: {
defaultLink: 'http://example.org',
title: 'sometitle',
}
},
});
model = new (EditorApplication.module('blocks.social').SocialIconModel)();
});
it('has a socialIcon type', function () {
expect(model.get('type')).to.equal('socialIcon');
});
it('has a link', function () {
expect(model.get('link')).to.be.a('string');
expect(model.get('link')).to.equal('http://example.org');
});
it('has an image', function () {
expect(model.get('image')).to.equal('someimage.jpg');
});
it('has height', function () {
expect(model.get('height')).to.equal('32px');
});
it('has width', function () {
expect(model.get('width')).to.equal('32px');
});
it('has text', function () {
expect(model.get('text')).to.equal('sometitle');
});
}); });
describe('block view', function () { it('has an icon set it uses', function () {
var model; expect(model.get('iconSet')).to.be.a('string');
beforeEach(function () {
global.stubChannel(EditorApplication);
global.stubAvailableStyles(EditorApplication, {
socialIconSets: {
'default': {
'custom': 'http://www.sott.net/images/icons/big_x.png',
},
'light': {
'custom': 'http://content.indiainfoline.com/wc/news/ImageGallery/css/close_32x32.png',
},
},
socialIcons: {
'custom': {
title: 'Custom',
linkFieldName: 'Page URL',
defaultLink: 'http://example.org',
},
},
});
model = new (EditorApplication.module('blocks.social').SocialBlockModel)({
type: 'social',
iconSet: 'default',
icons: [
{
type: 'socialIcon',
iconType: 'custom',
link: 'somelink.htm',
image: 'someimage.png',
text: 'some text',
}
],
});
});
it('renders', function () {
var view = new (EditorApplication.module('blocks.social').SocialBlockView)({model: model});
expect(view.render).to.not.throw();
expect(view.$('.mailpoet_social')).to.have.length(1);
});
describe('once rendered', function () {
var model, view;
before(function () {
global.stubChannel(EditorApplication);
model = new (EditorApplication.module('blocks.social').SocialBlockModel)({
type: 'social',
iconSet: 'default',
icons: [
{
type: 'socialIcon',
iconType: 'custom',
link: 'http://example.org/',
image: 'http://example.org/someimage.png',
text: 'some text',
},
{
type: 'socialIcon',
iconType: 'facebook',
link: 'http://facebook.com/',
image: 'http://facebook.com/icon.png',
text: 'Facebook icon',
},
],
});
view = new (EditorApplication.module('blocks.social').SocialBlockView)({model: model});
view.render();
});
it('shows multiple social icons', function () {
expect(view.$('.mailpoet_social a').eq(0).prop('href')).to.equal('http://example.org/');
expect(view.$('.mailpoet_social img').eq(0).prop('src')).to.equal('http://example.org/someimage.png');
expect(view.$('.mailpoet_social img').eq(0).prop('alt')).to.equal('some text');
expect(view.$('.mailpoet_social a').eq(1).prop('href')).to.equal('http://facebook.com/');
expect(view.$('.mailpoet_social img').eq(1).prop('src')).to.equal('http://facebook.com/icon.png');
expect(view.$('.mailpoet_social img').eq(1).prop('alt')).to.equal('Facebook icon');
});
});
}); });
describe('block settings view', function () { it('has icons', function () {
var model; expect(model.get('icons')).to.be.an.instanceof(Backbone.Collection);
beforeEach(function () {
global.stubChannel(EditorApplication);
global.stubAvailableStyles(EditorApplication, {
socialIconSets: {
'default': {
'custom': 'someimage.png',
},
'light': {
'custom': 'http://content.indiainfoline.com/wc/news/ImageGallery/css/close_32x32.png',
},
},
socialIcons: {
'custom': {
title: 'Custom',
linkFieldName: 'Page URL',
defaultLink: 'http://example.org',
},
},
});
model = new (EditorApplication.module('blocks.social').SocialBlockModel)({
type: 'social',
iconSet: 'default',
icons: [
{
type: 'socialIcon',
iconType: 'custom',
link: 'somelink.htm',
image: 'someimage.png',
height: '32px',
width: '32px',
text: 'some text',
}
],
});
});
it('renders', function () {
var view = new (EditorApplication.module('blocks.social').SocialBlockSettingsView)({model: model});
expect(view.render).to.not.throw();
});
describe('once rendered', function () {
var model, view;
beforeEach(function () {
global.stubChannel(EditorApplication);
global.stubAvailableStyles(EditorApplication, {
socialIconSets: {
'default': {
'custom': 'http://www.sott.net/images/icons/big_x.png',
},
'light': {
'custom': 'http://content.indiainfoline.com/wc/news/ImageGallery/css/close_32x32.png',
},
},
socialIcons: {
'custom': {
title: 'Custom',
linkFieldName: 'Page URL',
defaultLink: 'http://example.org',
},
},
});
model = new (EditorApplication.module('blocks.social').SocialBlockModel)({
type: 'social',
iconSet: 'default',
icons: [
{
type: 'socialIcon',
iconType: 'custom',
link: 'somelink.htm',
image: 'someimage.png',
height: '32px',
width: '32px',
text: 'some text',
}
],
});
view = new (EditorApplication.module('blocks.social').SocialBlockSettingsView)({model: model});
view.render();
});
it('updates icons in settings if iconset changes', function() {
view.$('.mailpoet_social_icon_set').last().click();
expect(view.$('.mailpoet_social_icon_field_image').val()).to.equal(EditorApplication.getAvailableStyles().get('socialIconSets.light.custom'));
});
it('removes the icon when "remove" is clicked', function() {
view.$('.mailpoet_delete_block').click();
expect(model.get('icons').length).to.equal(0);
expect(view.$('.mailpoet_social_icon_settings').length).to.equal(0);
});
it('adds another icon when "Add another social network" is pressed', function() {
view.$('.mailpoet_add_social_icon').click();
expect(model.get('icons').length).to.equal(2);
});
it.skip('closes the sidepanel after "Done" is clicked', function () {
var mock = sinon.mock().once();
global.MailPoet.Modal.cancel = mock;
view.$('.mailpoet_done_editing').click();
mock.verify();
delete(global.MailPoet.Modal.cancel);
});
});
}); });
it("uses defaults from config when they are set", function () {
global.stubConfig(EditorApplication, {
blockDefaults: {
social: {
iconSet: 'customConfigIconSet',
},
},
});
var model = new (EditorApplication.module('blocks.social').SocialBlockModel)();
expect(model.get('iconSet')).to.equal('customConfigIconSet');
});
});
describe('icon model', function () {
var model;
before(function () {
global.stubChannel(EditorApplication);
global.stubAvailableStyles(EditorApplication, {
'socialIconSets.default.custom': 'someimage.jpg',
});
global.stubConfig(EditorApplication, {
socialIcons: {
custom: {
defaultLink: 'http://example.org',
title: 'sometitle',
}
},
});
model = new (EditorApplication.module('blocks.social').SocialIconModel)();
});
it('has a socialIcon type', function () {
expect(model.get('type')).to.equal('socialIcon');
});
it('has a link', function () {
expect(model.get('link')).to.be.a('string');
expect(model.get('link')).to.equal('http://example.org');
});
it('has an image', function () {
expect(model.get('image')).to.equal('someimage.jpg');
});
it('has height', function () {
expect(model.get('height')).to.equal('32px');
});
it('has width', function () {
expect(model.get('width')).to.equal('32px');
});
it('has text', function () {
expect(model.get('text')).to.equal('sometitle');
});
});
describe('block view', function () {
var model;
beforeEach(function () {
global.stubChannel(EditorApplication);
global.stubAvailableStyles(EditorApplication, {
socialIconSets: {
'default': {
'custom': 'http://www.sott.net/images/icons/big_x.png',
},
'light': {
'custom': 'http://content.indiainfoline.com/wc/news/ImageGallery/css/close_32x32.png',
},
},
socialIcons: {
'custom': {
title: 'Custom',
linkFieldName: 'Page URL',
defaultLink: 'http://example.org',
},
},
});
model = new (EditorApplication.module('blocks.social').SocialBlockModel)({
type: 'social',
iconSet: 'default',
icons: [
{
type: 'socialIcon',
iconType: 'custom',
link: 'somelink.htm',
image: 'someimage.png',
text: 'some text',
}
],
});
});
it('renders', function () {
var view = new (EditorApplication.module('blocks.social').SocialBlockView)({model: model});
expect(view.render).to.not.throw();
expect(view.$('.mailpoet_social')).to.have.length(1);
});
describe('once rendered', function () {
var model, view;
before(function () {
global.stubChannel(EditorApplication);
model = new (EditorApplication.module('blocks.social').SocialBlockModel)({
type: 'social',
iconSet: 'default',
icons: [
{
type: 'socialIcon',
iconType: 'custom',
link: 'http://example.org/',
image: 'http://example.org/someimage.png',
text: 'some text',
},
{
type: 'socialIcon',
iconType: 'facebook',
link: 'http://facebook.com/',
image: 'http://facebook.com/icon.png',
text: 'Facebook icon',
},
],
});
view = new (EditorApplication.module('blocks.social').SocialBlockView)({model: model});
view.render();
});
it('shows multiple social icons', function () {
expect(view.$('.mailpoet_social a').eq(0).prop('href')).to.equal('http://example.org/');
expect(view.$('.mailpoet_social img').eq(0).prop('src')).to.equal('http://example.org/someimage.png');
expect(view.$('.mailpoet_social img').eq(0).prop('alt')).to.equal('some text');
expect(view.$('.mailpoet_social a').eq(1).prop('href')).to.equal('http://facebook.com/');
expect(view.$('.mailpoet_social img').eq(1).prop('src')).to.equal('http://facebook.com/icon.png');
expect(view.$('.mailpoet_social img').eq(1).prop('alt')).to.equal('Facebook icon');
});
});
});
describe('block settings view', function () {
var model;
beforeEach(function () {
global.stubChannel(EditorApplication);
global.stubAvailableStyles(EditorApplication, {
socialIconSets: {
'default': {
'custom': 'someimage.png',
},
'light': {
'custom': 'http://content.indiainfoline.com/wc/news/ImageGallery/css/close_32x32.png',
},
},
socialIcons: {
'custom': {
title: 'Custom',
linkFieldName: 'Page URL',
defaultLink: 'http://example.org',
},
},
});
model = new (EditorApplication.module('blocks.social').SocialBlockModel)({
type: 'social',
iconSet: 'default',
icons: [
{
type: 'socialIcon',
iconType: 'custom',
link: 'somelink.htm',
image: 'someimage.png',
height: '32px',
width: '32px',
text: 'some text',
}
],
});
});
it('renders', function () {
var view = new (EditorApplication.module('blocks.social').SocialBlockSettingsView)({model: model});
expect(view.render).to.not.throw();
});
describe('once rendered', function () {
var model, view;
beforeEach(function () {
global.stubChannel(EditorApplication);
global.stubAvailableStyles(EditorApplication, {
socialIconSets: {
'default': {
'custom': 'http://www.sott.net/images/icons/big_x.png',
},
'light': {
'custom': 'http://content.indiainfoline.com/wc/news/ImageGallery/css/close_32x32.png',
},
},
socialIcons: {
'custom': {
title: 'Custom',
linkFieldName: 'Page URL',
defaultLink: 'http://example.org',
},
},
});
model = new (EditorApplication.module('blocks.social').SocialBlockModel)({
type: 'social',
iconSet: 'default',
icons: [
{
type: 'socialIcon',
iconType: 'custom',
link: 'somelink.htm',
image: 'someimage.png',
height: '32px',
width: '32px',
text: 'some text',
}
],
});
view = new (EditorApplication.module('blocks.social').SocialBlockSettingsView)({model: model});
view.render();
});
it('updates icons in settings if iconset changes', function() {
view.$('.mailpoet_social_icon_set').last().click();
expect(view.$('.mailpoet_social_icon_field_image').val()).to.equal(EditorApplication.getAvailableStyles().get('socialIconSets.light.custom'));
});
it('removes the icon when "remove" is clicked', function() {
view.$('.mailpoet_delete_block').click();
expect(model.get('icons').length).to.equal(0);
expect(view.$('.mailpoet_social_icon_settings').length).to.equal(0);
});
it('adds another icon when "Add another social network" is pressed', function() {
view.$('.mailpoet_add_social_icon').click();
expect(model.get('icons').length).to.equal(2);
});
it.skip('closes the sidepanel after "Done" is clicked', function () {
var mock = sinon.mock().once();
global.MailPoet.Modal.cancel = mock;
view.$('.mailpoet_done_editing').click();
mock.verify();
delete(global.MailPoet.Modal.cancel);
});
});
});
}); });
}); });

View File

@ -4,140 +4,139 @@ define('test/newsletter_editor/blocks/spacer', [
], function(EditorApplication) { ], function(EditorApplication) {
describe('Spacer', function () { describe('Spacer', function () {
describe('model', function () { describe('model', function () {
var model; var model;
beforeEach(function () { beforeEach(function () {
global.stubChannel(EditorApplication); global.stubChannel(EditorApplication);
global.stubConfig(EditorApplication, { global.stubConfig(EditorApplication, {
blockDefaults: {}, blockDefaults: {},
}); });
global.stubAvailableStyles(EditorApplication); global.stubAvailableStyles(EditorApplication);
model = new (EditorApplication.module('blocks.spacer').SpacerBlockModel)(); model = new (EditorApplication.module('blocks.spacer').SpacerBlockModel)();
});
afterEach(function () {
delete EditorApplication.getChannel;
});
it('has spacer type', function () {
expect(model.get('type')).to.equal('spacer');
});
it('has height', function () {
expect(model.get('styles.block.height')).to.match(/\d+px/);
});
it('has a background color', function () {
expect(model.get('styles.block.backgroundColor')).to.match(/^(#[abcdef0-9]{6})|transparent$/);
});
it("changes attributes with set", function () {
var newValue = '33px';
model.set('styles.block.height', newValue);
expect(model.get('styles.block.height')).to.equal(newValue);
});
it("triggers autosave if any attribute changes", function () {
var mock = sinon.mock().exactly(2).withArgs('autoSave');
EditorApplication.getChannel = sinon.stub().returns({
trigger: mock,
});
model.set('styles.block.backgroundColor', '#000000');
model.set('styles.block.height', '77px');
mock.verify();
});
it("uses defaults from config when they are set", function () {
global.stubConfig(EditorApplication, {
blockDefaults: {
spacer: {
styles: {
block: {
backgroundColor: '#567890',
height: '19px',
},
},
},
},
});
var model = new (EditorApplication.module('blocks.spacer').SpacerBlockModel)();
expect(model.get('styles.block.backgroundColor')).to.equal('#567890');
expect(model.get('styles.block.height')).to.equal('19px');
});
}); });
describe('block view', function () { afterEach(function () {
global.stubChannel(EditorApplication); delete EditorApplication.getChannel;
global.stubConfig(EditorApplication);
global.stubAvailableStyles(EditorApplication);
var model = new (EditorApplication.module('blocks.spacer').SpacerBlockModel)(),
view;
beforeEach(function () {
global.stubChannel(EditorApplication);
view = new (EditorApplication.module('blocks.spacer').SpacerBlockView)({model: model});
});
it('renders', function () {
expect(view.render).to.not.throw();
expect(view.$('.mailpoet_spacer')).to.have.length(1);
expect(view.$('.mailpoet_spacer').css('background-color')).to.equal(model.get('styles.block.backgroundColor'));
expect(view.$('.mailpoet_spacer').css('height')).to.equal(model.get('styles.block.height'));
});
it('rerenders if model attributes change', function () {
view.render();
model.set('styles.block.height', '71px');
expect(view.$('.mailpoet_spacer').css('height')).to.equal('71px');
});
}); });
describe('settings view', function () { it('has spacer type', function () {
global.stubChannel(EditorApplication); expect(model.get('type')).to.equal('spacer');
global.stubConfig(EditorApplication);
var model = new (EditorApplication.module('blocks.spacer').SpacerBlockModel)(),
view;
beforeEach(function () {
global.stubChannel(EditorApplication);
view = new (EditorApplication.module('blocks.spacer').SpacerBlockSettingsView)({model: model});
});
it('renders', function () {
expect(view.render).to.not.throw();
});
describe('once rendered', function () {
var view, model;
beforeEach(function() {
global.stubChannel(EditorApplication);
global.stubConfig(EditorApplication);
model = new (EditorApplication.module('blocks.spacer').SpacerBlockModel)();
view = new (EditorApplication.module('blocks.spacer').SpacerBlockSettingsView)({model: model});
view.render();
});
it('updates the model when background color changes', function () {
view.$('.mailpoet_field_spacer_background_color').val('#123456').change();
expect(model.get('styles.block.backgroundColor')).to.equal('#123456');
});
it.skip('closes the sidepanel after "Done" is clicked', function () {
var mock = sinon.mock().once();
global.MailPoet.Modal.cancel = mock;
view.$('.mailpoet_done_editing').click();
mock.verify();
delete(global.MailPoet.Modal.cancel);
});
});
}); });
it('has height', function () {
expect(model.get('styles.block.height')).to.match(/\d+px/);
});
it('has a background color', function () {
expect(model.get('styles.block.backgroundColor')).to.match(/^(#[abcdef0-9]{6})|transparent$/);
});
it("changes attributes with set", function () {
var newValue = '33px';
model.set('styles.block.height', newValue);
expect(model.get('styles.block.height')).to.equal(newValue);
});
it("triggers autosave if any attribute changes", function () {
var mock = sinon.mock().exactly(2).withArgs('autoSave');
EditorApplication.getChannel = sinon.stub().returns({
trigger: mock,
});
model.set('styles.block.backgroundColor', '#000000');
model.set('styles.block.height', '77px');
mock.verify();
});
it("uses defaults from config when they are set", function () {
global.stubConfig(EditorApplication, {
blockDefaults: {
spacer: {
styles: {
block: {
backgroundColor: '#567890',
height: '19px',
},
},
},
},
});
var model = new (EditorApplication.module('blocks.spacer').SpacerBlockModel)();
expect(model.get('styles.block.backgroundColor')).to.equal('#567890');
expect(model.get('styles.block.height')).to.equal('19px');
});
});
describe('block view', function () {
global.stubChannel(EditorApplication);
global.stubConfig(EditorApplication);
global.stubAvailableStyles(EditorApplication);
var model = new (EditorApplication.module('blocks.spacer').SpacerBlockModel)(),
view;
beforeEach(function () {
global.stubChannel(EditorApplication);
view = new (EditorApplication.module('blocks.spacer').SpacerBlockView)({model: model});
});
it('renders', function () {
expect(view.render).to.not.throw();
expect(view.$('.mailpoet_spacer')).to.have.length(1);
expect(view.$('.mailpoet_spacer').css('background-color')).to.equal(model.get('styles.block.backgroundColor'));
expect(view.$('.mailpoet_spacer').css('height')).to.equal(model.get('styles.block.height'));
});
it('rerenders if model attributes change', function () {
view.render();
model.set('styles.block.height', '71px');
expect(view.$('.mailpoet_spacer').css('height')).to.equal('71px');
});
});
describe('settings view', function () {
global.stubChannel(EditorApplication);
global.stubConfig(EditorApplication);
var model = new (EditorApplication.module('blocks.spacer').SpacerBlockModel)(),
view;
beforeEach(function () {
global.stubChannel(EditorApplication);
view = new (EditorApplication.module('blocks.spacer').SpacerBlockSettingsView)({model: model});
});
it('renders', function () {
expect(view.render).to.not.throw();
});
describe('once rendered', function () {
var view, model;
beforeEach(function() {
global.stubChannel(EditorApplication);
global.stubConfig(EditorApplication);
model = new (EditorApplication.module('blocks.spacer').SpacerBlockModel)();
view = new (EditorApplication.module('blocks.spacer').SpacerBlockSettingsView)({model: model});
view.render();
});
it('updates the model when background color changes', function () {
view.$('.mailpoet_field_spacer_background_color').val('#123456').change();
expect(model.get('styles.block.backgroundColor')).to.equal('#123456');
});
it.skip('closes the sidepanel after "Done" is clicked', function () {
var mock = sinon.mock().once();
global.MailPoet.Modal.cancel = mock;
view.$('.mailpoet_done_editing').click();
mock.verify();
delete(global.MailPoet.Modal.cancel);
});
});
});
}); });
}); });

View File

@ -4,69 +4,68 @@ define('test/newsletter_editor/blocks/text', [
], function(EditorApplication) { ], function(EditorApplication) {
describe('Text', function () { describe('Text', function () {
describe('model', function () { describe('model', function () {
var model; var model;
beforeEach(function () { beforeEach(function () {
global.stubChannel(EditorApplication); global.stubChannel(EditorApplication);
global.stubConfig(EditorApplication); global.stubConfig(EditorApplication);
model = new (EditorApplication.module('blocks.text').TextBlockModel)(); model = new (EditorApplication.module('blocks.text').TextBlockModel)();
});
it('has a text type', function () {
expect(model.get('type')).to.equal('text');
});
it('has text', function () {
expect(model.get('text')).to.be.a('string');
});
it("uses defaults from config when they are set", function () {
global.stubConfig(EditorApplication, {
blockDefaults: {
text: {
text: 'some custom config text',
},
},
});
var model = new (EditorApplication.module('blocks.text').TextBlockModel)();
expect(model.get('text')).to.equal('some custom config text');
});
}); });
describe('block view', function () { it('has a text type', function () {
expect(model.get('type')).to.equal('text');
});
it('has text', function () {
expect(model.get('text')).to.be.a('string');
});
it("uses defaults from config when they are set", function () {
global.stubConfig(EditorApplication, {
blockDefaults: {
text: {
text: 'some custom config text',
},
},
});
var model = new (EditorApplication.module('blocks.text').TextBlockModel)();
expect(model.get('text')).to.equal('some custom config text');
});
});
describe('block view', function () {
global.stubConfig(EditorApplication);
var model = new (EditorApplication.module('blocks.text').TextBlockModel)(),
view = new (EditorApplication.module('blocks.text').TextBlockView)({model: model});
it('renders', function () {
expect(view.render).to.not.throw();
expect(view.$('.mailpoet_content')).to.have.length(1);
});
describe('once rendered', function () {
var model = new (EditorApplication.module('blocks.text').TextBlockModel)(),
view;
beforeEach(function () {
global.stubConfig(EditorApplication); global.stubConfig(EditorApplication);
var model = new (EditorApplication.module('blocks.text').TextBlockModel)(), view = new (EditorApplication.module('blocks.text').TextBlockView)({model: model});
view = new (EditorApplication.module('blocks.text').TextBlockView)({model: model}); view.render();
});
it('renders', function () { it('has a deletion tool', function () {
expect(view.render).to.not.throw(); expect(view.$('.mailpoet_delete_block')).to.have.length(1);
expect(view.$('.mailpoet_content')).to.have.length(1); });
});
describe('once rendered', function () { it('has a move tool', function () {
var model = new (EditorApplication.module('blocks.text').TextBlockModel)(), expect(view.$('.mailpoet_move_block')).to.have.length(1);
view; });
beforeEach(function () { it('does not have a settings tool', function () {
global.stubConfig(EditorApplication); expect(view.$('.mailpoet_edit_block')).to.have.length(0);
view = new (EditorApplication.module('blocks.text').TextBlockView)({model: model}); });
view.render();
});
it('has a deletion tool', function () {
expect(view.$('.mailpoet_delete_block')).to.have.length(1);
});
it('has a move tool', function () {
expect(view.$('.mailpoet_move_block')).to.have.length(1);
});
it('does not have a settings tool', function () {
expect(view.$('.mailpoet_edit_block')).to.have.length(0);
});
});
}); });
});
}); });
}); });

View File

@ -4,12 +4,12 @@ define('test/newsletter_editor/components/config', [
], function(EditorApplication) { ], function(EditorApplication) {
describe('Config', function () { describe('Config', function () {
it('loads and stores configuration', function() { it('loads and stores configuration', function() {
EditorApplication.module('components.config').setConfig({ EditorApplication.module('components.config').setConfig({
testConfig: 'testValue', testConfig: 'testValue',
});
var model = EditorApplication.module('components.config').getConfig();
expect(model.get('testConfig')).to.equal('testValue');
}); });
var model = EditorApplication.module('components.config').getConfig();
expect(model.get('testConfig')).to.equal('testValue');
});
}); });
}); });

View File

@ -4,85 +4,85 @@ define('test/newsletter_editor/components/content', [
], function(EditorApplication) { ], function(EditorApplication) {
describe('Content', function() { describe('Content', function() {
describe('newsletter model', function() { describe('newsletter model', function() {
var model; var model;
beforeEach(function() { beforeEach(function() {
model = new (EditorApplication.module('components.content').NewsletterModel)({ model = new (EditorApplication.module('components.content').NewsletterModel)({
styles: { styles: {
style1: 'style1Value', style1: 'style1Value',
style2: 'style2Value', style2: 'style2Value',
}, },
data: { data: {
data1: 'data1Value', data1: 'data1Value',
data2: 'data2Value', data2: 'data2Value',
}, },
someField: 'someValue' someField: 'someValue'
}); });
});
it('triggers autosave on change', function() {
var mock = sinon.mock({ trigger: function() {} }).expects('trigger').once().withArgs('autoSave');
global.stubChannel(EditorApplication, {
trigger: mock,
});
model.set('someField', 'anotherValue');
mock.verify();
});
it('does not include styles and data attributes in its JSON', function() {
var json = model.toJSON();
expect(json).to.deep.equal({someField: 'someValue'});
});
}); });
describe('block types', function() { it('triggers autosave on change', function() {
it('registers a block type view and model', function() { var mock = sinon.mock({ trigger: function() {} }).expects('trigger').once().withArgs('autoSave');
var blockModel = new Backbone.SuperModel(), global.stubChannel(EditorApplication, {
blockView = new Backbone.View(); trigger: mock,
EditorApplication.module('components.content').registerBlockType('testType', { });
blockModel: blockModel, model.set('someField', 'anotherValue');
blockView: blockView, mock.verify();
});
expect(EditorApplication.module('components.content').getBlockTypeModel('testType')).to.deep.equal(blockModel);
expect(EditorApplication.module('components.content').getBlockTypeView('testType')).to.deep.equal(blockView);
});
}); });
describe('transformation to json', function() { it('does not include styles and data attributes in its JSON', function() {
it('includes data, styles and initial newsletter fields', function() { var json = model.toJSON();
var dataField = { expect(json).to.deep.equal({someField: 'someValue'});
containerModelField: 'containerModelValue',
}, stylesField = {
globalStylesField: 'globalStylesValue',
}, newsletterFields = {
newsletter_subject: 'test newsletter subject',
};
EditorApplication._contentContainer = {
toJSON: function() {
return dataField;
}
};
EditorApplication.getGlobalStyles = function() {
return {
toJSON: function() {
return stylesField;
},
};
};
EditorApplication.getNewsletter = function() {
return {
toJSON: function() {
return newsletterFields;
},
};
};
var json = EditorApplication.module('components.content').toJSON();
expect(json).to.deep.equal(_.extend({
data: dataField,
styles: stylesField
}, newsletterFields));
});
}); });
});
describe('block types', function() {
it('registers a block type view and model', function() {
var blockModel = new Backbone.SuperModel(),
blockView = new Backbone.View();
EditorApplication.module('components.content').registerBlockType('testType', {
blockModel: blockModel,
blockView: blockView,
});
expect(EditorApplication.module('components.content').getBlockTypeModel('testType')).to.deep.equal(blockModel);
expect(EditorApplication.module('components.content').getBlockTypeView('testType')).to.deep.equal(blockView);
});
});
describe('transformation to json', function() {
it('includes data, styles and initial newsletter fields', function() {
var dataField = {
containerModelField: 'containerModelValue',
}, stylesField = {
globalStylesField: 'globalStylesValue',
}, newsletterFields = {
newsletter_subject: 'test newsletter subject',
};
EditorApplication._contentContainer = {
toJSON: function() {
return dataField;
}
};
EditorApplication.getGlobalStyles = function() {
return {
toJSON: function() {
return stylesField;
},
};
};
EditorApplication.getNewsletter = function() {
return {
toJSON: function() {
return newsletterFields;
},
};
};
var json = EditorApplication.module('components.content').toJSON();
expect(json).to.deep.equal(_.extend({
data: dataField,
styles: stylesField
}, newsletterFields));
});
});
}); });
}); });

View File

@ -4,45 +4,44 @@ define('test/newsletter_editor/components/heading', [
], function(EditorApplication) { ], function(EditorApplication) {
describe('Heading', function() { describe('Heading', function() {
describe('view', function() { describe('view', function() {
var view; var view;
beforeEach(function() { beforeEach(function() {
var model = new Backbone.SuperModel({ var model = new Backbone.SuperModel({
newsletter_subject: 'a test subject', newsletter_subject: 'a test subject',
}); });
view = new (EditorApplication.module("components.heading").HeadingView)({ view = new (EditorApplication.module("components.heading").HeadingView)({
model: model, model: model,
}); });
});
it('renders', function() {
expect(view.render).to.not.throw();
});
describe('once rendered', function() {
var view, model;
beforeEach(function() {
model = new Backbone.SuperModel({
newsletter_subject: 'a test subject',
newsletter_preheader: 'a test preheader',
});
view = new (EditorApplication.module("components.heading").HeadingView)({
model: model,
});
view.render();
});
it('changes the model when subject field is changed', function() {
view.$('.mailpoet_input_title').val('a new testing subject').keyup();
expect(model.get('newsletter_subject')).to.equal('a new testing subject');
});
it('changes the model when preheader field is changed', function() {
view.$('.mailpoet_input_preheader').val('a new testing preheader').keyup();
expect(model.get('newsletter_preheader')).to.equal('a new testing preheader');
});
});
}); });
});
it('renders', function() {
expect(view.render).to.not.throw();
});
describe('once rendered', function() {
var view, model;
beforeEach(function() {
model = new Backbone.SuperModel({
newsletter_subject: 'a test subject',
newsletter_preheader: 'a test preheader',
});
view = new (EditorApplication.module("components.heading").HeadingView)({
model: model,
});
view.render();
});
it('changes the model when subject field is changed', function() {
view.$('.mailpoet_input_title').val('a new testing subject').keyup();
expect(model.get('newsletter_subject')).to.equal('a new testing subject');
});
it('changes the model when preheader field is changed', function() {
view.$('.mailpoet_input_preheader').val('a new testing preheader').keyup();
expect(model.get('newsletter_preheader')).to.equal('a new testing preheader');
});
});
});
});
}); });

View File

@ -4,78 +4,77 @@ define('test/newsletter_editor/components/save', [
], function(EditorApplication) { ], function(EditorApplication) {
describe('Save', function() { describe('Save', function() {
describe('save method', function() { describe('save method', function() {
it('triggers beforeEditorSave event', function() { it('triggers beforeEditorSave event', function() {
var spy = sinon.spy(); var spy = sinon.spy();
global.stubChannel(EditorApplication, { global.stubChannel(EditorApplication, {
trigger: spy, trigger: spy,
}); });
global.mailpoet_post_wpi = sinon.stub(); global.mailpoet_post_wpi = sinon.stub();
EditorApplication.toJSON = sinon.stub(); EditorApplication.toJSON = sinon.stub();
EditorApplication.module("components.save").save(); EditorApplication.module("components.save").save();
expect(spy.withArgs('beforeEditorSave').calledOnce).to.be.true; expect(spy.withArgs('beforeEditorSave').calledOnce).to.be.true;
});
it.skip('triggers afterEditorSave event', function() {
var stub = sinon.stub().callsArgWith(2, { success: true }),
spy = sinon.spy();
global.mailpoet_post_wpi = stub;
global.stubChannel(EditorApplication, {
trigger: spy,
});
EditorApplication.toJSON = sinon.stub();
EditorApplication.module("components.save").save();
expect(spy.withArgs('afterEditorSave').calledOnce).to.be.true;
});
it.skip('sends newsletter json to server for saving', function() {
var mock = sinon.mock({ mailpoet_post_wpi: function() {} }).expects('mailpoet_post_wpi').once();
global.stubChannel(EditorApplication);
global.mailpoet_post_wpi = mock;
EditorApplication.toJSON = sinon.stub().returns({});
EditorApplication.module("components.save").save();
mock.verify();
});
}); });
describe('view', function() { it.skip('triggers afterEditorSave event', function() {
var view; var stub = sinon.stub().callsArgWith(2, { success: true }),
before(function() { spy = sinon.spy();
EditorApplication._contentContainer = { isValid: sinon.stub().returns(true) }; global.mailpoet_post_wpi = stub;
global.stubConfig(EditorApplication); global.stubChannel(EditorApplication, {
view = new (EditorApplication.module('components.save').SaveView)(); trigger: spy,
}); });
EditorApplication.toJSON = sinon.stub();
it('renders', function() { EditorApplication.module("components.save").save();
expect(view.render).to.not.throw(); expect(spy.withArgs('afterEditorSave').calledOnce).to.be.true;
});
describe('once rendered', function() {
var view;
beforeEach(function() {
EditorApplication._contentContainer = { isValid: sinon.stub().returns(true) };
view = new (EditorApplication.module('components.save').SaveView)();
view.render();
});
it('triggers newsletter saving when clicked on save button', function() {
var mock = sinon.mock({ trigger: function() {} }).expects('trigger').once().withArgs('save');
global.stubChannel(EditorApplication, {
trigger: mock,
});
view.$('.mailpoet_save_button').click();
mock.verify();
});
it('displays saving options when clicked on save options button', function() {
view.$('.mailpoet_save_show_options').click();
expect(view.$('.mailpoet_save_options')).to.not.have.$class('mailpoet_hidden');
});
});
}); });
it.skip('sends newsletter json to server for saving', function() {
var mock = sinon.mock({ mailpoet_post_wpi: function() {} }).expects('mailpoet_post_wpi').once();
global.stubChannel(EditorApplication);
global.mailpoet_post_wpi = mock;
EditorApplication.toJSON = sinon.stub().returns({});
EditorApplication.module("components.save").save();
mock.verify();
});
});
describe('view', function() {
var view;
before(function() {
EditorApplication._contentContainer = { isValid: sinon.stub().returns(true) };
global.stubConfig(EditorApplication);
view = new (EditorApplication.module('components.save').SaveView)();
});
it('renders', function() {
expect(view.render).to.not.throw();
});
describe('once rendered', function() {
var view;
beforeEach(function() {
EditorApplication._contentContainer = { isValid: sinon.stub().returns(true) };
view = new (EditorApplication.module('components.save').SaveView)();
view.render();
});
it('triggers newsletter saving when clicked on save button', function() {
var mock = sinon.mock({ trigger: function() {} }).expects('trigger').once().withArgs('save');
global.stubChannel(EditorApplication, {
trigger: mock,
});
view.$('.mailpoet_save_button').click();
mock.verify();
});
it('displays saving options when clicked on save options button', function() {
view.$('.mailpoet_save_show_options').click();
expect(view.$('.mailpoet_save_options')).to.not.have.$class('mailpoet_hidden');
});
});
});
}); });
}); });

View File

@ -4,186 +4,184 @@ define('test/newsletter_editor/components/sidebar', [
], function(EditorApplication) { ], function(EditorApplication) {
describe('Sidebar', function() { describe('Sidebar', function() {
describe('content view', function() {
describe('content view', function() { var view;
var view; beforeEach(function() {
beforeEach(function() { view = new (EditorApplication.module('components.sidebar').SidebarWidgetsView)({
view = new (EditorApplication.module('components.sidebar').SidebarWidgetsView)({ collection: new Backbone.Collection([]),
collection: new Backbone.Collection([]), });
});
});
it('renders', function() {
expect(view.render).to.not.throw();
});
}); });
describe('layout view', function() { it('renders', function() {
var view; expect(view.render).to.not.throw();
beforeEach(function() { });
view = new (EditorApplication.module('components.sidebar').SidebarLayoutWidgetsView)({ });
collection: new Backbone.Collection([]),
});
});
it('renders', function() { describe('layout view', function() {
expect(view.render).to.not.throw(); var view;
}); beforeEach(function() {
view = new (EditorApplication.module('components.sidebar').SidebarLayoutWidgetsView)({
collection: new Backbone.Collection([]),
});
}); });
describe('styles view', function() { it('renders', function() {
var view; expect(view.render).to.not.throw();
beforeEach(function() { });
view = new (EditorApplication.module('components.sidebar').SidebarStylesView)({ });
model: new Backbone.SuperModel({}),
availableStyles: new Backbone.SuperModel({}),
});
});
it('renders', function() { describe('styles view', function() {
expect(view.render).to.not.throw(); var view;
}); beforeEach(function() {
view = new (EditorApplication.module('components.sidebar').SidebarStylesView)({
describe('once rendered', function() { model: new Backbone.SuperModel({}),
var model, availableStyles, view; availableStyles: new Backbone.SuperModel({}),
before(function() { });
model = new Backbone.SuperModel({
text: {
fontColor: '#000000',
fontFamily: 'Arial',
},
h1: {
fontColor: '#000001',
fontFamily: 'Arial',
},
h2: {
fontColor: '#000002',
fontFamily: 'Arial',
},
h3: {
fontColor: '#000003',
fontFamily: 'Arial',
},
link: {
fontColor: '#000005',
textDecoration: 'none',
},
newsletter: {
backgroundColor: '#090909',
},
background: {
backgroundColor: '#020202',
},
});
availableStyles = new Backbone.SuperModel({
fonts: ['Arial', 'Times New Roman', 'Tahoma', 'Comic Sans', 'Lucida'],
textSizes: [
'9px', '10px',
],
headingSizes: [
'10px', '12px', '14px', '16px', '18px',
],
});
view = new (EditorApplication.module('components.sidebar').SidebarStylesView)({
model: model,
availableStyles: availableStyles,
});
view.render();
});
it('changes model if text font color field changes', function() {
view.$('#mailpoet_text_font_color').val('#123456').change();
expect(model.get('text.fontColor')).to.equal('#123456');
});
it('changes model if h1 font color field changes', function() {
view.$('#mailpoet_h1_font_color').val('#123457').change();
expect(model.get('h1.fontColor')).to.equal('#123457');
});
it('changes model if h2 font color field changes', function() {
view.$('#mailpoet_h2_font_color').val('#123458').change();
expect(model.get('h2.fontColor')).to.equal('#123458');
});
it('changes model if h3 font color field changes', function() {
view.$('#mailpoet_h3_font_color').val('#123426').change();
expect(model.get('h3.fontColor')).to.equal('#123426');
});
it('changes model if link font color field changes', function() {
view.$('#mailpoet_a_font_color').val('#323232').change();
expect(model.get('link.fontColor')).to.equal('#323232');
});
it('changes model if newsletter background color field changes', function() {
view.$('#mailpoet_newsletter_background_color').val('#636237').change();
expect(model.get('newsletter.backgroundColor')).to.equal('#636237');
});
it('changes model if background color field changes', function() {
view.$('#mailpoet_background_color').val('#878587').change();
expect(model.get('background.backgroundColor')).to.equal('#878587');
});
it('changes model if text font family field changes', function() {
view.$('#mailpoet_text_font_family').val('Times New Roman').change();
expect(model.get('text.fontFamily')).to.equal('Times New Roman');
});
it('changes model if h1 font family field changes', function() {
view.$('#mailpoet_h1_font_family').val('Comic Sans').change();
expect(model.get('h1.fontFamily')).to.equal('Comic Sans');
});
it('changes model if h2 font family field changes', function() {
view.$('#mailpoet_h2_font_family').val('Tahoma').change();
expect(model.get('h2.fontFamily')).to.equal('Tahoma');
});
it('changes model if h3 font family field changes', function() {
view.$('#mailpoet_h3_font_family').val('Lucida').change();
expect(model.get('h3.fontFamily')).to.equal('Lucida');
});
it('changes model if text font size field changes', function() {
view.$('#mailpoet_text_font_size').val('9px').change();
expect(model.get('text.fontSize')).to.equal('9px');
});
it('changes model if h1 font size field changes', function() {
view.$('#mailpoet_h1_font_size').val('12px').change();
expect(model.get('h1.fontSize')).to.equal('12px');
});
it('changes model if h2 font size field changes', function() {
view.$('#mailpoet_h2_font_size').val('14px').change();
expect(model.get('h2.fontSize')).to.equal('14px');
});
it('changes model if h3 font size field changes', function() {
view.$('#mailpoet_h3_font_size').val('16px').change();
expect(model.get('h3.fontSize')).to.equal('16px');
});
it('changes model if link underline field changes', function() {
view.$('#mailpoet_a_font_underline').prop('checked', true).change();
expect(model.get('link.textDecoration')).to.equal('underline');
});
});
}); });
describe('preview view', function() { it('renders', function() {
var view; expect(view.render).to.not.throw();
beforeEach(function() { });
view = new (EditorApplication.module('components.sidebar').SidebarPreviewView)();
describe('once rendered', function() {
var model, availableStyles, view;
before(function() {
model = new Backbone.SuperModel({
text: {
fontColor: '#000000',
fontFamily: 'Arial',
},
h1: {
fontColor: '#000001',
fontFamily: 'Arial',
},
h2: {
fontColor: '#000002',
fontFamily: 'Arial',
},
h3: {
fontColor: '#000003',
fontFamily: 'Arial',
},
link: {
fontColor: '#000005',
textDecoration: 'none',
},
newsletter: {
backgroundColor: '#090909',
},
background: {
backgroundColor: '#020202',
},
});
availableStyles = new Backbone.SuperModel({
fonts: ['Arial', 'Times New Roman', 'Tahoma', 'Comic Sans', 'Lucida'],
textSizes: [
'9px', '10px',
],
headingSizes: [
'10px', '12px', '14px', '16px', '18px',
],
});
view = new (EditorApplication.module('components.sidebar').SidebarStylesView)({
model: model,
availableStyles: availableStyles,
}); });
it('renders', function() { view.render();
expect(view.render).to.not.throw(); });
});
it('changes model if text font color field changes', function() {
view.$('#mailpoet_text_font_color').val('#123456').change();
expect(model.get('text.fontColor')).to.equal('#123456');
});
it('changes model if h1 font color field changes', function() {
view.$('#mailpoet_h1_font_color').val('#123457').change();
expect(model.get('h1.fontColor')).to.equal('#123457');
});
it('changes model if h2 font color field changes', function() {
view.$('#mailpoet_h2_font_color').val('#123458').change();
expect(model.get('h2.fontColor')).to.equal('#123458');
});
it('changes model if h3 font color field changes', function() {
view.$('#mailpoet_h3_font_color').val('#123426').change();
expect(model.get('h3.fontColor')).to.equal('#123426');
});
it('changes model if link font color field changes', function() {
view.$('#mailpoet_a_font_color').val('#323232').change();
expect(model.get('link.fontColor')).to.equal('#323232');
});
it('changes model if newsletter background color field changes', function() {
view.$('#mailpoet_newsletter_background_color').val('#636237').change();
expect(model.get('newsletter.backgroundColor')).to.equal('#636237');
});
it('changes model if background color field changes', function() {
view.$('#mailpoet_background_color').val('#878587').change();
expect(model.get('background.backgroundColor')).to.equal('#878587');
});
it('changes model if text font family field changes', function() {
view.$('#mailpoet_text_font_family').val('Times New Roman').change();
expect(model.get('text.fontFamily')).to.equal('Times New Roman');
});
it('changes model if h1 font family field changes', function() {
view.$('#mailpoet_h1_font_family').val('Comic Sans').change();
expect(model.get('h1.fontFamily')).to.equal('Comic Sans');
});
it('changes model if h2 font family field changes', function() {
view.$('#mailpoet_h2_font_family').val('Tahoma').change();
expect(model.get('h2.fontFamily')).to.equal('Tahoma');
});
it('changes model if h3 font family field changes', function() {
view.$('#mailpoet_h3_font_family').val('Lucida').change();
expect(model.get('h3.fontFamily')).to.equal('Lucida');
});
it('changes model if text font size field changes', function() {
view.$('#mailpoet_text_font_size').val('9px').change();
expect(model.get('text.fontSize')).to.equal('9px');
});
it('changes model if h1 font size field changes', function() {
view.$('#mailpoet_h1_font_size').val('12px').change();
expect(model.get('h1.fontSize')).to.equal('12px');
});
it('changes model if h2 font size field changes', function() {
view.$('#mailpoet_h2_font_size').val('14px').change();
expect(model.get('h2.fontSize')).to.equal('14px');
});
it('changes model if h3 font size field changes', function() {
view.$('#mailpoet_h3_font_size').val('16px').change();
expect(model.get('h3.fontSize')).to.equal('16px');
});
it('changes model if link underline field changes', function() {
view.$('#mailpoet_a_font_underline').prop('checked', true).change();
expect(model.get('link.textDecoration')).to.equal('underline');
});
}); });
});
describe('preview view', function() {
var view;
beforeEach(function() {
view = new (EditorApplication.module('components.sidebar').SidebarPreviewView)();
});
it('renders', function() {
expect(view.render).to.not.throw();
});
});
}); });
}); });

View File

@ -4,43 +4,42 @@ define('test/newsletter_editor/components/config', [
], function(EditorApplication) { ], function(EditorApplication) {
describe('Styles', function () { describe('Styles', function () {
it('loads and stores globally available styles', function() { it('loads and stores globally available styles', function() {
EditorApplication.module('components.styles').setGlobalStyles({ EditorApplication.module('components.styles').setGlobalStyles({
testStyle: 'testValue', testStyle: 'testValue',
}); });
var model = EditorApplication.module('components.styles').getGlobalStyles(); var model = EditorApplication.module('components.styles').getGlobalStyles();
expect(model.get('testStyle')).to.equal('testValue'); expect(model.get('testStyle')).to.equal('testValue');
});
describe('model', function() {
var model;
beforeEach(function() {
model = new (EditorApplication.module('components.styles').StylesModel)();
}); });
describe('model', function() { it('triggers autoSave when changed', function() {
var model; var mock = sinon.mock({ trigger: function(){}}).expects('trigger').once().withExactArgs('autoSave');
beforeEach(function() { EditorApplication.getChannel = function() {
model = new (EditorApplication.module('components.styles').StylesModel)(); return {
}); trigger: mock,
};
};
model.set('text.fontColor', '#123456');
mock.verify();
});
});
it('triggers autoSave when changed', function() { describe('view', function() {
var mock = sinon.mock({ trigger: function(){}}).expects('trigger').once().withExactArgs('autoSave'); var model, view;
EditorApplication.getChannel = function() { beforeEach(function() {
return { model = new (EditorApplication.module('components.styles').StylesModel)();
trigger: mock, view = new (EditorApplication.module('components.styles').StylesView)({ model: model });
};
};
model.set('text.fontColor', '#123456');
mock.verify();
});
}); });
describe('view', function() { it('renders', function() {
var model, view; expect(view.render).to.not.throw();
beforeEach(function() {
model = new (EditorApplication.module('components.styles').StylesModel)();
view = new (EditorApplication.module('components.styles').StylesView)({ model: model });
});
it('renders', function() {
expect(view.render).to.not.throw();
});
}); });
});
}); });
}); });