Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
ai
noblogs-wp
Commits
9d4a0d31
Commit
9d4a0d31
authored
Aug 26, 2017
by
lucha
Browse files
Wordpress 4.8.1
parent
1db6da7d
Changes
51
Expand all
Hide whitespace changes
Inline
Side-by-side
wp-admin/about.php
View file @
9d4a0d31
...
...
@@ -43,6 +43,28 @@ include( ABSPATH . 'wp-admin/admin-header.php' );
<a
href=
"freedoms.php"
class=
"nav-tab"
>
<?php
_e
(
'Freedoms'
);
?>
</a>
</h2>
<div
class=
"changelog point-releases"
>
<h3>
<?php
_e
(
'Maintenance Release'
);
?>
</h3>
<p>
<?php
printf
(
/* translators: 1: WordPress version number, 2: plural number of bugs. */
_n
(
'<strong>Version %1$s</strong> addressed %2$s bug.'
,
'<strong>Version %1$s</strong> addressed %2$s bugs.'
,
29
),
'4.8.1'
,
number_format_i18n
(
29
)
);
?>
<?php
/* translators: %s: Codex URL */
printf
(
__
(
'For more information, see <a href="%s">the release notes</a>.'
),
'https://codex.wordpress.org/Version_4.8.1'
);
?>
</p>
</div>
<div
class=
"feature-section one-col"
>
<div
class=
"col"
>
<h2>
<?php
_e
(
'An Update with You in Mind'
);
?>
</h2>
...
...
wp-admin/css/themes-rtl.css
View file @
9d4a0d31
...
...
@@ -1644,6 +1644,8 @@ body.full-overlay-active {
min-width
:
299px
;
max-width
:
599px
;
width
:
18%
;
width
:
-webkit-calc
(
18%
-
1px
);
width
:
calc
(
18%
-
1px
);
height
:
45px
;
border-top
:
1px
solid
#ddd
;
background
:
#eee
;
...
...
wp-admin/css/themes-rtl.min.css
View file @
9d4a0d31
This diff is collapsed.
Click to expand it.
wp-admin/css/themes.css
View file @
9d4a0d31
...
...
@@ -1644,6 +1644,8 @@ body.full-overlay-active {
min-width
:
299px
;
max-width
:
599px
;
width
:
18%
;
width
:
-webkit-calc
(
18%
-
1px
);
width
:
calc
(
18%
-
1px
);
height
:
45px
;
border-top
:
1px
solid
#ddd
;
background
:
#eee
;
...
...
wp-admin/css/themes.min.css
View file @
9d4a0d31
This diff is collapsed.
Click to expand it.
wp-admin/css/widgets-rtl.css
View file @
9d4a0d31
...
...
@@ -619,6 +619,29 @@ div#widgets-right .widget-top:hover,
cursor
:
move
;
}
/* =Specific widget styling
-------------------------------------------------------------- */
.text-widget-fields
{
position
:
relative
;
}
.text-widget-fields
[
hidden
]
{
display
:
none
;
}
.text-widget-fields
.wp-pointer.wp-pointer-top
{
position
:
absolute
;
z-index
:
3
;
top
:
100px
;
left
:
10px
;
right
:
10px
;
}
.text-widget-fields
.wp-pointer
.wp-pointer-arrow
{
right
:
auto
;
left
:
15px
;
}
.text-widget-fields
.wp-pointer
.wp-pointer-buttons
{
line-height
:
1.4em
;
}
/* =Media Queries
-------------------------------------------------------------- */
...
...
wp-admin/css/widgets-rtl.min.css
View file @
9d4a0d31
This diff is collapsed.
Click to expand it.
wp-admin/css/widgets.css
View file @
9d4a0d31
...
...
@@ -619,6 +619,29 @@ div#widgets-right .widget-top:hover,
cursor
:
move
;
}
/* =Specific widget styling
-------------------------------------------------------------- */
.text-widget-fields
{
position
:
relative
;
}
.text-widget-fields
[
hidden
]
{
display
:
none
;
}
.text-widget-fields
.wp-pointer.wp-pointer-top
{
position
:
absolute
;
z-index
:
3
;
top
:
100px
;
right
:
10px
;
left
:
10px
;
}
.text-widget-fields
.wp-pointer
.wp-pointer-arrow
{
left
:
auto
;
right
:
15px
;
}
.text-widget-fields
.wp-pointer
.wp-pointer-buttons
{
line-height
:
1.4em
;
}
/* =Media Queries
-------------------------------------------------------------- */
...
...
wp-admin/css/widgets.min.css
View file @
9d4a0d31
This diff is collapsed.
Click to expand it.
wp-admin/includes/class-wp-comments-list-table.php
View file @
9d4a0d31
...
...
@@ -319,6 +319,11 @@ class WP_Comments_List_Table extends WP_List_Table {
*/
protected
function
extra_tablenav
(
$which
)
{
global
$comment_status
,
$comment_type
;
static
$has_items
;
if
(
!
isset
(
$has_items
)
)
{
$has_items
=
$this
->
has_items
();
}
?>
<div
class=
"alignleft actions"
>
<?php
...
...
@@ -354,7 +359,7 @@ class WP_Comments_List_Table extends WP_List_Table {
submit_button
(
__
(
'Filter'
),
''
,
'filter_action'
,
false
,
array
(
'id'
=>
'post-query-submit'
)
);
}
if
(
(
'spam'
===
$comment_status
||
'trash'
===
$comment_status
)
&&
current_user_can
(
'moderate_comments'
)
&&
$
this
->
has_items
()
)
{
if
(
(
'spam'
===
$comment_status
||
'trash'
===
$comment_status
)
&&
current_user_can
(
'moderate_comments'
)
&&
$has_items
)
{
wp_nonce_field
(
'bulk-destroy'
,
'_destroy_nonce'
);
$title
=
(
'spam'
===
$comment_status
)
?
esc_attr__
(
'Empty Spam'
)
:
esc_attr__
(
'Empty Trash'
);
submit_button
(
$title
,
'apply'
,
'delete_all'
,
false
);
...
...
wp-admin/includes/options.php
View file @
9d4a0d31
...
...
@@ -100,8 +100,8 @@ jQuery(document).ready(function() {
return
;
jQuery
(
'
#permalink_structure
'
).
val
(
this
.
value
);
});
jQuery
(
'
#permalink_structure
'
).
focus
(
function
()
{
jQuery
(
"
#custom_selection
"
).
attr
(
'
checked
'
,
'
checked
'
);
jQuery
(
'
#permalink_structure
'
).
on
(
'
click input
'
,
function
()
{
jQuery
(
'
#custom_selection
'
).
prop
(
'
checked
'
,
true
);
});
});
</script>
...
...
wp-admin/js/customize-controls.js
View file @
9d4a0d31
...
...
@@ -5507,6 +5507,13 @@
}
);
}
());
// Make sure TinyMCE dialogs appear above Customizer UI.
$
(
document
).
one
(
'
wp-before-tinymce-init
'
,
function
()
{
if
(
!
window
.
tinymce
.
ui
.
FloatPanel
.
zIndex
||
window
.
tinymce
.
ui
.
FloatPanel
.
zIndex
<
500001
)
{
window
.
tinymce
.
ui
.
FloatPanel
.
zIndex
=
500001
;
}
}
);
api
.
trigger
(
'
ready
'
);
});
...
...
wp-admin/js/customize-controls.min.js
View file @
9d4a0d31
This diff is collapsed.
Click to expand it.
wp-admin/js/customize-nav-menus.js
View file @
9d4a0d31
...
...
@@ -2229,8 +2229,7 @@
}
}
);
control
.
container
.
find
(
'
.menu-delete-item
'
).
on
(
'
click
'
,
function
(
event
)
{
event
.
stopPropagation
();
control
.
container
.
find
(
'
.menu-delete-item .button-link-delete
'
).
on
(
'
click
'
,
function
(
event
)
{
event
.
preventDefault
();
control
.
setting
.
set
(
false
);
});
...
...
wp-admin/js/customize-nav-menus.min.js
View file @
9d4a0d31
This diff is collapsed.
Click to expand it.
wp-admin/js/widgets/media-widgets.js
View file @
9d4a0d31
...
...
@@ -184,6 +184,12 @@ wp.mediaWidgets = ( function( $ ) {
return
;
}
// If video, test for Vimeo and YouTube, otherwise, renderFail(). This should be removed once #34115 is resolved.
if
(
'
video
'
===
this
.
controller
.
options
.
mimeType
&&
!
/vimeo|youtu
\.?
be/
.
test
(
urlParser
.
host
)
)
{
embedLinkView
.
renderFail
();
return
;
}
embedLinkView
.
dfd
=
$
.
ajax
({
url
:
wp
.
media
.
view
.
settings
.
oEmbedProxyUrl
,
data
:
{
...
...
@@ -429,7 +435,8 @@ wp.mediaWidgets = ( function( $ ) {
*
* @param {Object} options - Options.
* @param {Backbone.Model} options.model - Model.
* @param {jQuery} options.el - Control container element.
* @param {jQuery} options.el - Control field container element.
* @param {jQuery} options.syncContainer - Container element where fields are synced for the server.
* @returns {void}
*/
initialize
:
function
initialize
(
options
)
{
...
...
@@ -437,12 +444,19 @@ wp.mediaWidgets = ( function( $ ) {
Backbone
.
View
.
prototype
.
initialize
.
call
(
control
,
options
);
if
(
!
control
.
el
)
{
throw
new
Error
(
'
Missing options.el
'
);
}
if
(
!
(
control
.
model
instanceof
component
.
MediaWidgetModel
)
)
{
throw
new
Error
(
'
Missing options.model
'
);
}
if
(
!
options
.
el
)
{
throw
new
Error
(
'
Missing options.el
'
);
}
if
(
!
options
.
syncContainer
)
{
throw
new
Error
(
'
Missing options.syncContainer
'
);
}
control
.
syncContainer
=
options
.
syncContainer
;
control
.
$el
.
addClass
(
'
media-widget-control
'
);
// Allow methods to be passed in with control context preserved.
_
.
bindAll
(
control
,
'
syncModelToInputs
'
,
'
render
'
,
'
updateSelectedAttachment
'
,
'
renderPreview
'
);
...
...
@@ -547,7 +561,7 @@ wp.mediaWidgets = ( function( $ ) {
*/
syncModelToInputs
:
function
syncModelToInputs
()
{
var
control
=
this
;
control
.
$el
.
next
(
'
.widget-content
'
)
.
find
(
'
.media-widget-instance-property
'
).
each
(
function
()
{
control
.
syncContainer
.
find
(
'
.media-widget-instance-property
'
).
each
(
function
()
{
var
input
=
$
(
this
),
value
;
value
=
control
.
model
.
get
(
input
.
data
(
'
property
'
)
);
if
(
_
.
isUndefined
(
value
)
)
{
...
...
@@ -1003,9 +1017,8 @@ wp.mediaWidgets = ( function( $ ) {
* @returns {void}
*/
component
.
handleWidgetAdded
=
function
handleWidgetAdded
(
event
,
widgetContainer
)
{
var
widgetContent
,
control
Container
,
widgetForm
,
idBase
,
ControlConstructor
,
ModelConstructor
,
modelAttributes
,
widgetControl
,
widgetModel
,
widgetId
,
widgetInside
,
animatedCheckDelay
=
50
,
renderWhenAnimationDone
;
var
fieldContainer
,
sync
Container
,
widgetForm
,
idBase
,
ControlConstructor
,
ModelConstructor
,
modelAttributes
,
widgetControl
,
widgetModel
,
widgetId
,
widgetInside
,
animatedCheckDelay
=
50
,
renderWhenAnimationDone
;
widgetForm
=
widgetContainer
.
find
(
'
> .widget-inside > .form, > .widget-inside > form
'
);
// Note: '.form' appears in the customizer, whereas 'form' on the widgets admin screen.
widgetContent
=
widgetForm
.
find
(
'
> .widget-content
'
);
idBase
=
widgetForm
.
find
(
'
> .id_base
'
).
val
();
widgetId
=
widgetForm
.
find
(
'
> .widget-id
'
).
val
();
...
...
@@ -1032,8 +1045,9 @@ wp.mediaWidgets = ( function( $ ) {
* components", the JS template is rendered outside of the normal form
* container.
*/
controlContainer
=
$
(
'
<div class="media-widget-control"></div>
'
);
widgetContent
.
before
(
controlContainer
);
fieldContainer
=
$
(
'
<div></div>
'
);
syncContainer
=
widgetContainer
.
find
(
'
.widget-content:first
'
);
syncContainer
.
before
(
fieldContainer
);
/*
* Sync the widget instance model attributes onto the hidden inputs that widgets currently use to store the state.
...
...
@@ -1041,7 +1055,7 @@ wp.mediaWidgets = ( function( $ ) {
* from the start, without having to sync with hidden fields. See <https://core.trac.wordpress.org/ticket/33507>.
*/
modelAttributes
=
{};
widgetContent
.
find
(
'
.media-widget-instance-property
'
).
each
(
function
()
{
syncContainer
.
find
(
'
.media-widget-instance-property
'
).
each
(
function
()
{
var
input
=
$
(
this
);
modelAttributes
[
input
.
data
(
'
property
'
)
]
=
input
.
val
();
});
...
...
@@ -1050,7 +1064,8 @@ wp.mediaWidgets = ( function( $ ) {
widgetModel
=
new
ModelConstructor
(
modelAttributes
);
widgetControl
=
new
ControlConstructor
({
el
:
controlContainer
,
el
:
fieldContainer
,
syncContainer
:
syncContainer
,
model
:
widgetModel
});
...
...
@@ -1078,6 +1093,51 @@ wp.mediaWidgets = ( function( $ ) {
component
.
widgetControls
[
widgetModel
.
get
(
'
widget_id
'
)
]
=
widgetControl
;
};
/**
* Setup widget in accessibility mode.
*
* @returns {void}
*/
component
.
setupAccessibleMode
=
function
setupAccessibleMode
()
{
var
widgetForm
,
widgetId
,
idBase
,
widgetControl
,
ControlConstructor
,
ModelConstructor
,
modelAttributes
,
fieldContainer
,
syncContainer
;
widgetForm
=
$
(
'
.editwidget > form
'
);
if
(
0
===
widgetForm
.
length
)
{
return
;
}
idBase
=
widgetForm
.
find
(
'
> .widget-control-actions > .id_base
'
).
val
();
ControlConstructor
=
component
.
controlConstructors
[
idBase
];
if
(
!
ControlConstructor
)
{
return
;
}
widgetId
=
widgetForm
.
find
(
'
> .widget-control-actions > .widget-id
'
).
val
();
ModelConstructor
=
component
.
modelConstructors
[
idBase
]
||
component
.
MediaWidgetModel
;
fieldContainer
=
$
(
'
<div></div>
'
);
syncContainer
=
widgetForm
.
find
(
'
> .widget-inside
'
);
syncContainer
.
before
(
fieldContainer
);
modelAttributes
=
{};
syncContainer
.
find
(
'
.media-widget-instance-property
'
).
each
(
function
()
{
var
input
=
$
(
this
);
modelAttributes
[
input
.
data
(
'
property
'
)
]
=
input
.
val
();
});
modelAttributes
.
widget_id
=
widgetId
;
widgetControl
=
new
ControlConstructor
({
el
:
fieldContainer
,
syncContainer
:
syncContainer
,
model
:
new
ModelConstructor
(
modelAttributes
)
});
component
.
modelCollection
.
add
(
[
widgetControl
.
model
]
);
component
.
widgetControls
[
widgetControl
.
model
.
get
(
'
widget_id
'
)
]
=
widgetControl
;
widgetControl
.
render
();
};
/**
* Sync widget instance data sanitized from server back onto widget model.
*
...
...
@@ -1146,6 +1206,11 @@ wp.mediaWidgets = ( function( $ ) {
var
widgetContainer
=
$
(
this
);
component
.
handleWidgetAdded
(
new
jQuery
.
Event
(
'
widget-added
'
),
widgetContainer
);
});
// Accessibility mode.
$
(
window
).
on
(
'
load
'
,
function
()
{
component
.
setupAccessibleMode
();
});
});
};
...
...
wp-admin/js/widgets/media-widgets.min.js
View file @
9d4a0d31
This diff is collapsed.
Click to expand it.
wp-admin/js/widgets/text-widgets.js
View file @
9d4a0d31
...
...
@@ -3,7 +3,9 @@
wp
.
textWidgets
=
(
function
(
$
)
{
'
use strict
'
;
var
component
=
{};
var
component
=
{
dismissedPointers
:
[]
};
/**
* Text widget control.
...
...
@@ -24,9 +26,9 @@ wp.textWidgets = ( function( $ ) {
/**
* Initialize.
*
* @param {Object}
options - Options.
* @param {
Backbone.Model
} options.
mod
el -
Model
.
* @param {jQuery}
options.el - Control container element
.
* @param {Object} options - Options.
* @param {
jQuery
} options.el -
Control field container element
.
* @param {jQuery}
options.syncContainer - Container element where fields are synced for the server
.
* @returns {void}
*/
initialize
:
function
initialize
(
options
)
{
...
...
@@ -35,42 +37,97 @@ wp.textWidgets = ( function( $ ) {
if
(
!
options
.
el
)
{
throw
new
Error
(
'
Missing options.el
'
);
}
if
(
!
options
.
syncContainer
)
{
throw
new
Error
(
'
Missing options.syncContainer
'
);
}
Backbone
.
View
.
prototype
.
initialize
.
call
(
control
,
options
);
control
.
syncContainer
=
options
.
syncContainer
;
control
.
$el
.
addClass
(
'
text-widget-fields
'
);
control
.
$el
.
html
(
wp
.
template
(
'
widget-text-control-fields
'
)
);
control
.
customHtmlWidgetPointer
=
control
.
$el
.
find
(
'
.wp-pointer.custom-html-widget-pointer
'
);
if
(
control
.
customHtmlWidgetPointer
.
length
)
{
control
.
customHtmlWidgetPointer
.
find
(
'
.close
'
).
on
(
'
click
'
,
function
(
event
)
{
event
.
preventDefault
();
control
.
customHtmlWidgetPointer
.
hide
();
$
(
'
#
'
+
control
.
fields
.
text
.
attr
(
'
id
'
)
+
'
-html
'
).
focus
();
control
.
dismissPointers
(
[
'
text_widget_custom_html
'
]
);
});
control
.
customHtmlWidgetPointer
.
find
(
'
.add-widget
'
).
on
(
'
click
'
,
function
(
event
)
{
event
.
preventDefault
();
control
.
customHtmlWidgetPointer
.
hide
();
control
.
openAvailableWidgetsPanel
();
});
}
/*
* Create a container element for the widget control fields.
* This is inserted into the DOM immediately before the the .widget-content
* element because the contents of this element are essentially "managed"
* by PHP, where each widget update cause the entire element to be emptied
* and replaced with the rendered output of WP_Widget::form() which is
* sent back in Ajax request made to save/update the widget instance.
* To prevent a "flash of replaced DOM elements and re-initialized JS
* components", the JS template is rendered outside of the normal form
* container.
*/
control
.
fieldContainer
=
$
(
'
<div class="text-widget-fields"></div>
'
);
control
.
fieldContainer
.
html
(
wp
.
template
(
'
widget-text-control-fields
'
)
);
control
.
widgetContentContainer
=
control
.
$el
.
find
(
'
.widget-content:first
'
);
control
.
widgetContentContainer
.
before
(
control
.
fieldContainer
);
control
.
pasteHtmlPointer
=
control
.
$el
.
find
(
'
.wp-pointer.paste-html-pointer
'
);
if
(
control
.
pasteHtmlPointer
.
length
)
{
control
.
pasteHtmlPointer
.
find
(
'
.close
'
).
on
(
'
click
'
,
function
(
event
)
{
event
.
preventDefault
();
control
.
pasteHtmlPointer
.
hide
();
control
.
editor
.
focus
();
control
.
dismissPointers
(
[
'
text_widget_custom_html
'
,
'
text_widget_paste_html
'
]
);
});
}
control
.
fields
=
{
title
:
control
.
fieldContainer
.
find
(
'
.title
'
),
text
:
control
.
fieldContainer
.
find
(
'
.text
'
)
title
:
control
.
$el
.
find
(
'
.title
'
),
text
:
control
.
$el
.
find
(
'
.text
'
)
};
// Sync input fields to hidden sync fields which actually get sent to the server.
_
.
each
(
control
.
fields
,
function
(
fieldInput
,
fieldName
)
{
fieldInput
.
on
(
'
input change
'
,
function
updateSyncField
()
{
var
syncInput
=
control
.
widgetContent
Container
.
find
(
'
input[type=hidden].
'
+
fieldName
);
if
(
syncInput
.
val
()
!==
$
(
this
)
.
val
()
)
{
syncInput
.
val
(
$
(
this
)
.
val
()
);
var
syncInput
=
control
.
sync
Container
.
find
(
'
input[type=hidden].
'
+
fieldName
);
if
(
syncInput
.
val
()
!==
fieldInput
.
val
()
)
{
syncInput
.
val
(
fieldInput
.
val
()
);
syncInput
.
trigger
(
'
change
'
);
}
});
// Note that syncInput cannot be re-used because it will be destroyed with each widget-updated event.
fieldInput
.
val
(
control
.
widgetContentContainer
.
find
(
'
input[type=hidden].
'
+
fieldName
).
val
()
);
fieldInput
.
val
(
control
.
syncContainer
.
find
(
'
input[type=hidden].
'
+
fieldName
).
val
()
);
});
},
/**
* Dismiss pointers for Custom HTML widget.
*
* @since 4.8.1
*
* @param {Array} pointers Pointer IDs to dismiss.
* @returns {void}
*/
dismissPointers
:
function
dismissPointers
(
pointers
)
{
_
.
each
(
pointers
,
function
(
pointer
)
{
wp
.
ajax
.
post
(
'
dismiss-wp-pointer
'
,
{
pointer
:
pointer
});
component
.
dismissedPointers
.
push
(
pointer
);
});
},
/**
* Open available widgets panel.
*
* @since 4.8.1
* @returns {void}
*/
openAvailableWidgetsPanel
:
function
openAvailableWidgetsPanel
()
{
var
sidebarControl
;
wp
.
customize
.
section
.
each
(
function
(
section
)
{
if
(
section
.
extended
(
wp
.
customize
.
Widgets
.
SidebarSection
)
&&
section
.
expanded
()
)
{
sidebarControl
=
wp
.
customize
.
control
(
'
sidebars_widgets[
'
+
section
.
params
.
sidebarId
+
'
]
'
);
}
});
if
(
!
sidebarControl
)
{
return
;
}
setTimeout
(
function
()
{
// Timeout to prevent click event from causing panel to immediately collapse.
wp
.
customize
.
Widgets
.
availableWidgetsPanel
.
open
(
sidebarControl
);
wp
.
customize
.
Widgets
.
availableWidgetsPanel
.
$search
.
val
(
'
HTML
'
).
trigger
(
'
keyup
'
);
});
},
...
...
@@ -87,11 +144,11 @@ wp.textWidgets = ( function( $ ) {
var
control
=
this
,
syncInput
;
if
(
!
control
.
fields
.
title
.
is
(
document
.
activeElement
)
)
{
syncInput
=
control
.
widgetContent
Container
.
find
(
'
input[type=hidden].title
'
);
syncInput
=
control
.
sync
Container
.
find
(
'
input[type=hidden].title
'
);
control
.
fields
.
title
.
val
(
syncInput
.
val
()
);
}
syncInput
=
control
.
widgetContent
Container
.
find
(
'
input[type=hidden].text
'
);
syncInput
=
control
.
sync
Container
.
find
(
'
input[type=hidden].text
'
);
if
(
control
.
fields
.
text
.
is
(
'
:visible
'
)
)
{
if
(
!
control
.
fields
.
text
.
is
(
document
.
activeElement
)
)
{
control
.
fields
.
text
.
val
(
syncInput
.
val
()
);
...
...
@@ -107,23 +164,77 @@ wp.textWidgets = ( function( $ ) {
* @returns {void}
*/
initializeEditor
:
function
initializeEditor
()
{
var
control
=
this
,
changeDebounceDelay
=
1000
,
id
,
textarea
,
restoreTextMode
=
false
;
var
control
=
this
,
changeDebounceDelay
=
1000
,
id
,
textarea
,
triggerChangeIfDirty
,
restoreTextMode
=
false
,
needsTextareaChangeTrigger
=
false
;
textarea
=
control
.
fields
.
text
;
id
=
textarea
.
attr
(
'
id
'
);
/**
* Trigger change if dirty.
*
* @returns {void}
*/
triggerChangeIfDirty
=
function
()
{
var
updateWidgetBuffer
=
300
;
// See wp.customize.Widgets.WidgetControl._setupUpdateUI() which uses 250ms for updateWidgetDebounced.
if
(
control
.
editor
.
isDirty
()
)
{
/*
* Account for race condition in customizer where user clicks Save & Publish while
* focus was just previously given to to the editor. Since updates to the editor
* are debounced at 1 second and since widget input changes are only synced to
* settings after 250ms, the customizer needs to be put into the processing
* state during the time between the change event is triggered and updateWidget
* logic starts. Note that the debounced update-widget request should be able
* to be removed with the removal of the update-widget request entirely once
* widgets are able to mutate their own instance props directly in JS without
* having to make server round-trips to call the respective WP_Widget::update()
* callbacks. See <https://core.trac.wordpress.org/ticket/33507>.
*/
if
(
wp
.
customize
&&
wp
.
customize
.
state
)
{
wp
.
customize
.
state
(
'
processing
'
).
set
(
wp
.
customize
.
state
(
'
processing
'
).
get
()
+
1
);
_
.
delay
(
function
()
{
wp
.
customize
.
state
(
'
processing
'
).
set
(
wp
.
customize
.
state
(
'
processing
'
).
get
()
-
1
);
},
updateWidgetBuffer
);
}
if
(
!
control
.
editor
.
isHidden
()
)
{
control
.
editor
.
save
();
}
}
// Trigger change on textarea when it is dirty for sake of widgets in the Customizer needing to sync form inputs to setting models.
if
(
needsTextareaChangeTrigger
)
{
textarea
.
trigger
(
'
change
'
);
needsTextareaChangeTrigger
=
false
;
}
};
// Just-in-time force-update the hidden input fields.
control
.
syncContainer
.
closest
(
'
.widget
'
).
find
(
'
[name=savewidget]:first
'
).
on
(
'
click
'
,
function
onClickSaveButton
()
{
triggerChangeIfDirty
();
});
/**
* Build (or re-build) the visual editor.
*
* @returns {void}
*/
function
buildEditor
()
{
var
editor
,
triggerChangeIfDirty
,
onIni
t
;
var
editor
,
onInit
,
showPointerElemen
t
;
// Abort building if the textarea is gone, likely due to the widget having been deleted entirely.
if
(
!
document
.
getElementById
(
id
)
)
{
return
;
}
// The user has disabled TinyMCE.
if
(
typeof
window
.
tinymce
===
'
undefined
'
)
{
wp
.
editor
.
initialize
(
id
,
{
quicktags
:
true
});
return
;
}
// Destroy any existing editor so that it can be re-initialized after a widget-updated event.
if
(
tinymce
.
get
(
id
)
)
{
restoreTextMode
=
tinymce
.
get
(
id
).
isHidden
();
...
...
@@ -137,6 +248,20 @@ wp.textWidgets = ( function( $ ) {
quicktags
:
true
});
/**
* Show a pointer, focus on dismiss, and speak the contents for a11y.
*
* @param {jQuery} pointerElement Pointer element.
* @returns {void}
*/
showPointerElement
=
function
(
pointerElement
)
{
pointerElement
.
show
();
pointerElement
.
find
(
'
.close
'
).
focus
();
wp
.
a11y
.
speak
(
pointerElement
.
find
(
'
h3, p
'
).
map
(
function
()
{
return
$
(
this
).
text
();
}
).
get
().
join
(
'
\n\n
'
)
);
};
editor
=
window
.
tinymce
.
get
(
id
);
if
(
!
editor
)
{
throw
new
Error
(
'
Failed to initialize editor
'
);
...
...
@@ -150,8 +275,36 @@ wp.textWidgets = ( function( $ ) {
// If a prior mce instance was replaced, and it was in text mode, toggle to text mode.