Once upon a midnight dreary, while I coded, weak and weary,
In many a strange and curious file of forgotten lore—
While I pondered, blaming Nacin, my notifications suddenly awakened,
As of someone quietly DMing;—DMing me, I can’t ignore.
“’Tis some contributor,” I muttered, “DMing me an idea or four—
Only this and nothing more.”
Ah, distinctly I remember, at WordCamp US, last December;
A mad proposal nearly laid me—down out cold—upon the floor.
Curious, I listened closely;—to a plan I agreed with, mostly—
A way to make our JavaScript—JavaScript which was a chore—
Maintainable, extendable, for the future, is what I saw.
Guten-ready for evermore.
Open here I switch to Slack, when, with many a patch and hack,
In there stepped Omar, a JavaScript developer hardcore;
Pronouncing all the changes fit; ready now to be commit;
“There’s nothing else for us to do,” DMing me, “It’s done!” he swore—
“No longer random guessing at which file need next be explored—
Let’s move on, we’re all aboard.”
Moved all together, grouped and managed, in folders all is packaged,
The code had all been cleaned and tidied, important parts moved to the fore,
“Though this change be useful here,” I said, “it is too large, I fear,
We couldn’t manage such a patch, we’ve done nothing like this before—
Tell me where doth go this change, change to make our codebase soar!”
Quoth Omar, “In WordPress Core.”
Props omarreis for shepherding this significant change.
Props adamsilverstein, aduth, atimmer, dingo_bastard, frank-klein, gziolo, herregroen, jaswrks, jeremyfelt, jipmoors, jorbin, netweb, ocean90, pento, tjnowell, and youknowriad for testing, feedback, discussion, encouragement, commiserations, etc.
I make no apologies for this commit message.
Fixes #43055.
git-svn-id: https://develop.svn.wordpress.org/trunk@43309 602fd350-edb4-49c9-b593-d223f7449a82
@@ -0,0 +1,97 @@
|
||||
/* global postboxes, commentL10n */
|
||||
|
||||
/**
|
||||
* Binds to the document ready event.
|
||||
*
|
||||
* @since 2.5.0
|
||||
*
|
||||
* @param {jQuery} $ The jQuery object.
|
||||
*/
|
||||
jQuery(document).ready( function($) {
|
||||
|
||||
postboxes.add_postbox_toggles('comment');
|
||||
|
||||
var $timestampdiv = $('#timestampdiv'),
|
||||
$timestamp = $( '#timestamp' ),
|
||||
stamp = $timestamp.html(),
|
||||
$timestampwrap = $timestampdiv.find( '.timestamp-wrap' ),
|
||||
$edittimestamp = $timestampdiv.siblings( 'a.edit-timestamp' );
|
||||
|
||||
/**
|
||||
* Adds event that opens the time stamp form if the form is hidden.
|
||||
*
|
||||
* @listens $edittimestamp:click
|
||||
*
|
||||
* @param {Event} event The event object.
|
||||
* @returns {void}
|
||||
*/
|
||||
$edittimestamp.click( function( event ) {
|
||||
if ( $timestampdiv.is( ':hidden' ) ) {
|
||||
// Slide down the form and set focus on the first field.
|
||||
$timestampdiv.slideDown( 'fast', function() {
|
||||
$( 'input, select', $timestampwrap ).first().focus();
|
||||
} );
|
||||
$(this).hide();
|
||||
}
|
||||
event.preventDefault();
|
||||
});
|
||||
|
||||
/**
|
||||
* Resets the time stamp values when the cancel button is clicked.
|
||||
*
|
||||
* @listens .cancel-timestamp:click
|
||||
*
|
||||
* @param {Event} event The event object.
|
||||
* @returns {void}
|
||||
*/
|
||||
|
||||
$timestampdiv.find('.cancel-timestamp').click( function( event ) {
|
||||
// Move focus back to the Edit link.
|
||||
$edittimestamp.show().focus();
|
||||
$timestampdiv.slideUp( 'fast' );
|
||||
$('#mm').val($('#hidden_mm').val());
|
||||
$('#jj').val($('#hidden_jj').val());
|
||||
$('#aa').val($('#hidden_aa').val());
|
||||
$('#hh').val($('#hidden_hh').val());
|
||||
$('#mn').val($('#hidden_mn').val());
|
||||
$timestamp.html( stamp );
|
||||
event.preventDefault();
|
||||
});
|
||||
|
||||
/**
|
||||
* Sets the time stamp values when the ok button is clicked.
|
||||
*
|
||||
* @listens .save-timestamp:click
|
||||
*
|
||||
* @param {Event} event The event object.
|
||||
* @returns {void}
|
||||
*/
|
||||
$timestampdiv.find('.save-timestamp').click( function( event ) { // crazyhorse - multiple ok cancels
|
||||
var aa = $('#aa').val(), mm = $('#mm').val(), jj = $('#jj').val(), hh = $('#hh').val(), mn = $('#mn').val(),
|
||||
newD = new Date( aa, mm - 1, jj, hh, mn );
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
if ( newD.getFullYear() != aa || (1 + newD.getMonth()) != mm || newD.getDate() != jj || newD.getMinutes() != mn ) {
|
||||
$timestampwrap.addClass( 'form-invalid' );
|
||||
return;
|
||||
} else {
|
||||
$timestampwrap.removeClass( 'form-invalid' );
|
||||
}
|
||||
|
||||
$timestamp.html(
|
||||
commentL10n.submittedOn + ' <b>' +
|
||||
commentL10n.dateFormat
|
||||
.replace( '%1$s', $( 'option[value="' + mm + '"]', '#mm' ).attr( 'data-text' ) )
|
||||
.replace( '%2$s', parseInt( jj, 10 ) )
|
||||
.replace( '%3$s', aa )
|
||||
.replace( '%4$s', ( '00' + hh ).slice( -2 ) )
|
||||
.replace( '%5$s', ( '00' + mn ).slice( -2 ) ) +
|
||||
'</b> '
|
||||
);
|
||||
|
||||
// Move focus back to the Edit link.
|
||||
$edittimestamp.show().focus();
|
||||
$timestampdiv.slideUp( 'fast' );
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,141 @@
|
||||
/* global ajaxurl */
|
||||
|
||||
/**
|
||||
* Registers all events for customizing the background.
|
||||
*
|
||||
* @since 3.0.0
|
||||
*
|
||||
* @requires jQuery
|
||||
*/
|
||||
(function($) {
|
||||
$(document).ready(function() {
|
||||
var frame,
|
||||
bgImage = $( '#custom-background-image' );
|
||||
|
||||
/**
|
||||
* Instantiates the WordPress color picker and binds the change and clear events.
|
||||
*
|
||||
* @since 3.5.0
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
$('#background-color').wpColorPicker({
|
||||
change: function( event, ui ) {
|
||||
bgImage.css('background-color', ui.color.toString());
|
||||
},
|
||||
clear: function() {
|
||||
bgImage.css('background-color', '');
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Alters the background size CSS property whenever the background size input has changed.
|
||||
*
|
||||
* @since 4.7.0
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
$( 'select[name="background-size"]' ).change( function() {
|
||||
bgImage.css( 'background-size', $( this ).val() );
|
||||
});
|
||||
|
||||
/**
|
||||
* Alters the background position CSS property whenever the background position input has changed.
|
||||
*
|
||||
* @since 4.7.0
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
$( 'input[name="background-position"]' ).change( function() {
|
||||
bgImage.css( 'background-position', $( this ).val() );
|
||||
});
|
||||
|
||||
/**
|
||||
* Alters the background repeat CSS property whenever the background repeat input has changed.
|
||||
*
|
||||
* @since 3.0.0
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
$( 'input[name="background-repeat"]' ).change( function() {
|
||||
bgImage.css( 'background-repeat', $( this ).is( ':checked' ) ? 'repeat' : 'no-repeat' );
|
||||
});
|
||||
|
||||
/**
|
||||
* Alters the background attachment CSS property whenever the background attachment input has changed.
|
||||
*
|
||||
* @since 4.7.0
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
$( 'input[name="background-attachment"]' ).change( function() {
|
||||
bgImage.css( 'background-attachment', $( this ).is( ':checked' ) ? 'scroll' : 'fixed' );
|
||||
});
|
||||
|
||||
/**
|
||||
* Binds the event for opening the WP Media dialog.
|
||||
*
|
||||
* @since 3.5.0
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
$('#choose-from-library-link').click( function( event ) {
|
||||
var $el = $(this);
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
// If the media frame already exists, reopen it.
|
||||
if ( frame ) {
|
||||
frame.open();
|
||||
return;
|
||||
}
|
||||
|
||||
// Create the media frame.
|
||||
frame = wp.media.frames.customBackground = wp.media({
|
||||
// Set the title of the modal.
|
||||
title: $el.data('choose'),
|
||||
|
||||
// Tell the modal to show only images.
|
||||
library: {
|
||||
type: 'image'
|
||||
},
|
||||
|
||||
// Customize the submit button.
|
||||
button: {
|
||||
// Set the text of the button.
|
||||
text: $el.data('update'),
|
||||
/*
|
||||
* Tell the button not to close the modal, since we're
|
||||
* going to refresh the page when the image is selected.
|
||||
*/
|
||||
close: false
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* When an image is selected, run a callback.
|
||||
*
|
||||
* @since 3.5.0
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
frame.on( 'select', function() {
|
||||
// Grab the selected attachment.
|
||||
var attachment = frame.state().get('selection').first();
|
||||
|
||||
// Run an AJAX request to set the background image.
|
||||
$.post( ajaxurl, {
|
||||
action: 'set-background-image',
|
||||
attachment_id: attachment.id,
|
||||
size: 'full'
|
||||
}).done( function() {
|
||||
// When the request completes, reload the window.
|
||||
window.location.reload();
|
||||
});
|
||||
});
|
||||
|
||||
// Finally, open the modal.
|
||||
frame.open();
|
||||
});
|
||||
});
|
||||
})(jQuery);
|
||||
@@ -0,0 +1,84 @@
|
||||
/* global isRtl */
|
||||
|
||||
/**
|
||||
* Initializes the custom header selection page.
|
||||
*
|
||||
* @since 3.5.0
|
||||
*
|
||||
* @deprecated 4.1.0 The page this is used on is never linked to from the UI.
|
||||
* Setting a custom header is completely handled by the Customizer.
|
||||
*/
|
||||
(function($) {
|
||||
var frame;
|
||||
|
||||
$( function() {
|
||||
// Fetch available headers.
|
||||
var $headers = $('.available-headers');
|
||||
|
||||
// Apply jQuery.masonry once the images have loaded.
|
||||
$headers.imagesLoaded( function() {
|
||||
$headers.masonry({
|
||||
itemSelector: '.default-header',
|
||||
isRTL: !! ( 'undefined' != typeof isRtl && isRtl )
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Opens the 'choose from library' frame and creates it if it doesn't exist.
|
||||
*
|
||||
* @since 3.5.0
|
||||
* @deprecated 4.1.0
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
$('#choose-from-library-link').click( function( event ) {
|
||||
var $el = $(this);
|
||||
event.preventDefault();
|
||||
|
||||
// If the media frame already exists, reopen it.
|
||||
if ( frame ) {
|
||||
frame.open();
|
||||
return;
|
||||
}
|
||||
|
||||
// Create the media frame.
|
||||
frame = wp.media.frames.customHeader = wp.media({
|
||||
// Set the title of the modal.
|
||||
title: $el.data('choose'),
|
||||
|
||||
// Tell the modal to show only images.
|
||||
library: {
|
||||
type: 'image'
|
||||
},
|
||||
|
||||
// Customize the submit button.
|
||||
button: {
|
||||
// Set the text of the button.
|
||||
text: $el.data('update'),
|
||||
// Tell the button not to close the modal, since we're
|
||||
// going to refresh the page when the image is selected.
|
||||
close: false
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Updates the window location to include the selected attachment.
|
||||
*
|
||||
* @since 3.5.0
|
||||
* @deprecated 4.1.0
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
frame.on( 'select', function() {
|
||||
// Grab the selected attachment.
|
||||
var attachment = frame.state().get('selection').first(),
|
||||
link = $el.data('updateLink');
|
||||
|
||||
// Tell the browser to navigate to the crop step.
|
||||
window.location = link + '&file=' + attachment.id;
|
||||
});
|
||||
|
||||
frame.open();
|
||||
});
|
||||
});
|
||||
}(jQuery));
|
||||
@@ -0,0 +1,998 @@
|
||||
/* global adminCommentsL10n, thousandsSeparator, list_args, QTags, ajaxurl, wpAjax */
|
||||
var setCommentsList, theList, theExtraList, commentReply;
|
||||
|
||||
(function($) {
|
||||
var getCount, updateCount, updateCountText, updatePending, updateApproved,
|
||||
updateHtmlTitle, updateDashboardText, adminTitle = document.title,
|
||||
isDashboard = $('#dashboard_right_now').length,
|
||||
titleDiv, titleRegEx;
|
||||
|
||||
getCount = function(el) {
|
||||
var n = parseInt( el.html().replace(/[^0-9]+/g, ''), 10 );
|
||||
if ( isNaN(n) ) {
|
||||
return 0;
|
||||
}
|
||||
return n;
|
||||
};
|
||||
|
||||
updateCount = function(el, n) {
|
||||
var n1 = '';
|
||||
if ( isNaN(n) ) {
|
||||
return;
|
||||
}
|
||||
n = n < 1 ? '0' : n.toString();
|
||||
if ( n.length > 3 ) {
|
||||
while ( n.length > 3 ) {
|
||||
n1 = thousandsSeparator + n.substr(n.length - 3) + n1;
|
||||
n = n.substr(0, n.length - 3);
|
||||
}
|
||||
n = n + n1;
|
||||
}
|
||||
el.html(n);
|
||||
};
|
||||
|
||||
updateApproved = function( diff, commentPostId ) {
|
||||
var postSelector = '.post-com-count-' + commentPostId,
|
||||
noClass = 'comment-count-no-comments',
|
||||
approvedClass = 'comment-count-approved',
|
||||
approved,
|
||||
noComments;
|
||||
|
||||
updateCountText( 'span.approved-count', diff );
|
||||
|
||||
if ( ! commentPostId ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// cache selectors to not get dupes
|
||||
approved = $( 'span.' + approvedClass, postSelector );
|
||||
noComments = $( 'span.' + noClass, postSelector );
|
||||
|
||||
approved.each(function() {
|
||||
var a = $(this), n = getCount(a) + diff;
|
||||
if ( n < 1 )
|
||||
n = 0;
|
||||
|
||||
if ( 0 === n ) {
|
||||
a.removeClass( approvedClass ).addClass( noClass );
|
||||
} else {
|
||||
a.addClass( approvedClass ).removeClass( noClass );
|
||||
}
|
||||
updateCount( a, n );
|
||||
});
|
||||
|
||||
noComments.each(function() {
|
||||
var a = $(this);
|
||||
if ( diff > 0 ) {
|
||||
a.removeClass( noClass ).addClass( approvedClass );
|
||||
} else {
|
||||
a.addClass( noClass ).removeClass( approvedClass );
|
||||
}
|
||||
updateCount( a, diff );
|
||||
});
|
||||
};
|
||||
|
||||
updateCountText = function( selector, diff ) {
|
||||
$( selector ).each(function() {
|
||||
var a = $(this), n = getCount(a) + diff;
|
||||
if ( n < 1 ) {
|
||||
n = 0;
|
||||
}
|
||||
updateCount( a, n );
|
||||
});
|
||||
};
|
||||
|
||||
updateDashboardText = function ( response ) {
|
||||
if ( ! isDashboard || ! response || ! response.i18n_comments_text ) {
|
||||
return;
|
||||
}
|
||||
|
||||
var rightNow = $( '#dashboard_right_now' );
|
||||
|
||||
$( '.comment-count a', rightNow ).text( response.i18n_comments_text );
|
||||
$( '.comment-mod-count a', rightNow ).text( response.i18n_moderation_text )
|
||||
.parent()
|
||||
[ response.in_moderation > 0 ? 'removeClass' : 'addClass' ]( 'hidden' );
|
||||
};
|
||||
|
||||
updateHtmlTitle = function ( diff ) {
|
||||
var newTitle, regExMatch, titleCount, commentFrag;
|
||||
|
||||
titleRegEx = titleRegEx || new RegExp( adminCommentsL10n.docTitleCommentsCount.replace( '%s', '\\([0-9' + thousandsSeparator + ']+\\)' ) + '?' );
|
||||
// count funcs operate on a $'d element
|
||||
titleDiv = titleDiv || $( '<div />' );
|
||||
newTitle = adminTitle;
|
||||
|
||||
commentFrag = titleRegEx.exec( document.title );
|
||||
if ( commentFrag ) {
|
||||
commentFrag = commentFrag[0];
|
||||
titleDiv.html( commentFrag );
|
||||
titleCount = getCount( titleDiv ) + diff;
|
||||
} else {
|
||||
titleDiv.html( 0 );
|
||||
titleCount = diff;
|
||||
}
|
||||
|
||||
if ( titleCount >= 1 ) {
|
||||
updateCount( titleDiv, titleCount );
|
||||
regExMatch = titleRegEx.exec( document.title );
|
||||
if ( regExMatch ) {
|
||||
newTitle = document.title.replace( regExMatch[0], adminCommentsL10n.docTitleCommentsCount.replace( '%s', titleDiv.text() ) + ' ' );
|
||||
}
|
||||
} else {
|
||||
regExMatch = titleRegEx.exec( newTitle );
|
||||
if ( regExMatch ) {
|
||||
newTitle = newTitle.replace( regExMatch[0], adminCommentsL10n.docTitleComments );
|
||||
}
|
||||
}
|
||||
document.title = newTitle;
|
||||
};
|
||||
|
||||
updatePending = function( diff, commentPostId ) {
|
||||
var postSelector = '.post-com-count-' + commentPostId,
|
||||
noClass = 'comment-count-no-pending',
|
||||
noParentClass = 'post-com-count-no-pending',
|
||||
pendingClass = 'comment-count-pending',
|
||||
pending,
|
||||
noPending;
|
||||
|
||||
if ( ! isDashboard ) {
|
||||
updateHtmlTitle( diff );
|
||||
}
|
||||
|
||||
$( 'span.pending-count' ).each(function() {
|
||||
var a = $(this), n = getCount(a) + diff;
|
||||
if ( n < 1 )
|
||||
n = 0;
|
||||
a.closest('.awaiting-mod')[ 0 === n ? 'addClass' : 'removeClass' ]('count-0');
|
||||
updateCount( a, n );
|
||||
});
|
||||
|
||||
if ( ! commentPostId ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// cache selectors to not get dupes
|
||||
pending = $( 'span.' + pendingClass, postSelector );
|
||||
noPending = $( 'span.' + noClass, postSelector );
|
||||
|
||||
pending.each(function() {
|
||||
var a = $(this), n = getCount(a) + diff;
|
||||
if ( n < 1 )
|
||||
n = 0;
|
||||
|
||||
if ( 0 === n ) {
|
||||
a.parent().addClass( noParentClass );
|
||||
a.removeClass( pendingClass ).addClass( noClass );
|
||||
} else {
|
||||
a.parent().removeClass( noParentClass );
|
||||
a.addClass( pendingClass ).removeClass( noClass );
|
||||
}
|
||||
updateCount( a, n );
|
||||
});
|
||||
|
||||
noPending.each(function() {
|
||||
var a = $(this);
|
||||
if ( diff > 0 ) {
|
||||
a.parent().removeClass( noParentClass );
|
||||
a.removeClass( noClass ).addClass( pendingClass );
|
||||
} else {
|
||||
a.parent().addClass( noParentClass );
|
||||
a.addClass( noClass ).removeClass( pendingClass );
|
||||
}
|
||||
updateCount( a, diff );
|
||||
});
|
||||
};
|
||||
|
||||
setCommentsList = function() {
|
||||
var totalInput, perPageInput, pageInput, dimAfter, delBefore, updateTotalCount, delAfter, refillTheExtraList, diff,
|
||||
lastConfidentTime = 0;
|
||||
|
||||
totalInput = $('input[name="_total"]', '#comments-form');
|
||||
perPageInput = $('input[name="_per_page"]', '#comments-form');
|
||||
pageInput = $('input[name="_page"]', '#comments-form');
|
||||
|
||||
// Updates the current total (stored in the _total input)
|
||||
updateTotalCount = function( total, time, setConfidentTime ) {
|
||||
if ( time < lastConfidentTime )
|
||||
return;
|
||||
|
||||
if ( setConfidentTime )
|
||||
lastConfidentTime = time;
|
||||
|
||||
totalInput.val( total.toString() );
|
||||
};
|
||||
|
||||
// this fires when viewing "All"
|
||||
dimAfter = function( r, settings ) {
|
||||
var editRow, replyID, replyButton, response,
|
||||
c = $( '#' + settings.element );
|
||||
|
||||
if ( true !== settings.parsed ) {
|
||||
response = settings.parsed.responses[0];
|
||||
}
|
||||
|
||||
editRow = $('#replyrow');
|
||||
replyID = $('#comment_ID', editRow).val();
|
||||
replyButton = $('#replybtn', editRow);
|
||||
|
||||
if ( c.is('.unapproved') ) {
|
||||
if ( settings.data.id == replyID )
|
||||
replyButton.text(adminCommentsL10n.replyApprove);
|
||||
|
||||
c.find( '.row-actions span.view' ).addClass( 'hidden' ).end()
|
||||
.find( 'div.comment_status' ).html( '0' );
|
||||
|
||||
} else {
|
||||
if ( settings.data.id == replyID )
|
||||
replyButton.text(adminCommentsL10n.reply);
|
||||
|
||||
c.find( '.row-actions span.view' ).removeClass( 'hidden' ).end()
|
||||
.find( 'div.comment_status' ).html( '1' );
|
||||
}
|
||||
|
||||
diff = $('#' + settings.element).is('.' + settings.dimClass) ? 1 : -1;
|
||||
if ( response ) {
|
||||
updateDashboardText( response.supplemental );
|
||||
updatePending( diff, response.supplemental.postId );
|
||||
updateApproved( -1 * diff, response.supplemental.postId );
|
||||
} else {
|
||||
updatePending( diff );
|
||||
updateApproved( -1 * diff );
|
||||
}
|
||||
};
|
||||
|
||||
// Send current total, page, per_page and url
|
||||
delBefore = function( settings, list ) {
|
||||
var note, id, el, n, h, a, author,
|
||||
action = false,
|
||||
wpListsData = $( settings.target ).attr( 'data-wp-lists' );
|
||||
|
||||
settings.data._total = totalInput.val() || 0;
|
||||
settings.data._per_page = perPageInput.val() || 0;
|
||||
settings.data._page = pageInput.val() || 0;
|
||||
settings.data._url = document.location.href;
|
||||
settings.data.comment_status = $('input[name="comment_status"]', '#comments-form').val();
|
||||
|
||||
if ( wpListsData.indexOf(':trash=1') != -1 )
|
||||
action = 'trash';
|
||||
else if ( wpListsData.indexOf(':spam=1') != -1 )
|
||||
action = 'spam';
|
||||
|
||||
if ( action ) {
|
||||
id = wpListsData.replace(/.*?comment-([0-9]+).*/, '$1');
|
||||
el = $('#comment-' + id);
|
||||
note = $('#' + action + '-undo-holder').html();
|
||||
|
||||
el.find('.check-column :checkbox').prop('checked', false); // Uncheck the row so as not to be affected by Bulk Edits.
|
||||
|
||||
if ( el.siblings('#replyrow').length && commentReply.cid == id )
|
||||
commentReply.close();
|
||||
|
||||
if ( el.is('tr') ) {
|
||||
n = el.children(':visible').length;
|
||||
author = $('.author strong', el).text();
|
||||
h = $('<tr id="undo-' + id + '" class="undo un' + action + '" style="display:none;"><td colspan="' + n + '">' + note + '</td></tr>');
|
||||
} else {
|
||||
author = $('.comment-author', el).text();
|
||||
h = $('<div id="undo-' + id + '" style="display:none;" class="undo un' + action + '">' + note + '</div>');
|
||||
}
|
||||
|
||||
el.before(h);
|
||||
|
||||
$('strong', '#undo-' + id).text(author);
|
||||
a = $('.undo a', '#undo-' + id);
|
||||
a.attr('href', 'comment.php?action=un' + action + 'comment&c=' + id + '&_wpnonce=' + settings.data._ajax_nonce);
|
||||
a.attr('data-wp-lists', 'delete:the-comment-list:comment-' + id + '::un' + action + '=1');
|
||||
a.attr('class', 'vim-z vim-destructive');
|
||||
$('.avatar', el).first().clone().prependTo('#undo-' + id + ' .' + action + '-undo-inside');
|
||||
|
||||
a.click(function( e ){
|
||||
e.preventDefault();
|
||||
e.stopPropagation(); // ticket #35904
|
||||
list.wpList.del(this);
|
||||
$('#undo-' + id).css( {backgroundColor:'#ceb'} ).fadeOut(350, function(){
|
||||
$(this).remove();
|
||||
$('#comment-' + id).css('backgroundColor', '').fadeIn(300, function(){ $(this).show(); });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return settings;
|
||||
};
|
||||
|
||||
// In admin-ajax.php, we send back the unix time stamp instead of 1 on success
|
||||
delAfter = function( r, settings ) {
|
||||
var total_items_i18n, total, animated, animatedCallback,
|
||||
response = true === settings.parsed ? {} : settings.parsed.responses[0],
|
||||
commentStatus = true === settings.parsed ? '' : response.supplemental.status,
|
||||
commentPostId = true === settings.parsed ? '' : response.supplemental.postId,
|
||||
newTotal = true === settings.parsed ? '' : response.supplemental,
|
||||
|
||||
targetParent = $( settings.target ).parent(),
|
||||
commentRow = $('#' + settings.element),
|
||||
|
||||
spamDiff, trashDiff, pendingDiff, approvedDiff,
|
||||
|
||||
approved = commentRow.hasClass( 'approved' ),
|
||||
unapproved = commentRow.hasClass( 'unapproved' ),
|
||||
spammed = commentRow.hasClass( 'spam' ),
|
||||
trashed = commentRow.hasClass( 'trash' ),
|
||||
undoing = false; // ticket #35904
|
||||
|
||||
updateDashboardText( newTotal );
|
||||
|
||||
// the order of these checks is important
|
||||
// .unspam can also have .approve or .unapprove
|
||||
// .untrash can also have .approve or .unapprove
|
||||
|
||||
if ( targetParent.is( 'span.undo' ) ) {
|
||||
// the comment was spammed
|
||||
if ( targetParent.hasClass( 'unspam' ) ) {
|
||||
spamDiff = -1;
|
||||
|
||||
if ( 'trash' === commentStatus ) {
|
||||
trashDiff = 1;
|
||||
} else if ( '1' === commentStatus ) {
|
||||
approvedDiff = 1;
|
||||
} else if ( '0' === commentStatus ) {
|
||||
pendingDiff = 1;
|
||||
}
|
||||
|
||||
// the comment was trashed
|
||||
} else if ( targetParent.hasClass( 'untrash' ) ) {
|
||||
trashDiff = -1;
|
||||
|
||||
if ( 'spam' === commentStatus ) {
|
||||
spamDiff = 1;
|
||||
} else if ( '1' === commentStatus ) {
|
||||
approvedDiff = 1;
|
||||
} else if ( '0' === commentStatus ) {
|
||||
pendingDiff = 1;
|
||||
}
|
||||
}
|
||||
|
||||
undoing = true;
|
||||
|
||||
// user clicked "Spam"
|
||||
} else if ( targetParent.is( 'span.spam' ) ) {
|
||||
// the comment is currently approved
|
||||
if ( approved ) {
|
||||
approvedDiff = -1;
|
||||
// the comment is currently pending
|
||||
} else if ( unapproved ) {
|
||||
pendingDiff = -1;
|
||||
// the comment was in the trash
|
||||
} else if ( trashed ) {
|
||||
trashDiff = -1;
|
||||
}
|
||||
// you can't spam an item on the spam screen
|
||||
spamDiff = 1;
|
||||
|
||||
// user clicked "Unspam"
|
||||
} else if ( targetParent.is( 'span.unspam' ) ) {
|
||||
if ( approved ) {
|
||||
pendingDiff = 1;
|
||||
} else if ( unapproved ) {
|
||||
approvedDiff = 1;
|
||||
} else if ( trashed ) {
|
||||
// the comment was previously approved
|
||||
if ( targetParent.hasClass( 'approve' ) ) {
|
||||
approvedDiff = 1;
|
||||
// the comment was previously pending
|
||||
} else if ( targetParent.hasClass( 'unapprove' ) ) {
|
||||
pendingDiff = 1;
|
||||
}
|
||||
} else if ( spammed ) {
|
||||
if ( targetParent.hasClass( 'approve' ) ) {
|
||||
approvedDiff = 1;
|
||||
|
||||
} else if ( targetParent.hasClass( 'unapprove' ) ) {
|
||||
pendingDiff = 1;
|
||||
}
|
||||
}
|
||||
// you can Unspam an item on the spam screen
|
||||
spamDiff = -1;
|
||||
|
||||
// user clicked "Trash"
|
||||
} else if ( targetParent.is( 'span.trash' ) ) {
|
||||
if ( approved ) {
|
||||
approvedDiff = -1;
|
||||
} else if ( unapproved ) {
|
||||
pendingDiff = -1;
|
||||
// the comment was in the spam queue
|
||||
} else if ( spammed ) {
|
||||
spamDiff = -1;
|
||||
}
|
||||
// you can't trash an item on the trash screen
|
||||
trashDiff = 1;
|
||||
|
||||
// user clicked "Restore"
|
||||
} else if ( targetParent.is( 'span.untrash' ) ) {
|
||||
if ( approved ) {
|
||||
pendingDiff = 1;
|
||||
} else if ( unapproved ) {
|
||||
approvedDiff = 1;
|
||||
} else if ( trashed ) {
|
||||
if ( targetParent.hasClass( 'approve' ) ) {
|
||||
approvedDiff = 1;
|
||||
} else if ( targetParent.hasClass( 'unapprove' ) ) {
|
||||
pendingDiff = 1;
|
||||
}
|
||||
}
|
||||
// you can't go from trash to spam
|
||||
// you can untrash on the trash screen
|
||||
trashDiff = -1;
|
||||
|
||||
// User clicked "Approve"
|
||||
} else if ( targetParent.is( 'span.approve:not(.unspam):not(.untrash)' ) ) {
|
||||
approvedDiff = 1;
|
||||
pendingDiff = -1;
|
||||
|
||||
// User clicked "Unapprove"
|
||||
} else if ( targetParent.is( 'span.unapprove:not(.unspam):not(.untrash)' ) ) {
|
||||
approvedDiff = -1;
|
||||
pendingDiff = 1;
|
||||
|
||||
// User clicked "Delete Permanently"
|
||||
} else if ( targetParent.is( 'span.delete' ) ) {
|
||||
if ( spammed ) {
|
||||
spamDiff = -1;
|
||||
} else if ( trashed ) {
|
||||
trashDiff = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if ( pendingDiff ) {
|
||||
updatePending( pendingDiff, commentPostId );
|
||||
updateCountText( 'span.all-count', pendingDiff );
|
||||
}
|
||||
|
||||
if ( approvedDiff ) {
|
||||
updateApproved( approvedDiff, commentPostId );
|
||||
updateCountText( 'span.all-count', approvedDiff );
|
||||
}
|
||||
|
||||
if ( spamDiff ) {
|
||||
updateCountText( 'span.spam-count', spamDiff );
|
||||
}
|
||||
|
||||
if ( trashDiff ) {
|
||||
updateCountText( 'span.trash-count', trashDiff );
|
||||
}
|
||||
|
||||
if (
|
||||
( ( 'trash' === settings.data.comment_status ) && !getCount( $( 'span.trash-count' ) ) ) ||
|
||||
( ( 'spam' === settings.data.comment_status ) && !getCount( $( 'span.spam-count' ) ) )
|
||||
) {
|
||||
$( '#delete_all' ).hide();
|
||||
}
|
||||
|
||||
if ( ! isDashboard ) {
|
||||
total = totalInput.val() ? parseInt( totalInput.val(), 10 ) : 0;
|
||||
if ( $(settings.target).parent().is('span.undo') )
|
||||
total++;
|
||||
else
|
||||
total--;
|
||||
|
||||
if ( total < 0 )
|
||||
total = 0;
|
||||
|
||||
if ( 'object' === typeof r ) {
|
||||
if ( response.supplemental.total_items_i18n && lastConfidentTime < response.supplemental.time ) {
|
||||
total_items_i18n = response.supplemental.total_items_i18n || '';
|
||||
if ( total_items_i18n ) {
|
||||
$('.displaying-num').text( total_items_i18n );
|
||||
$('.total-pages').text( response.supplemental.total_pages_i18n );
|
||||
$('.tablenav-pages').find('.next-page, .last-page').toggleClass('disabled', response.supplemental.total_pages == $('.current-page').val());
|
||||
}
|
||||
updateTotalCount( total, response.supplemental.time, true );
|
||||
} else if ( response.supplemental.time ) {
|
||||
updateTotalCount( total, response.supplemental.time, false );
|
||||
}
|
||||
} else {
|
||||
updateTotalCount( total, r, false );
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! theExtraList || theExtraList.length === 0 || theExtraList.children().length === 0 || undoing ) {
|
||||
return;
|
||||
}
|
||||
|
||||
theList.get(0).wpList.add( theExtraList.children( ':eq(0):not(.no-items)' ).remove().clone() );
|
||||
|
||||
refillTheExtraList();
|
||||
|
||||
animated = $( ':animated', '#the-comment-list' );
|
||||
animatedCallback = function () {
|
||||
if ( ! $( '#the-comment-list tr:visible' ).length ) {
|
||||
theList.get(0).wpList.add( theExtraList.find( '.no-items' ).clone() );
|
||||
}
|
||||
};
|
||||
|
||||
if ( animated.length ) {
|
||||
animated.promise().done( animatedCallback );
|
||||
} else {
|
||||
animatedCallback();
|
||||
}
|
||||
};
|
||||
|
||||
refillTheExtraList = function(ev) {
|
||||
var args = $.query.get(), total_pages = $('.total-pages').text(), per_page = $('input[name="_per_page"]', '#comments-form').val();
|
||||
|
||||
if (! args.paged)
|
||||
args.paged = 1;
|
||||
|
||||
if (args.paged > total_pages) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ev) {
|
||||
theExtraList.empty();
|
||||
args.number = Math.min(8, per_page); // see WP_Comments_List_Table::prepare_items() @ class-wp-comments-list-table.php
|
||||
} else {
|
||||
args.number = 1;
|
||||
args.offset = Math.min(8, per_page) - 1; // fetch only the next item on the extra list
|
||||
}
|
||||
|
||||
args.no_placeholder = true;
|
||||
|
||||
args.paged ++;
|
||||
|
||||
// $.query.get() needs some correction to be sent into an ajax request
|
||||
if ( true === args.comment_type )
|
||||
args.comment_type = '';
|
||||
|
||||
args = $.extend(args, {
|
||||
'action': 'fetch-list',
|
||||
'list_args': list_args,
|
||||
'_ajax_fetch_list_nonce': $('#_ajax_fetch_list_nonce').val()
|
||||
});
|
||||
|
||||
$.ajax({
|
||||
url: ajaxurl,
|
||||
global: false,
|
||||
dataType: 'json',
|
||||
data: args,
|
||||
success: function(response) {
|
||||
theExtraList.get(0).wpList.add( response.rows );
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
theExtraList = $('#the-extra-comment-list').wpList( { alt: '', delColor: 'none', addColor: 'none' } );
|
||||
theList = $('#the-comment-list').wpList( { alt: '', delBefore: delBefore, dimAfter: dimAfter, delAfter: delAfter, addColor: 'none' } )
|
||||
.bind('wpListDelEnd', function(e, s){
|
||||
var wpListsData = $(s.target).attr('data-wp-lists'), id = s.element.replace(/[^0-9]+/g, '');
|
||||
|
||||
if ( wpListsData.indexOf(':trash=1') != -1 || wpListsData.indexOf(':spam=1') != -1 )
|
||||
$('#undo-' + id).fadeIn(300, function(){ $(this).show(); });
|
||||
});
|
||||
};
|
||||
|
||||
commentReply = {
|
||||
cid : '',
|
||||
act : '',
|
||||
originalContent : '',
|
||||
|
||||
init : function() {
|
||||
var row = $('#replyrow');
|
||||
|
||||
$('a.cancel', row).click(function() { return commentReply.revert(); });
|
||||
$('a.save', row).click(function() { return commentReply.send(); });
|
||||
$( 'input#author-name, input#author-email, input#author-url', row ).keypress( function( e ) {
|
||||
if ( e.which == 13 ) {
|
||||
commentReply.send();
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
// add events
|
||||
$('#the-comment-list .column-comment > p').dblclick(function(){
|
||||
commentReply.toggle($(this).parent());
|
||||
});
|
||||
|
||||
$('#doaction, #doaction2, #post-query-submit').click(function(){
|
||||
if ( $('#the-comment-list #replyrow').length > 0 )
|
||||
commentReply.close();
|
||||
});
|
||||
|
||||
this.comments_listing = $('#comments-form > input[name="comment_status"]').val() || '';
|
||||
|
||||
/* $(listTable).bind('beforeChangePage', function(){
|
||||
commentReply.close();
|
||||
}); */
|
||||
},
|
||||
|
||||
addEvents : function(r) {
|
||||
r.each(function() {
|
||||
$(this).find('.column-comment > p').dblclick(function(){
|
||||
commentReply.toggle($(this).parent());
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
toggle : function(el) {
|
||||
if ( 'none' !== $( el ).css( 'display' ) && ( $( '#replyrow' ).parent().is('#com-reply') || window.confirm( adminCommentsL10n.warnQuickEdit ) ) ) {
|
||||
$( el ).find( 'a.vim-q' ).click();
|
||||
}
|
||||
},
|
||||
|
||||
revert : function() {
|
||||
|
||||
if ( $('#the-comment-list #replyrow').length < 1 )
|
||||
return false;
|
||||
|
||||
$('#replyrow').fadeOut('fast', function(){
|
||||
commentReply.close();
|
||||
});
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
close : function() {
|
||||
var commentRow = $(),
|
||||
replyRow = $( '#replyrow' );
|
||||
|
||||
// replyrow is not showing?
|
||||
if ( replyRow.parent().is( '#com-reply' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( this.cid ) {
|
||||
commentRow = $( '#comment-' + this.cid );
|
||||
}
|
||||
|
||||
/*
|
||||
* When closing the Quick Edit form, show the comment row and move focus
|
||||
* back to the Quick Edit button.
|
||||
*/
|
||||
if ( 'edit-comment' === this.act ) {
|
||||
commentRow.fadeIn( 300, function() {
|
||||
commentRow
|
||||
.show()
|
||||
.find( '.vim-q' )
|
||||
.attr( 'aria-expanded', 'false' )
|
||||
.focus();
|
||||
} ).css( 'backgroundColor', '' );
|
||||
}
|
||||
|
||||
// When closing the Reply form, move focus back to the Reply button.
|
||||
if ( 'replyto-comment' === this.act ) {
|
||||
commentRow.find( '.vim-r' )
|
||||
.attr( 'aria-expanded', 'false' )
|
||||
.focus();
|
||||
}
|
||||
|
||||
// reset the Quicktags buttons
|
||||
if ( typeof QTags != 'undefined' )
|
||||
QTags.closeAllTags('replycontent');
|
||||
|
||||
$('#add-new-comment').css('display', '');
|
||||
|
||||
replyRow.hide();
|
||||
$( '#com-reply' ).append( replyRow );
|
||||
$('#replycontent').css('height', '').val('');
|
||||
$('#edithead input').val('');
|
||||
$( '.notice-error', replyRow )
|
||||
.addClass( 'hidden' )
|
||||
.find( '.error' ).empty();
|
||||
$( '.spinner', replyRow ).removeClass( 'is-active' );
|
||||
|
||||
this.cid = '';
|
||||
this.originalContent = '';
|
||||
},
|
||||
|
||||
open : function(comment_id, post_id, action) {
|
||||
var editRow, rowData, act, replyButton, editHeight,
|
||||
t = this,
|
||||
c = $('#comment-' + comment_id),
|
||||
h = c.height(),
|
||||
colspanVal = 0;
|
||||
|
||||
if ( ! this.discardCommentChanges() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
t.close();
|
||||
t.cid = comment_id;
|
||||
|
||||
editRow = $('#replyrow');
|
||||
rowData = $('#inline-'+comment_id);
|
||||
action = action || 'replyto';
|
||||
act = 'edit' == action ? 'edit' : 'replyto';
|
||||
act = t.act = act + '-comment';
|
||||
t.originalContent = $('textarea.comment', rowData).val();
|
||||
colspanVal = $( '> th:visible, > td:visible', c ).length;
|
||||
|
||||
// Make sure it's actually a table and there's a `colspan` value to apply.
|
||||
if ( editRow.hasClass( 'inline-edit-row' ) && 0 !== colspanVal ) {
|
||||
$( 'td', editRow ).attr( 'colspan', colspanVal );
|
||||
}
|
||||
|
||||
$('#action', editRow).val(act);
|
||||
$('#comment_post_ID', editRow).val(post_id);
|
||||
$('#comment_ID', editRow).val(comment_id);
|
||||
|
||||
if ( action == 'edit' ) {
|
||||
$( '#author-name', editRow ).val( $( 'div.author', rowData ).text() );
|
||||
$('#author-email', editRow).val( $('div.author-email', rowData).text() );
|
||||
$('#author-url', editRow).val( $('div.author-url', rowData).text() );
|
||||
$('#status', editRow).val( $('div.comment_status', rowData).text() );
|
||||
$('#replycontent', editRow).val( $('textarea.comment', rowData).val() );
|
||||
$( '#edithead, #editlegend, #savebtn', editRow ).show();
|
||||
$('#replyhead, #replybtn, #addhead, #addbtn', editRow).hide();
|
||||
|
||||
if ( h > 120 ) {
|
||||
// Limit the maximum height when editing very long comments to make it more manageable.
|
||||
// The textarea is resizable in most browsers, so the user can adjust it if needed.
|
||||
editHeight = h > 500 ? 500 : h;
|
||||
$('#replycontent', editRow).css('height', editHeight + 'px');
|
||||
}
|
||||
|
||||
c.after( editRow ).fadeOut('fast', function(){
|
||||
$('#replyrow').fadeIn(300, function(){ $(this).show(); });
|
||||
});
|
||||
} else if ( action == 'add' ) {
|
||||
$('#addhead, #addbtn', editRow).show();
|
||||
$( '#replyhead, #replybtn, #edithead, #editlegend, #savebtn', editRow ) .hide();
|
||||
$('#the-comment-list').prepend(editRow);
|
||||
$('#replyrow').fadeIn(300);
|
||||
} else {
|
||||
replyButton = $('#replybtn', editRow);
|
||||
$( '#edithead, #editlegend, #savebtn, #addhead, #addbtn', editRow ).hide();
|
||||
$('#replyhead, #replybtn', editRow).show();
|
||||
c.after(editRow);
|
||||
|
||||
if ( c.hasClass('unapproved') ) {
|
||||
replyButton.text(adminCommentsL10n.replyApprove);
|
||||
} else {
|
||||
replyButton.text(adminCommentsL10n.reply);
|
||||
}
|
||||
|
||||
$('#replyrow').fadeIn(300, function(){ $(this).show(); });
|
||||
}
|
||||
|
||||
setTimeout(function() {
|
||||
var rtop, rbottom, scrollTop, vp, scrollBottom;
|
||||
|
||||
rtop = $('#replyrow').offset().top;
|
||||
rbottom = rtop + $('#replyrow').height();
|
||||
scrollTop = window.pageYOffset || document.documentElement.scrollTop;
|
||||
vp = document.documentElement.clientHeight || window.innerHeight || 0;
|
||||
scrollBottom = scrollTop + vp;
|
||||
|
||||
if ( scrollBottom - 20 < rbottom )
|
||||
window.scroll(0, rbottom - vp + 35);
|
||||
else if ( rtop - 20 < scrollTop )
|
||||
window.scroll(0, rtop - 35);
|
||||
|
||||
$('#replycontent').focus().keyup(function(e){
|
||||
if ( e.which == 27 )
|
||||
commentReply.revert(); // close on Escape
|
||||
});
|
||||
}, 600);
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
send : function() {
|
||||
var post = {},
|
||||
$errorNotice = $( '#replysubmit .error-notice' );
|
||||
|
||||
$errorNotice.addClass( 'hidden' );
|
||||
$( '#replysubmit .spinner' ).addClass( 'is-active' );
|
||||
|
||||
$('#replyrow input').not(':button').each(function() {
|
||||
var t = $(this);
|
||||
post[ t.attr('name') ] = t.val();
|
||||
});
|
||||
|
||||
post.content = $('#replycontent').val();
|
||||
post.id = post.comment_post_ID;
|
||||
post.comments_listing = this.comments_listing;
|
||||
post.p = $('[name="p"]').val();
|
||||
|
||||
if ( $('#comment-' + $('#comment_ID').val()).hasClass('unapproved') )
|
||||
post.approve_parent = 1;
|
||||
|
||||
$.ajax({
|
||||
type : 'POST',
|
||||
url : ajaxurl,
|
||||
data : post,
|
||||
success : function(x) { commentReply.show(x); },
|
||||
error : function(r) { commentReply.error(r); }
|
||||
});
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
show : function(xml) {
|
||||
var t = this, r, c, id, bg, pid;
|
||||
|
||||
if ( typeof(xml) == 'string' ) {
|
||||
t.error({'responseText': xml});
|
||||
return false;
|
||||
}
|
||||
|
||||
r = wpAjax.parseAjaxResponse(xml);
|
||||
if ( r.errors ) {
|
||||
t.error({'responseText': wpAjax.broken});
|
||||
return false;
|
||||
}
|
||||
|
||||
t.revert();
|
||||
|
||||
r = r.responses[0];
|
||||
id = '#comment-' + r.id;
|
||||
|
||||
if ( 'edit-comment' == t.act )
|
||||
$(id).remove();
|
||||
|
||||
if ( r.supplemental.parent_approved ) {
|
||||
pid = $('#comment-' + r.supplemental.parent_approved);
|
||||
updatePending( -1, r.supplemental.parent_post_id );
|
||||
|
||||
if ( this.comments_listing == 'moderated' ) {
|
||||
pid.animate( { 'backgroundColor':'#CCEEBB' }, 400, function(){
|
||||
pid.fadeOut();
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ( r.supplemental.i18n_comments_text ) {
|
||||
if ( isDashboard ) {
|
||||
updateDashboardText( r.supplemental );
|
||||
} else {
|
||||
updateApproved( 1, r.supplemental.parent_post_id );
|
||||
updateCountText( 'span.all-count', 1 );
|
||||
}
|
||||
}
|
||||
|
||||
c = $.trim(r.data); // Trim leading whitespaces
|
||||
$(c).hide();
|
||||
$('#replyrow').after(c);
|
||||
|
||||
id = $(id);
|
||||
t.addEvents(id);
|
||||
bg = id.hasClass('unapproved') ? '#FFFFE0' : id.closest('.widefat, .postbox').css('backgroundColor');
|
||||
|
||||
id.animate( { 'backgroundColor':'#CCEEBB' }, 300 )
|
||||
.animate( { 'backgroundColor': bg }, 300, function() {
|
||||
if ( pid && pid.length ) {
|
||||
pid.animate( { 'backgroundColor':'#CCEEBB' }, 300 )
|
||||
.animate( { 'backgroundColor': bg }, 300 )
|
||||
.removeClass('unapproved').addClass('approved')
|
||||
.find('div.comment_status').html('1');
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
error : function(r) {
|
||||
var er = r.statusText,
|
||||
$errorNotice = $( '#replysubmit .notice-error' ),
|
||||
$error = $errorNotice.find( '.error' );
|
||||
|
||||
$( '#replysubmit .spinner' ).removeClass( 'is-active' );
|
||||
|
||||
if ( r.responseText )
|
||||
er = r.responseText.replace( /<.[^<>]*?>/g, '' );
|
||||
|
||||
if ( er ) {
|
||||
$errorNotice.removeClass( 'hidden' );
|
||||
$error.html( er );
|
||||
}
|
||||
},
|
||||
|
||||
addcomment: function(post_id) {
|
||||
var t = this;
|
||||
|
||||
$('#add-new-comment').fadeOut(200, function(){
|
||||
t.open(0, post_id, 'add');
|
||||
$('table.comments-box').css('display', '');
|
||||
$('#no-comments').remove();
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Alert the user if they have unsaved changes on a comment that will be
|
||||
* lost if they proceed.
|
||||
*
|
||||
* @returns {boolean}
|
||||
*/
|
||||
discardCommentChanges: function() {
|
||||
var editRow = $( '#replyrow' );
|
||||
|
||||
if ( this.originalContent === $( '#replycontent', editRow ).val() ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return window.confirm( adminCommentsL10n.warnCommentChanges );
|
||||
}
|
||||
};
|
||||
|
||||
$(document).ready(function(){
|
||||
var make_hotkeys_redirect, edit_comment, toggle_all, make_bulk;
|
||||
|
||||
setCommentsList();
|
||||
commentReply.init();
|
||||
|
||||
$(document).on( 'click', 'span.delete a.delete', function( e ) {
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
if ( typeof $.table_hotkeys != 'undefined' ) {
|
||||
make_hotkeys_redirect = function(which) {
|
||||
return function() {
|
||||
var first_last, l;
|
||||
|
||||
first_last = 'next' == which? 'first' : 'last';
|
||||
l = $('.tablenav-pages .'+which+'-page:not(.disabled)');
|
||||
if (l.length)
|
||||
window.location = l[0].href.replace(/\&hotkeys_highlight_(first|last)=1/g, '')+'&hotkeys_highlight_'+first_last+'=1';
|
||||
};
|
||||
};
|
||||
|
||||
edit_comment = function(event, current_row) {
|
||||
window.location = $('span.edit a', current_row).attr('href');
|
||||
};
|
||||
|
||||
toggle_all = function() {
|
||||
$('#cb-select-all-1').data( 'wp-toggle', 1 ).trigger( 'click' ).removeData( 'wp-toggle' );
|
||||
};
|
||||
|
||||
make_bulk = function(value) {
|
||||
return function() {
|
||||
var scope = $('select[name="action"]');
|
||||
$('option[value="' + value + '"]', scope).prop('selected', true);
|
||||
$('#doaction').click();
|
||||
};
|
||||
};
|
||||
|
||||
$.table_hotkeys(
|
||||
$('table.widefat'),
|
||||
[
|
||||
'a', 'u', 's', 'd', 'r', 'q', 'z',
|
||||
['e', edit_comment],
|
||||
['shift+x', toggle_all],
|
||||
['shift+a', make_bulk('approve')],
|
||||
['shift+s', make_bulk('spam')],
|
||||
['shift+d', make_bulk('delete')],
|
||||
['shift+t', make_bulk('trash')],
|
||||
['shift+z', make_bulk('untrash')],
|
||||
['shift+u', make_bulk('unapprove')]
|
||||
],
|
||||
{
|
||||
highlight_first: adminCommentsL10n.hotkeys_highlight_first,
|
||||
highlight_last: adminCommentsL10n.hotkeys_highlight_last,
|
||||
prev_page_link_cb: make_hotkeys_redirect('prev'),
|
||||
next_page_link_cb: make_hotkeys_redirect('next'),
|
||||
hotkeys_opts: {
|
||||
disableInInput: true,
|
||||
type: 'keypress',
|
||||
noDisable: '.check-column input[type="checkbox"]'
|
||||
},
|
||||
cycle_expr: '#the-comment-list tr',
|
||||
start_row_index: 0
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Quick Edit and Reply have an inline comment editor.
|
||||
$( '#the-comment-list' ).on( 'click', '.comment-inline', function() {
|
||||
var $el = $( this ),
|
||||
action = 'replyto';
|
||||
|
||||
if ( 'undefined' !== typeof $el.data( 'action' ) ) {
|
||||
action = $el.data( 'action' );
|
||||
}
|
||||
|
||||
$( this ).attr( 'aria-expanded', 'true' );
|
||||
commentReply.open( $el.data( 'commentId' ), $el.data( 'postId' ), action );
|
||||
} );
|
||||
});
|
||||
|
||||
})(jQuery);
|
||||
@@ -0,0 +1,555 @@
|
||||
/* global inlineEditL10n, ajaxurl, typenow */
|
||||
/**
|
||||
* This file contains the functions needed for the inline editing of posts.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*/
|
||||
|
||||
window.wp = window.wp || {};
|
||||
|
||||
/**
|
||||
* Manages the quick edit and bulk edit windows for editing posts or pages.
|
||||
*
|
||||
* @namespace inlineEditPost
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @type {Object}
|
||||
*
|
||||
* @property {string} type The type of inline editor.
|
||||
* @property {string} what The prefix before the post id.
|
||||
*
|
||||
*/
|
||||
var inlineEditPost;
|
||||
( function( $, wp ) {
|
||||
|
||||
inlineEditPost = {
|
||||
|
||||
/**
|
||||
* Initializes the inline and bulk post editor.
|
||||
*
|
||||
* Binds event handlers to the escape key to close the inline editor
|
||||
* and to the save and close buttons. Changes DOM to be ready for inline
|
||||
* editing. Adds event handler to bulk edit.
|
||||
*
|
||||
* @memberof inlineEditPost
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
init : function(){
|
||||
var t = this, qeRow = $('#inline-edit'), bulkRow = $('#bulk-edit');
|
||||
|
||||
t.type = $('table.widefat').hasClass('pages') ? 'page' : 'post';
|
||||
// Post id prefix.
|
||||
t.what = '#post-';
|
||||
|
||||
/**
|
||||
* Binds the escape key to revert the changes and close the quick editor.
|
||||
*
|
||||
* @returns {boolean} The result of revert.
|
||||
*/
|
||||
qeRow.keyup(function(e){
|
||||
// Revert changes if escape key is pressed.
|
||||
if ( e.which === 27 ) {
|
||||
return inlineEditPost.revert();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Binds the escape key to revert the changes and close the bulk editor.
|
||||
*
|
||||
* @returns {boolean} The result of revert.
|
||||
*/
|
||||
bulkRow.keyup(function(e){
|
||||
// Revert changes if escape key is pressed.
|
||||
if ( e.which === 27 ) {
|
||||
return inlineEditPost.revert();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Reverts changes and close the quick editor if the cancel button is clicked.
|
||||
*
|
||||
* @returns {boolean} The result of revert.
|
||||
*/
|
||||
$( '.cancel', qeRow ).click( function() {
|
||||
return inlineEditPost.revert();
|
||||
});
|
||||
|
||||
/**
|
||||
* Saves changes in the quick editor if the save(named: update) button is clicked.
|
||||
*
|
||||
* @returns {boolean} The result of save.
|
||||
*/
|
||||
$( '.save', qeRow ).click( function() {
|
||||
return inlineEditPost.save(this);
|
||||
});
|
||||
|
||||
/**
|
||||
* If enter is pressed, and the target is not the cancel button, save the post.
|
||||
*
|
||||
* @returns {boolean} The result of save.
|
||||
*/
|
||||
$('td', qeRow).keydown(function(e){
|
||||
if ( e.which === 13 && ! $( e.target ).hasClass( 'cancel' ) ) {
|
||||
return inlineEditPost.save(this);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Reverts changes and close the bulk editor if the cancel button is clicked.
|
||||
*
|
||||
* @returns {boolean} The result of revert.
|
||||
*/
|
||||
$( '.cancel', bulkRow ).click( function() {
|
||||
return inlineEditPost.revert();
|
||||
});
|
||||
|
||||
/**
|
||||
* Disables the password input field when the private post checkbox is checked.
|
||||
*/
|
||||
$('#inline-edit .inline-edit-private input[value="private"]').click( function(){
|
||||
var pw = $('input.inline-edit-password-input');
|
||||
if ( $(this).prop('checked') ) {
|
||||
pw.val('').prop('disabled', true);
|
||||
} else {
|
||||
pw.prop('disabled', false);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Binds click event to the .editinline button which opens the quick editor.
|
||||
*/
|
||||
$( '#the-list' ).on( 'click', '.editinline', function() {
|
||||
$( this ).attr( 'aria-expanded', 'true' );
|
||||
inlineEditPost.edit( this );
|
||||
});
|
||||
|
||||
$('#bulk-edit').find('fieldset:first').after(
|
||||
$('#inline-edit fieldset.inline-edit-categories').clone()
|
||||
).siblings( 'fieldset:last' ).prepend(
|
||||
$('#inline-edit label.inline-edit-tags').clone()
|
||||
);
|
||||
|
||||
$('select[name="_status"] option[value="future"]', bulkRow).remove();
|
||||
|
||||
/**
|
||||
* Adds onclick events to the apply buttons.
|
||||
*/
|
||||
$('#doaction, #doaction2').click(function(e){
|
||||
var n;
|
||||
|
||||
t.whichBulkButtonId = $( this ).attr( 'id' );
|
||||
n = t.whichBulkButtonId.substr( 2 );
|
||||
|
||||
if ( 'edit' === $( 'select[name="' + n + '"]' ).val() ) {
|
||||
e.preventDefault();
|
||||
t.setBulk();
|
||||
} else if ( $('form#posts-filter tr.inline-editor').length > 0 ) {
|
||||
t.revert();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Toggles the quick edit window, hiding it when it's active and showing it when
|
||||
* inactive.
|
||||
*
|
||||
* @memberof inlineEditPost
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @param {Object} el Element within a post table row.
|
||||
*/
|
||||
toggle : function(el){
|
||||
var t = this;
|
||||
$( t.what + t.getId( el ) ).css( 'display' ) === 'none' ? t.revert() : t.edit( el );
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates the bulk editor row to edit multiple posts at once.
|
||||
*
|
||||
* @memberof inlineEditPost
|
||||
* @since 2.7.0
|
||||
*/
|
||||
setBulk : function(){
|
||||
var te = '', type = this.type, c = true;
|
||||
this.revert();
|
||||
|
||||
$( '#bulk-edit td' ).attr( 'colspan', $( 'th:visible, td:visible', '.widefat:first thead' ).length );
|
||||
|
||||
// Insert the editor at the top of the table with an empty row above to maintain zebra striping.
|
||||
$('table.widefat tbody').prepend( $('#bulk-edit') ).prepend('<tr class="hidden"></tr>');
|
||||
$('#bulk-edit').addClass('inline-editor').show();
|
||||
|
||||
/**
|
||||
* Create a HTML div with the title and a link(delete-icon) for each selected
|
||||
* post.
|
||||
*
|
||||
* Get the selected posts based on the checked checkboxes in the post table.
|
||||
*/
|
||||
$( 'tbody th.check-column input[type="checkbox"]' ).each( function() {
|
||||
|
||||
// If the checkbox for a post is selected, add the post to the edit list.
|
||||
if ( $(this).prop('checked') ) {
|
||||
c = false;
|
||||
var id = $(this).val(), theTitle;
|
||||
theTitle = $('#inline_'+id+' .post_title').html() || inlineEditL10n.notitle;
|
||||
te += '<div id="ttle'+id+'"><a id="_'+id+'" class="ntdelbutton" title="'+inlineEditL10n.ntdeltitle+'">X</a>'+theTitle+'</div>';
|
||||
}
|
||||
});
|
||||
|
||||
// If no checkboxes where checked, just hide the quick/bulk edit rows.
|
||||
if ( c ) {
|
||||
return this.revert();
|
||||
}
|
||||
|
||||
// Add onclick events to the delete-icons in the bulk editors the post title list.
|
||||
$('#bulk-titles').html(te);
|
||||
/**
|
||||
* Binds on click events to the checkboxes before the posts in the table.
|
||||
*
|
||||
* @listens click
|
||||
*/
|
||||
$('#bulk-titles a').click(function(){
|
||||
var id = $(this).attr('id').substr(1);
|
||||
|
||||
$('table.widefat input[value="' + id + '"]').prop('checked', false);
|
||||
$('#ttle'+id).remove();
|
||||
});
|
||||
|
||||
// Enable auto-complete for tags when editing posts.
|
||||
if ( 'post' === type ) {
|
||||
$( 'tr.inline-editor textarea[data-wp-taxonomy]' ).each( function ( i, element ) {
|
||||
/*
|
||||
* While Quick Edit clones the form each time, Bulk Edit always re-uses
|
||||
* the same form. Let's check if an autocomplete instance already exists.
|
||||
*/
|
||||
if ( $( element ).autocomplete( 'instance' ) ) {
|
||||
// jQuery equivalent of `continue` within an `each()` loop.
|
||||
return;
|
||||
}
|
||||
|
||||
$( element ).wpTagsSuggest();
|
||||
} );
|
||||
}
|
||||
|
||||
// Scrolls to the top of the table where the editor is rendered.
|
||||
$('html, body').animate( { scrollTop: 0 }, 'fast' );
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates a quick edit window for the post that has been clicked.
|
||||
*
|
||||
* @memberof inlineEditPost
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @param {number|Object} id The id of the clicked post or an element within a post
|
||||
* table row.
|
||||
* @returns {boolean} Always returns false at the end of execution.
|
||||
*/
|
||||
edit : function(id) {
|
||||
var t = this, fields, editRow, rowData, status, pageOpt, pageLevel, nextPage, pageLoop = true, nextLevel, f, val, pw;
|
||||
t.revert();
|
||||
|
||||
if ( typeof(id) === 'object' ) {
|
||||
id = t.getId(id);
|
||||
}
|
||||
|
||||
fields = ['post_title', 'post_name', 'post_author', '_status', 'jj', 'mm', 'aa', 'hh', 'mn', 'ss', 'post_password', 'post_format', 'menu_order', 'page_template'];
|
||||
if ( t.type === 'page' ) {
|
||||
fields.push('post_parent');
|
||||
}
|
||||
|
||||
// Add the new edit row with an extra blank row underneath to maintain zebra striping.
|
||||
editRow = $('#inline-edit').clone(true);
|
||||
$( 'td', editRow ).attr( 'colspan', $( 'th:visible, td:visible', '.widefat:first thead' ).length );
|
||||
|
||||
$(t.what+id).removeClass('is-expanded').hide().after(editRow).after('<tr class="hidden"></tr>');
|
||||
|
||||
// Populate fields in the quick edit window.
|
||||
rowData = $('#inline_'+id);
|
||||
if ( !$(':input[name="post_author"] option[value="' + $('.post_author', rowData).text() + '"]', editRow).val() ) {
|
||||
|
||||
// The post author no longer has edit capabilities, so we need to add them to the list of authors.
|
||||
$(':input[name="post_author"]', editRow).prepend('<option value="' + $('.post_author', rowData).text() + '">' + $('#' + t.type + '-' + id + ' .author').text() + '</option>');
|
||||
}
|
||||
if ( $( ':input[name="post_author"] option', editRow ).length === 1 ) {
|
||||
$('label.inline-edit-author', editRow).hide();
|
||||
}
|
||||
|
||||
for ( f = 0; f < fields.length; f++ ) {
|
||||
val = $('.'+fields[f], rowData);
|
||||
|
||||
/**
|
||||
* Replaces the image for a Twemoji(Twitter emoji) with it's alternate text.
|
||||
*
|
||||
* @returns Alternate text from the image.
|
||||
*/
|
||||
val.find( 'img' ).replaceWith( function() { return this.alt; } );
|
||||
val = val.text();
|
||||
$(':input[name="' + fields[f] + '"]', editRow).val( val );
|
||||
}
|
||||
|
||||
if ( $( '.comment_status', rowData ).text() === 'open' ) {
|
||||
$( 'input[name="comment_status"]', editRow ).prop( 'checked', true );
|
||||
}
|
||||
if ( $( '.ping_status', rowData ).text() === 'open' ) {
|
||||
$( 'input[name="ping_status"]', editRow ).prop( 'checked', true );
|
||||
}
|
||||
if ( $( '.sticky', rowData ).text() === 'sticky' ) {
|
||||
$( 'input[name="sticky"]', editRow ).prop( 'checked', true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the select boxes for the categories.
|
||||
*/
|
||||
$('.post_category', rowData).each(function(){
|
||||
var taxname,
|
||||
term_ids = $(this).text();
|
||||
|
||||
if ( term_ids ) {
|
||||
taxname = $(this).attr('id').replace('_'+id, '');
|
||||
$('ul.'+taxname+'-checklist :checkbox', editRow).val(term_ids.split(','));
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Gets all the taxonomies for live auto-fill suggestions when typing the name
|
||||
* of a tag.
|
||||
*/
|
||||
$('.tags_input', rowData).each(function(){
|
||||
var terms = $(this),
|
||||
taxname = $(this).attr('id').replace('_' + id, ''),
|
||||
textarea = $('textarea.tax_input_' + taxname, editRow),
|
||||
comma = inlineEditL10n.comma;
|
||||
|
||||
terms.find( 'img' ).replaceWith( function() { return this.alt; } );
|
||||
terms = terms.text();
|
||||
|
||||
if ( terms ) {
|
||||
if ( ',' !== comma ) {
|
||||
terms = terms.replace(/,/g, comma);
|
||||
}
|
||||
textarea.val(terms);
|
||||
}
|
||||
|
||||
textarea.wpTagsSuggest();
|
||||
});
|
||||
|
||||
// Handle the post status.
|
||||
status = $('._status', rowData).text();
|
||||
if ( 'future' !== status ) {
|
||||
$('select[name="_status"] option[value="future"]', editRow).remove();
|
||||
}
|
||||
|
||||
pw = $( '.inline-edit-password-input' ).prop( 'disabled', false );
|
||||
if ( 'private' === status ) {
|
||||
$('input[name="keep_private"]', editRow).prop('checked', true);
|
||||
pw.val( '' ).prop( 'disabled', true );
|
||||
}
|
||||
|
||||
// Remove the current page and children from the parent dropdown.
|
||||
pageOpt = $('select[name="post_parent"] option[value="' + id + '"]', editRow);
|
||||
if ( pageOpt.length > 0 ) {
|
||||
pageLevel = pageOpt[0].className.split('-')[1];
|
||||
nextPage = pageOpt;
|
||||
while ( pageLoop ) {
|
||||
nextPage = nextPage.next('option');
|
||||
if ( nextPage.length === 0 ) {
|
||||
break;
|
||||
}
|
||||
|
||||
nextLevel = nextPage[0].className.split('-')[1];
|
||||
|
||||
if ( nextLevel <= pageLevel ) {
|
||||
pageLoop = false;
|
||||
} else {
|
||||
nextPage.remove();
|
||||
nextPage = pageOpt;
|
||||
}
|
||||
}
|
||||
pageOpt.remove();
|
||||
}
|
||||
|
||||
$(editRow).attr('id', 'edit-'+id).addClass('inline-editor').show();
|
||||
$('.ptitle', editRow).focus();
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Saves the changes made in the quick edit window to the post.
|
||||
* AJAX saving is only for Quick Edit and not for bulk edit.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @param {int} id The id for the post that has been changed.
|
||||
* @returns {boolean} false, so the form does not submit when pressing
|
||||
* Enter on a focused field.
|
||||
*/
|
||||
save : function(id) {
|
||||
var params, fields, page = $('.post_status_page').val() || '';
|
||||
|
||||
if ( typeof(id) === 'object' ) {
|
||||
id = this.getId(id);
|
||||
}
|
||||
|
||||
$( 'table.widefat .spinner' ).addClass( 'is-active' );
|
||||
|
||||
params = {
|
||||
action: 'inline-save',
|
||||
post_type: typenow,
|
||||
post_ID: id,
|
||||
edit_date: 'true',
|
||||
post_status: page
|
||||
};
|
||||
|
||||
fields = $('#edit-'+id).find(':input').serialize();
|
||||
params = fields + '&' + $.param(params);
|
||||
|
||||
// Make ajax request.
|
||||
$.post( ajaxurl, params,
|
||||
function(r) {
|
||||
var $errorNotice = $( '#edit-' + id + ' .inline-edit-save .notice-error' ),
|
||||
$error = $errorNotice.find( '.error' );
|
||||
|
||||
$( 'table.widefat .spinner' ).removeClass( 'is-active' );
|
||||
$( '.ac_results' ).hide();
|
||||
|
||||
if (r) {
|
||||
if ( -1 !== r.indexOf( '<tr' ) ) {
|
||||
$(inlineEditPost.what+id).siblings('tr.hidden').addBack().remove();
|
||||
$('#edit-'+id).before(r).remove();
|
||||
$( inlineEditPost.what + id ).hide().fadeIn( 400, function() {
|
||||
// Move focus back to the Quick Edit button. $( this ) is the row being animated.
|
||||
$( this ).find( '.editinline' )
|
||||
.attr( 'aria-expanded', 'false' )
|
||||
.focus();
|
||||
wp.a11y.speak( inlineEditL10n.saved );
|
||||
});
|
||||
} else {
|
||||
r = r.replace( /<.[^<>]*?>/g, '' );
|
||||
$errorNotice.removeClass( 'hidden' );
|
||||
$error.html( r );
|
||||
wp.a11y.speak( $error.text() );
|
||||
}
|
||||
} else {
|
||||
$errorNotice.removeClass( 'hidden' );
|
||||
$error.html( inlineEditL10n.error );
|
||||
wp.a11y.speak( inlineEditL10n.error );
|
||||
}
|
||||
},
|
||||
'html');
|
||||
|
||||
// Prevent submitting the form when pressing Enter on a focused field.
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Hides and empties the Quick Edit and/or Bulk Edit windows.
|
||||
*
|
||||
* @memberof inlineEditPost
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @returns {boolean} Always returns false.
|
||||
*/
|
||||
revert : function(){
|
||||
var $tableWideFat = $( '.widefat' ),
|
||||
id = $( '.inline-editor', $tableWideFat ).attr( 'id' );
|
||||
|
||||
if ( id ) {
|
||||
$( '.spinner', $tableWideFat ).removeClass( 'is-active' );
|
||||
$( '.ac_results' ).hide();
|
||||
|
||||
if ( 'bulk-edit' === id ) {
|
||||
|
||||
// Hide the bulk editor.
|
||||
$( '#bulk-edit', $tableWideFat ).removeClass( 'inline-editor' ).hide().siblings( '.hidden' ).remove();
|
||||
$('#bulk-titles').empty();
|
||||
|
||||
// Store the empty bulk editor in a hidden element.
|
||||
$('#inlineedit').append( $('#bulk-edit') );
|
||||
|
||||
// Move focus back to the Bulk Action button that was activated.
|
||||
$( '#' + inlineEditPost.whichBulkButtonId ).focus();
|
||||
} else {
|
||||
|
||||
// Remove both the inline-editor and its hidden tr siblings.
|
||||
$('#'+id).siblings('tr.hidden').addBack().remove();
|
||||
id = id.substr( id.lastIndexOf('-') + 1 );
|
||||
|
||||
// Show the post row and move focus back to the Quick Edit button.
|
||||
$( this.what + id ).show().find( '.editinline' )
|
||||
.attr( 'aria-expanded', 'false' )
|
||||
.focus();
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the id for a the post that you want to quick edit from the row in the quick
|
||||
* edit table.
|
||||
*
|
||||
* @memberof inlineEditPost
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @param {Object} o DOM row object to get the id for.
|
||||
* @returns {string} The post id extracted from the table row in the object.
|
||||
*/
|
||||
getId : function(o) {
|
||||
var id = $(o).closest('tr').attr('id'),
|
||||
parts = id.split('-');
|
||||
return parts[parts.length - 1];
|
||||
}
|
||||
};
|
||||
|
||||
$( document ).ready( function(){ inlineEditPost.init(); } );
|
||||
|
||||
// Show/hide locks on posts.
|
||||
$( document ).on( 'heartbeat-tick.wp-check-locked-posts', function( e, data ) {
|
||||
var locked = data['wp-check-locked-posts'] || {};
|
||||
|
||||
$('#the-list tr').each( function(i, el) {
|
||||
var key = el.id, row = $(el), lock_data, avatar;
|
||||
|
||||
if ( locked.hasOwnProperty( key ) ) {
|
||||
if ( ! row.hasClass('wp-locked') ) {
|
||||
lock_data = locked[key];
|
||||
row.find('.column-title .locked-text').text( lock_data.text );
|
||||
row.find('.check-column checkbox').prop('checked', false);
|
||||
|
||||
if ( lock_data.avatar_src ) {
|
||||
avatar = $( '<img class="avatar avatar-18 photo" width="18" height="18" alt="" />' ).attr( 'src', lock_data.avatar_src.replace( /&/g, '&' ) );
|
||||
row.find('.column-title .locked-avatar').empty().append( avatar );
|
||||
}
|
||||
row.addClass('wp-locked');
|
||||
}
|
||||
} else if ( row.hasClass('wp-locked') ) {
|
||||
// Make room for the CSS animation
|
||||
row.removeClass('wp-locked').delay(1000).find('.locked-info span').empty();
|
||||
}
|
||||
});
|
||||
}).on( 'heartbeat-send.wp-check-locked-posts', function( e, data ) {
|
||||
var check = [];
|
||||
|
||||
$('#the-list tr').each( function(i, el) {
|
||||
if ( el.id ) {
|
||||
check.push( el.id );
|
||||
}
|
||||
});
|
||||
|
||||
if ( check.length ) {
|
||||
data['wp-check-locked-posts'] = check;
|
||||
}
|
||||
}).ready( function() {
|
||||
|
||||
// Set the heartbeat interval to 15 sec.
|
||||
if ( typeof wp !== 'undefined' && wp.heartbeat ) {
|
||||
wp.heartbeat.interval( 15 );
|
||||
}
|
||||
});
|
||||
|
||||
})( jQuery, window.wp );
|
||||
@@ -0,0 +1,293 @@
|
||||
/* global inlineEditL10n, ajaxurl */
|
||||
/**
|
||||
* This file is used on the term overview page to power quick-editing terms.
|
||||
*/
|
||||
|
||||
window.wp = window.wp || {};
|
||||
|
||||
/**
|
||||
* Consists of functions relevant to the inline taxonomy editor.
|
||||
*
|
||||
* @namespace inlineEditTax
|
||||
*
|
||||
* @property {string} type The type of inline edit we are currently on.
|
||||
* @property {string} what The type property with a hash prefixed and a dash
|
||||
* suffixed.
|
||||
*/
|
||||
var inlineEditTax;
|
||||
|
||||
( function( $, wp ) {
|
||||
|
||||
inlineEditTax = {
|
||||
|
||||
/**
|
||||
* Initializes the inline taxonomy editor by adding event handlers to be able to
|
||||
* quick edit.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @this inlineEditTax
|
||||
* @memberof inlineEditTax
|
||||
* @returns {void}
|
||||
*/
|
||||
init : function() {
|
||||
var t = this, row = $('#inline-edit');
|
||||
|
||||
t.type = $('#the-list').attr('data-wp-lists').substr(5);
|
||||
t.what = '#'+t.type+'-';
|
||||
|
||||
$( '#the-list' ).on( 'click', '.editinline', function() {
|
||||
$( this ).attr( 'aria-expanded', 'true' );
|
||||
inlineEditTax.edit( this );
|
||||
});
|
||||
|
||||
/**
|
||||
* Cancels inline editing when pressing escape inside the inline editor.
|
||||
*
|
||||
* @param {Object} e The keyup event that has been triggered.
|
||||
*/
|
||||
row.keyup( function( e ) {
|
||||
// 27 = [escape]
|
||||
if ( e.which === 27 ) {
|
||||
return inlineEditTax.revert();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Cancels inline editing when clicking the cancel button.
|
||||
*/
|
||||
$( '.cancel', row ).click( function() {
|
||||
return inlineEditTax.revert();
|
||||
});
|
||||
|
||||
/**
|
||||
* Saves the inline edits when clicking the save button.
|
||||
*/
|
||||
$( '.save', row ).click( function() {
|
||||
return inlineEditTax.save(this);
|
||||
});
|
||||
|
||||
/**
|
||||
* Saves the inline edits when pressing enter inside the inline editor.
|
||||
*/
|
||||
$( 'input, select', row ).keydown( function( e ) {
|
||||
// 13 = [enter]
|
||||
if ( e.which === 13 ) {
|
||||
return inlineEditTax.save( this );
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Saves the inline edits on submitting the inline edit form.
|
||||
*/
|
||||
$( '#posts-filter input[type="submit"]' ).mousedown( function() {
|
||||
t.revert();
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Toggles the quick edit based on if it is currently shown or hidden.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @this inlineEditTax
|
||||
* @memberof inlineEditTax
|
||||
*
|
||||
* @param {HTMLElement} el An element within the table row or the table row
|
||||
* itself that we want to quick edit.
|
||||
* @returns {void}
|
||||
*/
|
||||
toggle : function(el) {
|
||||
var t = this;
|
||||
|
||||
$(t.what+t.getId(el)).css('display') === 'none' ? t.revert() : t.edit(el);
|
||||
},
|
||||
|
||||
/**
|
||||
* Shows the quick editor
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @this inlineEditTax
|
||||
* @memberof inlineEditTax
|
||||
*
|
||||
* @param {string|HTMLElement} id The ID of the term we want to quick edit or an
|
||||
* element within the table row or the
|
||||
* table row itself.
|
||||
* @returns {boolean} Always returns false.
|
||||
*/
|
||||
edit : function(id) {
|
||||
var editRow, rowData, val,
|
||||
t = this;
|
||||
t.revert();
|
||||
|
||||
// Makes sure we can pass an HTMLElement as the ID.
|
||||
if ( typeof(id) === 'object' ) {
|
||||
id = t.getId(id);
|
||||
}
|
||||
|
||||
editRow = $('#inline-edit').clone(true), rowData = $('#inline_'+id);
|
||||
$( 'td', editRow ).attr( 'colspan', $( 'th:visible, td:visible', '.wp-list-table.widefat:first thead' ).length );
|
||||
|
||||
$(t.what+id).hide().after(editRow).after('<tr class="hidden"></tr>');
|
||||
|
||||
val = $('.name', rowData);
|
||||
val.find( 'img' ).replaceWith( function() { return this.alt; } );
|
||||
val = val.text();
|
||||
$(':input[name="name"]', editRow).val( val );
|
||||
|
||||
val = $('.slug', rowData);
|
||||
val.find( 'img' ).replaceWith( function() { return this.alt; } );
|
||||
val = val.text();
|
||||
$(':input[name="slug"]', editRow).val( val );
|
||||
|
||||
$(editRow).attr('id', 'edit-'+id).addClass('inline-editor').show();
|
||||
$('.ptitle', editRow).eq(0).focus();
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Saves the quick edit data.
|
||||
*
|
||||
* Saves the quick edit data to the server and replaces the table row with the
|
||||
* HTML retrieved from the server.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @this inlineEditTax
|
||||
* @memberof inlineEditTax
|
||||
*
|
||||
* @param {string|HTMLElement} id The ID of the term we want to quick edit or an
|
||||
* element within the table row or the
|
||||
* table row itself.
|
||||
* @returns {boolean} Always returns false.
|
||||
*/
|
||||
save : function(id) {
|
||||
var params, fields, tax = $('input[name="taxonomy"]').val() || '';
|
||||
|
||||
// Makes sure we can pass an HTMLElement as the ID.
|
||||
if( typeof(id) === 'object' ) {
|
||||
id = this.getId(id);
|
||||
}
|
||||
|
||||
$( 'table.widefat .spinner' ).addClass( 'is-active' );
|
||||
|
||||
params = {
|
||||
action: 'inline-save-tax',
|
||||
tax_type: this.type,
|
||||
tax_ID: id,
|
||||
taxonomy: tax
|
||||
};
|
||||
|
||||
fields = $('#edit-'+id).find(':input').serialize();
|
||||
params = fields + '&' + $.param(params);
|
||||
|
||||
// Do the ajax request to save the data to the server.
|
||||
$.post( ajaxurl, params,
|
||||
/**
|
||||
* Handles the response from the server
|
||||
*
|
||||
* Handles the response from the server, replaces the table row with the response
|
||||
* from the server.
|
||||
*
|
||||
* @param {string} r The string with which to replace the table row.
|
||||
*/
|
||||
function(r) {
|
||||
var row, new_id, option_value,
|
||||
$errorNotice = $( '#edit-' + id + ' .inline-edit-save .notice-error' ),
|
||||
$error = $errorNotice.find( '.error' );
|
||||
|
||||
$( 'table.widefat .spinner' ).removeClass( 'is-active' );
|
||||
|
||||
if (r) {
|
||||
if ( -1 !== r.indexOf( '<tr' ) ) {
|
||||
$(inlineEditTax.what+id).siblings('tr.hidden').addBack().remove();
|
||||
new_id = $(r).attr('id');
|
||||
|
||||
$('#edit-'+id).before(r).remove();
|
||||
|
||||
if ( new_id ) {
|
||||
option_value = new_id.replace( inlineEditTax.type + '-', '' );
|
||||
row = $( '#' + new_id );
|
||||
} else {
|
||||
option_value = id;
|
||||
row = $( inlineEditTax.what + id );
|
||||
}
|
||||
|
||||
// Update the value in the Parent dropdown.
|
||||
$( '#parent' ).find( 'option[value=' + option_value + ']' ).text( row.find( '.row-title' ).text() );
|
||||
|
||||
row.hide().fadeIn( 400, function() {
|
||||
// Move focus back to the Quick Edit button.
|
||||
row.find( '.editinline' )
|
||||
.attr( 'aria-expanded', 'false' )
|
||||
.focus();
|
||||
wp.a11y.speak( inlineEditL10n.saved );
|
||||
});
|
||||
|
||||
} else {
|
||||
$errorNotice.removeClass( 'hidden' );
|
||||
$error.html( r );
|
||||
/*
|
||||
* Some error strings may contain HTML entities (e.g. `“`), let's use
|
||||
* the HTML element's text.
|
||||
*/
|
||||
wp.a11y.speak( $error.text() );
|
||||
}
|
||||
} else {
|
||||
$errorNotice.removeClass( 'hidden' );
|
||||
$error.html( inlineEditL10n.error );
|
||||
wp.a11y.speak( inlineEditL10n.error );
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Prevent submitting the form when pressing Enter on a focused field.
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Closes the quick edit form.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @this inlineEditTax
|
||||
* @memberof inlineEditTax
|
||||
* @returns {void}
|
||||
*/
|
||||
revert : function() {
|
||||
var id = $('table.widefat tr.inline-editor').attr('id');
|
||||
|
||||
if ( id ) {
|
||||
$( 'table.widefat .spinner' ).removeClass( 'is-active' );
|
||||
$('#'+id).siblings('tr.hidden').addBack().remove();
|
||||
id = id.substr( id.lastIndexOf('-') + 1 );
|
||||
|
||||
// Show the taxonomy row and move focus back to the Quick Edit button.
|
||||
$( this.what + id ).show().find( '.editinline' )
|
||||
.attr( 'aria-expanded', 'false' )
|
||||
.focus();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieves the ID of the term of the element inside the table row.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @memberof inlineEditTax
|
||||
*
|
||||
* @param {HTMLElement} o An element within the table row or the table row itself.
|
||||
* @returns {string} The ID of the term based on the element.
|
||||
*/
|
||||
getId : function(o) {
|
||||
var id = o.tagName === 'TR' ? o.id : $(o).parents('tr').attr('id'), parts = id.split('-');
|
||||
|
||||
return parts[parts.length - 1];
|
||||
}
|
||||
};
|
||||
|
||||
$(document).ready(function(){inlineEditTax.init();});
|
||||
|
||||
})( jQuery, window.wp );
|
||||
@@ -0,0 +1,69 @@
|
||||
/* global postboxes, deleteUserSetting, setUserSetting, getUserSetting */
|
||||
|
||||
jQuery(document).ready( function($) {
|
||||
|
||||
var newCat, noSyncChecks = false, syncChecks, catAddAfter;
|
||||
|
||||
$('#link_name').focus();
|
||||
// postboxes
|
||||
postboxes.add_postbox_toggles('link');
|
||||
|
||||
// category tabs
|
||||
$('#category-tabs a').click(function(){
|
||||
var t = $(this).attr('href');
|
||||
$(this).parent().addClass('tabs').siblings('li').removeClass('tabs');
|
||||
$('.tabs-panel').hide();
|
||||
$(t).show();
|
||||
if ( '#categories-all' == t )
|
||||
deleteUserSetting('cats');
|
||||
else
|
||||
setUserSetting('cats','pop');
|
||||
return false;
|
||||
});
|
||||
if ( getUserSetting('cats') )
|
||||
$('#category-tabs a[href="#categories-pop"]').click();
|
||||
|
||||
// Ajax Cat
|
||||
newCat = $('#newcat').one( 'focus', function() { $(this).val( '' ).removeClass( 'form-input-tip' ); } );
|
||||
$('#link-category-add-submit').click( function() { newCat.focus(); } );
|
||||
syncChecks = function() {
|
||||
if ( noSyncChecks )
|
||||
return;
|
||||
noSyncChecks = true;
|
||||
var th = $(this), c = th.is(':checked'), id = th.val().toString();
|
||||
$('#in-link-category-' + id + ', #in-popular-link_category-' + id).prop( 'checked', c );
|
||||
noSyncChecks = false;
|
||||
};
|
||||
|
||||
catAddAfter = function( r, s ) {
|
||||
$(s.what + ' response_data', r).each( function() {
|
||||
var t = $($(this).text());
|
||||
t.find( 'label' ).each( function() {
|
||||
var th = $(this), val = th.find('input').val(), id = th.find('input')[0].id, name = $.trim( th.text() ), o;
|
||||
$('#' + id).change( syncChecks );
|
||||
o = $( '<option value="' + parseInt( val, 10 ) + '"></option>' ).text( name );
|
||||
} );
|
||||
} );
|
||||
};
|
||||
|
||||
$('#categorychecklist').wpList( {
|
||||
alt: '',
|
||||
what: 'link-category',
|
||||
response: 'category-ajax-response',
|
||||
addAfter: catAddAfter
|
||||
} );
|
||||
|
||||
$('a[href="#categories-all"]').click(function(){deleteUserSetting('cats');});
|
||||
$('a[href="#categories-pop"]').click(function(){setUserSetting('cats','pop');});
|
||||
if ( 'pop' == getUserSetting('cats') )
|
||||
$('a[href="#categories-pop"]').click();
|
||||
|
||||
$('#category-add-toggle').click( function() {
|
||||
$(this).parents('div:first').toggleClass( 'wp-hidden-children' );
|
||||
$('#category-tabs a[href="#categories-all"]').click();
|
||||
$('#newcategory').focus();
|
||||
return false;
|
||||
} );
|
||||
|
||||
$('.categorychecklist :checkbox').change( syncChecks ).filter( ':checked' ).change();
|
||||
});
|
||||
@@ -0,0 +1,115 @@
|
||||
/* global tinymce, QTags */
|
||||
|
||||
/**
|
||||
* Contains global functions for the media upload within the post edit screen.
|
||||
*
|
||||
* Updates the ThickBox anchor href and the ThickBox's own properties in order
|
||||
* to set the size and position on every resize event. Also adds a function to
|
||||
* send HTML or text to the currently active editor.
|
||||
*
|
||||
* @file
|
||||
* @since 2.5.0
|
||||
*
|
||||
* @requires jQuery
|
||||
*/
|
||||
|
||||
var wpActiveEditor, send_to_editor;
|
||||
|
||||
/**
|
||||
* Sends the HTML passed in the parameters to TinyMCE.
|
||||
*
|
||||
* @since 2.5.0
|
||||
*
|
||||
* @global
|
||||
*
|
||||
* @param {string} html The HTML to be sent to the editor.
|
||||
* @returns {void|boolean} Returns false when both TinyMCE and QTags instances
|
||||
* are unavailable. This means that the HTML was not
|
||||
* sent to the editor.
|
||||
*/
|
||||
send_to_editor = function( html ) {
|
||||
var editor,
|
||||
hasTinymce = typeof tinymce !== 'undefined',
|
||||
hasQuicktags = typeof QTags !== 'undefined';
|
||||
|
||||
// If no active editor is set, try to set it.
|
||||
if ( ! wpActiveEditor ) {
|
||||
if ( hasTinymce && tinymce.activeEditor ) {
|
||||
editor = tinymce.activeEditor;
|
||||
wpActiveEditor = editor.id;
|
||||
} else if ( ! hasQuicktags ) {
|
||||
return false;
|
||||
}
|
||||
} else if ( hasTinymce ) {
|
||||
editor = tinymce.get( wpActiveEditor );
|
||||
}
|
||||
|
||||
// If the editor is set and not hidden, insert the HTML into the content of the
|
||||
// editor.
|
||||
if ( editor && ! editor.isHidden() ) {
|
||||
editor.execCommand( 'mceInsertContent', false, html );
|
||||
} else if ( hasQuicktags ) {
|
||||
// If quick tags are available, insert the HTML into its content.
|
||||
QTags.insertContent( html );
|
||||
} else {
|
||||
// If neither the TinyMCE editor and the quick tags are available, add the HTML
|
||||
// to the current active editor.
|
||||
document.getElementById( wpActiveEditor ).value += html;
|
||||
}
|
||||
|
||||
// If the old thickbox remove function exists, call it.
|
||||
if ( window.tb_remove ) {
|
||||
try { window.tb_remove(); } catch( e ) {}
|
||||
}
|
||||
};
|
||||
|
||||
var tb_position;
|
||||
(function($) {
|
||||
/**
|
||||
* Recalculates and applies the new ThickBox position based on the current
|
||||
* window size.
|
||||
*
|
||||
* @since 2.6.0
|
||||
*
|
||||
* @global
|
||||
*
|
||||
* @returns {Object[]} Array containing jQuery objects for all the found
|
||||
* ThickBox anchors.
|
||||
*/
|
||||
tb_position = function() {
|
||||
var tbWindow = $('#TB_window'),
|
||||
width = $(window).width(),
|
||||
H = $(window).height(),
|
||||
W = ( 833 < width ) ? 833 : width,
|
||||
adminbar_height = 0;
|
||||
|
||||
if ( $('#wpadminbar').length ) {
|
||||
adminbar_height = parseInt( $('#wpadminbar').css('height'), 10 );
|
||||
}
|
||||
|
||||
if ( tbWindow.length ) {
|
||||
tbWindow.width( W - 50 ).height( H - 45 - adminbar_height );
|
||||
$('#TB_iframeContent').width( W - 50 ).height( H - 75 - adminbar_height );
|
||||
tbWindow.css({'margin-left': '-' + parseInt( ( ( W - 50 ) / 2 ), 10 ) + 'px'});
|
||||
if ( typeof document.body.style.maxWidth !== 'undefined' )
|
||||
tbWindow.css({'top': 20 + adminbar_height + 'px', 'margin-top': '0'});
|
||||
}
|
||||
|
||||
/**
|
||||
* Recalculates the new height and width for all links with a ThickBox class.
|
||||
*
|
||||
* @since 2.6.0
|
||||
*/
|
||||
return $('a.thickbox').each( function() {
|
||||
var href = $(this).attr('href');
|
||||
if ( ! href ) return;
|
||||
href = href.replace(/&width=[0-9]+/g, '');
|
||||
href = href.replace(/&height=[0-9]+/g, '');
|
||||
$(this).attr( 'href', href + '&width=' + ( W - 80 ) + '&height=' + ( H - 85 - adminbar_height ) );
|
||||
});
|
||||
};
|
||||
|
||||
// Add handler to recalculates the ThickBox position when the window is resized.
|
||||
$(window).resize(function(){ tb_position(); });
|
||||
|
||||
})(jQuery);
|
||||
@@ -0,0 +1,207 @@
|
||||
/* global ajaxurl, attachMediaBoxL10n, _wpMediaGridSettings, showNotice */
|
||||
|
||||
/**
|
||||
* Creates a dialog containing posts that can have a particular media attached
|
||||
* to it.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @namespace findPosts
|
||||
*
|
||||
* @requires jQuery
|
||||
*/
|
||||
var findPosts;
|
||||
|
||||
( function( $ ){
|
||||
findPosts = {
|
||||
/**
|
||||
* Opens a dialog to attach media to a post.
|
||||
*
|
||||
* Adds an overlay prior to retrieving a list of posts to attach the media to.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @memberOf findPosts
|
||||
*
|
||||
* @param {string} af_name The name of the affected element.
|
||||
* @param {string} af_val The value of the affected post element.
|
||||
*
|
||||
* @returns {boolean} Always returns false.
|
||||
*/
|
||||
open: function( af_name, af_val ) {
|
||||
var overlay = $( '.ui-find-overlay' );
|
||||
|
||||
if ( overlay.length === 0 ) {
|
||||
$( 'body' ).append( '<div class="ui-find-overlay"></div>' );
|
||||
findPosts.overlay();
|
||||
}
|
||||
|
||||
overlay.show();
|
||||
|
||||
if ( af_name && af_val ) {
|
||||
// #affected is a hidden input field in the dialog that keeps track of which media should be attached.
|
||||
$( '#affected' ).attr( 'name', af_name ).val( af_val );
|
||||
}
|
||||
|
||||
$( '#find-posts' ).show();
|
||||
|
||||
// Close the dialog when the escape key is pressed.
|
||||
$('#find-posts-input').focus().keyup( function( event ){
|
||||
if ( event.which == 27 ) {
|
||||
findPosts.close();
|
||||
}
|
||||
});
|
||||
|
||||
// Retrieves a list of applicable posts for media attachment and shows them.
|
||||
findPosts.send();
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Clears the found posts lists before hiding the attach media dialog.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @memberOf findPosts
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
close: function() {
|
||||
$('#find-posts-response').empty();
|
||||
$('#find-posts').hide();
|
||||
$( '.ui-find-overlay' ).hide();
|
||||
},
|
||||
|
||||
/**
|
||||
* Binds a click event listener to the overlay which closes the attach media
|
||||
* dialog.
|
||||
*
|
||||
* @since 3.5.0
|
||||
*
|
||||
* @memberOf findPosts
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
overlay: function() {
|
||||
$( '.ui-find-overlay' ).on( 'click', function () {
|
||||
findPosts.close();
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieves and displays posts based on the search term.
|
||||
*
|
||||
* Sends a post request to the admin_ajax.php, requesting posts based on the
|
||||
* search term provided by the user. Defaults to all posts if no search term is
|
||||
* provided.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @memberOf findPosts
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
send: function() {
|
||||
var post = {
|
||||
ps: $( '#find-posts-input' ).val(),
|
||||
action: 'find_posts',
|
||||
_ajax_nonce: $('#_ajax_nonce').val()
|
||||
},
|
||||
spinner = $( '.find-box-search .spinner' );
|
||||
|
||||
spinner.addClass( 'is-active' );
|
||||
|
||||
/**
|
||||
* Send a POST request to admin_ajax.php, hide the spinner and replace the list
|
||||
* of posts with the response data. If an error occurs, display it.
|
||||
*/
|
||||
$.ajax( ajaxurl, {
|
||||
type: 'POST',
|
||||
data: post,
|
||||
dataType: 'json'
|
||||
}).always( function() {
|
||||
spinner.removeClass( 'is-active' );
|
||||
}).done( function( x ) {
|
||||
if ( ! x.success ) {
|
||||
$( '#find-posts-response' ).text( attachMediaBoxL10n.error );
|
||||
}
|
||||
|
||||
$( '#find-posts-response' ).html( x.data );
|
||||
}).fail( function() {
|
||||
$( '#find-posts-response' ).text( attachMediaBoxL10n.error );
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Initializes the file once the DOM is fully loaded and attaches events to the
|
||||
* various form elements.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
$( document ).ready( function() {
|
||||
var settings, $mediaGridWrap = $( '#wp-media-grid' );
|
||||
|
||||
// Opens a manage media frame into the grid.
|
||||
if ( $mediaGridWrap.length && window.wp && window.wp.media ) {
|
||||
settings = _wpMediaGridSettings;
|
||||
|
||||
window.wp.media({
|
||||
frame: 'manage',
|
||||
container: $mediaGridWrap,
|
||||
library: settings.queryVars
|
||||
}).open();
|
||||
}
|
||||
|
||||
// Prevents form submission if no post has been selected.
|
||||
$( '#find-posts-submit' ).click( function( event ) {
|
||||
if ( ! $( '#find-posts-response input[type="radio"]:checked' ).length )
|
||||
event.preventDefault();
|
||||
});
|
||||
|
||||
// Submits the search query when hitting the enter key in the search input.
|
||||
$( '#find-posts .find-box-search :input' ).keypress( function( event ) {
|
||||
if ( 13 == event.which ) {
|
||||
findPosts.send();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
// Binds the click event to the search button.
|
||||
$( '#find-posts-search' ).click( findPosts.send );
|
||||
|
||||
// Binds the close dialog click event.
|
||||
$( '#find-posts-close' ).click( findPosts.close );
|
||||
|
||||
// Binds the bulk action events to the submit buttons.
|
||||
$( '#doaction, #doaction2' ).click( function( event ) {
|
||||
|
||||
/*
|
||||
* Retrieves all select elements for bulk actions that have a name starting with `action`
|
||||
* and handle its action based on its value.
|
||||
*/
|
||||
$( 'select[name^="action"]' ).each( function() {
|
||||
var optionValue = $( this ).val();
|
||||
|
||||
if ( 'attach' === optionValue ) {
|
||||
event.preventDefault();
|
||||
findPosts.open();
|
||||
} else if ( 'delete' === optionValue ) {
|
||||
if ( ! showNotice.warn() ) {
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Enables clicking on the entire table row.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
$( '.find-box-inside' ).on( 'click', 'tr', function() {
|
||||
$( this ).find( '.found-radio input' ).prop( 'checked', true );
|
||||
});
|
||||
});
|
||||
})( jQuery );
|
||||
@@ -0,0 +1,220 @@
|
||||
/* global plugininstallL10n, tb_click, tb_remove */
|
||||
|
||||
/**
|
||||
* @file Functionality for the plugin install screens.
|
||||
*/
|
||||
var tb_position;
|
||||
jQuery( document ).ready( function( $ ) {
|
||||
|
||||
var tbWindow,
|
||||
$iframeBody,
|
||||
$tabbables,
|
||||
$firstTabbable,
|
||||
$lastTabbable,
|
||||
$focusedBefore = $(),
|
||||
$uploadViewToggle = $( '.upload-view-toggle' ),
|
||||
$wrap = $ ( '.wrap' ),
|
||||
$body = $( document.body );
|
||||
|
||||
tb_position = function() {
|
||||
var width = $( window ).width(),
|
||||
H = $( window ).height() - ( ( 792 < width ) ? 60 : 20 ),
|
||||
W = ( 792 < width ) ? 772 : width - 20;
|
||||
|
||||
tbWindow = $( '#TB_window' );
|
||||
|
||||
if ( tbWindow.length ) {
|
||||
tbWindow.width( W ).height( H );
|
||||
$( '#TB_iframeContent' ).width( W ).height( H );
|
||||
tbWindow.css({
|
||||
'margin-left': '-' + parseInt( ( W / 2 ), 10 ) + 'px'
|
||||
});
|
||||
if ( typeof document.body.style.maxWidth !== 'undefined' ) {
|
||||
tbWindow.css({
|
||||
'top': '30px',
|
||||
'margin-top': '0'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return $( 'a.thickbox' ).each( function() {
|
||||
var href = $( this ).attr( 'href' );
|
||||
if ( ! href ) {
|
||||
return;
|
||||
}
|
||||
href = href.replace( /&width=[0-9]+/g, '' );
|
||||
href = href.replace( /&height=[0-9]+/g, '' );
|
||||
$(this).attr( 'href', href + '&width=' + W + '&height=' + ( H ) );
|
||||
});
|
||||
};
|
||||
|
||||
$( window ).resize( function() {
|
||||
tb_position();
|
||||
});
|
||||
|
||||
/*
|
||||
* Custom events: when a Thickbox iframe has loaded and when the Thickbox
|
||||
* modal gets removed from the DOM.
|
||||
*/
|
||||
$body
|
||||
.on( 'thickbox:iframe:loaded', tbWindow, function() {
|
||||
/*
|
||||
* Return if it's not the modal with the plugin details iframe. Other
|
||||
* thickbox instances might want to load an iframe with content from
|
||||
* an external domain. Avoid to access the iframe contents when we're
|
||||
* not sure the iframe loads from the same domain.
|
||||
*/
|
||||
if ( ! tbWindow.hasClass( 'plugin-details-modal' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
iframeLoaded();
|
||||
})
|
||||
.on( 'thickbox:removed', function() {
|
||||
// Set focus back to the element that opened the modal dialog.
|
||||
// Note: IE 8 would need this wrapped in a fake setTimeout `0`.
|
||||
$focusedBefore.focus();
|
||||
});
|
||||
|
||||
function iframeLoaded() {
|
||||
var $iframe = tbWindow.find( '#TB_iframeContent' );
|
||||
|
||||
// Get the iframe body.
|
||||
$iframeBody = $iframe.contents().find( 'body' );
|
||||
|
||||
// Get the tabbable elements and handle the keydown event on first load.
|
||||
handleTabbables();
|
||||
|
||||
// Set initial focus on the "Close" button.
|
||||
$firstTabbable.focus();
|
||||
|
||||
/*
|
||||
* When the "Install" button is disabled (e.g. the Plugin is already installed)
|
||||
* then we can't predict where the last focusable element is. We need to get
|
||||
* the tabbable elements and handle the keydown event again and again,
|
||||
* each time the active tab panel changes.
|
||||
*/
|
||||
$( '#plugin-information-tabs a', $iframeBody ).on( 'click', function() {
|
||||
handleTabbables();
|
||||
});
|
||||
|
||||
// Close the modal when pressing Escape.
|
||||
$iframeBody.on( 'keydown', function( event ) {
|
||||
if ( 27 !== event.which ) {
|
||||
return;
|
||||
}
|
||||
tb_remove();
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the tabbable elements and detach/attach the keydown event.
|
||||
* Called after the iframe has fully loaded so we have all the elements we need.
|
||||
* Called again each time a Tab gets clicked.
|
||||
* @todo Consider to implement a WordPress general utility for this and don't use jQuery UI.
|
||||
*/
|
||||
function handleTabbables() {
|
||||
var $firstAndLast;
|
||||
// Get all the tabbable elements.
|
||||
$tabbables = $( ':tabbable', $iframeBody );
|
||||
// Our first tabbable element is always the "Close" button.
|
||||
$firstTabbable = tbWindow.find( '#TB_closeWindowButton' );
|
||||
// Get the last tabbable element.
|
||||
$lastTabbable = $tabbables.last();
|
||||
// Make a jQuery collection.
|
||||
$firstAndLast = $firstTabbable.add( $lastTabbable );
|
||||
// Detach any previously attached keydown event.
|
||||
$firstAndLast.off( 'keydown.wp-plugin-details' );
|
||||
// Attach again the keydown event on the first and last focusable elements.
|
||||
$firstAndLast.on( 'keydown.wp-plugin-details', function( event ) {
|
||||
constrainTabbing( event );
|
||||
});
|
||||
}
|
||||
|
||||
// Constrain tabbing within the plugin modal dialog.
|
||||
function constrainTabbing( event ) {
|
||||
if ( 9 !== event.which ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( $lastTabbable[0] === event.target && ! event.shiftKey ) {
|
||||
event.preventDefault();
|
||||
$firstTabbable.focus();
|
||||
} else if ( $firstTabbable[0] === event.target && event.shiftKey ) {
|
||||
event.preventDefault();
|
||||
$lastTabbable.focus();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Open the Plugin details modal. The event is delegated to get also the links
|
||||
* in the plugins search tab, after the AJAX search rebuilds the HTML. It's
|
||||
* delegated on the closest ancestor and not on the body to avoid conflicts
|
||||
* with other handlers, see Trac ticket #43082.
|
||||
*/
|
||||
$( '.wrap' ).on( 'click', '.thickbox.open-plugin-details-modal', function( e ) {
|
||||
// The `data-title` attribute is used only in the Plugin screens.
|
||||
var title = $( this ).data( 'title' ) ? plugininstallL10n.plugin_information + ' ' + $( this ).data( 'title' ) : plugininstallL10n.plugin_modal_label;
|
||||
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
// Store the element that has focus before opening the modal dialog, i.e. the control which opens it.
|
||||
$focusedBefore = $( this );
|
||||
|
||||
tb_click.call(this);
|
||||
|
||||
// Set ARIA role, ARIA label, and add a CSS class.
|
||||
tbWindow
|
||||
.attr({
|
||||
'role': 'dialog',
|
||||
'aria-label': plugininstallL10n.plugin_modal_label
|
||||
})
|
||||
.addClass( 'plugin-details-modal' );
|
||||
|
||||
// Set title attribute on the iframe.
|
||||
tbWindow.find( '#TB_iframeContent' ).attr( 'title', title );
|
||||
});
|
||||
|
||||
/* Plugin install related JS */
|
||||
$( '#plugin-information-tabs a' ).click( function( event ) {
|
||||
var tab = $( this ).attr( 'name' );
|
||||
event.preventDefault();
|
||||
|
||||
// Flip the tab
|
||||
$( '#plugin-information-tabs a.current' ).removeClass( 'current' );
|
||||
$( this ).addClass( 'current' );
|
||||
|
||||
// Only show the fyi box in the description section, on smaller screen, where it's otherwise always displayed at the top.
|
||||
if ( 'description' !== tab && $( window ).width() < 772 ) {
|
||||
$( '#plugin-information-content' ).find( '.fyi' ).hide();
|
||||
} else {
|
||||
$( '#plugin-information-content' ).find( '.fyi' ).show();
|
||||
}
|
||||
|
||||
// Flip the content.
|
||||
$( '#section-holder div.section' ).hide(); // Hide 'em all.
|
||||
$( '#section-' + tab ).show();
|
||||
});
|
||||
|
||||
/*
|
||||
* When a user presses the "Upload Plugin" button, show the upload form in place
|
||||
* rather than sending them to the devoted upload plugin page.
|
||||
* The `?tab=upload` page still exists for no-js support and for plugins that
|
||||
* might access it directly. When we're in this page, let the link behave
|
||||
* like a link. Otherwise we're in the normal plugin installer pages and the
|
||||
* link should behave like a toggle button.
|
||||
*/
|
||||
if ( ! $wrap.hasClass( 'plugin-install-tab-upload' ) ) {
|
||||
$uploadViewToggle
|
||||
.attr({
|
||||
role: 'button',
|
||||
'aria-expanded': 'false'
|
||||
})
|
||||
.on( 'click', function( event ) {
|
||||
event.preventDefault();
|
||||
$body.toggleClass( 'show-upload-view' );
|
||||
$uploadViewToggle.attr( 'aria-expanded', $body.hasClass( 'show-upload-view' ) );
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,446 @@
|
||||
/**
|
||||
* Contains the postboxes logic, opening and closing postboxes, reordering and saving
|
||||
* the state and ordering to the database.
|
||||
*
|
||||
* @since 2.5.0
|
||||
* @requires jQuery
|
||||
*/
|
||||
|
||||
/* global ajaxurl, postBoxL10n */
|
||||
|
||||
/**
|
||||
* This object contains all function to handle the behaviour of the post boxes. The post boxes are the boxes you see
|
||||
* around the content on the edit page.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @namespace postboxes
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
var postboxes;
|
||||
|
||||
(function($) {
|
||||
var $document = $( document );
|
||||
|
||||
postboxes = {
|
||||
|
||||
/**
|
||||
* Handles a click on either the postbox heading or the postbox open/close icon.
|
||||
*
|
||||
* Opens or closes the postbox. Expects `this` to equal the clicked element.
|
||||
* Calls postboxes.pbshow if the postbox has been opened, calls postboxes.pbhide
|
||||
* if the postbox has been closed.
|
||||
*
|
||||
* @since 4.4.0
|
||||
* @memberof postboxes
|
||||
* @fires postboxes#postbox-toggled
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
handle_click : function () {
|
||||
var $el = $( this ),
|
||||
p = $el.parent( '.postbox' ),
|
||||
id = p.attr( 'id' ),
|
||||
ariaExpandedValue;
|
||||
|
||||
if ( 'dashboard_browser_nag' === id ) {
|
||||
return;
|
||||
}
|
||||
|
||||
p.toggleClass( 'closed' );
|
||||
|
||||
ariaExpandedValue = ! p.hasClass( 'closed' );
|
||||
|
||||
if ( $el.hasClass( 'handlediv' ) ) {
|
||||
// The handle button was clicked.
|
||||
$el.attr( 'aria-expanded', ariaExpandedValue );
|
||||
} else {
|
||||
// The handle heading was clicked.
|
||||
$el.closest( '.postbox' ).find( 'button.handlediv' )
|
||||
.attr( 'aria-expanded', ariaExpandedValue );
|
||||
}
|
||||
|
||||
if ( postboxes.page !== 'press-this' ) {
|
||||
postboxes.save_state( postboxes.page );
|
||||
}
|
||||
|
||||
if ( id ) {
|
||||
if ( !p.hasClass('closed') && $.isFunction( postboxes.pbshow ) ) {
|
||||
postboxes.pbshow( id );
|
||||
} else if ( p.hasClass('closed') && $.isFunction( postboxes.pbhide ) ) {
|
||||
postboxes.pbhide( id );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires when a postbox has been opened or closed.
|
||||
*
|
||||
* Contains a jQuery object with the relevant postbox element.
|
||||
*
|
||||
* @since 4.0.0
|
||||
* @ignore
|
||||
*
|
||||
* @event postboxes#postbox-toggled
|
||||
* @type {Object}
|
||||
*/
|
||||
$document.trigger( 'postbox-toggled', p );
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds event handlers to all postboxes and screen option on the current page.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @memberof postboxes
|
||||
*
|
||||
* @param {string} page The page we are currently on.
|
||||
* @param {Object} [args]
|
||||
* @param {Function} args.pbshow A callback that is called when a postbox opens.
|
||||
* @param {Function} args.pbhide A callback that is called when a postbox closes.
|
||||
* @returns {void}
|
||||
*/
|
||||
add_postbox_toggles : function (page, args) {
|
||||
var $handles = $( '.postbox .hndle, .postbox .handlediv' );
|
||||
|
||||
this.page = page;
|
||||
this.init( page, args );
|
||||
|
||||
$handles.on( 'click.postboxes', this.handle_click );
|
||||
|
||||
/**
|
||||
* @since 2.7.0
|
||||
*/
|
||||
$('.postbox .hndle a').click( function(e) {
|
||||
e.stopPropagation();
|
||||
});
|
||||
|
||||
/**
|
||||
* Hides a postbox.
|
||||
*
|
||||
* Event handler for the postbox dismiss button. After clicking the button
|
||||
* the postbox will be hidden.
|
||||
*
|
||||
* @since 3.2.0
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
$( '.postbox a.dismiss' ).on( 'click.postboxes', function( e ) {
|
||||
var hide_id = $(this).parents('.postbox').attr('id') + '-hide';
|
||||
e.preventDefault();
|
||||
$( '#' + hide_id ).prop('checked', false).triggerHandler('click');
|
||||
});
|
||||
|
||||
/**
|
||||
* Hides the postbox element
|
||||
*
|
||||
* Event handler for the screen options checkboxes. When a checkbox is
|
||||
* clicked this function will hide or show the relevant postboxes.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @ignore
|
||||
*
|
||||
* @fires postboxes#postbox-toggled
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
$('.hide-postbox-tog').bind('click.postboxes', function() {
|
||||
var $el = $(this),
|
||||
boxId = $el.val(),
|
||||
$postbox = $( '#' + boxId );
|
||||
|
||||
if ( $el.prop( 'checked' ) ) {
|
||||
$postbox.show();
|
||||
if ( $.isFunction( postboxes.pbshow ) ) {
|
||||
postboxes.pbshow( boxId );
|
||||
}
|
||||
} else {
|
||||
$postbox.hide();
|
||||
if ( $.isFunction( postboxes.pbhide ) ) {
|
||||
postboxes.pbhide( boxId );
|
||||
}
|
||||
}
|
||||
|
||||
postboxes.save_state( page );
|
||||
postboxes._mark_area();
|
||||
|
||||
/**
|
||||
* @since 4.0.0
|
||||
* @see postboxes.handle_click
|
||||
*/
|
||||
$document.trigger( 'postbox-toggled', $postbox );
|
||||
});
|
||||
|
||||
/**
|
||||
* Changes the amount of columns based on the layout preferences.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
$('.columns-prefs input[type="radio"]').bind('click.postboxes', function(){
|
||||
var n = parseInt($(this).val(), 10);
|
||||
|
||||
if ( n ) {
|
||||
postboxes._pb_edit(n);
|
||||
postboxes.save_order( page );
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Initializes all the postboxes, mainly their sortable behaviour.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @memberof postboxes
|
||||
*
|
||||
* @param {string} page The page we are currently on.
|
||||
* @param {Object} [args={}] The arguments for the postbox initializer.
|
||||
* @param {Function} args.pbshow A callback that is called when a postbox opens.
|
||||
* @param {Function} args.pbhide A callback that is called when a postbox
|
||||
* closes.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
init : function(page, args) {
|
||||
var isMobile = $( document.body ).hasClass( 'mobile' ),
|
||||
$handleButtons = $( '.postbox .handlediv' );
|
||||
|
||||
$.extend( this, args || {} );
|
||||
$('#wpbody-content').css('overflow','hidden');
|
||||
$('.meta-box-sortables').sortable({
|
||||
placeholder: 'sortable-placeholder',
|
||||
connectWith: '.meta-box-sortables',
|
||||
items: '.postbox',
|
||||
handle: '.hndle',
|
||||
cursor: 'move',
|
||||
delay: ( isMobile ? 200 : 0 ),
|
||||
distance: 2,
|
||||
tolerance: 'pointer',
|
||||
forcePlaceholderSize: true,
|
||||
helper: function( event, element ) {
|
||||
/* `helper: 'clone'` is equivalent to `return element.clone();`
|
||||
* Cloning a checked radio and then inserting that clone next to the original
|
||||
* radio unchecks the original radio (since only one of the two can be checked).
|
||||
* We get around this by renaming the helper's inputs' name attributes so that,
|
||||
* when the helper is inserted into the DOM for the sortable, no radios are
|
||||
* duplicated, and no original radio gets unchecked.
|
||||
*/
|
||||
return element.clone()
|
||||
.find( ':input' )
|
||||
.attr( 'name', function( i, currentName ) {
|
||||
return 'sort_' + parseInt( Math.random() * 100000, 10 ).toString() + '_' + currentName;
|
||||
} )
|
||||
.end();
|
||||
},
|
||||
opacity: 0.65,
|
||||
stop: function() {
|
||||
var $el = $( this );
|
||||
|
||||
if ( $el.find( '#dashboard_browser_nag' ).is( ':visible' ) && 'dashboard_browser_nag' != this.firstChild.id ) {
|
||||
$el.sortable('cancel');
|
||||
return;
|
||||
}
|
||||
|
||||
postboxes.save_order(page);
|
||||
},
|
||||
receive: function(e,ui) {
|
||||
if ( 'dashboard_browser_nag' == ui.item[0].id )
|
||||
$(ui.sender).sortable('cancel');
|
||||
|
||||
postboxes._mark_area();
|
||||
$document.trigger( 'postbox-moved', ui.item );
|
||||
}
|
||||
});
|
||||
|
||||
if ( isMobile ) {
|
||||
$(document.body).bind('orientationchange.postboxes', function(){ postboxes._pb_change(); });
|
||||
this._pb_change();
|
||||
}
|
||||
|
||||
this._mark_area();
|
||||
|
||||
// Set the handle buttons `aria-expanded` attribute initial value on page load.
|
||||
$handleButtons.each( function () {
|
||||
var $el = $( this );
|
||||
$el.attr( 'aria-expanded', ! $el.parent( '.postbox' ).hasClass( 'closed' ) );
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Saves the state of the postboxes to the server.
|
||||
*
|
||||
* It sends two lists, one with all the closed postboxes, one with all the
|
||||
* hidden postboxes.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @memberof postboxes
|
||||
*
|
||||
* @param {string} page The page we are currently on.
|
||||
* @returns {void}
|
||||
*/
|
||||
save_state : function(page) {
|
||||
var closed, hidden;
|
||||
|
||||
// Return on the nav-menus.php screen, see #35112.
|
||||
if ( 'nav-menus' === page ) {
|
||||
return;
|
||||
}
|
||||
|
||||
closed = $( '.postbox' ).filter( '.closed' ).map( function() { return this.id; } ).get().join( ',' );
|
||||
hidden = $( '.postbox' ).filter( ':hidden' ).map( function() { return this.id; } ).get().join( ',' );
|
||||
|
||||
$.post(ajaxurl, {
|
||||
action: 'closed-postboxes',
|
||||
closed: closed,
|
||||
hidden: hidden,
|
||||
closedpostboxesnonce: jQuery('#closedpostboxesnonce').val(),
|
||||
page: page
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Saves the order of the postboxes to the server.
|
||||
*
|
||||
* Sends a list of all postboxes inside a sortable area to the server.
|
||||
*
|
||||
* @since 2.8.0
|
||||
* @memberof postboxes
|
||||
*
|
||||
* @param {string} page The page we are currently on.
|
||||
* @returns {void}
|
||||
*/
|
||||
save_order : function(page) {
|
||||
var postVars, page_columns = $('.columns-prefs input:checked').val() || 0;
|
||||
|
||||
postVars = {
|
||||
action: 'meta-box-order',
|
||||
_ajax_nonce: $('#meta-box-order-nonce').val(),
|
||||
page_columns: page_columns,
|
||||
page: page
|
||||
};
|
||||
|
||||
$('.meta-box-sortables').each( function() {
|
||||
postVars[ 'order[' + this.id.split( '-' )[0] + ']' ] = $( this ).sortable( 'toArray' ).join( ',' );
|
||||
} );
|
||||
|
||||
$.post( ajaxurl, postVars );
|
||||
},
|
||||
|
||||
/**
|
||||
* Marks empty postbox areas.
|
||||
*
|
||||
* Adds a message to empty sortable areas on the dashboard page. Also adds a
|
||||
* border around the side area on the post edit screen if there are no postboxes
|
||||
* present.
|
||||
*
|
||||
* @since 3.3.0
|
||||
* @memberof postboxes
|
||||
* @access private
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
_mark_area : function() {
|
||||
var visible = $('div.postbox:visible').length, side = $('#post-body #side-sortables');
|
||||
|
||||
$( '#dashboard-widgets .meta-box-sortables:visible' ).each( function() {
|
||||
var t = $(this);
|
||||
|
||||
if ( visible == 1 || t.children('.postbox:visible').length ) {
|
||||
t.removeClass('empty-container');
|
||||
}
|
||||
else {
|
||||
t.addClass('empty-container');
|
||||
t.attr('data-emptyString', postBoxL10n.postBoxEmptyString);
|
||||
}
|
||||
});
|
||||
|
||||
if ( side.length ) {
|
||||
if ( side.children('.postbox:visible').length )
|
||||
side.removeClass('empty-container');
|
||||
else if ( $('#postbox-container-1').css('width') == '280px' )
|
||||
side.addClass('empty-container');
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Changes the amount of columns on the post edit page.
|
||||
*
|
||||
* @since 3.3.0
|
||||
* @memberof postboxes
|
||||
* @fires postboxes#postboxes-columnchange
|
||||
* @access private
|
||||
*
|
||||
* @param {number} n The amount of columns to divide the post edit page in.
|
||||
* @returns {void}
|
||||
*/
|
||||
_pb_edit : function(n) {
|
||||
var el = $('.metabox-holder').get(0);
|
||||
|
||||
if ( el ) {
|
||||
el.className = el.className.replace(/columns-\d+/, 'columns-' + n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires when the amount of columns on the post edit page has been changed.
|
||||
*
|
||||
* @since 4.0.0
|
||||
* @ignore
|
||||
*
|
||||
* @event postboxes#postboxes-columnchange
|
||||
*/
|
||||
$( document ).trigger( 'postboxes-columnchange' );
|
||||
},
|
||||
|
||||
/**
|
||||
* Changes the amount of columns the postboxes are in based on the current
|
||||
* orientation of the browser.
|
||||
*
|
||||
* @since 3.3.0
|
||||
* @memberof postboxes
|
||||
* @access private
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
_pb_change : function() {
|
||||
var check = $( 'label.columns-prefs-1 input[type="radio"]' );
|
||||
|
||||
switch ( window.orientation ) {
|
||||
case 90:
|
||||
case -90:
|
||||
if ( !check.length || !check.is(':checked') )
|
||||
this._pb_edit(2);
|
||||
break;
|
||||
case 0:
|
||||
case 180:
|
||||
if ( $('#poststuff').length ) {
|
||||
this._pb_edit(1);
|
||||
} else {
|
||||
if ( !check.length || !check.is(':checked') )
|
||||
this._pb_edit(2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
/* Callbacks */
|
||||
|
||||
/**
|
||||
* @since 2.7.0
|
||||
* @memberof postboxes
|
||||
* @access public
|
||||
* @property {Function|boolean} pbshow A callback that is called when a postbox
|
||||
* is opened.
|
||||
*/
|
||||
pbshow : false,
|
||||
|
||||
/**
|
||||
* @since 2.7.0
|
||||
* @memberof postboxes
|
||||
* @access public
|
||||
* @property {Function|boolean} pbhide A callback that is called when a postbox
|
||||
* is closed.
|
||||
*/
|
||||
pbhide : false
|
||||
};
|
||||
|
||||
}(jQuery));
|
||||
@@ -0,0 +1,24 @@
|
||||
/* global setPostThumbnailL10n, ajaxurl, post_id, alert */
|
||||
/* exported WPSetAsThumbnail */
|
||||
|
||||
function WPSetAsThumbnail( id, nonce ) {
|
||||
var $link = jQuery('a#wp-post-thumbnail-' + id);
|
||||
|
||||
$link.text( setPostThumbnailL10n.saving );
|
||||
jQuery.post(ajaxurl, {
|
||||
action: 'set-post-thumbnail', post_id: post_id, thumbnail_id: id, _ajax_nonce: nonce, cookie: encodeURIComponent( document.cookie )
|
||||
}, function(str){
|
||||
var win = window.dialogArguments || opener || parent || top;
|
||||
$link.text( setPostThumbnailL10n.setThumbnail );
|
||||
if ( str == '0' ) {
|
||||
alert( setPostThumbnailL10n.error );
|
||||
} else {
|
||||
jQuery('a.wp-post-thumbnail').show();
|
||||
$link.text( setPostThumbnailL10n.done );
|
||||
$link.fadeOut( 2000 );
|
||||
win.WPSetThumbnailID(id);
|
||||
win.WPSetThumbnailHTML(str);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,432 @@
|
||||
/* jshint curly: false, eqeqeq: false */
|
||||
/* global ajaxurl */
|
||||
|
||||
var tagBox, array_unique_noempty;
|
||||
|
||||
( function( $ ) {
|
||||
var tagDelimiter = ( window.tagsSuggestL10n && window.tagsSuggestL10n.tagDelimiter ) || ',';
|
||||
|
||||
/**
|
||||
* Filters unique items and returns a new array.
|
||||
*
|
||||
* Filters all items from an array into a new array containing only the unique
|
||||
* items. This also excludes whitespace or empty values.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @global
|
||||
*
|
||||
* @param {Array} array The array to filter through.
|
||||
*
|
||||
* @return {Array} A new array containing only the unique items.
|
||||
*/
|
||||
array_unique_noempty = function( array ) {
|
||||
var out = [];
|
||||
|
||||
// Trim the values and ensure they are unique.
|
||||
$.each( array, function( key, val ) {
|
||||
val = $.trim( val );
|
||||
|
||||
if ( val && $.inArray( val, out ) === -1 ) {
|
||||
out.push( val );
|
||||
}
|
||||
} );
|
||||
|
||||
return out;
|
||||
};
|
||||
|
||||
/**
|
||||
* The TagBox object.
|
||||
*
|
||||
* Contains functions to create and manage tags that can be associated with a
|
||||
* post.
|
||||
*
|
||||
* @since 2.9.0
|
||||
*
|
||||
* @global
|
||||
*/
|
||||
tagBox = {
|
||||
/**
|
||||
* Cleans up tags by removing redundant characters.
|
||||
*
|
||||
* @since 2.9.0
|
||||
* @memberOf tagBox
|
||||
*
|
||||
* @param {string} tags Comma separated tags that need to be cleaned up.
|
||||
*
|
||||
* @return {string} The cleaned up tags.
|
||||
*/
|
||||
clean : function( tags ) {
|
||||
if ( ',' !== tagDelimiter ) {
|
||||
tags = tags.replace( new RegExp( tagDelimiter, 'g' ), ',' );
|
||||
}
|
||||
|
||||
tags = tags.replace(/\s*,\s*/g, ',').replace(/,+/g, ',').replace(/[,\s]+$/, '').replace(/^[,\s]+/, '');
|
||||
|
||||
if ( ',' !== tagDelimiter ) {
|
||||
tags = tags.replace( /,/g, tagDelimiter );
|
||||
}
|
||||
|
||||
return tags;
|
||||
},
|
||||
|
||||
/**
|
||||
* Parses tags and makes them editable.
|
||||
*
|
||||
* @since 2.9.0
|
||||
* @memberOf tagBox
|
||||
*
|
||||
* @param {Object} el The tag element to retrieve the ID from.
|
||||
*
|
||||
* @return {boolean} Always returns false.
|
||||
*/
|
||||
parseTags : function(el) {
|
||||
var id = el.id,
|
||||
num = id.split('-check-num-')[1],
|
||||
taxbox = $(el).closest('.tagsdiv'),
|
||||
thetags = taxbox.find('.the-tags'),
|
||||
current_tags = thetags.val().split( tagDelimiter ),
|
||||
new_tags = [];
|
||||
|
||||
delete current_tags[num];
|
||||
|
||||
// Sanitize the current tags and push them as if they're new tags.
|
||||
$.each( current_tags, function( key, val ) {
|
||||
val = $.trim( val );
|
||||
if ( val ) {
|
||||
new_tags.push( val );
|
||||
}
|
||||
});
|
||||
|
||||
thetags.val( this.clean( new_tags.join( tagDelimiter ) ) );
|
||||
|
||||
this.quickClicks( taxbox );
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates clickable links, buttons and fields for adding or editing tags.
|
||||
*
|
||||
* @since 2.9.0
|
||||
* @memberOf tagBox
|
||||
*
|
||||
* @param {Object} el The container HTML element.
|
||||
*
|
||||
* @return {void}
|
||||
*/
|
||||
quickClicks : function( el ) {
|
||||
var thetags = $('.the-tags', el),
|
||||
tagchecklist = $('.tagchecklist', el),
|
||||
id = $(el).attr('id'),
|
||||
current_tags, disabled;
|
||||
|
||||
if ( ! thetags.length )
|
||||
return;
|
||||
|
||||
disabled = thetags.prop('disabled');
|
||||
|
||||
current_tags = thetags.val().split( tagDelimiter );
|
||||
tagchecklist.empty();
|
||||
|
||||
/**
|
||||
* Creates a delete button if tag editing is enabled, before adding it to the tag list.
|
||||
*
|
||||
* @since 2.5.0
|
||||
* @memberOf tagBox
|
||||
*
|
||||
* @param {string} key The index of the current tag.
|
||||
* @param {string} val The value of the current tag.
|
||||
*
|
||||
* @return {void}
|
||||
*/
|
||||
$.each( current_tags, function( key, val ) {
|
||||
var listItem, xbutton;
|
||||
|
||||
val = $.trim( val );
|
||||
|
||||
if ( ! val )
|
||||
return;
|
||||
|
||||
// Create a new list item, and ensure the text is properly escaped.
|
||||
listItem = $( '<li />' ).text( val );
|
||||
|
||||
// If tags editing isn't disabled, create the X button.
|
||||
if ( ! disabled ) {
|
||||
/*
|
||||
* Build the X buttons, hide the X icon with aria-hidden and
|
||||
* use visually hidden text for screen readers.
|
||||
*/
|
||||
xbutton = $( '<button type="button" id="' + id + '-check-num-' + key + '" class="ntdelbutton">' +
|
||||
'<span class="remove-tag-icon" aria-hidden="true"></span>' +
|
||||
'<span class="screen-reader-text">' + window.tagsSuggestL10n.removeTerm + ' ' + listItem.html() + '</span>' +
|
||||
'</button>' );
|
||||
|
||||
/**
|
||||
* Handles the click and keypress event of the tag remove button.
|
||||
*
|
||||
* Makes sure the focus ends up in the tag input field when using
|
||||
* the keyboard to delete the tag.
|
||||
*
|
||||
* @since 4.2.0
|
||||
*
|
||||
* @param {Event} e The click or keypress event to handle.
|
||||
*
|
||||
* @return {void}
|
||||
*/
|
||||
xbutton.on( 'click keypress', function( e ) {
|
||||
// On click or when using the Enter/Spacebar keys.
|
||||
if ( 'click' === e.type || 13 === e.keyCode || 32 === e.keyCode ) {
|
||||
/*
|
||||
* When using the keyboard, move focus back to the
|
||||
* add new tag field. Note: when releasing the pressed
|
||||
* key this will fire the `keyup` event on the input.
|
||||
*/
|
||||
if ( 13 === e.keyCode || 32 === e.keyCode ) {
|
||||
$( this ).closest( '.tagsdiv' ).find( 'input.newtag' ).focus();
|
||||
}
|
||||
|
||||
tagBox.userAction = 'remove';
|
||||
tagBox.parseTags( this );
|
||||
}
|
||||
});
|
||||
|
||||
listItem.prepend( ' ' ).prepend( xbutton );
|
||||
}
|
||||
|
||||
// Append the list item to the tag list.
|
||||
tagchecklist.append( listItem );
|
||||
});
|
||||
|
||||
// The buttons list is built now, give feedback to screen reader users.
|
||||
tagBox.screenReadersMessage();
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds a new tag.
|
||||
*
|
||||
* Also ensures that the quick links are properly generated.
|
||||
*
|
||||
* @since 2.9.0
|
||||
* @memberOf tagBox
|
||||
*
|
||||
* @param {Object} el The container HTML element.
|
||||
* @param {Object|boolean} a When this is an HTML element the text of that
|
||||
* element will be used for the new tag.
|
||||
* @param {number|boolean} f If this value is not passed then the tag input
|
||||
* field is focused.
|
||||
*
|
||||
* @return {boolean} Always returns false.
|
||||
*/
|
||||
flushTags : function( el, a, f ) {
|
||||
var tagsval, newtags, text,
|
||||
tags = $( '.the-tags', el ),
|
||||
newtag = $( 'input.newtag', el );
|
||||
|
||||
a = a || false;
|
||||
|
||||
text = a ? $(a).text() : newtag.val();
|
||||
|
||||
/*
|
||||
* Return if there's no new tag or if the input field is empty.
|
||||
* Note: when using the keyboard to add tags, focus is moved back to
|
||||
* the input field and the `keyup` event attached on this field will
|
||||
* fire when releasing the pressed key. Checking also for the field
|
||||
* emptiness avoids to set the tags and call quickClicks() again.
|
||||
*/
|
||||
if ( 'undefined' == typeof( text ) || '' === text ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
tagsval = tags.val();
|
||||
newtags = tagsval ? tagsval + tagDelimiter + text : text;
|
||||
|
||||
newtags = this.clean( newtags );
|
||||
newtags = array_unique_noempty( newtags.split( tagDelimiter ) ).join( tagDelimiter );
|
||||
tags.val( newtags );
|
||||
this.quickClicks( el );
|
||||
|
||||
if ( ! a )
|
||||
newtag.val('');
|
||||
if ( 'undefined' == typeof( f ) )
|
||||
newtag.focus();
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieves the available tags and creates a tagcloud.
|
||||
*
|
||||
* Retrieves the available tags from the database and creates an interactive
|
||||
* tagcloud. Clicking a tag will add it.
|
||||
*
|
||||
* @since 2.9.0
|
||||
* @memberOf tagBox
|
||||
*
|
||||
* @param {string} id The ID to extract the taxonomy from.
|
||||
*
|
||||
* @return {void}
|
||||
*/
|
||||
get : function( id ) {
|
||||
var tax = id.substr( id.indexOf('-') + 1 );
|
||||
|
||||
/**
|
||||
* Puts a received tag cloud into a DOM element.
|
||||
*
|
||||
* The tag cloud HTML is generated on the server.
|
||||
*
|
||||
* @since 2.9.0
|
||||
*
|
||||
* @param {number|string} r The response message from the AJAX call.
|
||||
* @param {string} stat The status of the AJAX request.
|
||||
*
|
||||
* @return {void}
|
||||
*/
|
||||
$.post( ajaxurl, { 'action': 'get-tagcloud', 'tax': tax }, function( r, stat ) {
|
||||
if ( 0 === r || 'success' != stat ) {
|
||||
return;
|
||||
}
|
||||
|
||||
r = $( '<div id="tagcloud-' + tax + '" class="the-tagcloud">' + r + '</div>' );
|
||||
|
||||
/**
|
||||
* Adds a new tag when a tag in the tagcloud is clicked.
|
||||
*
|
||||
* @since 2.9.0
|
||||
*
|
||||
* @return {boolean} Returns false to prevent the default action.
|
||||
*/
|
||||
$( 'a', r ).click( function() {
|
||||
tagBox.userAction = 'add';
|
||||
tagBox.flushTags( $( '#' + tax ), this );
|
||||
return false;
|
||||
});
|
||||
|
||||
$( '#' + id ).after( r );
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Track the user's last action.
|
||||
*
|
||||
* @since 4.7.0
|
||||
*/
|
||||
userAction: '',
|
||||
|
||||
/**
|
||||
* Dispatches an audible message to screen readers.
|
||||
*
|
||||
* This will inform the user when a tag has been added or removed.
|
||||
*
|
||||
* @since 4.7.0
|
||||
*
|
||||
* @return {void}
|
||||
*/
|
||||
screenReadersMessage: function() {
|
||||
var message;
|
||||
|
||||
switch ( this.userAction ) {
|
||||
case 'remove':
|
||||
message = window.tagsSuggestL10n.termRemoved;
|
||||
break;
|
||||
|
||||
case 'add':
|
||||
message = window.tagsSuggestL10n.termAdded;
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
window.wp.a11y.speak( message, 'assertive' );
|
||||
},
|
||||
|
||||
/**
|
||||
* Initializes the tags box by setting up the links, buttons. Sets up event
|
||||
* handling.
|
||||
*
|
||||
* This includes handling of pressing the enter key in the input field and the
|
||||
* retrieval of tag suggestions.
|
||||
*
|
||||
* @since 2.9.0
|
||||
* @memberOf tagBox
|
||||
*
|
||||
* @return {void}
|
||||
*/
|
||||
init : function() {
|
||||
var ajaxtag = $('div.ajaxtag');
|
||||
|
||||
$('.tagsdiv').each( function() {
|
||||
tagBox.quickClicks( this );
|
||||
});
|
||||
|
||||
$( '.tagadd', ajaxtag ).click( function() {
|
||||
tagBox.userAction = 'add';
|
||||
tagBox.flushTags( $( this ).closest( '.tagsdiv' ) );
|
||||
});
|
||||
|
||||
/**
|
||||
* Handles pressing enter on the new tag input field.
|
||||
*
|
||||
* Prevents submitting the post edit form.
|
||||
*
|
||||
* @since 2.9.0
|
||||
*
|
||||
* @param {Event} event The keypress event that occurred.
|
||||
*
|
||||
* @return {void}
|
||||
*/
|
||||
$( 'input.newtag', ajaxtag ).keypress( function( event ) {
|
||||
if ( 13 == event.which ) {
|
||||
tagBox.userAction = 'add';
|
||||
tagBox.flushTags( $( this ).closest( '.tagsdiv' ) );
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
}
|
||||
}).keypress( function( event ) {
|
||||
if ( 13 == event.which ) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
}
|
||||
}).each( function( i, element ) {
|
||||
$( element ).wpTagsSuggest();
|
||||
});
|
||||
|
||||
/**
|
||||
* Before a post is saved the value currently in the new tag input field will be
|
||||
* added as a tag.
|
||||
*
|
||||
* @since 2.9.0
|
||||
*
|
||||
* @return {void}
|
||||
*/
|
||||
$('#post').submit(function(){
|
||||
$('div.tagsdiv').each( function() {
|
||||
tagBox.flushTags(this, false, 1);
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Handles clicking on the tag cloud link.
|
||||
*
|
||||
* Makes sure the ARIA attributes are set correctly.
|
||||
*
|
||||
* @since 2.9.0
|
||||
*
|
||||
* @return {void}
|
||||
*/
|
||||
$('.tagcloud-link').click(function(){
|
||||
// On the first click, fetch the tag cloud and insert it in the DOM.
|
||||
tagBox.get( $( this ).attr( 'id' ) );
|
||||
// Update button state, remove previous click event and attach a new one to toggle the cloud.
|
||||
$( this )
|
||||
.attr( 'aria-expanded', 'true' )
|
||||
.unbind()
|
||||
.click( function() {
|
||||
$( this )
|
||||
.attr( 'aria-expanded', 'false' === $( this ).attr( 'aria-expanded' ) ? 'true' : 'false' )
|
||||
.siblings( '.the-tagcloud' ).toggle();
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
}( jQuery ));
|
||||
@@ -0,0 +1,166 @@
|
||||
/**
|
||||
* Default settings for jQuery UI Autocomplete for use with non-hierarchical taxonomies.
|
||||
*/
|
||||
( function( $ ) {
|
||||
if ( typeof window.tagsSuggestL10n === 'undefined' || typeof window.uiAutocompleteL10n === 'undefined' ) {
|
||||
return;
|
||||
}
|
||||
|
||||
var separator = window.tagsSuggestL10n.tagDelimiter || ',';
|
||||
|
||||
function split( val ) {
|
||||
return val.split( new RegExp( separator + '\\s*' ) );
|
||||
}
|
||||
|
||||
function getLast( term ) {
|
||||
return split( term ).pop();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add UI Autocomplete to an input or textarea element with presets for use
|
||||
* with non-hierarchical taxonomies.
|
||||
*
|
||||
* Example: `$( element ).wpTagsSuggest( options )`.
|
||||
*
|
||||
* The taxonomy can be passed in a `data-wp-taxonomy` attribute on the element or
|
||||
* can be in `options.taxonomy`.
|
||||
*
|
||||
* @since 4.7.0
|
||||
*
|
||||
* @param {object} options Options that are passed to UI Autocomplete. Can be used to override the default settings.
|
||||
* @returns {object} jQuery instance.
|
||||
*/
|
||||
$.fn.wpTagsSuggest = function( options ) {
|
||||
var cache;
|
||||
var last;
|
||||
var $element = $( this );
|
||||
|
||||
options = options || {};
|
||||
|
||||
var taxonomy = options.taxonomy || $element.attr( 'data-wp-taxonomy' ) || 'post_tag';
|
||||
|
||||
delete( options.taxonomy );
|
||||
|
||||
options = $.extend( {
|
||||
source: function( request, response ) {
|
||||
var term;
|
||||
|
||||
if ( last === request.term ) {
|
||||
response( cache );
|
||||
return;
|
||||
}
|
||||
|
||||
term = getLast( request.term );
|
||||
|
||||
$.get( window.tagsSuggestL10n.restURL, {
|
||||
_fields: [ 'id', 'name' ],
|
||||
taxonomy: taxonomy,
|
||||
search: term
|
||||
} ).always( function() {
|
||||
$element.removeClass( 'ui-autocomplete-loading' ); // UI fails to remove this sometimes?
|
||||
} ).done( function( data ) {
|
||||
cache = data;
|
||||
response( data );
|
||||
} );
|
||||
|
||||
last = request.term;
|
||||
},
|
||||
focus: function( event, ui ) {
|
||||
$element.attr( 'aria-activedescendant', 'wp-tags-autocomplete-' + ui.item.id );
|
||||
|
||||
// Don't empty the input field when using the arrow keys to
|
||||
// highlight items. See api.jqueryui.com/autocomplete/#event-focus
|
||||
event.preventDefault();
|
||||
},
|
||||
select: function( event, ui ) {
|
||||
var tags = split( $element.val() );
|
||||
// Remove the last user input.
|
||||
tags.pop();
|
||||
// Append the new tag and an empty element to get one more separator at the end.
|
||||
tags.push( ui.item.name, '' );
|
||||
|
||||
$element.val( tags.join( separator + ' ' ) );
|
||||
|
||||
if ( $.ui.keyCode.TAB === event.keyCode ) {
|
||||
// Audible confirmation message when a tag has been selected.
|
||||
window.wp.a11y.speak( window.tagsSuggestL10n.termSelected, 'assertive' );
|
||||
event.preventDefault();
|
||||
} else if ( $.ui.keyCode.ENTER === event.keyCode ) {
|
||||
// Do not close Quick Edit / Bulk Edit
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
open: function() {
|
||||
$element.attr( 'aria-expanded', 'true' );
|
||||
},
|
||||
close: function() {
|
||||
$element.attr( 'aria-expanded', 'false' );
|
||||
},
|
||||
minLength: window.tagsSuggestL10n.minChars,
|
||||
position: {
|
||||
my: 'left top+2',
|
||||
at: 'left bottom',
|
||||
collision: 'none'
|
||||
},
|
||||
messages: {
|
||||
noResults: window.uiAutocompleteL10n.noResults,
|
||||
results: function( number ) {
|
||||
if ( number > 1 ) {
|
||||
return window.uiAutocompleteL10n.manyResults.replace( '%d', number );
|
||||
}
|
||||
|
||||
return window.uiAutocompleteL10n.oneResult;
|
||||
}
|
||||
}
|
||||
}, options );
|
||||
|
||||
$element.on( 'keydown', function() {
|
||||
$element.removeAttr( 'aria-activedescendant' );
|
||||
} )
|
||||
.autocomplete( options )
|
||||
.autocomplete( 'instance' )._renderItem = function( ul, item ) {
|
||||
return $( '<li role="option" id="wp-tags-autocomplete-' + item.id + '">' )
|
||||
.text( item.name )
|
||||
.appendTo( ul );
|
||||
};
|
||||
|
||||
$element.attr( {
|
||||
'role': 'combobox',
|
||||
'aria-autocomplete': 'list',
|
||||
'aria-expanded': 'false',
|
||||
'aria-owns': $element.autocomplete( 'widget' ).attr( 'id' )
|
||||
} )
|
||||
.on( 'focus', function() {
|
||||
var inputValue = split( $element.val() ).pop();
|
||||
|
||||
// Don't trigger a search if the field is empty.
|
||||
// Also, avoids screen readers announce `No search results`.
|
||||
if ( inputValue ) {
|
||||
$element.autocomplete( 'search' );
|
||||
}
|
||||
} )
|
||||
// Returns a jQuery object containing the menu element.
|
||||
.autocomplete( 'widget' )
|
||||
.addClass( 'wp-tags-autocomplete' )
|
||||
.attr( 'role', 'listbox' )
|
||||
.removeAttr( 'tabindex' ) // Remove the `tabindex=0` attribute added by jQuery UI.
|
||||
|
||||
// Looks like Safari and VoiceOver need an `aria-selected` attribute. See ticket #33301.
|
||||
// The `menufocus` and `menublur` events are the same events used to add and remove
|
||||
// the `ui-state-focus` CSS class on the menu items. See jQuery UI Menu Widget.
|
||||
.on( 'menufocus', function( event, ui ) {
|
||||
ui.item.attr( 'aria-selected', 'true' );
|
||||
})
|
||||
.on( 'menublur', function() {
|
||||
// The `menublur` event returns an object where the item is `null`
|
||||
// so we need to find the active item with other means.
|
||||
$( this ).find( '[aria-selected="true"]' ).removeAttr( 'aria-selected' );
|
||||
});
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
}( jQuery ) );
|
||||
@@ -0,0 +1,144 @@
|
||||
/* global ajaxurl, wpAjax, tagsl10n, showNotice, validateForm */
|
||||
/**
|
||||
* Contains logic for deleting and adding tags.
|
||||
*
|
||||
* For deleting tags it makes a request to the server to delete the tag.
|
||||
* For adding tags it makes a request to the server to add the tag.
|
||||
*/
|
||||
|
||||
jQuery(document).ready(function($) {
|
||||
|
||||
/**
|
||||
* Adds an event handler to the delete term link on the term overview page.
|
||||
*
|
||||
* Cancels default event handling and event bubbling.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @returns boolean Always returns false to cancel the default event handling.
|
||||
*/
|
||||
$( '#the-list' ).on( 'click', '.delete-tag', function() {
|
||||
var t = $(this), tr = t.parents('tr'), r = true, data;
|
||||
|
||||
if ( 'undefined' != showNotice )
|
||||
r = showNotice.warn();
|
||||
|
||||
if ( r ) {
|
||||
data = t.attr('href').replace(/[^?]*\?/, '').replace(/action=delete/, 'action=delete-tag');
|
||||
|
||||
/**
|
||||
* Makes a request to the server to delete the term that corresponds to the
|
||||
* delete term button.
|
||||
*
|
||||
* @param {string} r The response from the server.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
$.post(ajaxurl, data, function(r){
|
||||
if ( '1' == r ) {
|
||||
$('#ajax-response').empty();
|
||||
tr.fadeOut('normal', function(){ tr.remove(); });
|
||||
|
||||
/**
|
||||
* Removes the term from the parent box and the tag cloud.
|
||||
*
|
||||
* `data.match(/tag_ID=(\d+)/)[1]` matches the term id from the data variable.
|
||||
* This term id is then used to select the relevant HTML elements:
|
||||
* The parent box and the tag cloud.
|
||||
*/
|
||||
$('select#parent option[value="' + data.match(/tag_ID=(\d+)/)[1] + '"]').remove();
|
||||
$('a.tag-link-' + data.match(/tag_ID=(\d+)/)[1]).remove();
|
||||
|
||||
} else if ( '-1' == r ) {
|
||||
$('#ajax-response').empty().append('<div class="error"><p>' + tagsl10n.noPerm + '</p></div>');
|
||||
tr.children().css('backgroundColor', '');
|
||||
|
||||
} else {
|
||||
$('#ajax-response').empty().append('<div class="error"><p>' + tagsl10n.broken + '</p></div>');
|
||||
tr.children().css('backgroundColor', '');
|
||||
}
|
||||
});
|
||||
|
||||
tr.children().css('backgroundColor', '#f33');
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
/**
|
||||
* Adds a deletion confirmation when removing a tag.
|
||||
*
|
||||
* @since 4.8.0
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
$( '#edittag' ).on( 'click', '.delete', function( e ) {
|
||||
if ( 'undefined' === typeof showNotice ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Confirms the deletion, a negative response means the deletion must not be executed.
|
||||
var response = showNotice.warn();
|
||||
if ( ! response ) {
|
||||
e.preventDefault();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Adds an event handler to the form submit on the term overview page.
|
||||
*
|
||||
* Cancels default event handling and event bubbling.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @returns boolean Always returns false to cancel the default event handling.
|
||||
*/
|
||||
$('#submit').click(function(){
|
||||
var form = $(this).parents('form');
|
||||
|
||||
if ( ! validateForm( form ) )
|
||||
return false;
|
||||
|
||||
/**
|
||||
* Does a request to the server to add a new term to the database
|
||||
*
|
||||
* @param {string} r The response from the server.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
$.post(ajaxurl, $('#addtag').serialize(), function(r){
|
||||
var res, parent, term, indent, i;
|
||||
|
||||
$('#ajax-response').empty();
|
||||
res = wpAjax.parseAjaxResponse( r, 'ajax-response' );
|
||||
if ( ! res || res.errors )
|
||||
return;
|
||||
|
||||
parent = form.find( 'select#parent' ).val();
|
||||
|
||||
if ( parent > 0 && $('#tag-' + parent ).length > 0 ) // If the parent exists on this page, insert it below. Else insert it at the top of the list.
|
||||
$( '.tags #tag-' + parent ).after( res.responses[0].supplemental.noparents ); // As the parent exists, Insert the version with - - - prefixed
|
||||
else
|
||||
$( '.tags' ).prepend( res.responses[0].supplemental.parents ); // As the parent is not visible, Insert the version with Parent - Child - ThisTerm
|
||||
|
||||
$('.tags .no-items').remove();
|
||||
|
||||
if ( form.find('select#parent') ) {
|
||||
// Parents field exists, Add new term to the list.
|
||||
term = res.responses[1].supplemental;
|
||||
|
||||
// Create an indent for the Parent field
|
||||
indent = '';
|
||||
for ( i = 0; i < res.responses[1].position; i++ )
|
||||
indent += ' ';
|
||||
|
||||
form.find( 'select#parent option:selected' ).after( '<option value="' + term.term_id + '">' + indent + term.name + '</option>' );
|
||||
}
|
||||
|
||||
$('input[type="text"]:visible, textarea:visible', form).val('');
|
||||
});
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
});
|
||||
@@ -0,0 +1,470 @@
|
||||
/* global ajaxurl, pwsL10n, userProfileL10n */
|
||||
(function($) {
|
||||
var updateLock = false,
|
||||
|
||||
$pass1Row,
|
||||
$pass1Wrap,
|
||||
$pass1,
|
||||
$pass1Text,
|
||||
$pass1Label,
|
||||
$pass2,
|
||||
$weakRow,
|
||||
$weakCheckbox,
|
||||
$toggleButton,
|
||||
$submitButtons,
|
||||
$submitButton,
|
||||
currentPass,
|
||||
inputEvent;
|
||||
|
||||
/*
|
||||
* Use feature detection to determine whether password inputs should use
|
||||
* the `keyup` or `input` event. Input is preferred but lacks support
|
||||
* in legacy browsers.
|
||||
*/
|
||||
if ( 'oninput' in document.createElement( 'input' ) ) {
|
||||
inputEvent = 'input';
|
||||
} else {
|
||||
inputEvent = 'keyup';
|
||||
}
|
||||
|
||||
function generatePassword() {
|
||||
if ( typeof zxcvbn !== 'function' ) {
|
||||
setTimeout( generatePassword, 50 );
|
||||
return;
|
||||
} else if ( ! $pass1.val() ) {
|
||||
// zxcvbn loaded before user entered password.
|
||||
$pass1.val( $pass1.data( 'pw' ) );
|
||||
$pass1.trigger( 'pwupdate' );
|
||||
showOrHideWeakPasswordCheckbox();
|
||||
}
|
||||
else {
|
||||
// zxcvbn loaded after the user entered password, check strength.
|
||||
check_pass_strength();
|
||||
showOrHideWeakPasswordCheckbox();
|
||||
}
|
||||
|
||||
if ( 1 !== parseInt( $toggleButton.data( 'start-masked' ), 10 ) ) {
|
||||
$pass1Wrap.addClass( 'show-password' );
|
||||
} else {
|
||||
$toggleButton.trigger( 'click' );
|
||||
}
|
||||
|
||||
// Once zxcvbn loads, passwords strength is known.
|
||||
$( '#pw-weak-text-label' ).html( userProfileL10n.warnWeak );
|
||||
}
|
||||
|
||||
function bindPass1() {
|
||||
currentPass = $pass1.val();
|
||||
|
||||
$pass1Wrap = $pass1.parent();
|
||||
|
||||
$pass1Text = $( '<input type="text"/>' )
|
||||
.attr( {
|
||||
'id': 'pass1-text',
|
||||
'name': 'pass1-text',
|
||||
'autocomplete': 'off'
|
||||
} )
|
||||
.addClass( $pass1[0].className )
|
||||
.data( 'pw', $pass1.data( 'pw' ) )
|
||||
.val( $pass1.val() )
|
||||
.on( inputEvent, function () {
|
||||
if ( $pass1Text.val() === currentPass ) {
|
||||
return;
|
||||
}
|
||||
$pass2.val( $pass1Text.val() );
|
||||
$pass1.val( $pass1Text.val() ).trigger( 'pwupdate' );
|
||||
currentPass = $pass1Text.val();
|
||||
} );
|
||||
|
||||
$pass1.after( $pass1Text );
|
||||
|
||||
if ( 1 === parseInt( $pass1.data( 'reveal' ), 10 ) ) {
|
||||
generatePassword();
|
||||
}
|
||||
|
||||
$pass1.on( inputEvent + ' pwupdate', function () {
|
||||
if ( $pass1.val() === currentPass ) {
|
||||
return;
|
||||
}
|
||||
|
||||
currentPass = $pass1.val();
|
||||
if ( $pass1Text.val() !== currentPass ) {
|
||||
$pass1Text.val( currentPass );
|
||||
}
|
||||
$pass1.add( $pass1Text ).removeClass( 'short bad good strong' );
|
||||
showOrHideWeakPasswordCheckbox();
|
||||
} );
|
||||
}
|
||||
|
||||
function resetToggle() {
|
||||
$toggleButton
|
||||
.data( 'toggle', 0 )
|
||||
.attr({
|
||||
'aria-label': userProfileL10n.ariaHide
|
||||
})
|
||||
.find( '.text' )
|
||||
.text( userProfileL10n.hide )
|
||||
.end()
|
||||
.find( '.dashicons' )
|
||||
.removeClass( 'dashicons-visibility' )
|
||||
.addClass( 'dashicons-hidden' );
|
||||
|
||||
$pass1Text.focus();
|
||||
|
||||
$pass1Label.attr( 'for', 'pass1-text' );
|
||||
}
|
||||
|
||||
function bindToggleButton() {
|
||||
$toggleButton = $pass1Row.find('.wp-hide-pw');
|
||||
$toggleButton.show().on( 'click', function () {
|
||||
if ( 1 === parseInt( $toggleButton.data( 'toggle' ), 10 ) ) {
|
||||
$pass1Wrap.addClass( 'show-password' );
|
||||
|
||||
resetToggle();
|
||||
|
||||
if ( ! _.isUndefined( $pass1Text[0].setSelectionRange ) ) {
|
||||
$pass1Text[0].setSelectionRange( 0, 100 );
|
||||
}
|
||||
} else {
|
||||
$pass1Wrap.removeClass( 'show-password' );
|
||||
$toggleButton
|
||||
.data( 'toggle', 1 )
|
||||
.attr({
|
||||
'aria-label': userProfileL10n.ariaShow
|
||||
})
|
||||
.find( '.text' )
|
||||
.text( userProfileL10n.show )
|
||||
.end()
|
||||
.find( '.dashicons' )
|
||||
.removeClass('dashicons-hidden')
|
||||
.addClass('dashicons-visibility');
|
||||
|
||||
$pass1.focus();
|
||||
|
||||
$pass1Label.attr( 'for', 'pass1' );
|
||||
|
||||
if ( ! _.isUndefined( $pass1[0].setSelectionRange ) ) {
|
||||
$pass1[0].setSelectionRange( 0, 100 );
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function bindPasswordForm() {
|
||||
var $passwordWrapper,
|
||||
$generateButton,
|
||||
$cancelButton;
|
||||
|
||||
$pass1Row = $('.user-pass1-wrap');
|
||||
$pass1Label = $pass1Row.find('th label').attr( 'for', 'pass1-text' );
|
||||
|
||||
// hide this
|
||||
$('.user-pass2-wrap').hide();
|
||||
|
||||
$submitButton = $( '#submit, #wp-submit' ).on( 'click', function () {
|
||||
updateLock = false;
|
||||
});
|
||||
|
||||
$submitButtons = $submitButton.add( ' #createusersub' );
|
||||
|
||||
$weakRow = $( '.pw-weak' );
|
||||
$weakCheckbox = $weakRow.find( '.pw-checkbox' );
|
||||
$weakCheckbox.change( function() {
|
||||
$submitButtons.prop( 'disabled', ! $weakCheckbox.prop( 'checked' ) );
|
||||
} );
|
||||
|
||||
$pass1 = $('#pass1');
|
||||
if ( $pass1.length ) {
|
||||
bindPass1();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fix a LastPass mismatch issue, LastPass only changes pass2.
|
||||
*
|
||||
* This fixes the issue by copying any changes from the hidden
|
||||
* pass2 field to the pass1 field, then running check_pass_strength.
|
||||
*/
|
||||
$pass2 = $('#pass2').on( inputEvent, function () {
|
||||
if ( $pass2.val().length > 0 ) {
|
||||
$pass1.val( $pass2.val() );
|
||||
$pass2.val('');
|
||||
currentPass = '';
|
||||
$pass1.trigger( 'pwupdate' );
|
||||
}
|
||||
} );
|
||||
|
||||
// Disable hidden inputs to prevent autofill and submission.
|
||||
if ( $pass1.is( ':hidden' ) ) {
|
||||
$pass1.prop( 'disabled', true );
|
||||
$pass2.prop( 'disabled', true );
|
||||
$pass1Text.prop( 'disabled', true );
|
||||
}
|
||||
|
||||
$passwordWrapper = $pass1Row.find( '.wp-pwd' );
|
||||
$generateButton = $pass1Row.find( 'button.wp-generate-pw' );
|
||||
|
||||
bindToggleButton();
|
||||
|
||||
if ( $generateButton.length ) {
|
||||
$passwordWrapper.hide();
|
||||
}
|
||||
|
||||
$generateButton.show();
|
||||
$generateButton.on( 'click', function () {
|
||||
updateLock = true;
|
||||
|
||||
$generateButton.hide();
|
||||
$passwordWrapper.show();
|
||||
|
||||
// Enable the inputs when showing.
|
||||
$pass1.attr( 'disabled', false );
|
||||
$pass2.attr( 'disabled', false );
|
||||
$pass1Text.attr( 'disabled', false );
|
||||
|
||||
if ( $pass1Text.val().length === 0 ) {
|
||||
generatePassword();
|
||||
}
|
||||
|
||||
_.defer( function() {
|
||||
$pass1Text.focus();
|
||||
if ( ! _.isUndefined( $pass1Text[0].setSelectionRange ) ) {
|
||||
$pass1Text[0].setSelectionRange( 0, 100 );
|
||||
}
|
||||
}, 0 );
|
||||
} );
|
||||
|
||||
$cancelButton = $pass1Row.find( 'button.wp-cancel-pw' );
|
||||
$cancelButton.on( 'click', function () {
|
||||
updateLock = false;
|
||||
|
||||
// Clear any entered password.
|
||||
$pass1Text.val( '' );
|
||||
|
||||
// Generate a new password.
|
||||
wp.ajax.post( 'generate-password' )
|
||||
.done( function( data ) {
|
||||
$pass1.data( 'pw', data );
|
||||
} );
|
||||
|
||||
$generateButton.show();
|
||||
$passwordWrapper.hide();
|
||||
|
||||
$weakRow.hide( 0, function () {
|
||||
$weakCheckbox.removeProp( 'checked' );
|
||||
} );
|
||||
|
||||
// Disable the inputs when hiding to prevent autofill and submission.
|
||||
$pass1.prop( 'disabled', true );
|
||||
$pass2.prop( 'disabled', true );
|
||||
$pass1Text.prop( 'disabled', true );
|
||||
|
||||
resetToggle();
|
||||
|
||||
if ( $pass1Row.closest( 'form' ).is( '#your-profile' ) ) {
|
||||
// Clear password field to prevent update
|
||||
$pass1.val( '' ).trigger( 'pwupdate' );
|
||||
$submitButtons.prop( 'disabled', false );
|
||||
}
|
||||
} );
|
||||
|
||||
$pass1Row.closest( 'form' ).on( 'submit', function () {
|
||||
updateLock = false;
|
||||
|
||||
$pass1.prop( 'disabled', false );
|
||||
$pass2.prop( 'disabled', false );
|
||||
$pass2.val( $pass1.val() );
|
||||
$pass1Wrap.removeClass( 'show-password' );
|
||||
});
|
||||
}
|
||||
|
||||
function check_pass_strength() {
|
||||
var pass1 = $('#pass1').val(), strength;
|
||||
|
||||
$('#pass-strength-result').removeClass('short bad good strong');
|
||||
if ( ! pass1 ) {
|
||||
$('#pass-strength-result').html( ' ' );
|
||||
return;
|
||||
}
|
||||
|
||||
strength = wp.passwordStrength.meter( pass1, wp.passwordStrength.userInputBlacklist(), pass1 );
|
||||
|
||||
switch ( strength ) {
|
||||
case -1:
|
||||
$( '#pass-strength-result' ).addClass( 'bad' ).html( pwsL10n.unknown );
|
||||
break;
|
||||
case 2:
|
||||
$('#pass-strength-result').addClass('bad').html( pwsL10n.bad );
|
||||
break;
|
||||
case 3:
|
||||
$('#pass-strength-result').addClass('good').html( pwsL10n.good );
|
||||
break;
|
||||
case 4:
|
||||
$('#pass-strength-result').addClass('strong').html( pwsL10n.strong );
|
||||
break;
|
||||
case 5:
|
||||
$('#pass-strength-result').addClass('short').html( pwsL10n.mismatch );
|
||||
break;
|
||||
default:
|
||||
$('#pass-strength-result').addClass('short').html( pwsL10n['short'] );
|
||||
}
|
||||
}
|
||||
|
||||
function showOrHideWeakPasswordCheckbox() {
|
||||
var passStrength = $('#pass-strength-result')[0];
|
||||
|
||||
if ( passStrength.className ) {
|
||||
$pass1.add( $pass1Text ).addClass( passStrength.className );
|
||||
if ( $( passStrength ).is( '.short, .bad' ) ) {
|
||||
if ( ! $weakCheckbox.prop( 'checked' ) ) {
|
||||
$submitButtons.prop( 'disabled', true );
|
||||
}
|
||||
$weakRow.show();
|
||||
} else {
|
||||
$submitButtons.prop( 'disabled', false );
|
||||
$weakRow.hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$(document).ready( function() {
|
||||
var $colorpicker, $stylesheet, user_id, current_user_id,
|
||||
select = $( '#display_name' ),
|
||||
current_name = select.val(),
|
||||
greeting = $( '#wp-admin-bar-my-account' ).find( '.display-name' );
|
||||
|
||||
$('#pass1').val('').on( inputEvent + ' pwupdate', check_pass_strength );
|
||||
$('#pass-strength-result').show();
|
||||
$('.color-palette').click( function() {
|
||||
$(this).siblings('input[name="admin_color"]').prop('checked', true);
|
||||
});
|
||||
|
||||
if ( select.length ) {
|
||||
$('#first_name, #last_name, #nickname').bind( 'blur.user_profile', function() {
|
||||
var dub = [],
|
||||
inputs = {
|
||||
display_nickname : $('#nickname').val() || '',
|
||||
display_username : $('#user_login').val() || '',
|
||||
display_firstname : $('#first_name').val() || '',
|
||||
display_lastname : $('#last_name').val() || ''
|
||||
};
|
||||
|
||||
if ( inputs.display_firstname && inputs.display_lastname ) {
|
||||
inputs.display_firstlast = inputs.display_firstname + ' ' + inputs.display_lastname;
|
||||
inputs.display_lastfirst = inputs.display_lastname + ' ' + inputs.display_firstname;
|
||||
}
|
||||
|
||||
$.each( $('option', select), function( i, el ){
|
||||
dub.push( el.value );
|
||||
});
|
||||
|
||||
$.each(inputs, function( id, value ) {
|
||||
if ( ! value ) {
|
||||
return;
|
||||
}
|
||||
|
||||
var val = value.replace(/<\/?[a-z][^>]*>/gi, '');
|
||||
|
||||
if ( inputs[id].length && $.inArray( val, dub ) === -1 ) {
|
||||
dub.push(val);
|
||||
$('<option />', {
|
||||
'text': val
|
||||
}).appendTo( select );
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Replaces "Howdy, *" in the admin toolbar whenever the display name dropdown is updated for one's own profile.
|
||||
*/
|
||||
select.on( 'change', function() {
|
||||
if ( user_id !== current_user_id ) {
|
||||
return;
|
||||
}
|
||||
|
||||
var display_name = $.trim( this.value ) || current_name;
|
||||
|
||||
greeting.text( display_name );
|
||||
} );
|
||||
}
|
||||
|
||||
$colorpicker = $( '#color-picker' );
|
||||
$stylesheet = $( '#colors-css' );
|
||||
user_id = $( 'input#user_id' ).val();
|
||||
current_user_id = $( 'input[name="checkuser_id"]' ).val();
|
||||
|
||||
$colorpicker.on( 'click.colorpicker', '.color-option', function() {
|
||||
var colors,
|
||||
$this = $(this);
|
||||
|
||||
if ( $this.hasClass( 'selected' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this.siblings( '.selected' ).removeClass( 'selected' );
|
||||
$this.addClass( 'selected' ).find( 'input[type="radio"]' ).prop( 'checked', true );
|
||||
|
||||
// Set color scheme
|
||||
if ( user_id === current_user_id ) {
|
||||
// Load the colors stylesheet.
|
||||
// The default color scheme won't have one, so we'll need to create an element.
|
||||
if ( 0 === $stylesheet.length ) {
|
||||
$stylesheet = $( '<link rel="stylesheet" />' ).appendTo( 'head' );
|
||||
}
|
||||
$stylesheet.attr( 'href', $this.children( '.css_url' ).val() );
|
||||
|
||||
// repaint icons
|
||||
if ( typeof wp !== 'undefined' && wp.svgPainter ) {
|
||||
try {
|
||||
colors = $.parseJSON( $this.children( '.icon_colors' ).val() );
|
||||
} catch ( error ) {}
|
||||
|
||||
if ( colors ) {
|
||||
wp.svgPainter.setColors( colors );
|
||||
wp.svgPainter.paint();
|
||||
}
|
||||
}
|
||||
|
||||
// update user option
|
||||
$.post( ajaxurl, {
|
||||
action: 'save-user-color-scheme',
|
||||
color_scheme: $this.children( 'input[name="admin_color"]' ).val(),
|
||||
nonce: $('#color-nonce').val()
|
||||
}).done( function( response ) {
|
||||
if ( response.success ) {
|
||||
$( 'body' ).removeClass( response.data.previousScheme ).addClass( response.data.currentScheme );
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
bindPasswordForm();
|
||||
});
|
||||
|
||||
$( '#destroy-sessions' ).on( 'click', function( e ) {
|
||||
var $this = $(this);
|
||||
|
||||
wp.ajax.post( 'destroy-sessions', {
|
||||
nonce: $( '#_wpnonce' ).val(),
|
||||
user_id: $( '#user_id' ).val()
|
||||
}).done( function( response ) {
|
||||
$this.prop( 'disabled', true );
|
||||
$this.siblings( '.notice' ).remove();
|
||||
$this.before( '<div class="notice notice-success inline"><p>' + response.message + '</p></div>' );
|
||||
}).fail( function( response ) {
|
||||
$this.siblings( '.notice' ).remove();
|
||||
$this.before( '<div class="notice notice-error inline"><p>' + response.message + '</p></div>' );
|
||||
});
|
||||
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
window.generatePassword = generatePassword;
|
||||
|
||||
/* Warn the user if password was generated but not saved */
|
||||
$( window ).on( 'beforeunload', function () {
|
||||
if ( true === updateLock ) {
|
||||
return userProfileL10n.warn;
|
||||
}
|
||||
} );
|
||||
|
||||
})(jQuery);
|
||||
@@ -0,0 +1,757 @@
|
||||
/*global ajaxurl, isRtl */
|
||||
var wpWidgets;
|
||||
(function($) {
|
||||
var $document = $( document );
|
||||
|
||||
wpWidgets = {
|
||||
/**
|
||||
* A closed Sidebar that gets a Widget dragged over it.
|
||||
*
|
||||
* @var {element|null}
|
||||
*/
|
||||
hoveredSidebar: null,
|
||||
|
||||
/**
|
||||
* Translations.
|
||||
*
|
||||
* Exported from PHP in wp_default_scripts().
|
||||
*
|
||||
* @var {object}
|
||||
*/
|
||||
l10n: {
|
||||
save: '{save}',
|
||||
saved: '{saved}',
|
||||
saveAlert: '{saveAlert}',
|
||||
widgetAdded: '{widgetAdded}'
|
||||
},
|
||||
|
||||
/**
|
||||
* Lookup of which widgets have had change events triggered.
|
||||
*
|
||||
* @var {object}
|
||||
*/
|
||||
dirtyWidgets: {},
|
||||
|
||||
init : function() {
|
||||
var rem, the_id,
|
||||
self = this,
|
||||
chooser = $('.widgets-chooser'),
|
||||
selectSidebar = chooser.find('.widgets-chooser-sidebars'),
|
||||
sidebars = $('div.widgets-sortables'),
|
||||
isRTL = !! ( 'undefined' !== typeof isRtl && isRtl );
|
||||
|
||||
// Handle the widgets containers in the right column.
|
||||
$( '#widgets-right .sidebar-name' )
|
||||
/*
|
||||
* Toggle the widgets containers when clicked and update the toggle
|
||||
* button `aria-expanded` attribute value.
|
||||
*/
|
||||
.click( function() {
|
||||
var $this = $( this ),
|
||||
$wrap = $this.closest( '.widgets-holder-wrap '),
|
||||
$toggle = $this.find( '.handlediv' );
|
||||
|
||||
if ( $wrap.hasClass( 'closed' ) ) {
|
||||
$wrap.removeClass( 'closed' );
|
||||
$toggle.attr( 'aria-expanded', 'true' );
|
||||
// Refresh the jQuery UI sortable items.
|
||||
$this.parent().sortable( 'refresh' );
|
||||
} else {
|
||||
$wrap.addClass( 'closed' );
|
||||
$toggle.attr( 'aria-expanded', 'false' );
|
||||
}
|
||||
|
||||
// Update the admin menu "sticky" state.
|
||||
$document.triggerHandler( 'wp-pin-menu' );
|
||||
})
|
||||
/*
|
||||
* Set the initial `aria-expanded` attribute value on the widgets
|
||||
* containers toggle button. The first one is expanded by default.
|
||||
*/
|
||||
.find( '.handlediv' ).each( function( index ) {
|
||||
if ( 0 === index ) {
|
||||
// jQuery equivalent of `continue` within an `each()` loop.
|
||||
return;
|
||||
}
|
||||
|
||||
$( this ).attr( 'aria-expanded', 'false' );
|
||||
});
|
||||
|
||||
// Show AYS dialog when there are unsaved widget changes.
|
||||
$( window ).on( 'beforeunload.widgets', function( event ) {
|
||||
var dirtyWidgetIds = [], unsavedWidgetsElements;
|
||||
$.each( self.dirtyWidgets, function( widgetId, dirty ) {
|
||||
if ( dirty ) {
|
||||
dirtyWidgetIds.push( widgetId );
|
||||
}
|
||||
});
|
||||
if ( 0 !== dirtyWidgetIds.length ) {
|
||||
unsavedWidgetsElements = $( '#widgets-right' ).find( '.widget' ).filter( function() {
|
||||
return -1 !== dirtyWidgetIds.indexOf( $( this ).prop( 'id' ).replace( /^widget-\d+_/, '' ) );
|
||||
});
|
||||
unsavedWidgetsElements.each( function() {
|
||||
if ( ! $( this ).hasClass( 'open' ) ) {
|
||||
$( this ).find( '.widget-title-action:first' ).click();
|
||||
}
|
||||
});
|
||||
|
||||
// Bring the first unsaved widget into view and focus on the first tabbable field.
|
||||
unsavedWidgetsElements.first().each( function() {
|
||||
if ( this.scrollIntoViewIfNeeded ) {
|
||||
this.scrollIntoViewIfNeeded();
|
||||
} else {
|
||||
this.scrollIntoView();
|
||||
}
|
||||
$( this ).find( '.widget-inside :tabbable:first' ).focus();
|
||||
} );
|
||||
|
||||
event.returnValue = wpWidgets.l10n.saveAlert;
|
||||
return event.returnValue;
|
||||
}
|
||||
});
|
||||
|
||||
// Handle the widgets containers in the left column.
|
||||
$( '#widgets-left .sidebar-name' ).click( function() {
|
||||
var $wrap = $( this ).closest( '.widgets-holder-wrap' );
|
||||
|
||||
$wrap
|
||||
.toggleClass( 'closed' )
|
||||
.find( '.handlediv' ).attr( 'aria-expanded', ! $wrap.hasClass( 'closed' ) );
|
||||
|
||||
// Update the admin menu "sticky" state.
|
||||
$document.triggerHandler( 'wp-pin-menu' );
|
||||
});
|
||||
|
||||
$(document.body).bind('click.widgets-toggle', function(e) {
|
||||
var target = $(e.target),
|
||||
css = { 'z-index': 100 },
|
||||
widget, inside, targetWidth, widgetWidth, margin, saveButton, widgetId,
|
||||
toggleBtn = target.closest( '.widget' ).find( '.widget-top button.widget-action' );
|
||||
|
||||
if ( target.parents('.widget-top').length && ! target.parents('#available-widgets').length ) {
|
||||
widget = target.closest('div.widget');
|
||||
inside = widget.children('.widget-inside');
|
||||
targetWidth = parseInt( widget.find('input.widget-width').val(), 10 );
|
||||
widgetWidth = widget.parent().width();
|
||||
widgetId = inside.find( '.widget-id' ).val();
|
||||
|
||||
// Save button is initially disabled, but is enabled when a field is changed.
|
||||
if ( ! widget.data( 'dirty-state-initialized' ) ) {
|
||||
saveButton = inside.find( '.widget-control-save' );
|
||||
saveButton.prop( 'disabled', true ).val( wpWidgets.l10n.saved );
|
||||
inside.on( 'input change', function() {
|
||||
self.dirtyWidgets[ widgetId ] = true;
|
||||
widget.addClass( 'widget-dirty' );
|
||||
saveButton.prop( 'disabled', false ).val( wpWidgets.l10n.save );
|
||||
});
|
||||
widget.data( 'dirty-state-initialized', true );
|
||||
}
|
||||
|
||||
if ( inside.is(':hidden') ) {
|
||||
if ( targetWidth > 250 && ( targetWidth + 30 > widgetWidth ) && widget.closest('div.widgets-sortables').length ) {
|
||||
if ( widget.closest('div.widget-liquid-right').length ) {
|
||||
margin = isRTL ? 'margin-right' : 'margin-left';
|
||||
} else {
|
||||
margin = isRTL ? 'margin-left' : 'margin-right';
|
||||
}
|
||||
|
||||
css[ margin ] = widgetWidth - ( targetWidth + 30 ) + 'px';
|
||||
widget.css( css );
|
||||
}
|
||||
/*
|
||||
* Don't change the order of attributes changes and animation:
|
||||
* it's important for screen readers, see ticket #31476.
|
||||
*/
|
||||
toggleBtn.attr( 'aria-expanded', 'true' );
|
||||
inside.slideDown( 'fast', function() {
|
||||
widget.addClass( 'open' );
|
||||
});
|
||||
} else {
|
||||
/*
|
||||
* Don't change the order of attributes changes and animation:
|
||||
* it's important for screen readers, see ticket #31476.
|
||||
*/
|
||||
toggleBtn.attr( 'aria-expanded', 'false' );
|
||||
inside.slideUp( 'fast', function() {
|
||||
widget.attr( 'style', '' );
|
||||
widget.removeClass( 'open' );
|
||||
});
|
||||
}
|
||||
} else if ( target.hasClass('widget-control-save') ) {
|
||||
wpWidgets.save( target.closest('div.widget'), 0, 1, 0 );
|
||||
e.preventDefault();
|
||||
} else if ( target.hasClass('widget-control-remove') ) {
|
||||
wpWidgets.save( target.closest('div.widget'), 1, 1, 0 );
|
||||
} else if ( target.hasClass('widget-control-close') ) {
|
||||
widget = target.closest('div.widget');
|
||||
widget.removeClass( 'open' );
|
||||
toggleBtn.attr( 'aria-expanded', 'false' );
|
||||
wpWidgets.close( widget );
|
||||
} else if ( target.attr( 'id' ) === 'inactive-widgets-control-remove' ) {
|
||||
wpWidgets.removeInactiveWidgets();
|
||||
e.preventDefault();
|
||||
}
|
||||
});
|
||||
|
||||
sidebars.children('.widget').each( function() {
|
||||
var $this = $(this);
|
||||
|
||||
wpWidgets.appendTitle( this );
|
||||
|
||||
if ( $this.find( 'p.widget-error' ).length ) {
|
||||
$this.find( '.widget-action' ).trigger( 'click' ).attr( 'aria-expanded', 'true' );
|
||||
}
|
||||
});
|
||||
|
||||
$('#widget-list').children('.widget').draggable({
|
||||
connectToSortable: 'div.widgets-sortables',
|
||||
handle: '> .widget-top > .widget-title',
|
||||
distance: 2,
|
||||
helper: 'clone',
|
||||
zIndex: 100,
|
||||
containment: '#wpwrap',
|
||||
refreshPositions: true,
|
||||
start: function( event, ui ) {
|
||||
var chooser = $(this).find('.widgets-chooser');
|
||||
|
||||
ui.helper.find('div.widget-description').hide();
|
||||
the_id = this.id;
|
||||
|
||||
if ( chooser.length ) {
|
||||
// Hide the chooser and move it out of the widget
|
||||
$( '#wpbody-content' ).append( chooser.hide() );
|
||||
// Delete the cloned chooser from the drag helper
|
||||
ui.helper.find('.widgets-chooser').remove();
|
||||
self.clearWidgetSelection();
|
||||
}
|
||||
},
|
||||
stop: function() {
|
||||
if ( rem ) {
|
||||
$(rem).hide();
|
||||
}
|
||||
|
||||
rem = '';
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Opens and closes previously closed Sidebars when Widgets are dragged over/out of them.
|
||||
*/
|
||||
sidebars.droppable( {
|
||||
tolerance: 'intersect',
|
||||
|
||||
/**
|
||||
* Open Sidebar when a Widget gets dragged over it.
|
||||
*
|
||||
* @ignore
|
||||
*
|
||||
* @param {object} event jQuery event object.
|
||||
*/
|
||||
over: function( event ) {
|
||||
var $wrap = $( event.target ).parent();
|
||||
|
||||
if ( wpWidgets.hoveredSidebar && ! $wrap.is( wpWidgets.hoveredSidebar ) ) {
|
||||
// Close the previous Sidebar as the Widget has been dragged onto another Sidebar.
|
||||
wpWidgets.closeSidebar( event );
|
||||
}
|
||||
|
||||
if ( $wrap.hasClass( 'closed' ) ) {
|
||||
wpWidgets.hoveredSidebar = $wrap;
|
||||
$wrap
|
||||
.removeClass( 'closed' )
|
||||
.find( '.handlediv' ).attr( 'aria-expanded', 'true' );
|
||||
}
|
||||
|
||||
$( this ).sortable( 'refresh' );
|
||||
},
|
||||
|
||||
/**
|
||||
* Close Sidebar when the Widget gets dragged out of it.
|
||||
*
|
||||
* @ignore
|
||||
*
|
||||
* @param {object} event jQuery event object.
|
||||
*/
|
||||
out: function( event ) {
|
||||
if ( wpWidgets.hoveredSidebar ) {
|
||||
wpWidgets.closeSidebar( event );
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
sidebars.sortable({
|
||||
placeholder: 'widget-placeholder',
|
||||
items: '> .widget',
|
||||
handle: '> .widget-top > .widget-title',
|
||||
cursor: 'move',
|
||||
distance: 2,
|
||||
containment: '#wpwrap',
|
||||
tolerance: 'pointer',
|
||||
refreshPositions: true,
|
||||
start: function( event, ui ) {
|
||||
var height, $this = $(this),
|
||||
$wrap = $this.parent(),
|
||||
inside = ui.item.children('.widget-inside');
|
||||
|
||||
if ( inside.css('display') === 'block' ) {
|
||||
ui.item.removeClass('open');
|
||||
ui.item.find( '.widget-top button.widget-action' ).attr( 'aria-expanded', 'false' );
|
||||
inside.hide();
|
||||
$(this).sortable('refreshPositions');
|
||||
}
|
||||
|
||||
if ( ! $wrap.hasClass('closed') ) {
|
||||
// Lock all open sidebars min-height when starting to drag.
|
||||
// Prevents jumping when dragging a widget from an open sidebar to a closed sidebar below.
|
||||
height = ui.item.hasClass('ui-draggable') ? $this.height() : 1 + $this.height();
|
||||
$this.css( 'min-height', height + 'px' );
|
||||
}
|
||||
},
|
||||
|
||||
stop: function( event, ui ) {
|
||||
var addNew, widgetNumber, $sidebar, $children, child, item,
|
||||
$widget = ui.item,
|
||||
id = the_id;
|
||||
|
||||
// Reset the var to hold a previously closed sidebar.
|
||||
wpWidgets.hoveredSidebar = null;
|
||||
|
||||
if ( $widget.hasClass('deleting') ) {
|
||||
wpWidgets.save( $widget, 1, 0, 1 ); // delete widget
|
||||
$widget.remove();
|
||||
return;
|
||||
}
|
||||
|
||||
addNew = $widget.find('input.add_new').val();
|
||||
widgetNumber = $widget.find('input.multi_number').val();
|
||||
|
||||
$widget.attr( 'style', '' ).removeClass('ui-draggable');
|
||||
the_id = '';
|
||||
|
||||
if ( addNew ) {
|
||||
if ( 'multi' === addNew ) {
|
||||
$widget.html(
|
||||
$widget.html().replace( /<[^<>]+>/g, function( tag ) {
|
||||
return tag.replace( /__i__|%i%/g, widgetNumber );
|
||||
})
|
||||
);
|
||||
|
||||
$widget.attr( 'id', id.replace( '__i__', widgetNumber ) );
|
||||
widgetNumber++;
|
||||
|
||||
$( 'div#' + id ).find( 'input.multi_number' ).val( widgetNumber );
|
||||
} else if ( 'single' === addNew ) {
|
||||
$widget.attr( 'id', 'new-' + id );
|
||||
rem = 'div#' + id;
|
||||
}
|
||||
|
||||
wpWidgets.save( $widget, 0, 0, 1 );
|
||||
$widget.find('input.add_new').val('');
|
||||
$document.trigger( 'widget-added', [ $widget ] );
|
||||
}
|
||||
|
||||
$sidebar = $widget.parent();
|
||||
|
||||
if ( $sidebar.parent().hasClass('closed') ) {
|
||||
$sidebar.parent()
|
||||
.removeClass( 'closed' )
|
||||
.find( '.handlediv' ).attr( 'aria-expanded', 'true' );
|
||||
|
||||
$children = $sidebar.children('.widget');
|
||||
|
||||
// Make sure the dropped widget is at the top
|
||||
if ( $children.length > 1 ) {
|
||||
child = $children.get(0);
|
||||
item = $widget.get(0);
|
||||
|
||||
if ( child.id && item.id && child.id !== item.id ) {
|
||||
$( child ).before( $widget );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( addNew ) {
|
||||
$widget.find( '.widget-action' ).trigger( 'click' );
|
||||
} else {
|
||||
wpWidgets.saveOrder( $sidebar.attr('id') );
|
||||
}
|
||||
},
|
||||
|
||||
activate: function() {
|
||||
$(this).parent().addClass( 'widget-hover' );
|
||||
},
|
||||
|
||||
deactivate: function() {
|
||||
// Remove all min-height added on "start"
|
||||
$(this).css( 'min-height', '' ).parent().removeClass( 'widget-hover' );
|
||||
},
|
||||
|
||||
receive: function( event, ui ) {
|
||||
var $sender = $( ui.sender );
|
||||
|
||||
// Don't add more widgets to orphaned sidebars
|
||||
if ( this.id.indexOf('orphaned_widgets') > -1 ) {
|
||||
$sender.sortable('cancel');
|
||||
return;
|
||||
}
|
||||
|
||||
// If the last widget was moved out of an orphaned sidebar, close and remove it.
|
||||
if ( $sender.attr('id').indexOf('orphaned_widgets') > -1 && ! $sender.children('.widget').length ) {
|
||||
$sender.parents('.orphan-sidebar').slideUp( 400, function(){ $(this).remove(); } );
|
||||
}
|
||||
}
|
||||
}).sortable( 'option', 'connectWith', 'div.widgets-sortables' );
|
||||
|
||||
$('#available-widgets').droppable({
|
||||
tolerance: 'pointer',
|
||||
accept: function(o){
|
||||
return $(o).parent().attr('id') !== 'widget-list';
|
||||
},
|
||||
drop: function(e,ui) {
|
||||
ui.draggable.addClass('deleting');
|
||||
$('#removing-widget').hide().children('span').empty();
|
||||
},
|
||||
over: function(e,ui) {
|
||||
ui.draggable.addClass('deleting');
|
||||
$('div.widget-placeholder').hide();
|
||||
|
||||
if ( ui.draggable.hasClass('ui-sortable-helper') ) {
|
||||
$('#removing-widget').show().children('span')
|
||||
.html( ui.draggable.find( 'div.widget-title' ).children( 'h3' ).html() );
|
||||
}
|
||||
},
|
||||
out: function(e,ui) {
|
||||
ui.draggable.removeClass('deleting');
|
||||
$('div.widget-placeholder').show();
|
||||
$('#removing-widget').hide().children('span').empty();
|
||||
}
|
||||
});
|
||||
|
||||
// Area Chooser
|
||||
$( '#widgets-right .widgets-holder-wrap' ).each( function( index, element ) {
|
||||
var $element = $( element ),
|
||||
name = $element.find( '.sidebar-name h2' ).text(),
|
||||
ariaLabel = $element.find( '.sidebar-name' ).data( 'add-to' ),
|
||||
id = $element.find( '.widgets-sortables' ).attr( 'id' ),
|
||||
li = $( '<li>' ),
|
||||
button = $( '<button>', {
|
||||
type: 'button',
|
||||
'aria-pressed': 'false',
|
||||
'class': 'widgets-chooser-button',
|
||||
'aria-label': ariaLabel
|
||||
} ).text( $.trim( name ) );
|
||||
|
||||
li.append( button );
|
||||
|
||||
if ( index === 0 ) {
|
||||
li.addClass( 'widgets-chooser-selected' );
|
||||
button.attr( 'aria-pressed', 'true' );
|
||||
}
|
||||
|
||||
selectSidebar.append( li );
|
||||
li.data( 'sidebarId', id );
|
||||
});
|
||||
|
||||
$( '#available-widgets .widget .widget-top' ).on( 'click.widgets-chooser', function() {
|
||||
var $widget = $( this ).closest( '.widget' ),
|
||||
toggleButton = $( this ).find( '.widget-action' ),
|
||||
chooserButtons = selectSidebar.find( '.widgets-chooser-button' );
|
||||
|
||||
if ( $widget.hasClass( 'widget-in-question' ) || $( '#widgets-left' ).hasClass( 'chooser' ) ) {
|
||||
toggleButton.attr( 'aria-expanded', 'false' );
|
||||
self.closeChooser();
|
||||
} else {
|
||||
// Open the chooser
|
||||
self.clearWidgetSelection();
|
||||
$( '#widgets-left' ).addClass( 'chooser' );
|
||||
// Add CSS class and insert the chooser after the widget description.
|
||||
$widget.addClass( 'widget-in-question' ).children( '.widget-description' ).after( chooser );
|
||||
// Open the chooser with a slide down animation.
|
||||
chooser.slideDown( 300, function() {
|
||||
// Update the toggle button aria-expanded attribute after previous DOM manipulations.
|
||||
toggleButton.attr( 'aria-expanded', 'true' );
|
||||
});
|
||||
|
||||
chooserButtons.on( 'click.widgets-chooser', function() {
|
||||
selectSidebar.find( '.widgets-chooser-selected' ).removeClass( 'widgets-chooser-selected' );
|
||||
chooserButtons.attr( 'aria-pressed', 'false' );
|
||||
$( this )
|
||||
.attr( 'aria-pressed', 'true' )
|
||||
.closest( 'li' ).addClass( 'widgets-chooser-selected' );
|
||||
} );
|
||||
}
|
||||
});
|
||||
|
||||
// Add event handlers
|
||||
chooser.on( 'click.widgets-chooser', function( event ) {
|
||||
var $target = $( event.target );
|
||||
|
||||
if ( $target.hasClass('button-primary') ) {
|
||||
self.addWidget( chooser );
|
||||
self.closeChooser();
|
||||
} else if ( $target.hasClass( 'widgets-chooser-cancel' ) ) {
|
||||
self.closeChooser();
|
||||
}
|
||||
}).on( 'keyup.widgets-chooser', function( event ) {
|
||||
if ( event.which === $.ui.keyCode.ESCAPE ) {
|
||||
self.closeChooser();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
saveOrder : function( sidebarId ) {
|
||||
var data = {
|
||||
action: 'widgets-order',
|
||||
savewidgets: $('#_wpnonce_widgets').val(),
|
||||
sidebars: []
|
||||
};
|
||||
|
||||
if ( sidebarId ) {
|
||||
$( '#' + sidebarId ).find( '.spinner:first' ).addClass( 'is-active' );
|
||||
}
|
||||
|
||||
$('div.widgets-sortables').each( function() {
|
||||
if ( $(this).sortable ) {
|
||||
data['sidebars[' + $(this).attr('id') + ']'] = $(this).sortable('toArray').join(',');
|
||||
}
|
||||
});
|
||||
|
||||
$.post( ajaxurl, data, function() {
|
||||
$( '#inactive-widgets-control-remove' ).prop( 'disabled' , ! $( '#wp_inactive_widgets .widget' ).length );
|
||||
$( '.spinner' ).removeClass( 'is-active' );
|
||||
});
|
||||
},
|
||||
|
||||
save : function( widget, del, animate, order ) {
|
||||
var self = this, data, a,
|
||||
sidebarId = widget.closest( 'div.widgets-sortables' ).attr( 'id' ),
|
||||
form = widget.find( 'form' ),
|
||||
isAdd = widget.find( 'input.add_new' ).val();
|
||||
|
||||
if ( ! del && ! isAdd && form.prop( 'checkValidity' ) && ! form[0].checkValidity() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
data = form.serialize();
|
||||
|
||||
widget = $(widget);
|
||||
$( '.spinner', widget ).addClass( 'is-active' );
|
||||
|
||||
a = {
|
||||
action: 'save-widget',
|
||||
savewidgets: $('#_wpnonce_widgets').val(),
|
||||
sidebar: sidebarId
|
||||
};
|
||||
|
||||
if ( del ) {
|
||||
a.delete_widget = 1;
|
||||
}
|
||||
|
||||
data += '&' + $.param(a);
|
||||
|
||||
$.post( ajaxurl, data, function(r) {
|
||||
var id = $('input.widget-id', widget).val();
|
||||
|
||||
if ( del ) {
|
||||
if ( ! $('input.widget_number', widget).val() ) {
|
||||
$('#available-widgets').find('input.widget-id').each(function(){
|
||||
if ( $(this).val() === id ) {
|
||||
$(this).closest('div.widget').show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if ( animate ) {
|
||||
order = 0;
|
||||
widget.slideUp( 'fast', function() {
|
||||
$( this ).remove();
|
||||
wpWidgets.saveOrder();
|
||||
delete self.dirtyWidgets[ id ];
|
||||
});
|
||||
} else {
|
||||
widget.remove();
|
||||
delete self.dirtyWidgets[ id ];
|
||||
|
||||
if ( sidebarId === 'wp_inactive_widgets' ) {
|
||||
$( '#inactive-widgets-control-remove' ).prop( 'disabled' , ! $( '#wp_inactive_widgets .widget' ).length );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$( '.spinner' ).removeClass( 'is-active' );
|
||||
if ( r && r.length > 2 ) {
|
||||
$( 'div.widget-content', widget ).html( r );
|
||||
wpWidgets.appendTitle( widget );
|
||||
|
||||
// Re-disable the save button.
|
||||
widget.find( '.widget-control-save' ).prop( 'disabled', true ).val( wpWidgets.l10n.saved );
|
||||
|
||||
widget.removeClass( 'widget-dirty' );
|
||||
|
||||
// Clear the dirty flag from the widget.
|
||||
delete self.dirtyWidgets[ id ];
|
||||
|
||||
$document.trigger( 'widget-updated', [ widget ] );
|
||||
|
||||
if ( sidebarId === 'wp_inactive_widgets' ) {
|
||||
$( '#inactive-widgets-control-remove' ).prop( 'disabled' , ! $( '#wp_inactive_widgets .widget' ).length );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( order ) {
|
||||
wpWidgets.saveOrder();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
removeInactiveWidgets : function() {
|
||||
var $element = $( '.remove-inactive-widgets' ), self = this, a, data;
|
||||
|
||||
$( '.spinner', $element ).addClass( 'is-active' );
|
||||
|
||||
a = {
|
||||
action : 'delete-inactive-widgets',
|
||||
removeinactivewidgets : $( '#_wpnonce_remove_inactive_widgets' ).val()
|
||||
};
|
||||
|
||||
data = $.param( a );
|
||||
|
||||
$.post( ajaxurl, data, function() {
|
||||
$( '#wp_inactive_widgets .widget' ).each(function() {
|
||||
var $widget = $( this );
|
||||
delete self.dirtyWidgets[ $widget.find( 'input.widget-id' ).val() ];
|
||||
$widget.remove();
|
||||
});
|
||||
$( '#inactive-widgets-control-remove' ).prop( 'disabled', true );
|
||||
$( '.spinner', $element ).removeClass( 'is-active' );
|
||||
} );
|
||||
},
|
||||
|
||||
appendTitle : function(widget) {
|
||||
var title = $('input[id*="-title"]', widget).val() || '';
|
||||
|
||||
if ( title ) {
|
||||
title = ': ' + title.replace(/<[^<>]+>/g, '').replace(/</g, '<').replace(/>/g, '>');
|
||||
}
|
||||
|
||||
$(widget).children('.widget-top').children('.widget-title').children()
|
||||
.children('.in-widget-title').html(title);
|
||||
|
||||
},
|
||||
|
||||
close : function(widget) {
|
||||
widget.children('.widget-inside').slideUp('fast', function() {
|
||||
widget.attr( 'style', '' )
|
||||
.find( '.widget-top button.widget-action' )
|
||||
.attr( 'aria-expanded', 'false' )
|
||||
.focus();
|
||||
});
|
||||
},
|
||||
|
||||
addWidget: function( chooser ) {
|
||||
var widget, widgetId, add, n, viewportTop, viewportBottom, sidebarBounds,
|
||||
sidebarId = chooser.find( '.widgets-chooser-selected' ).data('sidebarId'),
|
||||
sidebar = $( '#' + sidebarId );
|
||||
|
||||
widget = $('#available-widgets').find('.widget-in-question').clone();
|
||||
widgetId = widget.attr('id');
|
||||
add = widget.find( 'input.add_new' ).val();
|
||||
n = widget.find( 'input.multi_number' ).val();
|
||||
|
||||
// Remove the cloned chooser from the widget
|
||||
widget.find('.widgets-chooser').remove();
|
||||
|
||||
if ( 'multi' === add ) {
|
||||
widget.html(
|
||||
widget.html().replace( /<[^<>]+>/g, function(m) {
|
||||
return m.replace( /__i__|%i%/g, n );
|
||||
})
|
||||
);
|
||||
|
||||
widget.attr( 'id', widgetId.replace( '__i__', n ) );
|
||||
n++;
|
||||
$( '#' + widgetId ).find('input.multi_number').val(n);
|
||||
} else if ( 'single' === add ) {
|
||||
widget.attr( 'id', 'new-' + widgetId );
|
||||
$( '#' + widgetId ).hide();
|
||||
}
|
||||
|
||||
// Open the widgets container.
|
||||
sidebar.closest( '.widgets-holder-wrap' )
|
||||
.removeClass( 'closed' )
|
||||
.find( '.handlediv' ).attr( 'aria-expanded', 'true' );
|
||||
|
||||
sidebar.append( widget );
|
||||
sidebar.sortable('refresh');
|
||||
|
||||
wpWidgets.save( widget, 0, 0, 1 );
|
||||
// No longer "new" widget
|
||||
widget.find( 'input.add_new' ).val('');
|
||||
|
||||
$document.trigger( 'widget-added', [ widget ] );
|
||||
|
||||
/*
|
||||
* Check if any part of the sidebar is visible in the viewport. If it is, don't scroll.
|
||||
* Otherwise, scroll up to so the sidebar is in view.
|
||||
*
|
||||
* We do this by comparing the top and bottom, of the sidebar so see if they are within
|
||||
* the bounds of the viewport.
|
||||
*/
|
||||
viewportTop = $(window).scrollTop();
|
||||
viewportBottom = viewportTop + $(window).height();
|
||||
sidebarBounds = sidebar.offset();
|
||||
|
||||
sidebarBounds.bottom = sidebarBounds.top + sidebar.outerHeight();
|
||||
|
||||
if ( viewportTop > sidebarBounds.bottom || viewportBottom < sidebarBounds.top ) {
|
||||
$( 'html, body' ).animate({
|
||||
scrollTop: sidebarBounds.top - 130
|
||||
}, 200 );
|
||||
}
|
||||
|
||||
window.setTimeout( function() {
|
||||
// Cannot use a callback in the animation above as it fires twice,
|
||||
// have to queue this "by hand".
|
||||
widget.find( '.widget-title' ).trigger('click');
|
||||
// At the end of the animation, announce the widget has been added.
|
||||
window.wp.a11y.speak( wpWidgets.l10n.widgetAdded, 'assertive' );
|
||||
}, 250 );
|
||||
},
|
||||
|
||||
closeChooser: function() {
|
||||
var self = this,
|
||||
widgetInQuestion = $( '#available-widgets .widget-in-question' );
|
||||
|
||||
$( '.widgets-chooser' ).slideUp( 200, function() {
|
||||
$( '#wpbody-content' ).append( this );
|
||||
self.clearWidgetSelection();
|
||||
// Move focus back to the toggle button.
|
||||
widgetInQuestion.find( '.widget-action' ).attr( 'aria-expanded', 'false' ).focus();
|
||||
});
|
||||
},
|
||||
|
||||
clearWidgetSelection: function() {
|
||||
$( '#widgets-left' ).removeClass( 'chooser' );
|
||||
$( '.widget-in-question' ).removeClass( 'widget-in-question' );
|
||||
},
|
||||
|
||||
/**
|
||||
* Closes a Sidebar that was previously closed, but opened by dragging a Widget over it.
|
||||
*
|
||||
* Used when a Widget gets dragged in/out of the Sidebar and never dropped.
|
||||
*
|
||||
* @param {object} event jQuery event object.
|
||||
*/
|
||||
closeSidebar: function( event ) {
|
||||
this.hoveredSidebar
|
||||
.addClass( 'closed' )
|
||||
.find( '.handlediv' ).attr( 'aria-expanded', 'false' );
|
||||
|
||||
$( event.target ).css( 'min-height', '' );
|
||||
this.hoveredSidebar = null;
|
||||
}
|
||||
};
|
||||
|
||||
$document.ready( function(){ wpWidgets.init(); } );
|
||||
|
||||
})(jQuery);
|
||||
@@ -0,0 +1,278 @@
|
||||
/**
|
||||
* Generates the XHTML Friends Network 'rel' string from the inputs.
|
||||
*
|
||||
* @deprecated 3.5.0
|
||||
*/
|
||||
jQuery( document ).ready(function( $ ) {
|
||||
$( '#link_rel' ).prop( 'readonly', true );
|
||||
$( '#linkxfndiv input' ).bind( 'click keyup', function() {
|
||||
var isMe = $( '#me' ).is( ':checked' ), inputs = '';
|
||||
$( 'input.valinp' ).each( function() {
|
||||
if ( isMe ) {
|
||||
$( this ).prop( 'disabled', true ).parent().addClass( 'disabled' );
|
||||
} else {
|
||||
$( this ).removeAttr( 'disabled' ).parent().removeClass( 'disabled' );
|
||||
if ( $( this ).is( ':checked' ) && $( this ).val() !== '') {
|
||||
inputs += $( this ).val() + ' ';
|
||||
}
|
||||
}
|
||||
});
|
||||
$( '#link_rel' ).val( ( isMe ) ? 'me' : inputs.substr( 0,inputs.length - 1 ) );
|
||||
});
|
||||
});
|
||||
|
||||
// Privacy request action handling
|
||||
jQuery( document ).ready( function( $ ) {
|
||||
var strings = window.privacyToolsL10n || {};
|
||||
|
||||
function setActionState( $action, state ) {
|
||||
$action.children().hide();
|
||||
$action.children( '.' + state ).show();
|
||||
}
|
||||
|
||||
function clearResultsAfterRow( $requestRow ) {
|
||||
$requestRow.removeClass( 'has-request-results' );
|
||||
|
||||
if ( $requestRow.next().hasClass( 'request-results' ) ) {
|
||||
$requestRow.next().remove();
|
||||
}
|
||||
}
|
||||
|
||||
function appendResultsAfterRow( $requestRow, classes, summaryMessage, additionalMessages ) {
|
||||
var itemList = '',
|
||||
resultRowClasses = 'request-results';
|
||||
|
||||
clearResultsAfterRow( $requestRow );
|
||||
|
||||
if ( additionalMessages.length ) {
|
||||
$.each( additionalMessages, function( index, value ) {
|
||||
itemList = itemList + '<li>' + value + '</li>';
|
||||
});
|
||||
itemList = '<ul>' + itemList + '</ul>';
|
||||
}
|
||||
|
||||
$requestRow.addClass( 'has-request-results' );
|
||||
|
||||
if ( $requestRow.hasClass( 'status-request-confirmed' ) ) {
|
||||
resultRowClasses = resultRowClasses + ' status-request-confirmed';
|
||||
}
|
||||
|
||||
if ( $requestRow.hasClass( 'status-request-failed' ) ) {
|
||||
resultRowClasses = resultRowClasses + ' status-request-failed';
|
||||
}
|
||||
|
||||
$requestRow.after( function() {
|
||||
return '<tr class="' + resultRowClasses + '"><th colspan="5">' +
|
||||
'<div class="notice inline notice-alt ' + classes + '">' +
|
||||
'<p>' + summaryMessage + '</p>' +
|
||||
itemList +
|
||||
'</div>' +
|
||||
'</td>' +
|
||||
'</tr>';
|
||||
});
|
||||
}
|
||||
|
||||
$( '.export-personal-data-handle' ).click( function( event ) {
|
||||
|
||||
var $this = $( this ),
|
||||
$action = $this.parents( '.export-personal-data' ),
|
||||
$requestRow = $this.parents( 'tr' ),
|
||||
requestID = $action.data( 'request-id' ),
|
||||
nonce = $action.data( 'nonce' ),
|
||||
exportersCount = $action.data( 'exporters-count' ),
|
||||
sendAsEmail = $action.data( 'send-as-email' ) ? true : false;
|
||||
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
$action.blur();
|
||||
clearResultsAfterRow( $requestRow );
|
||||
|
||||
function onExportDoneSuccess( zipUrl ) {
|
||||
setActionState( $action, 'export-personal-data-success' );
|
||||
if ( 'undefined' !== typeof zipUrl ) {
|
||||
window.location = zipUrl;
|
||||
} else if ( ! sendAsEmail ) {
|
||||
onExportFailure( strings.noExportFile );
|
||||
}
|
||||
}
|
||||
|
||||
function onExportFailure( errorMessage ) {
|
||||
setActionState( $action, 'export-personal-data-failed' );
|
||||
if ( errorMessage ) {
|
||||
appendResultsAfterRow( $requestRow, 'notice-error', strings.exportError, [ errorMessage ] );
|
||||
}
|
||||
}
|
||||
|
||||
function doNextExport( exporterIndex, pageIndex ) {
|
||||
$.ajax(
|
||||
{
|
||||
url: window.ajaxurl,
|
||||
data: {
|
||||
action: 'wp-privacy-export-personal-data',
|
||||
exporter: exporterIndex,
|
||||
id: requestID,
|
||||
page: pageIndex,
|
||||
security: nonce,
|
||||
sendAsEmail: sendAsEmail
|
||||
},
|
||||
method: 'post'
|
||||
}
|
||||
).done( function( response ) {
|
||||
var responseData = response.data;
|
||||
|
||||
if ( ! response.success ) {
|
||||
|
||||
// e.g. invalid request ID
|
||||
onExportFailure( response.data );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! responseData.done ) {
|
||||
setTimeout( doNextExport( exporterIndex, pageIndex + 1 ) );
|
||||
} else {
|
||||
if ( exporterIndex < exportersCount ) {
|
||||
setTimeout( doNextExport( exporterIndex + 1, 1 ) );
|
||||
} else {
|
||||
onExportDoneSuccess( responseData.url );
|
||||
}
|
||||
}
|
||||
}).fail( function( jqxhr, textStatus, error ) {
|
||||
|
||||
// e.g. Nonce failure
|
||||
onExportFailure( error );
|
||||
});
|
||||
}
|
||||
|
||||
// And now, let's begin
|
||||
setActionState( $action, 'export-personal-data-processing' );
|
||||
doNextExport( 1, 1 );
|
||||
});
|
||||
|
||||
$( '.remove-personal-data-handle' ).click( function( event ) {
|
||||
|
||||
var $this = $( this ),
|
||||
$action = $this.parents( '.remove-personal-data' ),
|
||||
$requestRow = $this.parents( 'tr' ),
|
||||
requestID = $action.data( 'request-id' ),
|
||||
nonce = $action.data( 'nonce' ),
|
||||
erasersCount = $action.data( 'erasers-count' ),
|
||||
hasRemoved = false,
|
||||
hasRetained = false,
|
||||
messages = [];
|
||||
|
||||
event.stopPropagation();
|
||||
|
||||
$action.blur();
|
||||
clearResultsAfterRow( $requestRow );
|
||||
|
||||
function onErasureDoneSuccess() {
|
||||
var summaryMessage = strings.noDataFound;
|
||||
var classes = 'notice-success';
|
||||
|
||||
setActionState( $action, 'remove-personal-data-idle' );
|
||||
|
||||
if ( false === hasRemoved ) {
|
||||
if ( false === hasRetained ) {
|
||||
summaryMessage = strings.noDataFound;
|
||||
} else {
|
||||
summaryMessage = strings.noneRemoved;
|
||||
classes = 'notice-warning';
|
||||
}
|
||||
} else {
|
||||
if ( false === hasRetained ) {
|
||||
summaryMessage = strings.foundAndRemoved;
|
||||
} else {
|
||||
summaryMessage = strings.someNotRemoved;
|
||||
classes = 'notice-warning';
|
||||
}
|
||||
}
|
||||
appendResultsAfterRow( $requestRow, 'notice-success', summaryMessage, messages );
|
||||
}
|
||||
|
||||
function onErasureFailure() {
|
||||
setActionState( $action, 'remove-personal-data-failed' );
|
||||
appendResultsAfterRow( $requestRow, 'notice-error', strings.removalError, [] );
|
||||
}
|
||||
|
||||
function doNextErasure( eraserIndex, pageIndex ) {
|
||||
$.ajax({
|
||||
url: window.ajaxurl,
|
||||
data: {
|
||||
action: 'wp-privacy-erase-personal-data',
|
||||
eraser: eraserIndex,
|
||||
id: requestID,
|
||||
page: pageIndex,
|
||||
security: nonce
|
||||
},
|
||||
method: 'post'
|
||||
}).done( function( response ) {
|
||||
var responseData = response.data;
|
||||
|
||||
if ( ! response.success ) {
|
||||
onErasureFailure();
|
||||
return;
|
||||
}
|
||||
if ( responseData.items_removed ) {
|
||||
hasRemoved = hasRemoved || responseData.items_removed;
|
||||
}
|
||||
if ( responseData.items_retained ) {
|
||||
hasRetained = hasRetained || responseData.items_retained;
|
||||
}
|
||||
if ( responseData.messages ) {
|
||||
messages = messages.concat( responseData.messages );
|
||||
}
|
||||
if ( ! responseData.done ) {
|
||||
setTimeout( doNextErasure( eraserIndex, pageIndex + 1 ) );
|
||||
} else {
|
||||
if ( eraserIndex < erasersCount ) {
|
||||
setTimeout( doNextErasure( eraserIndex + 1, 1 ) );
|
||||
} else {
|
||||
onErasureDoneSuccess();
|
||||
}
|
||||
}
|
||||
}).fail( function() {
|
||||
onErasureFailure();
|
||||
});
|
||||
}
|
||||
|
||||
// And now, let's begin
|
||||
setActionState( $action, 'remove-personal-data-processing' );
|
||||
|
||||
doNextErasure( 1, 1 );
|
||||
});
|
||||
});
|
||||
|
||||
( function( $ ) {
|
||||
|
||||
// Privacy policy page, copy button.
|
||||
$( document ).on( 'click', function( event ) {
|
||||
var $target = $( event.target );
|
||||
var $parent, $container, range;
|
||||
|
||||
if ( $target.is( 'button.privacy-text-copy' ) ) {
|
||||
$parent = $target.parent().parent();
|
||||
$container = $parent.find( 'div.wp-suggested-text' );
|
||||
|
||||
if ( ! $container.length ) {
|
||||
$container = $parent.find( 'div.policy-text' );
|
||||
}
|
||||
|
||||
if ( $container.length ) {
|
||||
try {
|
||||
window.getSelection().removeAllRanges();
|
||||
range = document.createRange();
|
||||
$container.addClass( 'hide-privacy-policy-tutorial' );
|
||||
|
||||
range.selectNodeContents( $container[0] );
|
||||
window.getSelection().addRange( range );
|
||||
document.execCommand( 'copy' );
|
||||
|
||||
$container.removeClass( 'hide-privacy-policy-tutorial' );
|
||||
window.getSelection().removeAllRanges();
|
||||
} catch ( er ) {}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
} ( jQuery ) );
|
||||
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* Distraction-Free Writing (wp-fullscreen) backward compatibility stub.
|
||||
* Todo: remove at the end of 2016.
|
||||
*
|
||||
* Original was deprecated in 4.1, removed in 4.3.
|
||||
*/
|
||||
( function() {
|
||||
var noop = function(){};
|
||||
|
||||
window.wp = window.wp || {};
|
||||
window.wp.editor = window.wp.editor || {};
|
||||
window.wp.editor.fullscreen = {
|
||||
bind_resize: noop,
|
||||
dfwWidth: noop,
|
||||
off: noop,
|
||||
on: noop,
|
||||
refreshButtons: noop,
|
||||
resizeTextarea: noop,
|
||||
save: noop,
|
||||
switchmode: noop,
|
||||
toggleUI: noop,
|
||||
|
||||
settings: {},
|
||||
pubsub: {
|
||||
publish: noop,
|
||||
subscribe: noop,
|
||||
unsubscribe: noop,
|
||||
topics: {}
|
||||
},
|
||||
fade: {
|
||||
In: noop,
|
||||
Out: noop
|
||||
},
|
||||
ui: {
|
||||
fade: noop,
|
||||
init: noop
|
||||
}
|
||||
};
|
||||
}());
|
||||
@@ -0,0 +1,39 @@
|
||||
/* global ajaxurl */
|
||||
|
||||
/**
|
||||
* This file is used on media-upload.php which has been replaced by media-new.php and upload.php
|
||||
* Deprecated since 3.5.0
|
||||
*/
|
||||
jQuery(function($) {
|
||||
/**
|
||||
* Adds a click event handler to the element with a 'wp-gallery' class.
|
||||
*/
|
||||
$( 'body' ).bind( 'click.wp-gallery', function(e) {
|
||||
var target = $( e.target ), id, img_size;
|
||||
|
||||
if ( target.hasClass( 'wp-set-header' ) ) {
|
||||
// Opens the image to preview it full size.
|
||||
( window.dialogArguments || opener || parent || top ).location.href = target.data( 'location' );
|
||||
e.preventDefault();
|
||||
} else if ( target.hasClass( 'wp-set-background' ) ) {
|
||||
// Sets the image as background of the theme.
|
||||
id = target.data( 'attachment-id' );
|
||||
img_size = $( 'input[name="attachments[' + id + '][image-size]"]:checked').val();
|
||||
|
||||
/**
|
||||
* This AJAX action has been deprecated since 3.5.0, see custom-background.php
|
||||
*/
|
||||
jQuery.post(ajaxurl, {
|
||||
action: 'set-background-image',
|
||||
attachment_id: id,
|
||||
size: img_size
|
||||
}, function() {
|
||||
var win = window.dialogArguments || opener || parent || top;
|
||||
win.tb_remove();
|
||||
win.location.reload();
|
||||
});
|
||||
|
||||
e.preventDefault();
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,93 @@
|
||||
/**
|
||||
* Accordion-folding functionality.
|
||||
*
|
||||
* Markup with the appropriate classes will be automatically hidden,
|
||||
* with one section opening at a time when its title is clicked.
|
||||
* Use the following markup structure for accordion behavior:
|
||||
*
|
||||
* <div class="accordion-container">
|
||||
* <div class="accordion-section open">
|
||||
* <h3 class="accordion-section-title"></h3>
|
||||
* <div class="accordion-section-content">
|
||||
* </div>
|
||||
* </div>
|
||||
* <div class="accordion-section">
|
||||
* <h3 class="accordion-section-title"></h3>
|
||||
* <div class="accordion-section-content">
|
||||
* </div>
|
||||
* </div>
|
||||
* <div class="accordion-section">
|
||||
* <h3 class="accordion-section-title"></h3>
|
||||
* <div class="accordion-section-content">
|
||||
* </div>
|
||||
* </div>
|
||||
* </div>
|
||||
*
|
||||
* Note that any appropriate tags may be used, as long as the above classes are present.
|
||||
*
|
||||
* @since 3.6.0
|
||||
*/
|
||||
|
||||
( function( $ ){
|
||||
|
||||
$( document ).ready( function () {
|
||||
|
||||
// Expand/Collapse accordion sections on click.
|
||||
$( '.accordion-container' ).on( 'click keydown', '.accordion-section-title', function( e ) {
|
||||
if ( e.type === 'keydown' && 13 !== e.which ) { // "return" key
|
||||
return;
|
||||
}
|
||||
|
||||
e.preventDefault(); // Keep this AFTER the key filter above
|
||||
|
||||
accordionSwitch( $( this ) );
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* Close the current accordion section and open a new one.
|
||||
*
|
||||
* @param {Object} el Title element of the accordion section to toggle.
|
||||
* @since 3.6.0
|
||||
*/
|
||||
function accordionSwitch ( el ) {
|
||||
var section = el.closest( '.accordion-section' ),
|
||||
sectionToggleControl = section.find( '[aria-expanded]' ).first(),
|
||||
container = section.closest( '.accordion-container' ),
|
||||
siblings = container.find( '.open' ),
|
||||
siblingsToggleControl = siblings.find( '[aria-expanded]' ).first(),
|
||||
content = section.find( '.accordion-section-content' );
|
||||
|
||||
// This section has no content and cannot be expanded.
|
||||
if ( section.hasClass( 'cannot-expand' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Add a class to the container to let us know something is happening inside.
|
||||
// This helps in cases such as hiding a scrollbar while animations are executing.
|
||||
container.addClass( 'opening' );
|
||||
|
||||
if ( section.hasClass( 'open' ) ) {
|
||||
section.toggleClass( 'open' );
|
||||
content.toggle( true ).slideToggle( 150 );
|
||||
} else {
|
||||
siblingsToggleControl.attr( 'aria-expanded', 'false' );
|
||||
siblings.removeClass( 'open' );
|
||||
siblings.find( '.accordion-section-content' ).show().slideUp( 150 );
|
||||
content.toggle( false ).slideToggle( 150 );
|
||||
section.toggleClass( 'open' );
|
||||
}
|
||||
|
||||
// We have to wait for the animations to finish
|
||||
setTimeout(function(){
|
||||
container.removeClass( 'opening' );
|
||||
}, 150);
|
||||
|
||||
// If there's an element with an aria-expanded attribute, assume it's a toggle control and toggle the aria-expanded value.
|
||||
if ( sectionToggleControl ) {
|
||||
sectionToggleControl.attr( 'aria-expanded', String( sectionToggleControl.attr( 'aria-expanded' ) === 'false' ) );
|
||||
}
|
||||
}
|
||||
|
||||
})(jQuery);
|
||||
@@ -0,0 +1,387 @@
|
||||
/* jshint loopfunc: true */
|
||||
// use jQuery and hoverIntent if loaded
|
||||
if ( typeof(jQuery) != 'undefined' ) {
|
||||
if ( typeof(jQuery.fn.hoverIntent) == 'undefined' ) {
|
||||
/* jshint ignore:start */
|
||||
// hoverIntent v1.8.1 - Copy of wp-includes/js/hoverIntent.min.js
|
||||
!function(a){a.fn.hoverIntent=function(b,c,d){var e={interval:100,sensitivity:6,timeout:0};e="object"==typeof b?a.extend(e,b):a.isFunction(c)?a.extend(e,{over:b,out:c,selector:d}):a.extend(e,{over:b,out:b,selector:c});var f,g,h,i,j=function(a){f=a.pageX,g=a.pageY},k=function(b,c){return c.hoverIntent_t=clearTimeout(c.hoverIntent_t),Math.sqrt((h-f)*(h-f)+(i-g)*(i-g))<e.sensitivity?(a(c).off("mousemove.hoverIntent",j),c.hoverIntent_s=!0,e.over.apply(c,[b])):(h=f,i=g,c.hoverIntent_t=setTimeout(function(){k(b,c)},e.interval),void 0)},l=function(a,b){return b.hoverIntent_t=clearTimeout(b.hoverIntent_t),b.hoverIntent_s=!1,e.out.apply(b,[a])},m=function(b){var c=a.extend({},b),d=this;d.hoverIntent_t&&(d.hoverIntent_t=clearTimeout(d.hoverIntent_t)),"mouseenter"===b.type?(h=c.pageX,i=c.pageY,a(d).on("mousemove.hoverIntent",j),d.hoverIntent_s||(d.hoverIntent_t=setTimeout(function(){k(c,d)},e.interval))):(a(d).off("mousemove.hoverIntent",j),d.hoverIntent_s&&(d.hoverIntent_t=setTimeout(function(){l(c,d)},e.timeout)))};return this.on({"mouseenter.hoverIntent":m,"mouseleave.hoverIntent":m},e.selector)}}(jQuery);
|
||||
/* jshint ignore:end */
|
||||
}
|
||||
jQuery(document).ready(function($){
|
||||
var adminbar = $('#wpadminbar'), refresh, touchOpen, touchClose, disableHoverIntent = false;
|
||||
|
||||
refresh = function(i, el){ // force the browser to refresh the tabbing index
|
||||
var node = $(el), tab = node.attr('tabindex');
|
||||
if ( tab )
|
||||
node.attr('tabindex', '0').attr('tabindex', tab);
|
||||
};
|
||||
|
||||
touchOpen = function(unbind) {
|
||||
adminbar.find('li.menupop').on('click.wp-mobile-hover', function(e) {
|
||||
var el = $(this);
|
||||
|
||||
if ( el.parent().is('#wp-admin-bar-root-default') && !el.hasClass('hover') ) {
|
||||
e.preventDefault();
|
||||
adminbar.find('li.menupop.hover').removeClass('hover');
|
||||
el.addClass('hover');
|
||||
} else if ( !el.hasClass('hover') ) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
el.addClass('hover');
|
||||
} else if ( ! $( e.target ).closest( 'div' ).hasClass( 'ab-sub-wrapper' ) ) {
|
||||
// We're dealing with an already-touch-opened menu genericon (we know el.hasClass('hover')),
|
||||
// so close it on a second tap and prevent propag and defaults. See #29906
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
el.removeClass('hover');
|
||||
}
|
||||
|
||||
if ( unbind ) {
|
||||
$('li.menupop').off('click.wp-mobile-hover');
|
||||
disableHoverIntent = false;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
touchClose = function() {
|
||||
var mobileEvent = /Mobile\/.+Safari/.test(navigator.userAgent) ? 'touchstart' : 'click';
|
||||
// close any open drop-downs when the click/touch is not on the toolbar
|
||||
$(document.body).on( mobileEvent+'.wp-mobile-hover', function(e) {
|
||||
if ( !$(e.target).closest('#wpadminbar').length )
|
||||
adminbar.find('li.menupop.hover').removeClass('hover');
|
||||
});
|
||||
};
|
||||
|
||||
adminbar.removeClass('nojq').removeClass('nojs');
|
||||
|
||||
if ( 'ontouchstart' in window ) {
|
||||
adminbar.on('touchstart', function(){
|
||||
touchOpen(true);
|
||||
disableHoverIntent = true;
|
||||
});
|
||||
touchClose();
|
||||
} else if ( /IEMobile\/[1-9]/.test(navigator.userAgent) ) {
|
||||
touchOpen();
|
||||
touchClose();
|
||||
}
|
||||
|
||||
adminbar.find('li.menupop').hoverIntent({
|
||||
over: function() {
|
||||
if ( disableHoverIntent )
|
||||
return;
|
||||
|
||||
$(this).addClass('hover');
|
||||
},
|
||||
out: function() {
|
||||
if ( disableHoverIntent )
|
||||
return;
|
||||
|
||||
$(this).removeClass('hover');
|
||||
},
|
||||
timeout: 180,
|
||||
sensitivity: 7,
|
||||
interval: 100
|
||||
});
|
||||
|
||||
if ( window.location.hash )
|
||||
window.scrollBy( 0, -32 );
|
||||
|
||||
$('#wp-admin-bar-get-shortlink').click(function(e){
|
||||
e.preventDefault();
|
||||
$(this).addClass('selected').children('.shortlink-input').blur(function(){
|
||||
$(this).parents('#wp-admin-bar-get-shortlink').removeClass('selected');
|
||||
}).focus().select();
|
||||
});
|
||||
|
||||
$('#wpadminbar li.menupop > .ab-item').bind('keydown.adminbar', function(e){
|
||||
if ( e.which != 13 )
|
||||
return;
|
||||
|
||||
var target = $(e.target),
|
||||
wrap = target.closest('.ab-sub-wrapper'),
|
||||
parentHasHover = target.parent().hasClass('hover');
|
||||
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
|
||||
if ( !wrap.length )
|
||||
wrap = $('#wpadminbar .quicklinks');
|
||||
|
||||
wrap.find('.menupop').removeClass('hover');
|
||||
|
||||
if ( ! parentHasHover ) {
|
||||
target.parent().toggleClass('hover');
|
||||
}
|
||||
|
||||
target.siblings('.ab-sub-wrapper').find('.ab-item').each(refresh);
|
||||
}).each(refresh);
|
||||
|
||||
$('#wpadminbar .ab-item').bind('keydown.adminbar', function(e){
|
||||
if ( e.which != 27 )
|
||||
return;
|
||||
|
||||
var target = $(e.target);
|
||||
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
|
||||
target.closest('.hover').removeClass('hover').children('.ab-item').focus();
|
||||
target.siblings('.ab-sub-wrapper').find('.ab-item').each(refresh);
|
||||
});
|
||||
|
||||
adminbar.click( function(e) {
|
||||
if ( e.target.id != 'wpadminbar' && e.target.id != 'wp-admin-bar-top-secondary' ) {
|
||||
return;
|
||||
}
|
||||
|
||||
adminbar.find( 'li.menupop.hover' ).removeClass( 'hover' );
|
||||
$( 'html, body' ).animate( { scrollTop: 0 }, 'fast' );
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
// fix focus bug in WebKit
|
||||
$('.screen-reader-shortcut').keydown( function(e) {
|
||||
var id, ua;
|
||||
|
||||
if ( 13 != e.which )
|
||||
return;
|
||||
|
||||
id = $( this ).attr( 'href' );
|
||||
|
||||
ua = navigator.userAgent.toLowerCase();
|
||||
|
||||
if ( ua.indexOf('applewebkit') != -1 && id && id.charAt(0) == '#' ) {
|
||||
setTimeout(function () {
|
||||
$(id).focus();
|
||||
}, 100);
|
||||
}
|
||||
});
|
||||
|
||||
$( '#adminbar-search' ).on({
|
||||
focus: function() {
|
||||
$( '#adminbarsearch' ).addClass( 'adminbar-focused' );
|
||||
}, blur: function() {
|
||||
$( '#adminbarsearch' ).removeClass( 'adminbar-focused' );
|
||||
}
|
||||
} );
|
||||
|
||||
// Empty sessionStorage on logging out
|
||||
if ( 'sessionStorage' in window ) {
|
||||
$('#wp-admin-bar-logout a').click( function() {
|
||||
try {
|
||||
for ( var key in sessionStorage ) {
|
||||
if ( key.indexOf('wp-autosave-') != -1 )
|
||||
sessionStorage.removeItem(key);
|
||||
}
|
||||
} catch(e) {}
|
||||
});
|
||||
}
|
||||
|
||||
if ( navigator.userAgent && document.body.className.indexOf( 'no-font-face' ) === -1 &&
|
||||
/Android (1.0|1.1|1.5|1.6|2.0|2.1)|Nokia|Opera Mini|w(eb)?OSBrowser|webOS|UCWEB|Windows Phone OS 7|XBLWP7|ZuneWP7|MSIE 7/.test( navigator.userAgent ) ) {
|
||||
|
||||
document.body.className += ' no-font-face';
|
||||
}
|
||||
});
|
||||
} else {
|
||||
(function(d, w) {
|
||||
var addEvent = function( obj, type, fn ) {
|
||||
if ( obj.addEventListener )
|
||||
obj.addEventListener(type, fn, false);
|
||||
else if ( obj.attachEvent )
|
||||
obj.attachEvent('on' + type, function() { return fn.call(obj, window.event);});
|
||||
},
|
||||
|
||||
aB, hc = new RegExp('\\bhover\\b', 'g'), q = [],
|
||||
rselected = new RegExp('\\bselected\\b', 'g'),
|
||||
|
||||
/**
|
||||
* Get the timeout ID of the given element
|
||||
*/
|
||||
getTOID = function(el) {
|
||||
var i = q.length;
|
||||
while ( i-- ) {
|
||||
if ( q[i] && el == q[i][1] )
|
||||
return q[i][0];
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
addHoverClass = function(t) {
|
||||
var i, id, inA, hovering, ul, li,
|
||||
ancestors = [],
|
||||
ancestorLength = 0;
|
||||
|
||||
while ( t && t != aB && t != d ) {
|
||||
if ( 'LI' == t.nodeName.toUpperCase() ) {
|
||||
ancestors[ ancestors.length ] = t;
|
||||
id = getTOID(t);
|
||||
if ( id )
|
||||
clearTimeout( id );
|
||||
t.className = t.className ? ( t.className.replace(hc, '') + ' hover' ) : 'hover';
|
||||
hovering = t;
|
||||
}
|
||||
t = t.parentNode;
|
||||
}
|
||||
|
||||
// Remove any selected classes.
|
||||
if ( hovering && hovering.parentNode ) {
|
||||
ul = hovering.parentNode;
|
||||
if ( ul && 'UL' == ul.nodeName.toUpperCase() ) {
|
||||
i = ul.childNodes.length;
|
||||
while ( i-- ) {
|
||||
li = ul.childNodes[i];
|
||||
if ( li != hovering )
|
||||
li.className = li.className ? li.className.replace( rselected, '' ) : '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* remove the hover class for any objects not in the immediate element's ancestry */
|
||||
i = q.length;
|
||||
while ( i-- ) {
|
||||
inA = false;
|
||||
ancestorLength = ancestors.length;
|
||||
while( ancestorLength-- ) {
|
||||
if ( ancestors[ ancestorLength ] == q[i][1] )
|
||||
inA = true;
|
||||
}
|
||||
|
||||
if ( ! inA )
|
||||
q[i][1].className = q[i][1].className ? q[i][1].className.replace(hc, '') : '';
|
||||
}
|
||||
},
|
||||
|
||||
removeHoverClass = function(t) {
|
||||
while ( t && t != aB && t != d ) {
|
||||
if ( 'LI' == t.nodeName.toUpperCase() ) {
|
||||
(function(t) {
|
||||
var to = setTimeout(function() {
|
||||
t.className = t.className ? t.className.replace(hc, '') : '';
|
||||
}, 500);
|
||||
q[q.length] = [to, t];
|
||||
})(t);
|
||||
}
|
||||
t = t.parentNode;
|
||||
}
|
||||
},
|
||||
|
||||
clickShortlink = function(e) {
|
||||
var i, l, node,
|
||||
t = e.target || e.srcElement;
|
||||
|
||||
// Make t the shortlink menu item, or return.
|
||||
while ( true ) {
|
||||
// Check if we've gone past the shortlink node,
|
||||
// or if the user is clicking on the input.
|
||||
if ( ! t || t == d || t == aB )
|
||||
return;
|
||||
// Check if we've found the shortlink node.
|
||||
if ( t.id && t.id == 'wp-admin-bar-get-shortlink' )
|
||||
break;
|
||||
t = t.parentNode;
|
||||
}
|
||||
|
||||
// IE doesn't support preventDefault, and does support returnValue
|
||||
if ( e.preventDefault )
|
||||
e.preventDefault();
|
||||
e.returnValue = false;
|
||||
|
||||
if ( -1 == t.className.indexOf('selected') )
|
||||
t.className += ' selected';
|
||||
|
||||
for ( i = 0, l = t.childNodes.length; i < l; i++ ) {
|
||||
node = t.childNodes[i];
|
||||
if ( node.className && -1 != node.className.indexOf('shortlink-input') ) {
|
||||
node.focus();
|
||||
node.select();
|
||||
node.onblur = function() {
|
||||
t.className = t.className ? t.className.replace( rselected, '' ) : '';
|
||||
};
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
scrollToTop = function(t) {
|
||||
var distance, speed, step, steps, timer, speed_step;
|
||||
|
||||
// Ensure that the #wpadminbar was the target of the click.
|
||||
if ( t.id != 'wpadminbar' && t.id != 'wp-admin-bar-top-secondary' )
|
||||
return;
|
||||
|
||||
distance = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
|
||||
|
||||
if ( distance < 1 )
|
||||
return;
|
||||
|
||||
speed_step = distance > 800 ? 130 : 100;
|
||||
speed = Math.min( 12, Math.round( distance / speed_step ) );
|
||||
step = distance > 800 ? Math.round( distance / 30 ) : Math.round( distance / 20 );
|
||||
steps = [];
|
||||
timer = 0;
|
||||
|
||||
// Animate scrolling to the top of the page by generating steps to
|
||||
// the top of the page and shifting to each step at a set interval.
|
||||
while ( distance ) {
|
||||
distance -= step;
|
||||
if ( distance < 0 )
|
||||
distance = 0;
|
||||
steps.push( distance );
|
||||
|
||||
setTimeout( function() {
|
||||
window.scrollTo( 0, steps.shift() );
|
||||
}, timer * speed );
|
||||
|
||||
timer++;
|
||||
}
|
||||
};
|
||||
|
||||
addEvent(w, 'load', function() {
|
||||
aB = d.getElementById('wpadminbar');
|
||||
|
||||
if ( d.body && aB ) {
|
||||
d.body.appendChild( aB );
|
||||
|
||||
if ( aB.className )
|
||||
aB.className = aB.className.replace(/nojs/, '');
|
||||
|
||||
addEvent(aB, 'mouseover', function(e) {
|
||||
addHoverClass( e.target || e.srcElement );
|
||||
});
|
||||
|
||||
addEvent(aB, 'mouseout', function(e) {
|
||||
removeHoverClass( e.target || e.srcElement );
|
||||
});
|
||||
|
||||
addEvent(aB, 'click', clickShortlink );
|
||||
|
||||
addEvent(aB, 'click', function(e) {
|
||||
scrollToTop( e.target || e.srcElement );
|
||||
});
|
||||
|
||||
addEvent( document.getElementById('wp-admin-bar-logout'), 'click', function() {
|
||||
if ( 'sessionStorage' in window ) {
|
||||
try {
|
||||
for ( var key in sessionStorage ) {
|
||||
if ( key.indexOf('wp-autosave-') != -1 )
|
||||
sessionStorage.removeItem(key);
|
||||
}
|
||||
} catch(e) {}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if ( w.location.hash )
|
||||
w.scrollBy(0,-32);
|
||||
|
||||
if ( navigator.userAgent && document.body.className.indexOf( 'no-font-face' ) === -1 &&
|
||||
/Android (1.0|1.1|1.5|1.6|2.0|2.1)|Nokia|Opera Mini|w(eb)?OSBrowser|webOS|UCWEB|Windows Phone OS 7|XBLWP7|ZuneWP7|MSIE 7/.test( navigator.userAgent ) ) {
|
||||
|
||||
document.body.className += ' no-font-face';
|
||||
}
|
||||
});
|
||||
})(document, window);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
var wpAjax = jQuery.extend( {
|
||||
unserialize: function( s ) {
|
||||
var r = {}, q, pp, i, p;
|
||||
if ( !s ) { return r; }
|
||||
q = s.split('?'); if ( q[1] ) { s = q[1]; }
|
||||
pp = s.split('&');
|
||||
for ( i in pp ) {
|
||||
if ( jQuery.isFunction(pp.hasOwnProperty) && !pp.hasOwnProperty(i) ) { continue; }
|
||||
p = pp[i].split('=');
|
||||
r[p[0]] = p[1];
|
||||
}
|
||||
return r;
|
||||
},
|
||||
parseAjaxResponse: function( x, r, e ) { // 1 = good, 0 = strange (bad data?), -1 = you lack permission
|
||||
var parsed = {}, re = jQuery('#' + r).empty(), err = '';
|
||||
|
||||
if ( x && typeof x == 'object' && x.getElementsByTagName('wp_ajax') ) {
|
||||
parsed.responses = [];
|
||||
parsed.errors = false;
|
||||
jQuery('response', x).each( function() {
|
||||
var th = jQuery(this), child = jQuery(this.firstChild), response;
|
||||
response = { action: th.attr('action'), what: child.get(0).nodeName, id: child.attr('id'), oldId: child.attr('old_id'), position: child.attr('position') };
|
||||
response.data = jQuery( 'response_data', child ).text();
|
||||
response.supplemental = {};
|
||||
if ( !jQuery( 'supplemental', child ).children().each( function() {
|
||||
response.supplemental[this.nodeName] = jQuery(this).text();
|
||||
} ).length ) { response.supplemental = false; }
|
||||
response.errors = [];
|
||||
if ( !jQuery('wp_error', child).each( function() {
|
||||
var code = jQuery(this).attr('code'), anError, errorData, formField;
|
||||
anError = { code: code, message: this.firstChild.nodeValue, data: false };
|
||||
errorData = jQuery('wp_error_data[code="' + code + '"]', x);
|
||||
if ( errorData ) { anError.data = errorData.get(); }
|
||||
formField = jQuery( 'form-field', errorData ).text();
|
||||
if ( formField ) { code = formField; }
|
||||
if ( e ) { wpAjax.invalidateForm( jQuery('#' + e + ' :input[name="' + code + '"]' ).parents('.form-field:first') ); }
|
||||
err += '<p>' + anError.message + '</p>';
|
||||
response.errors.push( anError );
|
||||
parsed.errors = true;
|
||||
} ).length ) { response.errors = false; }
|
||||
parsed.responses.push( response );
|
||||
} );
|
||||
if ( err.length ) { re.html( '<div class="error">' + err + '</div>' ); }
|
||||
return parsed;
|
||||
}
|
||||
if ( isNaN(x) ) { return !re.html('<div class="error"><p>' + x + '</p></div>'); }
|
||||
x = parseInt(x,10);
|
||||
if ( -1 == x ) { return !re.html('<div class="error"><p>' + wpAjax.noPerm + '</p></div>'); }
|
||||
else if ( 0 === x ) { return !re.html('<div class="error"><p>' + wpAjax.broken + '</p></div>'); }
|
||||
return true;
|
||||
},
|
||||
invalidateForm: function ( selector ) {
|
||||
return jQuery( selector ).addClass( 'form-invalid' ).find('input').one( 'change wp-check-valid-field', function() { jQuery(this).closest('.form-invalid').removeClass( 'form-invalid' ); } );
|
||||
},
|
||||
validateForm: function( selector ) {
|
||||
selector = jQuery( selector );
|
||||
return !wpAjax.invalidateForm( selector.find('.form-required').filter( function() { return jQuery('input:visible', this).val() === ''; } ) ).length;
|
||||
}
|
||||
}, wpAjax || { noPerm: 'Sorry, you are not allowed to do that.', broken: 'Something went wrong.' } );
|
||||
|
||||
// Basic form validation
|
||||
jQuery(document).ready( function($){
|
||||
$('form.validate').submit( function() { return wpAjax.validateForm( $(this) ); } );
|
||||
});
|
||||
@@ -0,0 +1,117 @@
|
||||
/* global adminpage */
|
||||
// Interim login dialog
|
||||
(function($){
|
||||
var wrap, next;
|
||||
|
||||
function show() {
|
||||
var parent = $('#wp-auth-check'),
|
||||
form = $('#wp-auth-check-form'),
|
||||
noframe = wrap.find('.wp-auth-fallback-expired'),
|
||||
frame, loaded = false;
|
||||
|
||||
if ( form.length ) {
|
||||
// Add unload confirmation to counter (frame-busting) JS redirects
|
||||
$(window).on( 'beforeunload.wp-auth-check', function(e) {
|
||||
e.originalEvent.returnValue = window.authcheckL10n.beforeunload;
|
||||
});
|
||||
|
||||
frame = $('<iframe id="wp-auth-check-frame" frameborder="0">').attr( 'title', noframe.text() );
|
||||
frame.on( 'load', function() {
|
||||
var height, body;
|
||||
|
||||
loaded = true;
|
||||
// Remove the spinner to avoid unnecessary CPU/GPU usage.
|
||||
form.removeClass( 'loading' );
|
||||
|
||||
try {
|
||||
body = $(this).contents().find('body');
|
||||
height = body.height();
|
||||
} catch(e) {
|
||||
wrap.addClass('fallback');
|
||||
parent.css( 'max-height', '' );
|
||||
form.remove();
|
||||
noframe.focus();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( height ) {
|
||||
if ( body && body.hasClass('interim-login-success') )
|
||||
hide();
|
||||
else
|
||||
parent.css( 'max-height', height + 40 + 'px' );
|
||||
} else if ( ! body || ! body.length ) {
|
||||
// Catch "silent" iframe origin exceptions in WebKit after another page is loaded in the iframe
|
||||
wrap.addClass('fallback');
|
||||
parent.css( 'max-height', '' );
|
||||
form.remove();
|
||||
noframe.focus();
|
||||
}
|
||||
}).attr( 'src', form.data('src') );
|
||||
|
||||
form.append( frame );
|
||||
}
|
||||
|
||||
$( 'body' ).addClass( 'modal-open' );
|
||||
wrap.removeClass('hidden');
|
||||
|
||||
if ( frame ) {
|
||||
frame.focus();
|
||||
// WebKit doesn't throw an error if the iframe fails to load because of "X-Frame-Options: DENY" header.
|
||||
// Wait for 10 sec. and switch to the fallback text.
|
||||
setTimeout( function() {
|
||||
if ( ! loaded ) {
|
||||
wrap.addClass('fallback');
|
||||
form.remove();
|
||||
noframe.focus();
|
||||
}
|
||||
}, 10000 );
|
||||
} else {
|
||||
noframe.focus();
|
||||
}
|
||||
}
|
||||
|
||||
function hide() {
|
||||
$(window).off( 'beforeunload.wp-auth-check' );
|
||||
|
||||
// When on the Edit Post screen, speed up heartbeat after the user logs in to quickly refresh nonces
|
||||
if ( typeof adminpage !== 'undefined' && ( adminpage === 'post-php' || adminpage === 'post-new-php' ) &&
|
||||
typeof wp !== 'undefined' && wp.heartbeat ) {
|
||||
|
||||
$(document).off( 'heartbeat-tick.wp-auth-check' );
|
||||
wp.heartbeat.connectNow();
|
||||
}
|
||||
|
||||
wrap.fadeOut( 200, function() {
|
||||
wrap.addClass('hidden').css('display', '');
|
||||
$('#wp-auth-check-frame').remove();
|
||||
$( 'body' ).removeClass( 'modal-open' );
|
||||
});
|
||||
}
|
||||
|
||||
function schedule() {
|
||||
var interval = parseInt( window.authcheckL10n.interval, 10 ) || 180; // in seconds, default 3 min.
|
||||
next = ( new Date() ).getTime() + ( interval * 1000 );
|
||||
}
|
||||
|
||||
$( document ).on( 'heartbeat-tick.wp-auth-check', function( e, data ) {
|
||||
if ( 'wp-auth-check' in data ) {
|
||||
schedule();
|
||||
if ( ! data['wp-auth-check'] && wrap.hasClass('hidden') ) {
|
||||
show();
|
||||
} else if ( data['wp-auth-check'] && ! wrap.hasClass('hidden') ) {
|
||||
hide();
|
||||
}
|
||||
}
|
||||
}).on( 'heartbeat-send.wp-auth-check', function( e, data ) {
|
||||
if ( ( new Date() ).getTime() > next ) {
|
||||
data['wp-auth-check'] = true;
|
||||
}
|
||||
}).ready( function() {
|
||||
schedule();
|
||||
wrap = $('#wp-auth-check-wrap');
|
||||
wrap.find('.wp-auth-check-close').on( 'click', function() {
|
||||
hide();
|
||||
});
|
||||
});
|
||||
|
||||
}(jQuery));
|
||||
@@ -0,0 +1,355 @@
|
||||
/* global wpColorPickerL10n */
|
||||
( function( $, undef ) {
|
||||
|
||||
var ColorPicker,
|
||||
_before = '<button type="button" class="button wp-color-result" aria-expanded="false"><span class="wp-color-result-text"></span></button>',
|
||||
_after = '<div class="wp-picker-holder" />',
|
||||
_wrap = '<div class="wp-picker-container" />',
|
||||
_button = '<input type="button" class="button button-small" />',
|
||||
_wrappingLabel = '<label></label>',
|
||||
_wrappingLabelText = '<span class="screen-reader-text"></span>';
|
||||
|
||||
/**
|
||||
* Creates a jQuery UI color picker that is used in the theme customizer.
|
||||
*
|
||||
* @class $.widget.wp.wpColorPicker
|
||||
*
|
||||
* @since 3.5.0
|
||||
*/
|
||||
ColorPicker = /** @lends $.widget.wp.wpColorPicker.prototype */{
|
||||
options: {
|
||||
defaultColor: false,
|
||||
change: false,
|
||||
clear: false,
|
||||
hide: true,
|
||||
palettes: true,
|
||||
width: 255,
|
||||
mode: 'hsv',
|
||||
type: 'full',
|
||||
slider: 'horizontal'
|
||||
},
|
||||
/**
|
||||
* Creates a color picker that only allows you to adjust the hue.
|
||||
*
|
||||
* @since 3.5.0
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
_createHueOnly: function() {
|
||||
var self = this,
|
||||
el = self.element,
|
||||
color;
|
||||
|
||||
el.hide();
|
||||
|
||||
// Set the saturation to the maximum level.
|
||||
color = 'hsl(' + el.val() + ', 100, 50)';
|
||||
|
||||
// Create an instance of the color picker, using the hsl mode.
|
||||
el.iris( {
|
||||
mode: 'hsl',
|
||||
type: 'hue',
|
||||
hide: false,
|
||||
color: color,
|
||||
/**
|
||||
* Handles the onChange event if one has been defined in the options.
|
||||
*
|
||||
* @ignore
|
||||
*
|
||||
* @param {Event} event The event that's being called.
|
||||
* @param {HTMLElement} ui The HTMLElement containing the color picker.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
change: function( event, ui ) {
|
||||
if ( $.isFunction( self.options.change ) ) {
|
||||
self.options.change.call( this, event, ui );
|
||||
}
|
||||
},
|
||||
width: self.options.width,
|
||||
slider: self.options.slider
|
||||
} );
|
||||
},
|
||||
/**
|
||||
* Creates the color picker, sets default values, css classes and wraps it all in HTML.
|
||||
*
|
||||
* @since 3.5.0
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
_create: function() {
|
||||
// Return early if Iris support is missing.
|
||||
if ( ! $.support.iris ) {
|
||||
return;
|
||||
}
|
||||
|
||||
var self = this,
|
||||
el = self.element;
|
||||
|
||||
// Override default options with options bound to the element.
|
||||
$.extend( self.options, el.data() );
|
||||
|
||||
// Create a color picker which only allows adjustments to the hue.
|
||||
if ( self.options.type === 'hue' ) {
|
||||
return self._createHueOnly();
|
||||
}
|
||||
|
||||
// Bind the close event.
|
||||
self.close = $.proxy( self.close, self );
|
||||
|
||||
self.initialValue = el.val();
|
||||
|
||||
// Add a CSS class to the input field.
|
||||
el.addClass( 'wp-color-picker' );
|
||||
|
||||
/*
|
||||
* Check if there's already a wrapping label, e.g. in the Customizer.
|
||||
* If there's no label, add a default one to match the Customizer template.
|
||||
*/
|
||||
if ( ! el.parent( 'label' ).length ) {
|
||||
// Wrap the input field in the default label.
|
||||
el.wrap( _wrappingLabel );
|
||||
// Insert the default label text.
|
||||
self.wrappingLabelText = $( _wrappingLabelText )
|
||||
.insertBefore( el )
|
||||
.text( wpColorPickerL10n.defaultLabel );
|
||||
}
|
||||
|
||||
/*
|
||||
* At this point, either it's the standalone version or the Customizer
|
||||
* one, we have a wrapping label to use as hook in the DOM, let's store it.
|
||||
*/
|
||||
self.wrappingLabel = el.parent();
|
||||
|
||||
// Wrap the label in the main wrapper.
|
||||
self.wrappingLabel.wrap( _wrap );
|
||||
// Store a reference to the main wrapper.
|
||||
self.wrap = self.wrappingLabel.parent();
|
||||
// Set up the toggle button and insert it before the wrapping label.
|
||||
self.toggler = $( _before )
|
||||
.insertBefore( self.wrappingLabel )
|
||||
.css( { backgroundColor: self.initialValue } );
|
||||
// Set the toggle button span element text.
|
||||
self.toggler.find( '.wp-color-result-text' ).text( wpColorPickerL10n.pick );
|
||||
// Set up the Iris container and insert it after the wrapping label.
|
||||
self.pickerContainer = $( _after ).insertAfter( self.wrappingLabel );
|
||||
// Store a reference to the Clear/Default button.
|
||||
self.button = $( _button );
|
||||
|
||||
// Set up the Clear/Default button.
|
||||
if ( self.options.defaultColor ) {
|
||||
self.button
|
||||
.addClass( 'wp-picker-default' )
|
||||
.val( wpColorPickerL10n.defaultString )
|
||||
.attr( 'aria-label', wpColorPickerL10n.defaultAriaLabel );
|
||||
} else {
|
||||
self.button
|
||||
.addClass( 'wp-picker-clear' )
|
||||
.val( wpColorPickerL10n.clear )
|
||||
.attr( 'aria-label', wpColorPickerL10n.clearAriaLabel );
|
||||
}
|
||||
|
||||
// Wrap the wrapping label in its wrapper and append the Clear/Default button.
|
||||
self.wrappingLabel
|
||||
.wrap( '<span class="wp-picker-input-wrap hidden" />' )
|
||||
.after( self.button );
|
||||
|
||||
/*
|
||||
* The input wrapper now contains the label+input+Clear/Default button.
|
||||
* Store a reference to the input wrapper: we'll use this to toggle
|
||||
* the controls visibility.
|
||||
*/
|
||||
self.inputWrapper = el.closest( '.wp-picker-input-wrap' );
|
||||
|
||||
el.iris( {
|
||||
target: self.pickerContainer,
|
||||
hide: self.options.hide,
|
||||
width: self.options.width,
|
||||
mode: self.options.mode,
|
||||
palettes: self.options.palettes,
|
||||
/**
|
||||
* Handles the onChange event if one has been defined in the options and additionally
|
||||
* sets the background color for the toggler element.
|
||||
*
|
||||
* @since 3.5.0
|
||||
*
|
||||
* @ignore
|
||||
*
|
||||
* @param {Event} event The event that's being called.
|
||||
* @param {HTMLElement} ui The HTMLElement containing the color picker.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
change: function( event, ui ) {
|
||||
self.toggler.css( { backgroundColor: ui.color.toString() } );
|
||||
|
||||
if ( $.isFunction( self.options.change ) ) {
|
||||
self.options.change.call( this, event, ui );
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
el.val( self.initialValue );
|
||||
self._addListeners();
|
||||
|
||||
// Force the color picker to always be closed on initial load.
|
||||
if ( ! self.options.hide ) {
|
||||
self.toggler.click();
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Binds event listeners to the color picker.
|
||||
*
|
||||
* @since 3.5.0
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
_addListeners: function() {
|
||||
var self = this;
|
||||
|
||||
/**
|
||||
* Prevent any clicks inside this widget from leaking to the top and closing it.
|
||||
*
|
||||
* @since 3.5.0
|
||||
*
|
||||
* @param {Event} event The event that's being called.
|
||||
*
|
||||
* @returs {void}
|
||||
*/
|
||||
self.wrap.on( 'click.wpcolorpicker', function( event ) {
|
||||
event.stopPropagation();
|
||||
});
|
||||
|
||||
/**
|
||||
* Open or close the color picker depending on the class.
|
||||
*
|
||||
* @since 3.5
|
||||
*/
|
||||
self.toggler.click( function(){
|
||||
if ( self.toggler.hasClass( 'wp-picker-open' ) ) {
|
||||
self.close();
|
||||
} else {
|
||||
self.open();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Checks if value is empty when changing the color in the color picker.
|
||||
* If so, the background color is cleared.
|
||||
*
|
||||
* @since 3.5.0
|
||||
*
|
||||
* @param {Event} event The event that's being called.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
self.element.change( function( event ) {
|
||||
var me = $( this ),
|
||||
val = me.val();
|
||||
|
||||
if ( val === '' || val === '#' ) {
|
||||
self.toggler.css( 'backgroundColor', '' );
|
||||
// Fire clear callback if we have one.
|
||||
if ( $.isFunction( self.options.clear ) ) {
|
||||
self.options.clear.call( this, event );
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Enables the user to either clear the color in the color picker or revert back to the default color.
|
||||
*
|
||||
* @since 3.5.0
|
||||
*
|
||||
* @param {Event} event The event that's being called.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
self.button.click( function( event ) {
|
||||
var me = $( this );
|
||||
if ( me.hasClass( 'wp-picker-clear' ) ) {
|
||||
self.element.val( '' );
|
||||
self.toggler.css( 'backgroundColor', '' );
|
||||
if ( $.isFunction( self.options.clear ) ) {
|
||||
self.options.clear.call( this, event );
|
||||
}
|
||||
} else if ( me.hasClass( 'wp-picker-default' ) ) {
|
||||
self.element.val( self.options.defaultColor ).change();
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Opens the color picker dialog.
|
||||
*
|
||||
* @since 3.5.0
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
open: function() {
|
||||
this.element.iris( 'toggle' );
|
||||
this.inputWrapper.removeClass( 'hidden' );
|
||||
this.wrap.addClass( 'wp-picker-active' );
|
||||
this.toggler
|
||||
.addClass( 'wp-picker-open' )
|
||||
.attr( 'aria-expanded', 'true' );
|
||||
$( 'body' ).trigger( 'click.wpcolorpicker' ).on( 'click.wpcolorpicker', this.close );
|
||||
},
|
||||
/**
|
||||
* Closes the color picker dialog.
|
||||
*
|
||||
* @since 3.5.0
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
close: function() {
|
||||
this.element.iris( 'toggle' );
|
||||
this.inputWrapper.addClass( 'hidden' );
|
||||
this.wrap.removeClass( 'wp-picker-active' );
|
||||
this.toggler
|
||||
.removeClass( 'wp-picker-open' )
|
||||
.attr( 'aria-expanded', 'false' );
|
||||
$( 'body' ).off( 'click.wpcolorpicker', this.close );
|
||||
},
|
||||
/**
|
||||
* Returns the iris object if no new color is provided. If a new color is provided, it sets the new color.
|
||||
*
|
||||
* @param newColor {string|*} The new color to use. Can be undefined.
|
||||
*
|
||||
* @since 3.5.0
|
||||
*
|
||||
* @returns {string} The element's color
|
||||
*/
|
||||
color: function( newColor ) {
|
||||
if ( newColor === undef ) {
|
||||
return this.element.iris( 'option', 'color' );
|
||||
}
|
||||
this.element.iris( 'option', 'color', newColor );
|
||||
},
|
||||
/**
|
||||
* Returns the iris object if no new default color is provided.
|
||||
* If a new default color is provided, it sets the new default color.
|
||||
*
|
||||
* @param newDefaultColor {string|*} The new default color to use. Can be undefined.
|
||||
*
|
||||
* @since 3.5.0
|
||||
*
|
||||
* @returns {boolean|string} The element's color.
|
||||
*/
|
||||
defaultColor: function( newDefaultColor ) {
|
||||
if ( newDefaultColor === undef ) {
|
||||
return this.options.defaultColor;
|
||||
}
|
||||
|
||||
this.options.defaultColor = newDefaultColor;
|
||||
}
|
||||
};
|
||||
|
||||
// Register the color picker as a widget.
|
||||
$.widget( 'wp.wpColorPicker', ColorPicker );
|
||||
}( jQuery ) );
|
||||
@@ -0,0 +1,323 @@
|
||||
/**
|
||||
* Handles the addition of the comment form.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @namespace addComment
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
var addComment;
|
||||
addComment = ( function( window ) {
|
||||
// Avoid scope lookups on commonly used variables.
|
||||
var document = window.document;
|
||||
|
||||
// Settings.
|
||||
var config = {
|
||||
commentReplyClass : 'comment-reply-link',
|
||||
cancelReplyId : 'cancel-comment-reply-link',
|
||||
commentFormId : 'commentform',
|
||||
temporaryFormId : 'wp-temp-form-div',
|
||||
parentIdFieldId : 'comment_parent',
|
||||
postIdFieldId : 'comment_post_ID'
|
||||
};
|
||||
|
||||
// Check browser cuts the mustard.
|
||||
var cutsTheMustard = 'querySelector' in document && 'addEventListener' in window;
|
||||
|
||||
/*
|
||||
* Check browser supports dataset.
|
||||
* !! sets the variable to true if the property exists.
|
||||
*/
|
||||
var supportsDataset = !! document.body.dataset;
|
||||
|
||||
// For holding the cancel element.
|
||||
var cancelElement;
|
||||
|
||||
// For holding the comment form element.
|
||||
var commentFormElement;
|
||||
|
||||
// The respond element.
|
||||
var respondElement;
|
||||
|
||||
// Initialise the events.
|
||||
init();
|
||||
|
||||
/**
|
||||
* Add events to links classed .comment-reply-link.
|
||||
*
|
||||
* Searches the context for reply links and adds the JavaScript events
|
||||
* required to move the comment form. To allow for lazy loading of
|
||||
* comments this method is exposed as window.commentReply.init().
|
||||
*
|
||||
* @since 5.0.0
|
||||
*
|
||||
* @memberOf addComment
|
||||
*
|
||||
* @param {HTMLElement} context The parent DOM element to search for links.
|
||||
*/
|
||||
function init( context ) {
|
||||
if ( true !== cutsTheMustard ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get required elements.
|
||||
cancelElement = getElementById( config.cancelReplyId );
|
||||
commentFormElement = getElementById( config.commentFormId );
|
||||
|
||||
// No cancel element, no replies.
|
||||
if ( ! cancelElement ) {
|
||||
return;
|
||||
}
|
||||
|
||||
cancelElement.addEventListener( 'touchstart', cancelEvent );
|
||||
cancelElement.addEventListener( 'click', cancelEvent );
|
||||
|
||||
var links = replyLinks( context );
|
||||
var element;
|
||||
|
||||
for ( var i = 0, l = links.length; i < l; i++ ) {
|
||||
element = links[i];
|
||||
|
||||
element.addEventListener( 'touchstart', clickEvent );
|
||||
element.addEventListener( 'click', clickEvent );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all links classed .comment-reply-link.
|
||||
*
|
||||
* @since 5.0.0
|
||||
*
|
||||
* @param {HTMLElement} context The parent DOM element to search for links.
|
||||
*
|
||||
* @return {HTMLCollection|NodeList|Array}
|
||||
*/
|
||||
function replyLinks( context ) {
|
||||
var selectorClass = config.commentReplyClass;
|
||||
var allReplyLinks;
|
||||
|
||||
// childNodes is a handy check to ensure the context is a HTMLElement.
|
||||
if ( ! context || ! context.childNodes ) {
|
||||
context = document;
|
||||
}
|
||||
|
||||
if ( document.getElementsByClassName ) {
|
||||
// Fastest.
|
||||
allReplyLinks = context.getElementsByClassName( selectorClass );
|
||||
}
|
||||
else {
|
||||
// Fast.
|
||||
allReplyLinks = context.querySelectorAll( '.' + selectorClass );
|
||||
}
|
||||
|
||||
return allReplyLinks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel event handler.
|
||||
*
|
||||
* @since 5.0.0
|
||||
*
|
||||
* @param {Event} event The calling event.
|
||||
*/
|
||||
function cancelEvent( event ) {
|
||||
var cancelLink = this;
|
||||
var temporaryFormId = config.temporaryFormId;
|
||||
var temporaryElement = getElementById( temporaryFormId );
|
||||
|
||||
if ( ! temporaryElement || ! respondElement ) {
|
||||
// Conditions for cancel link fail.
|
||||
return;
|
||||
}
|
||||
|
||||
getElementById( config.parentIdFieldId ).value = '0';
|
||||
|
||||
// Move the respond form back in place of the temporary element.
|
||||
temporaryElement.parentNode.replaceChild( respondElement ,temporaryElement );
|
||||
cancelLink.style.display = 'none';
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
/**
|
||||
* Click event handler.
|
||||
*
|
||||
* @since 5.0.0
|
||||
*
|
||||
* @param {Event} event The calling event.
|
||||
*/
|
||||
function clickEvent( event ) {
|
||||
var replyLink = this,
|
||||
commId = getDataAttribute( replyLink, 'belowelement'),
|
||||
parentId = getDataAttribute( replyLink, 'commentid' ),
|
||||
respondId = getDataAttribute( replyLink, 'respondelement'),
|
||||
postId = getDataAttribute( replyLink, 'postid'),
|
||||
follow;
|
||||
|
||||
/*
|
||||
* Third party comments systems can hook into this function via the global scope,
|
||||
* therefore the click event needs to reference the global scope.
|
||||
*/
|
||||
follow = window.addComment.moveForm(commId, parentId, respondId, postId);
|
||||
if ( false === follow ) {
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Backward compatible getter of data-* attribute.
|
||||
*
|
||||
* Uses element.dataset if it exists, otherwise uses getAttribute.
|
||||
*
|
||||
* @since 5.0.0
|
||||
*
|
||||
* @param {HTMLElement} Element DOM element with the attribute.
|
||||
* @param {String} Attribute the attribute to get.
|
||||
*
|
||||
* @return {String}
|
||||
*/
|
||||
function getDataAttribute( element, attribute ) {
|
||||
if ( supportsDataset ) {
|
||||
return element.dataset[attribute];
|
||||
}
|
||||
else {
|
||||
return element.getAttribute( 'data-' + attribute );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get element by ID.
|
||||
*
|
||||
* Local alias for document.getElementById.
|
||||
*
|
||||
* @since 5.0.0
|
||||
*
|
||||
* @param {HTMLElement} The requested element.
|
||||
*/
|
||||
function getElementById( elementId ) {
|
||||
return document.getElementById( elementId );
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the reply form from its current position to the reply location.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @memberOf addComment
|
||||
*
|
||||
* @param {String} addBelowId HTML ID of element the form follows.
|
||||
* @param {String} commentId Database ID of comment being replied to.
|
||||
* @param {String} respondId HTML ID of 'respond' element.
|
||||
* @param {String} postId Database ID of the post.
|
||||
*/
|
||||
function moveForm( addBelowId, commentId, respondId, postId ) {
|
||||
// Get elements based on their IDs.
|
||||
var addBelowElement = getElementById( addBelowId );
|
||||
respondElement = getElementById( respondId );
|
||||
|
||||
// Get the hidden fields.
|
||||
var parentIdField = getElementById( config.parentIdFieldId );
|
||||
var postIdField = getElementById( config.postIdFieldId );
|
||||
var element, cssHidden, style;
|
||||
|
||||
if ( ! addBelowElement || ! respondElement || ! parentIdField ) {
|
||||
// Missing key elements, fail.
|
||||
return;
|
||||
}
|
||||
|
||||
addPlaceHolder( respondElement );
|
||||
|
||||
// Set the value of the post.
|
||||
if ( postId && postIdField ) {
|
||||
postIdField.value = postId;
|
||||
}
|
||||
|
||||
parentIdField.value = commentId;
|
||||
|
||||
cancelElement.style.display = '';
|
||||
addBelowElement.parentNode.insertBefore( respondElement, addBelowElement.nextSibling );
|
||||
|
||||
/*
|
||||
* This is for backward compatibility with third party commenting systems
|
||||
* hooking into the event using older techniques.
|
||||
*/
|
||||
cancelElement.onclick = function(){
|
||||
return false;
|
||||
};
|
||||
|
||||
// Focus on the first field in the comment form.
|
||||
try {
|
||||
for ( var i = 0; i < commentFormElement.elements.length; i++ ) {
|
||||
element = commentFormElement.elements[i];
|
||||
cssHidden = false;
|
||||
|
||||
// Get elements computed style.
|
||||
if ( 'getComputedStyle' in window ) {
|
||||
// Modern browsers.
|
||||
style = window.getComputedStyle( element );
|
||||
} else if ( document.documentElement.currentStyle ) {
|
||||
// IE 8.
|
||||
style = element.currentStyle;
|
||||
}
|
||||
|
||||
/*
|
||||
* For display none, do the same thing jQuery does. For visibility,
|
||||
* check the element computed style since browsers are already doing
|
||||
* the job for us. In fact, the visibility computed style is the actual
|
||||
* computed value and already takes into account the element ancestors.
|
||||
*/
|
||||
if ( ( element.offsetWidth <= 0 && element.offsetHeight <= 0 ) || style.visibility === 'hidden' ) {
|
||||
cssHidden = true;
|
||||
}
|
||||
|
||||
// Skip form elements that are hidden or disabled.
|
||||
if ( 'hidden' === element.type || element.disabled || cssHidden ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
element.focus();
|
||||
// Stop after the first focusable element.
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch(e) {
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* false is returned for backward compatibility with third party commenting systems
|
||||
* hooking into this function.
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add placeholder element.
|
||||
*
|
||||
* Places a place holder element above the #respond element for
|
||||
* the form to be returned to if needs be.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @param {HTMLelement} respondElement the #respond element holding comment form.
|
||||
*/
|
||||
function addPlaceHolder( respondElement ) {
|
||||
var temporaryFormId = config.temporaryFormId;
|
||||
var temporaryElement = getElementById( temporaryFormId );
|
||||
|
||||
if ( temporaryElement ) {
|
||||
// The element already exists, no need to recreate.
|
||||
return;
|
||||
}
|
||||
|
||||
temporaryElement = document.createElement( 'div' );
|
||||
temporaryElement.id = temporaryFormId;
|
||||
temporaryElement.style.display = 'none';
|
||||
respondElement.parentNode.insertBefore( temporaryElement, respondElement );
|
||||
}
|
||||
|
||||
return {
|
||||
init: init,
|
||||
moveForm: moveForm
|
||||
};
|
||||
})( window );
|
||||
@@ -0,0 +1,198 @@
|
||||
/* global userSettings */
|
||||
/* exported getUserSetting, setUserSetting, deleteUserSetting */
|
||||
// utility functions
|
||||
|
||||
var wpCookies = {
|
||||
// The following functions are from Cookie.js class in TinyMCE 3, Moxiecode, used under LGPL.
|
||||
|
||||
each: function( obj, cb, scope ) {
|
||||
var n, l;
|
||||
|
||||
if ( ! obj ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
scope = scope || obj;
|
||||
|
||||
if ( typeof( obj.length ) !== 'undefined' ) {
|
||||
for ( n = 0, l = obj.length; n < l; n++ ) {
|
||||
if ( cb.call( scope, obj[n], n, obj ) === false ) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for ( n in obj ) {
|
||||
if ( obj.hasOwnProperty(n) ) {
|
||||
if ( cb.call( scope, obj[n], n, obj ) === false ) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get a multi-values cookie.
|
||||
* Returns a JS object with the name: 'value' pairs.
|
||||
*/
|
||||
getHash: function( name ) {
|
||||
var cookie = this.get( name ), values;
|
||||
|
||||
if ( cookie ) {
|
||||
this.each( cookie.split('&'), function( pair ) {
|
||||
pair = pair.split('=');
|
||||
values = values || {};
|
||||
values[pair[0]] = pair[1];
|
||||
});
|
||||
}
|
||||
|
||||
return values;
|
||||
},
|
||||
|
||||
/**
|
||||
* Set a multi-values cookie.
|
||||
*
|
||||
* 'values_obj' is the JS object that is stored. It is encoded as URI in wpCookies.set().
|
||||
*/
|
||||
setHash: function( name, values_obj, expires, path, domain, secure ) {
|
||||
var str = '';
|
||||
|
||||
this.each( values_obj, function( val, key ) {
|
||||
str += ( ! str ? '' : '&' ) + key + '=' + val;
|
||||
});
|
||||
|
||||
this.set( name, str, expires, path, domain, secure );
|
||||
},
|
||||
|
||||
/**
|
||||
* Get a cookie.
|
||||
*/
|
||||
get: function( name ) {
|
||||
var e, b,
|
||||
cookie = document.cookie,
|
||||
p = name + '=';
|
||||
|
||||
if ( ! cookie ) {
|
||||
return;
|
||||
}
|
||||
|
||||
b = cookie.indexOf( '; ' + p );
|
||||
|
||||
if ( b === -1 ) {
|
||||
b = cookie.indexOf(p);
|
||||
|
||||
if ( b !== 0 ) {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
b += 2;
|
||||
}
|
||||
|
||||
e = cookie.indexOf( ';', b );
|
||||
|
||||
if ( e === -1 ) {
|
||||
e = cookie.length;
|
||||
}
|
||||
|
||||
return decodeURIComponent( cookie.substring( b + p.length, e ) );
|
||||
},
|
||||
|
||||
/**
|
||||
* Set a cookie.
|
||||
*
|
||||
* The 'expires' arg can be either a JS Date() object set to the expiration date (back-compat)
|
||||
* or the number of seconds until expiration
|
||||
*/
|
||||
set: function( name, value, expires, path, domain, secure ) {
|
||||
var d = new Date();
|
||||
|
||||
if ( typeof( expires ) === 'object' && expires.toGMTString ) {
|
||||
expires = expires.toGMTString();
|
||||
} else if ( parseInt( expires, 10 ) ) {
|
||||
d.setTime( d.getTime() + ( parseInt( expires, 10 ) * 1000 ) ); // time must be in milliseconds
|
||||
expires = d.toGMTString();
|
||||
} else {
|
||||
expires = '';
|
||||
}
|
||||
|
||||
document.cookie = name + '=' + encodeURIComponent( value ) +
|
||||
( expires ? '; expires=' + expires : '' ) +
|
||||
( path ? '; path=' + path : '' ) +
|
||||
( domain ? '; domain=' + domain : '' ) +
|
||||
( secure ? '; secure' : '' );
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove a cookie.
|
||||
*
|
||||
* This is done by setting it to an empty value and setting the expiration time in the past.
|
||||
*/
|
||||
remove: function( name, path, domain, secure ) {
|
||||
this.set( name, '', -1000, path, domain, secure );
|
||||
}
|
||||
};
|
||||
|
||||
// Returns the value as string. Second arg or empty string is returned when value is not set.
|
||||
function getUserSetting( name, def ) {
|
||||
var settings = getAllUserSettings();
|
||||
|
||||
if ( settings.hasOwnProperty( name ) ) {
|
||||
return settings[name];
|
||||
}
|
||||
|
||||
if ( typeof def !== 'undefined' ) {
|
||||
return def;
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
// Both name and value must be only ASCII letters, numbers or underscore
|
||||
// and the shorter, the better (cookies can store maximum 4KB). Not suitable to store text.
|
||||
// The value is converted and stored as string.
|
||||
function setUserSetting( name, value, _del ) {
|
||||
if ( 'object' !== typeof userSettings ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var uid = userSettings.uid,
|
||||
settings = wpCookies.getHash( 'wp-settings-' + uid ),
|
||||
path = userSettings.url,
|
||||
secure = !! userSettings.secure;
|
||||
|
||||
name = name.toString().replace( /[^A-Za-z0-9_-]/g, '' );
|
||||
|
||||
if ( typeof value === 'number' ) {
|
||||
value = parseInt( value, 10 );
|
||||
} else {
|
||||
value = value.toString().replace( /[^A-Za-z0-9_-]/g, '' );
|
||||
}
|
||||
|
||||
settings = settings || {};
|
||||
|
||||
if ( _del ) {
|
||||
delete settings[name];
|
||||
} else {
|
||||
settings[name] = value;
|
||||
}
|
||||
|
||||
wpCookies.setHash( 'wp-settings-' + uid, settings, 31536000, path, '', secure );
|
||||
wpCookies.set( 'wp-settings-time-' + uid, userSettings.time, 31536000, path, '', secure );
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
function deleteUserSetting( name ) {
|
||||
return setUserSetting( name, '', 1 );
|
||||
}
|
||||
|
||||
// Returns all settings as js object.
|
||||
function getAllUserSettings() {
|
||||
if ( 'object' !== typeof userSettings ) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return wpCookies.getHash( 'wp-settings-' + userSettings.uid ) || {};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Wrap the jQuery UI Dialog open function remove focus from tinyMCE.
|
||||
*/
|
||||
( function($) {
|
||||
$.widget('wp.wpdialog', $.ui.dialog, {
|
||||
open: function() {
|
||||
// Add beforeOpen event.
|
||||
if ( this.isOpen() || false === this._trigger('beforeOpen') ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Open the dialog.
|
||||
this._super();
|
||||
|
||||
// WebKit leaves focus in the TinyMCE editor unless we shift focus.
|
||||
this.element.focus();
|
||||
this._trigger('refresh');
|
||||
}
|
||||
});
|
||||
|
||||
$.wp.wpdialog.prototype.options.closeOnEscape = false;
|
||||
|
||||
})(jQuery);
|
||||
@@ -0,0 +1,212 @@
|
||||
(function ( window, document ) {
|
||||
'use strict';
|
||||
|
||||
var supportedBrowser = ( document.querySelector && window.addEventListener ),
|
||||
loaded = false,
|
||||
secret,
|
||||
secretTimeout,
|
||||
resizing;
|
||||
|
||||
function sendEmbedMessage( message, value ) {
|
||||
window.parent.postMessage( {
|
||||
message: message,
|
||||
value: value,
|
||||
secret: secret
|
||||
}, '*' );
|
||||
}
|
||||
|
||||
function onLoad() {
|
||||
if ( loaded ) {
|
||||
return;
|
||||
}
|
||||
loaded = true;
|
||||
|
||||
var share_dialog = document.querySelector( '.wp-embed-share-dialog' ),
|
||||
share_dialog_open = document.querySelector( '.wp-embed-share-dialog-open' ),
|
||||
share_dialog_close = document.querySelector( '.wp-embed-share-dialog-close' ),
|
||||
share_input = document.querySelectorAll( '.wp-embed-share-input' ),
|
||||
share_dialog_tabs = document.querySelectorAll( '.wp-embed-share-tab-button button' ),
|
||||
featured_image = document.querySelector( '.wp-embed-featured-image img' ),
|
||||
i;
|
||||
|
||||
if ( share_input ) {
|
||||
for ( i = 0; i < share_input.length; i++ ) {
|
||||
share_input[ i ].addEventListener( 'click', function ( e ) {
|
||||
e.target.select();
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
function openSharingDialog() {
|
||||
share_dialog.className = share_dialog.className.replace( 'hidden', '' );
|
||||
// Initial focus should go on the currently selected tab in the dialog.
|
||||
document.querySelector( '.wp-embed-share-tab-button [aria-selected="true"]' ).focus();
|
||||
}
|
||||
|
||||
function closeSharingDialog() {
|
||||
share_dialog.className += ' hidden';
|
||||
document.querySelector( '.wp-embed-share-dialog-open' ).focus();
|
||||
}
|
||||
|
||||
if ( share_dialog_open ) {
|
||||
share_dialog_open.addEventListener( 'click', function () {
|
||||
openSharingDialog();
|
||||
} );
|
||||
}
|
||||
|
||||
if ( share_dialog_close ) {
|
||||
share_dialog_close.addEventListener( 'click', function () {
|
||||
closeSharingDialog();
|
||||
} );
|
||||
}
|
||||
|
||||
function shareClickHandler( e ) {
|
||||
var currentTab = document.querySelector( '.wp-embed-share-tab-button [aria-selected="true"]' );
|
||||
currentTab.setAttribute( 'aria-selected', 'false' );
|
||||
document.querySelector( '#' + currentTab.getAttribute( 'aria-controls' ) ).setAttribute( 'aria-hidden', 'true' );
|
||||
|
||||
e.target.setAttribute( 'aria-selected', 'true' );
|
||||
document.querySelector( '#' + e.target.getAttribute( 'aria-controls' ) ).setAttribute( 'aria-hidden', 'false' );
|
||||
}
|
||||
|
||||
function shareKeyHandler( e ) {
|
||||
var target = e.target,
|
||||
previousSibling = target.parentElement.previousElementSibling,
|
||||
nextSibling = target.parentElement.nextElementSibling,
|
||||
newTab, newTabChild;
|
||||
|
||||
if ( 37 === e.keyCode ) {
|
||||
newTab = previousSibling;
|
||||
} else if ( 39 === e.keyCode ) {
|
||||
newTab = nextSibling;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( 'rtl' === document.documentElement.getAttribute( 'dir' ) ) {
|
||||
newTab = ( newTab === previousSibling ) ? nextSibling : previousSibling;
|
||||
}
|
||||
|
||||
if ( newTab ) {
|
||||
newTabChild = newTab.firstElementChild;
|
||||
|
||||
target.setAttribute( 'tabindex', '-1' );
|
||||
target.setAttribute( 'aria-selected', false );
|
||||
document.querySelector( '#' + target.getAttribute( 'aria-controls' ) ).setAttribute( 'aria-hidden', 'true' );
|
||||
|
||||
newTabChild.setAttribute( 'tabindex', '0' );
|
||||
newTabChild.setAttribute( 'aria-selected', 'true' );
|
||||
newTabChild.focus();
|
||||
document.querySelector( '#' + newTabChild.getAttribute( 'aria-controls' ) ).setAttribute( 'aria-hidden', 'false' );
|
||||
}
|
||||
}
|
||||
|
||||
if ( share_dialog_tabs ) {
|
||||
for ( i = 0; i < share_dialog_tabs.length; i++ ) {
|
||||
share_dialog_tabs[ i ].addEventListener( 'click', shareClickHandler );
|
||||
|
||||
share_dialog_tabs[ i ].addEventListener( 'keydown', shareKeyHandler );
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener( 'keydown', function ( e ) {
|
||||
if ( 27 === e.keyCode && -1 === share_dialog.className.indexOf( 'hidden' ) ) {
|
||||
closeSharingDialog();
|
||||
} else if ( 9 === e.keyCode ) {
|
||||
constrainTabbing( e );
|
||||
}
|
||||
}, false );
|
||||
|
||||
function constrainTabbing( e ) {
|
||||
// Need to re-get the selected tab each time.
|
||||
var firstFocusable = document.querySelector( '.wp-embed-share-tab-button [aria-selected="true"]' );
|
||||
|
||||
if ( share_dialog_close === e.target && ! e.shiftKey ) {
|
||||
firstFocusable.focus();
|
||||
e.preventDefault();
|
||||
} else if ( firstFocusable === e.target && e.shiftKey ) {
|
||||
share_dialog_close.focus();
|
||||
e.preventDefault();
|
||||
}
|
||||
}
|
||||
|
||||
if ( window.self === window.top ) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send this document's height to the parent (embedding) site.
|
||||
*/
|
||||
sendEmbedMessage( 'height', Math.ceil( document.body.getBoundingClientRect().height ) );
|
||||
|
||||
// Send the document's height again after the featured image has been loaded.
|
||||
if ( featured_image ) {
|
||||
featured_image.addEventListener( 'load', function() {
|
||||
sendEmbedMessage( 'height', Math.ceil( document.body.getBoundingClientRect().height ) );
|
||||
} );
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect clicks to external (_top) links.
|
||||
*/
|
||||
function linkClickHandler( e ) {
|
||||
var target = e.target,
|
||||
href;
|
||||
if ( target.hasAttribute( 'href' ) ) {
|
||||
href = target.getAttribute( 'href' );
|
||||
} else {
|
||||
href = target.parentElement.getAttribute( 'href' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Send link target to the parent (embedding) site.
|
||||
*/
|
||||
if ( href ) {
|
||||
sendEmbedMessage( 'link', href );
|
||||
e.preventDefault();
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener( 'click', linkClickHandler );
|
||||
}
|
||||
|
||||
/**
|
||||
* Iframe resize handler.
|
||||
*/
|
||||
function onResize() {
|
||||
if ( window.self === window.top ) {
|
||||
return;
|
||||
}
|
||||
|
||||
clearTimeout( resizing );
|
||||
|
||||
resizing = setTimeout( function () {
|
||||
sendEmbedMessage( 'height', Math.ceil( document.body.getBoundingClientRect().height ) );
|
||||
}, 100 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-get the secret when it was added later on.
|
||||
*/
|
||||
function getSecret() {
|
||||
if ( window.self === window.top || !!secret ) {
|
||||
return;
|
||||
}
|
||||
|
||||
secret = window.location.hash.replace( /.*secret=([\d\w]{10}).*/, '$1' );
|
||||
|
||||
clearTimeout( secretTimeout );
|
||||
|
||||
secretTimeout = setTimeout( function () {
|
||||
getSecret();
|
||||
}, 100 );
|
||||
}
|
||||
|
||||
if ( supportedBrowser ) {
|
||||
getSecret();
|
||||
document.documentElement.className = document.documentElement.className.replace( /\bno-js\b/, '' ) + ' js';
|
||||
document.addEventListener( 'DOMContentLoaded', onLoad, false );
|
||||
window.addEventListener( 'load', onLoad, false );
|
||||
window.addEventListener( 'resize', onResize, false );
|
||||
}
|
||||
})( window, document );
|
||||
@@ -0,0 +1,192 @@
|
||||
( function( window, document, settings ) {
|
||||
var src, ready, ii, tests;
|
||||
|
||||
// Create a canvas element for testing native browser support of emoji.
|
||||
var canvas = document.createElement( 'canvas' );
|
||||
var context = canvas.getContext && canvas.getContext( '2d' );
|
||||
|
||||
/**
|
||||
* Checks if two sets of Emoji characters render the same visually.
|
||||
*
|
||||
* @since 4.9.0
|
||||
*
|
||||
* @private
|
||||
*
|
||||
* @param {number[]} set1 Set of Emoji character codes.
|
||||
* @param {number[]} set2 Set of Emoji character codes.
|
||||
*
|
||||
* @return {boolean} True if the two sets render the same.
|
||||
*/
|
||||
function emojiSetsRenderIdentically( set1, set2 ) {
|
||||
var stringFromCharCode = String.fromCharCode;
|
||||
|
||||
// Cleanup from previous test.
|
||||
context.clearRect( 0, 0, canvas.width, canvas.height );
|
||||
context.fillText( stringFromCharCode.apply( this, set1 ), 0, 0 );
|
||||
var rendered1 = canvas.toDataURL();
|
||||
|
||||
// Cleanup from previous test.
|
||||
context.clearRect( 0, 0, canvas.width, canvas.height );
|
||||
context.fillText( stringFromCharCode.apply( this, set2 ), 0, 0 );
|
||||
var rendered2 = canvas.toDataURL();
|
||||
|
||||
return rendered1 === rendered2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detects if the browser supports rendering emoji or flag emoji.
|
||||
*
|
||||
* Flag emoji are a single glyph made of two characters, so some browsers
|
||||
* (notably, Firefox OS X) don't support them.
|
||||
*
|
||||
* @since 4.2.0
|
||||
*
|
||||
* @private
|
||||
*
|
||||
* @param {string} type Whether to test for support of "flag" or "emoji".
|
||||
*
|
||||
* @return {boolean} True if the browser can render emoji, false if it cannot.
|
||||
*/
|
||||
function browserSupportsEmoji( type ) {
|
||||
var isIdentical;
|
||||
|
||||
if ( ! context || ! context.fillText ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Chrome on OS X added native emoji rendering in M41. Unfortunately,
|
||||
* it doesn't work when the font is bolder than 500 weight. So, we
|
||||
* check for bold rendering support to avoid invisible emoji in Chrome.
|
||||
*/
|
||||
context.textBaseline = 'top';
|
||||
context.font = '600 32px Arial';
|
||||
|
||||
switch ( type ) {
|
||||
case 'flag':
|
||||
/*
|
||||
* Test for UN flag compatibility. This is the least supported of the letter locale flags,
|
||||
* so gives us an easy test for full support.
|
||||
*
|
||||
* To test for support, we try to render it, and compare the rendering to how it would look if
|
||||
* the browser doesn't render it correctly ([U] + [N]).
|
||||
*/
|
||||
isIdentical = emojiSetsRenderIdentically(
|
||||
[ 55356, 56826, 55356, 56819 ],
|
||||
[ 55356, 56826, 8203, 55356, 56819 ]
|
||||
);
|
||||
|
||||
if ( isIdentical ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test for English flag compatibility. England is a country in the United Kingdom, it
|
||||
* does not have a two letter locale code but rather an five letter sub-division code.
|
||||
*
|
||||
* To test for support, we try to render it, and compare the rendering to how it would look if
|
||||
* the browser doesn't render it correctly (black flag emoji + [G] + [B] + [E] + [N] + [G]).
|
||||
*/
|
||||
isIdentical = emojiSetsRenderIdentically(
|
||||
[ 55356, 57332, 56128, 56423, 56128, 56418, 56128, 56421, 56128, 56430, 56128, 56423, 56128, 56447 ],
|
||||
[ 55356, 57332, 8203, 56128, 56423, 8203, 56128, 56418, 8203, 56128, 56421, 8203, 56128, 56430, 8203, 56128, 56423, 8203, 56128, 56447 ]
|
||||
);
|
||||
|
||||
return ! isIdentical;
|
||||
case 'emoji':
|
||||
/*
|
||||
* Emoji allows people of all gender levitate and so does WordPress.
|
||||
*
|
||||
* To test for support, try to render a new emoji (woman in business suit levitating),
|
||||
* then compare it to how it would look if the browser doesn't render it correctly
|
||||
* (person in business suit levitating + female sign).
|
||||
*/
|
||||
isIdentical = emojiSetsRenderIdentically(
|
||||
[55357, 56692, 8205, 9792, 65039],
|
||||
[55357, 56692, 8203, 9792, 65039]
|
||||
);
|
||||
return ! isIdentical;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a script to the head of the document.
|
||||
*
|
||||
* @ignore
|
||||
*
|
||||
* @since 4.2.0
|
||||
*
|
||||
* @param {Object} src The url where the script is located.
|
||||
* @return {void}
|
||||
*/
|
||||
function addScript( src ) {
|
||||
var script = document.createElement( 'script' );
|
||||
|
||||
script.src = src;
|
||||
script.defer = script.type = 'text/javascript';
|
||||
document.getElementsByTagName( 'head' )[0].appendChild( script );
|
||||
}
|
||||
|
||||
tests = Array( 'flag', 'emoji' );
|
||||
|
||||
settings.supports = {
|
||||
everything: true,
|
||||
everythingExceptFlag: true
|
||||
};
|
||||
|
||||
/*
|
||||
* Tests the browser support for flag emojis and other emojis, and adjusts the
|
||||
* support settings accordingly.
|
||||
*/
|
||||
for( ii = 0; ii < tests.length; ii++ ) {
|
||||
settings.supports[ tests[ ii ] ] = browserSupportsEmoji( tests[ ii ] );
|
||||
|
||||
settings.supports.everything = settings.supports.everything && settings.supports[ tests[ ii ] ];
|
||||
|
||||
if ( 'flag' !== tests[ ii ] ) {
|
||||
settings.supports.everythingExceptFlag = settings.supports.everythingExceptFlag && settings.supports[ tests[ ii ] ];
|
||||
}
|
||||
}
|
||||
|
||||
settings.supports.everythingExceptFlag = settings.supports.everythingExceptFlag && ! settings.supports.flag;
|
||||
|
||||
// Sets DOMReady to false and assigns a ready function to settings.
|
||||
settings.DOMReady = false;
|
||||
settings.readyCallback = function() {
|
||||
settings.DOMReady = true;
|
||||
};
|
||||
|
||||
// When the browser can not render everything we need to load a polyfill.
|
||||
if ( ! settings.supports.everything ) {
|
||||
ready = function() {
|
||||
settings.readyCallback();
|
||||
};
|
||||
|
||||
/*
|
||||
* Cross-browser version of adding a dom ready event.
|
||||
*/
|
||||
if ( document.addEventListener ) {
|
||||
document.addEventListener( 'DOMContentLoaded', ready, false );
|
||||
window.addEventListener( 'load', ready, false );
|
||||
} else {
|
||||
window.attachEvent( 'onload', ready );
|
||||
document.attachEvent( 'onreadystatechange', function() {
|
||||
if ( 'complete' === document.readyState ) {
|
||||
settings.readyCallback();
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
src = settings.source || {};
|
||||
|
||||
if ( src.concatemoji ) {
|
||||
addScript( src.concatemoji );
|
||||
} else if ( src.wpemoji && src.twemoji ) {
|
||||
addScript( src.twemoji );
|
||||
addScript( src.wpemoji );
|
||||
}
|
||||
}
|
||||
|
||||
} )( window, document, window._wpemojiSettings );
|
||||
@@ -0,0 +1,237 @@
|
||||
/* global unescape, getUserSetting, setUserSetting */
|
||||
|
||||
jQuery(document).ready(function($) {
|
||||
var gallerySortable, gallerySortableInit, sortIt, clearAll, w, desc = false;
|
||||
|
||||
gallerySortableInit = function() {
|
||||
gallerySortable = $('#media-items').sortable( {
|
||||
items: 'div.media-item',
|
||||
placeholder: 'sorthelper',
|
||||
axis: 'y',
|
||||
distance: 2,
|
||||
handle: 'div.filename',
|
||||
stop: function() {
|
||||
// When an update has occurred, adjust the order for each item
|
||||
var all = $('#media-items').sortable('toArray'), len = all.length;
|
||||
$.each(all, function(i, id) {
|
||||
var order = desc ? (len - i) : (1 + i);
|
||||
$('#' + id + ' .menu_order input').val(order);
|
||||
});
|
||||
}
|
||||
} );
|
||||
};
|
||||
|
||||
sortIt = function() {
|
||||
var all = $('.menu_order_input'), len = all.length;
|
||||
all.each(function(i){
|
||||
var order = desc ? (len - i) : (1 + i);
|
||||
$(this).val(order);
|
||||
});
|
||||
};
|
||||
|
||||
clearAll = function(c) {
|
||||
c = c || 0;
|
||||
$('.menu_order_input').each( function() {
|
||||
if ( this.value === '0' || c ) {
|
||||
this.value = '';
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$('#asc').click( function( e ) {
|
||||
e.preventDefault();
|
||||
desc = false;
|
||||
sortIt();
|
||||
});
|
||||
$('#desc').click( function( e ) {
|
||||
e.preventDefault();
|
||||
desc = true;
|
||||
sortIt();
|
||||
});
|
||||
$('#clear').click( function( e ) {
|
||||
e.preventDefault();
|
||||
clearAll(1);
|
||||
});
|
||||
$('#showall').click( function( e ) {
|
||||
e.preventDefault();
|
||||
$('#sort-buttons span a').toggle();
|
||||
$('a.describe-toggle-on').hide();
|
||||
$('a.describe-toggle-off, table.slidetoggle').show();
|
||||
$('img.pinkynail').toggle(false);
|
||||
});
|
||||
$('#hideall').click( function( e ) {
|
||||
e.preventDefault();
|
||||
$('#sort-buttons span a').toggle();
|
||||
$('a.describe-toggle-on').show();
|
||||
$('a.describe-toggle-off, table.slidetoggle').hide();
|
||||
$('img.pinkynail').toggle(true);
|
||||
});
|
||||
|
||||
// initialize sortable
|
||||
gallerySortableInit();
|
||||
clearAll();
|
||||
|
||||
if ( $('#media-items>*').length > 1 ) {
|
||||
w = wpgallery.getWin();
|
||||
|
||||
$('#save-all, #gallery-settings').show();
|
||||
if ( typeof w.tinyMCE !== 'undefined' && w.tinyMCE.activeEditor && ! w.tinyMCE.activeEditor.isHidden() ) {
|
||||
wpgallery.mcemode = true;
|
||||
wpgallery.init();
|
||||
} else {
|
||||
$('#insert-gallery').show();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
jQuery(window).unload( function () { tinymce = tinyMCE = wpgallery = null; } ); // Cleanup
|
||||
|
||||
/* gallery settings */
|
||||
var tinymce = null, tinyMCE, wpgallery;
|
||||
|
||||
wpgallery = {
|
||||
mcemode : false,
|
||||
editor : {},
|
||||
dom : {},
|
||||
is_update : false,
|
||||
el : {},
|
||||
|
||||
I : function(e) {
|
||||
return document.getElementById(e);
|
||||
},
|
||||
|
||||
init: function() {
|
||||
var t = this, li, q, i, it, w = t.getWin();
|
||||
|
||||
if ( ! t.mcemode ) {
|
||||
return;
|
||||
}
|
||||
|
||||
li = ('' + document.location.search).replace(/^\?/, '').split('&');
|
||||
q = {};
|
||||
for (i=0; i<li.length; i++) {
|
||||
it = li[i].split('=');
|
||||
q[unescape(it[0])] = unescape(it[1]);
|
||||
}
|
||||
|
||||
if ( q.mce_rdomain ) {
|
||||
document.domain = q.mce_rdomain;
|
||||
}
|
||||
|
||||
// Find window & API
|
||||
tinymce = w.tinymce;
|
||||
tinyMCE = w.tinyMCE;
|
||||
t.editor = tinymce.EditorManager.activeEditor;
|
||||
|
||||
t.setup();
|
||||
},
|
||||
|
||||
getWin : function() {
|
||||
return window.dialogArguments || opener || parent || top;
|
||||
},
|
||||
|
||||
setup : function() {
|
||||
var t = this, a, ed = t.editor, g, columns, link, order, orderby;
|
||||
if ( ! t.mcemode ) {
|
||||
return;
|
||||
}
|
||||
|
||||
t.el = ed.selection.getNode();
|
||||
|
||||
if ( t.el.nodeName !== 'IMG' || ! ed.dom.hasClass(t.el, 'wpGallery') ) {
|
||||
if ( ( g = ed.dom.select('img.wpGallery') ) && g[0] ) {
|
||||
t.el = g[0];
|
||||
} else {
|
||||
if ( getUserSetting('galfile') === '1' ) {
|
||||
t.I('linkto-file').checked = 'checked';
|
||||
}
|
||||
if ( getUserSetting('galdesc') === '1' ) {
|
||||
t.I('order-desc').checked = 'checked';
|
||||
}
|
||||
if ( getUserSetting('galcols') ) {
|
||||
t.I('columns').value = getUserSetting('galcols');
|
||||
}
|
||||
if ( getUserSetting('galord') ) {
|
||||
t.I('orderby').value = getUserSetting('galord');
|
||||
}
|
||||
jQuery('#insert-gallery').show();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
a = ed.dom.getAttrib(t.el, 'title');
|
||||
a = ed.dom.decode(a);
|
||||
|
||||
if ( a ) {
|
||||
jQuery('#update-gallery').show();
|
||||
t.is_update = true;
|
||||
|
||||
columns = a.match(/columns=['"]([0-9]+)['"]/);
|
||||
link = a.match(/link=['"]([^'"]+)['"]/i);
|
||||
order = a.match(/order=['"]([^'"]+)['"]/i);
|
||||
orderby = a.match(/orderby=['"]([^'"]+)['"]/i);
|
||||
|
||||
if ( link && link[1] ) {
|
||||
t.I('linkto-file').checked = 'checked';
|
||||
}
|
||||
if ( order && order[1] ) {
|
||||
t.I('order-desc').checked = 'checked';
|
||||
}
|
||||
if ( columns && columns[1] ) {
|
||||
t.I('columns').value = '' + columns[1];
|
||||
}
|
||||
if ( orderby && orderby[1] ) {
|
||||
t.I('orderby').value = orderby[1];
|
||||
}
|
||||
} else {
|
||||
jQuery('#insert-gallery').show();
|
||||
}
|
||||
},
|
||||
|
||||
update : function() {
|
||||
var t = this, ed = t.editor, all = '', s;
|
||||
|
||||
if ( ! t.mcemode || ! t.is_update ) {
|
||||
s = '[gallery' + t.getSettings() + ']';
|
||||
t.getWin().send_to_editor(s);
|
||||
return;
|
||||
}
|
||||
|
||||
if ( t.el.nodeName !== 'IMG' ) {
|
||||
return;
|
||||
}
|
||||
|
||||
all = ed.dom.decode( ed.dom.getAttrib( t.el, 'title' ) );
|
||||
all = all.replace(/\s*(order|link|columns|orderby)=['"]([^'"]+)['"]/gi, '');
|
||||
all += t.getSettings();
|
||||
|
||||
ed.dom.setAttrib(t.el, 'title', all);
|
||||
t.getWin().tb_remove();
|
||||
},
|
||||
|
||||
getSettings : function() {
|
||||
var I = this.I, s = '';
|
||||
|
||||
if ( I('linkto-file').checked ) {
|
||||
s += ' link="file"';
|
||||
setUserSetting('galfile', '1');
|
||||
}
|
||||
|
||||
if ( I('order-desc').checked ) {
|
||||
s += ' order="DESC"';
|
||||
setUserSetting('galdesc', '1');
|
||||
}
|
||||
|
||||
if ( I('columns').value !== 3 ) {
|
||||
s += ' columns="' + I('columns').value + '"';
|
||||
setUserSetting('galcols', I('columns').value);
|
||||
}
|
||||
|
||||
if ( I('orderby').value !== 'menu_order' ) {
|
||||
s += ' orderby="' + I('orderby').value + '"';
|
||||
setUserSetting('galord', I('orderby').value);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,26 @@
|
||||
jQuery( function($) {
|
||||
|
||||
var select = $( '#language' ),
|
||||
submit = $( '#language-continue' );
|
||||
|
||||
if ( ! $( 'body' ).hasClass( 'language-chooser' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
select.focus().on( 'change', function() {
|
||||
var option = select.children( 'option:selected' );
|
||||
submit.attr({
|
||||
value: option.data( 'continue' ),
|
||||
lang: option.attr( 'lang' )
|
||||
});
|
||||
});
|
||||
|
||||
$( 'form' ).submit( function() {
|
||||
// Don't show a spinner for English and installed languages,
|
||||
// as there is nothing to download.
|
||||
if ( ! select.children( 'option:selected' ).data( 'installed' ) ) {
|
||||
$( this ).find( '.step .spinner' ).css( 'visibility', 'visible' );
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
@@ -0,0 +1,794 @@
|
||||
var wpLink;
|
||||
|
||||
( function( $, wpLinkL10n, wp ) {
|
||||
var editor, searchTimer, River, Query, correctedURL, linkNode,
|
||||
emailRegexp = /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,63}$/i,
|
||||
urlRegexp = /^(https?|ftp):\/\/[A-Z0-9.-]+\.[A-Z]{2,63}[^ "]*$/i,
|
||||
inputs = {},
|
||||
rivers = {},
|
||||
isTouch = ( 'ontouchend' in document );
|
||||
|
||||
function getLink() {
|
||||
return linkNode || editor.dom.getParent( editor.selection.getNode(), 'a[href]' );
|
||||
}
|
||||
|
||||
wpLink = {
|
||||
timeToTriggerRiver: 150,
|
||||
minRiverAJAXDuration: 200,
|
||||
riverBottomThreshold: 5,
|
||||
keySensitivity: 100,
|
||||
lastSearch: '',
|
||||
textarea: '',
|
||||
modalOpen: false,
|
||||
|
||||
init: function() {
|
||||
inputs.wrap = $('#wp-link-wrap');
|
||||
inputs.dialog = $( '#wp-link' );
|
||||
inputs.backdrop = $( '#wp-link-backdrop' );
|
||||
inputs.submit = $( '#wp-link-submit' );
|
||||
inputs.close = $( '#wp-link-close' );
|
||||
|
||||
// Input
|
||||
inputs.text = $( '#wp-link-text' );
|
||||
inputs.url = $( '#wp-link-url' );
|
||||
inputs.nonce = $( '#_ajax_linking_nonce' );
|
||||
inputs.openInNewTab = $( '#wp-link-target' );
|
||||
inputs.search = $( '#wp-link-search' );
|
||||
|
||||
// Build Rivers
|
||||
rivers.search = new River( $( '#search-results' ) );
|
||||
rivers.recent = new River( $( '#most-recent-results' ) );
|
||||
rivers.elements = inputs.dialog.find( '.query-results' );
|
||||
|
||||
// Get search notice text
|
||||
inputs.queryNotice = $( '#query-notice-message' );
|
||||
inputs.queryNoticeTextDefault = inputs.queryNotice.find( '.query-notice-default' );
|
||||
inputs.queryNoticeTextHint = inputs.queryNotice.find( '.query-notice-hint' );
|
||||
|
||||
// Bind event handlers
|
||||
inputs.dialog.keydown( wpLink.keydown );
|
||||
inputs.dialog.keyup( wpLink.keyup );
|
||||
inputs.submit.click( function( event ) {
|
||||
event.preventDefault();
|
||||
wpLink.update();
|
||||
});
|
||||
|
||||
inputs.close.add( inputs.backdrop ).add( '#wp-link-cancel button' ).click( function( event ) {
|
||||
event.preventDefault();
|
||||
wpLink.close();
|
||||
});
|
||||
|
||||
rivers.elements.on( 'river-select', wpLink.updateFields );
|
||||
|
||||
// Display 'hint' message when search field or 'query-results' box are focused
|
||||
inputs.search.on( 'focus.wplink', function() {
|
||||
inputs.queryNoticeTextDefault.hide();
|
||||
inputs.queryNoticeTextHint.removeClass( 'screen-reader-text' ).show();
|
||||
} ).on( 'blur.wplink', function() {
|
||||
inputs.queryNoticeTextDefault.show();
|
||||
inputs.queryNoticeTextHint.addClass( 'screen-reader-text' ).hide();
|
||||
} );
|
||||
|
||||
inputs.search.on( 'keyup input', function() {
|
||||
window.clearTimeout( searchTimer );
|
||||
searchTimer = window.setTimeout( function() {
|
||||
wpLink.searchInternalLinks();
|
||||
}, 500 );
|
||||
});
|
||||
|
||||
inputs.url.on( 'paste', function() {
|
||||
setTimeout( wpLink.correctURL, 0 );
|
||||
} );
|
||||
|
||||
inputs.url.on( 'blur', wpLink.correctURL );
|
||||
},
|
||||
|
||||
// If URL wasn't corrected last time and doesn't start with http:, https:, ? # or /, prepend http://
|
||||
correctURL: function () {
|
||||
var url = $.trim( inputs.url.val() );
|
||||
|
||||
if ( url && correctedURL !== url && ! /^(?:[a-z]+:|#|\?|\.|\/)/.test( url ) ) {
|
||||
inputs.url.val( 'http://' + url );
|
||||
correctedURL = url;
|
||||
}
|
||||
},
|
||||
|
||||
open: function( editorId, url, text, node ) {
|
||||
var ed,
|
||||
$body = $( document.body );
|
||||
|
||||
$body.addClass( 'modal-open' );
|
||||
wpLink.modalOpen = true;
|
||||
linkNode = node;
|
||||
|
||||
wpLink.range = null;
|
||||
|
||||
if ( editorId ) {
|
||||
window.wpActiveEditor = editorId;
|
||||
}
|
||||
|
||||
if ( ! window.wpActiveEditor ) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.textarea = $( '#' + window.wpActiveEditor ).get( 0 );
|
||||
|
||||
if ( typeof window.tinymce !== 'undefined' ) {
|
||||
// Make sure the link wrapper is the last element in the body,
|
||||
// or the inline editor toolbar may show above the backdrop.
|
||||
$body.append( inputs.backdrop, inputs.wrap );
|
||||
|
||||
ed = window.tinymce.get( window.wpActiveEditor );
|
||||
|
||||
if ( ed && ! ed.isHidden() ) {
|
||||
editor = ed;
|
||||
} else {
|
||||
editor = null;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! wpLink.isMCE() && document.selection ) {
|
||||
this.textarea.focus();
|
||||
this.range = document.selection.createRange();
|
||||
}
|
||||
|
||||
inputs.wrap.show();
|
||||
inputs.backdrop.show();
|
||||
|
||||
wpLink.refresh( url, text );
|
||||
|
||||
$( document ).trigger( 'wplink-open', inputs.wrap );
|
||||
},
|
||||
|
||||
isMCE: function() {
|
||||
return editor && ! editor.isHidden();
|
||||
},
|
||||
|
||||
refresh: function( url, text ) {
|
||||
var linkText = '';
|
||||
|
||||
// Refresh rivers (clear links, check visibility)
|
||||
rivers.search.refresh();
|
||||
rivers.recent.refresh();
|
||||
|
||||
if ( wpLink.isMCE() ) {
|
||||
wpLink.mceRefresh( url, text );
|
||||
} else {
|
||||
// For the Text editor the "Link text" field is always shown
|
||||
if ( ! inputs.wrap.hasClass( 'has-text-field' ) ) {
|
||||
inputs.wrap.addClass( 'has-text-field' );
|
||||
}
|
||||
|
||||
if ( document.selection ) {
|
||||
// Old IE
|
||||
linkText = document.selection.createRange().text || text || '';
|
||||
} else if ( typeof this.textarea.selectionStart !== 'undefined' &&
|
||||
( this.textarea.selectionStart !== this.textarea.selectionEnd ) ) {
|
||||
// W3C
|
||||
text = this.textarea.value.substring( this.textarea.selectionStart, this.textarea.selectionEnd ) || text || '';
|
||||
}
|
||||
|
||||
inputs.text.val( text );
|
||||
wpLink.setDefaultValues();
|
||||
}
|
||||
|
||||
if ( isTouch ) {
|
||||
// Close the onscreen keyboard
|
||||
inputs.url.focus().blur();
|
||||
} else {
|
||||
// Focus the URL field and highlight its contents.
|
||||
// If this is moved above the selection changes,
|
||||
// IE will show a flashing cursor over the dialog.
|
||||
window.setTimeout( function() {
|
||||
inputs.url[0].select();
|
||||
inputs.url.focus();
|
||||
} );
|
||||
}
|
||||
|
||||
// Load the most recent results if this is the first time opening the panel.
|
||||
if ( ! rivers.recent.ul.children().length ) {
|
||||
rivers.recent.ajax();
|
||||
}
|
||||
|
||||
correctedURL = inputs.url.val().replace( /^http:\/\//, '' );
|
||||
},
|
||||
|
||||
hasSelectedText: function( linkNode ) {
|
||||
var node, nodes, i, html = editor.selection.getContent();
|
||||
|
||||
// Partial html and not a fully selected anchor element
|
||||
if ( /</.test( html ) && ( ! /^<a [^>]+>[^<]+<\/a>$/.test( html ) || html.indexOf('href=') === -1 ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( linkNode ) {
|
||||
nodes = linkNode.childNodes;
|
||||
|
||||
if ( nodes.length === 0 ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for ( i = nodes.length - 1; i >= 0; i-- ) {
|
||||
node = nodes[i];
|
||||
|
||||
if ( node.nodeType != 3 && ! window.tinymce.dom.BookmarkManager.isBookmarkNode( node ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
mceRefresh: function( searchStr, text ) {
|
||||
var linkText, href,
|
||||
linkNode = getLink(),
|
||||
onlyText = this.hasSelectedText( linkNode );
|
||||
|
||||
if ( linkNode ) {
|
||||
linkText = linkNode.textContent || linkNode.innerText;
|
||||
href = editor.dom.getAttrib( linkNode, 'href' );
|
||||
|
||||
if ( ! $.trim( linkText ) ) {
|
||||
linkText = text || '';
|
||||
}
|
||||
|
||||
if ( searchStr && ( urlRegexp.test( searchStr ) || emailRegexp.test( searchStr ) ) ) {
|
||||
href = searchStr;
|
||||
}
|
||||
|
||||
if ( href !== '_wp_link_placeholder' ) {
|
||||
inputs.url.val( href );
|
||||
inputs.openInNewTab.prop( 'checked', '_blank' === editor.dom.getAttrib( linkNode, 'target' ) );
|
||||
inputs.submit.val( wpLinkL10n.update );
|
||||
} else {
|
||||
this.setDefaultValues( linkText );
|
||||
}
|
||||
|
||||
if ( searchStr && searchStr !== href ) {
|
||||
// The user has typed something in the inline dialog. Trigger a search with it.
|
||||
inputs.search.val( searchStr );
|
||||
} else {
|
||||
inputs.search.val( '' );
|
||||
}
|
||||
|
||||
// Always reset the search
|
||||
window.setTimeout( function() {
|
||||
wpLink.searchInternalLinks();
|
||||
} );
|
||||
} else {
|
||||
linkText = editor.selection.getContent({ format: 'text' }) || text || '';
|
||||
this.setDefaultValues( linkText );
|
||||
}
|
||||
|
||||
if ( onlyText ) {
|
||||
inputs.text.val( linkText );
|
||||
inputs.wrap.addClass( 'has-text-field' );
|
||||
} else {
|
||||
inputs.text.val( '' );
|
||||
inputs.wrap.removeClass( 'has-text-field' );
|
||||
}
|
||||
},
|
||||
|
||||
close: function( reset ) {
|
||||
$( document.body ).removeClass( 'modal-open' );
|
||||
wpLink.modalOpen = false;
|
||||
|
||||
if ( reset !== 'noReset' ) {
|
||||
if ( ! wpLink.isMCE() ) {
|
||||
wpLink.textarea.focus();
|
||||
|
||||
if ( wpLink.range ) {
|
||||
wpLink.range.moveToBookmark( wpLink.range.getBookmark() );
|
||||
wpLink.range.select();
|
||||
}
|
||||
} else {
|
||||
if ( editor.plugins.wplink ) {
|
||||
editor.plugins.wplink.close();
|
||||
}
|
||||
|
||||
editor.focus();
|
||||
}
|
||||
}
|
||||
|
||||
inputs.backdrop.hide();
|
||||
inputs.wrap.hide();
|
||||
|
||||
correctedURL = false;
|
||||
|
||||
$( document ).trigger( 'wplink-close', inputs.wrap );
|
||||
},
|
||||
|
||||
getAttrs: function() {
|
||||
wpLink.correctURL();
|
||||
|
||||
return {
|
||||
href: $.trim( inputs.url.val() ),
|
||||
target: inputs.openInNewTab.prop( 'checked' ) ? '_blank' : null
|
||||
};
|
||||
},
|
||||
|
||||
buildHtml: function(attrs) {
|
||||
var html = '<a href="' + attrs.href + '"';
|
||||
|
||||
if ( attrs.target ) {
|
||||
html += ' rel="noopener" target="' + attrs.target + '"';
|
||||
}
|
||||
|
||||
return html + '>';
|
||||
},
|
||||
|
||||
update: function() {
|
||||
if ( wpLink.isMCE() ) {
|
||||
wpLink.mceUpdate();
|
||||
} else {
|
||||
wpLink.htmlUpdate();
|
||||
}
|
||||
},
|
||||
|
||||
htmlUpdate: function() {
|
||||
var attrs, text, html, begin, end, cursor, selection,
|
||||
textarea = wpLink.textarea;
|
||||
|
||||
if ( ! textarea ) {
|
||||
return;
|
||||
}
|
||||
|
||||
attrs = wpLink.getAttrs();
|
||||
text = inputs.text.val();
|
||||
|
||||
var parser = document.createElement( 'a' );
|
||||
parser.href = attrs.href;
|
||||
|
||||
if ( 'javascript:' === parser.protocol || 'data:' === parser.protocol ) { // jshint ignore:line
|
||||
attrs.href = '';
|
||||
}
|
||||
|
||||
// If there's no href, return.
|
||||
if ( ! attrs.href ) {
|
||||
return;
|
||||
}
|
||||
|
||||
html = wpLink.buildHtml(attrs);
|
||||
|
||||
// Insert HTML
|
||||
if ( document.selection && wpLink.range ) {
|
||||
// IE
|
||||
// Note: If no text is selected, IE will not place the cursor
|
||||
// inside the closing tag.
|
||||
textarea.focus();
|
||||
wpLink.range.text = html + ( text || wpLink.range.text ) + '</a>';
|
||||
wpLink.range.moveToBookmark( wpLink.range.getBookmark() );
|
||||
wpLink.range.select();
|
||||
|
||||
wpLink.range = null;
|
||||
} else if ( typeof textarea.selectionStart !== 'undefined' ) {
|
||||
// W3C
|
||||
begin = textarea.selectionStart;
|
||||
end = textarea.selectionEnd;
|
||||
selection = text || textarea.value.substring( begin, end );
|
||||
html = html + selection + '</a>';
|
||||
cursor = begin + html.length;
|
||||
|
||||
// If no text is selected, place the cursor inside the closing tag.
|
||||
if ( begin === end && ! selection ) {
|
||||
cursor -= 4;
|
||||
}
|
||||
|
||||
textarea.value = (
|
||||
textarea.value.substring( 0, begin ) +
|
||||
html +
|
||||
textarea.value.substring( end, textarea.value.length )
|
||||
);
|
||||
|
||||
// Update cursor position
|
||||
textarea.selectionStart = textarea.selectionEnd = cursor;
|
||||
}
|
||||
|
||||
wpLink.close();
|
||||
textarea.focus();
|
||||
$( textarea ).trigger( 'change' );
|
||||
|
||||
// Audible confirmation message when a link has been inserted in the Editor.
|
||||
wp.a11y.speak( wpLinkL10n.linkInserted );
|
||||
},
|
||||
|
||||
mceUpdate: function() {
|
||||
var attrs = wpLink.getAttrs(),
|
||||
$link, text, hasText, $mceCaret;
|
||||
|
||||
var parser = document.createElement( 'a' );
|
||||
parser.href = attrs.href;
|
||||
|
||||
if ( 'javascript:' === parser.protocol || 'data:' === parser.protocol ) { // jshint ignore:line
|
||||
attrs.href = '';
|
||||
}
|
||||
|
||||
if ( ! attrs.href ) {
|
||||
editor.execCommand( 'unlink' );
|
||||
wpLink.close();
|
||||
return;
|
||||
}
|
||||
|
||||
$link = editor.$( getLink() );
|
||||
|
||||
editor.undoManager.transact( function() {
|
||||
if ( ! $link.length ) {
|
||||
editor.execCommand( 'mceInsertLink', false, { href: '_wp_link_placeholder', 'data-wp-temp-link': 1 } );
|
||||
$link = editor.$( 'a[data-wp-temp-link="1"]' ).removeAttr( 'data-wp-temp-link' );
|
||||
hasText = $.trim( $link.text() );
|
||||
}
|
||||
|
||||
if ( ! $link.length ) {
|
||||
editor.execCommand( 'unlink' );
|
||||
} else {
|
||||
if ( inputs.wrap.hasClass( 'has-text-field' ) ) {
|
||||
text = inputs.text.val();
|
||||
|
||||
if ( text ) {
|
||||
$link.text( text );
|
||||
} else if ( ! hasText ) {
|
||||
$link.text( attrs.href );
|
||||
}
|
||||
}
|
||||
|
||||
attrs['data-wplink-edit'] = null;
|
||||
attrs['data-mce-href'] = null; // attrs.href
|
||||
$link.attr( attrs );
|
||||
}
|
||||
} );
|
||||
|
||||
wpLink.close( 'noReset' );
|
||||
editor.focus();
|
||||
|
||||
if ( $link.length ) {
|
||||
$mceCaret = $link.parent( '#_mce_caret' );
|
||||
|
||||
if ( $mceCaret.length ) {
|
||||
$mceCaret.before( $link.removeAttr( 'data-mce-bogus' ) );
|
||||
}
|
||||
|
||||
editor.selection.select( $link[0] );
|
||||
editor.selection.collapse();
|
||||
|
||||
if ( editor.plugins.wplink ) {
|
||||
editor.plugins.wplink.checkLink( $link[0] );
|
||||
}
|
||||
}
|
||||
|
||||
editor.nodeChanged();
|
||||
|
||||
// Audible confirmation message when a link has been inserted in the Editor.
|
||||
wp.a11y.speak( wpLinkL10n.linkInserted );
|
||||
},
|
||||
|
||||
updateFields: function( e, li ) {
|
||||
inputs.url.val( li.children( '.item-permalink' ).val() );
|
||||
},
|
||||
|
||||
getUrlFromSelection: function( selection ) {
|
||||
if ( ! selection ) {
|
||||
if ( this.isMCE() ) {
|
||||
selection = editor.selection.getContent({ format: 'text' });
|
||||
} else if ( document.selection && wpLink.range ) {
|
||||
selection = wpLink.range.text;
|
||||
} else if ( typeof this.textarea.selectionStart !== 'undefined' ) {
|
||||
selection = this.textarea.value.substring( this.textarea.selectionStart, this.textarea.selectionEnd );
|
||||
}
|
||||
}
|
||||
|
||||
selection = $.trim( selection );
|
||||
|
||||
if ( selection && emailRegexp.test( selection ) ) {
|
||||
// Selection is email address
|
||||
return 'mailto:' + selection;
|
||||
} else if ( selection && urlRegexp.test( selection ) ) {
|
||||
// Selection is URL
|
||||
return selection.replace( /&|�?38;/gi, '&' );
|
||||
}
|
||||
|
||||
return '';
|
||||
},
|
||||
|
||||
setDefaultValues: function( selection ) {
|
||||
inputs.url.val( this.getUrlFromSelection( selection ) );
|
||||
|
||||
// Empty the search field and swap the "rivers".
|
||||
inputs.search.val('');
|
||||
wpLink.searchInternalLinks();
|
||||
|
||||
// Update save prompt.
|
||||
inputs.submit.val( wpLinkL10n.save );
|
||||
},
|
||||
|
||||
searchInternalLinks: function() {
|
||||
var waiting,
|
||||
search = inputs.search.val() || '';
|
||||
|
||||
if ( search.length > 2 ) {
|
||||
rivers.recent.hide();
|
||||
rivers.search.show();
|
||||
|
||||
// Don't search if the keypress didn't change the title.
|
||||
if ( wpLink.lastSearch == search )
|
||||
return;
|
||||
|
||||
wpLink.lastSearch = search;
|
||||
waiting = inputs.search.parent().find( '.spinner' ).addClass( 'is-active' );
|
||||
|
||||
rivers.search.change( search );
|
||||
rivers.search.ajax( function() {
|
||||
waiting.removeClass( 'is-active' );
|
||||
});
|
||||
} else {
|
||||
rivers.search.hide();
|
||||
rivers.recent.show();
|
||||
}
|
||||
},
|
||||
|
||||
next: function() {
|
||||
rivers.search.next();
|
||||
rivers.recent.next();
|
||||
},
|
||||
|
||||
prev: function() {
|
||||
rivers.search.prev();
|
||||
rivers.recent.prev();
|
||||
},
|
||||
|
||||
keydown: function( event ) {
|
||||
var fn, id;
|
||||
|
||||
// Escape key.
|
||||
if ( 27 === event.keyCode ) {
|
||||
wpLink.close();
|
||||
event.stopImmediatePropagation();
|
||||
// Tab key.
|
||||
} else if ( 9 === event.keyCode ) {
|
||||
id = event.target.id;
|
||||
|
||||
// wp-link-submit must always be the last focusable element in the dialog.
|
||||
// following focusable elements will be skipped on keyboard navigation.
|
||||
if ( id === 'wp-link-submit' && ! event.shiftKey ) {
|
||||
inputs.close.focus();
|
||||
event.preventDefault();
|
||||
} else if ( id === 'wp-link-close' && event.shiftKey ) {
|
||||
inputs.submit.focus();
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
|
||||
// Up Arrow and Down Arrow keys.
|
||||
if ( event.shiftKey || ( 38 !== event.keyCode && 40 !== event.keyCode ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( document.activeElement &&
|
||||
( document.activeElement.id === 'link-title-field' || document.activeElement.id === 'url-field' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Up Arrow key.
|
||||
fn = 38 === event.keyCode ? 'prev' : 'next';
|
||||
clearInterval( wpLink.keyInterval );
|
||||
wpLink[ fn ]();
|
||||
wpLink.keyInterval = setInterval( wpLink[ fn ], wpLink.keySensitivity );
|
||||
event.preventDefault();
|
||||
},
|
||||
|
||||
keyup: function( event ) {
|
||||
// Up Arrow and Down Arrow keys.
|
||||
if ( 38 === event.keyCode || 40 === event.keyCode ) {
|
||||
clearInterval( wpLink.keyInterval );
|
||||
event.preventDefault();
|
||||
}
|
||||
},
|
||||
|
||||
delayedCallback: function( func, delay ) {
|
||||
var timeoutTriggered, funcTriggered, funcArgs, funcContext;
|
||||
|
||||
if ( ! delay )
|
||||
return func;
|
||||
|
||||
setTimeout( function() {
|
||||
if ( funcTriggered )
|
||||
return func.apply( funcContext, funcArgs );
|
||||
// Otherwise, wait.
|
||||
timeoutTriggered = true;
|
||||
}, delay );
|
||||
|
||||
return function() {
|
||||
if ( timeoutTriggered )
|
||||
return func.apply( this, arguments );
|
||||
// Otherwise, wait.
|
||||
funcArgs = arguments;
|
||||
funcContext = this;
|
||||
funcTriggered = true;
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
River = function( element, search ) {
|
||||
var self = this;
|
||||
this.element = element;
|
||||
this.ul = element.children( 'ul' );
|
||||
this.contentHeight = element.children( '#link-selector-height' );
|
||||
this.waiting = element.find('.river-waiting');
|
||||
|
||||
this.change( search );
|
||||
this.refresh();
|
||||
|
||||
$( '#wp-link .query-results, #wp-link #link-selector' ).scroll( function() {
|
||||
self.maybeLoad();
|
||||
});
|
||||
element.on( 'click', 'li', function( event ) {
|
||||
self.select( $( this ), event );
|
||||
});
|
||||
};
|
||||
|
||||
$.extend( River.prototype, {
|
||||
refresh: function() {
|
||||
this.deselect();
|
||||
this.visible = this.element.is( ':visible' );
|
||||
},
|
||||
show: function() {
|
||||
if ( ! this.visible ) {
|
||||
this.deselect();
|
||||
this.element.show();
|
||||
this.visible = true;
|
||||
}
|
||||
},
|
||||
hide: function() {
|
||||
this.element.hide();
|
||||
this.visible = false;
|
||||
},
|
||||
// Selects a list item and triggers the river-select event.
|
||||
select: function( li, event ) {
|
||||
var liHeight, elHeight, liTop, elTop;
|
||||
|
||||
if ( li.hasClass( 'unselectable' ) || li == this.selected )
|
||||
return;
|
||||
|
||||
this.deselect();
|
||||
this.selected = li.addClass( 'selected' );
|
||||
// Make sure the element is visible
|
||||
liHeight = li.outerHeight();
|
||||
elHeight = this.element.height();
|
||||
liTop = li.position().top;
|
||||
elTop = this.element.scrollTop();
|
||||
|
||||
if ( liTop < 0 ) // Make first visible element
|
||||
this.element.scrollTop( elTop + liTop );
|
||||
else if ( liTop + liHeight > elHeight ) // Make last visible element
|
||||
this.element.scrollTop( elTop + liTop - elHeight + liHeight );
|
||||
|
||||
// Trigger the river-select event
|
||||
this.element.trigger( 'river-select', [ li, event, this ] );
|
||||
},
|
||||
deselect: function() {
|
||||
if ( this.selected )
|
||||
this.selected.removeClass( 'selected' );
|
||||
this.selected = false;
|
||||
},
|
||||
prev: function() {
|
||||
if ( ! this.visible )
|
||||
return;
|
||||
|
||||
var to;
|
||||
if ( this.selected ) {
|
||||
to = this.selected.prev( 'li' );
|
||||
if ( to.length )
|
||||
this.select( to );
|
||||
}
|
||||
},
|
||||
next: function() {
|
||||
if ( ! this.visible )
|
||||
return;
|
||||
|
||||
var to = this.selected ? this.selected.next( 'li' ) : $( 'li:not(.unselectable):first', this.element );
|
||||
if ( to.length )
|
||||
this.select( to );
|
||||
},
|
||||
ajax: function( callback ) {
|
||||
var self = this,
|
||||
delay = this.query.page == 1 ? 0 : wpLink.minRiverAJAXDuration,
|
||||
response = wpLink.delayedCallback( function( results, params ) {
|
||||
self.process( results, params );
|
||||
if ( callback )
|
||||
callback( results, params );
|
||||
}, delay );
|
||||
|
||||
this.query.ajax( response );
|
||||
},
|
||||
change: function( search ) {
|
||||
if ( this.query && this._search == search )
|
||||
return;
|
||||
|
||||
this._search = search;
|
||||
this.query = new Query( search );
|
||||
this.element.scrollTop( 0 );
|
||||
},
|
||||
process: function( results, params ) {
|
||||
var list = '', alt = true, classes = '',
|
||||
firstPage = params.page == 1;
|
||||
|
||||
if ( ! results ) {
|
||||
if ( firstPage ) {
|
||||
list += '<li class="unselectable no-matches-found"><span class="item-title"><em>' +
|
||||
wpLinkL10n.noMatchesFound + '</em></span></li>';
|
||||
}
|
||||
} else {
|
||||
$.each( results, function() {
|
||||
classes = alt ? 'alternate' : '';
|
||||
classes += this.title ? '' : ' no-title';
|
||||
list += classes ? '<li class="' + classes + '">' : '<li>';
|
||||
list += '<input type="hidden" class="item-permalink" value="' + this.permalink + '" />';
|
||||
list += '<span class="item-title">';
|
||||
list += this.title ? this.title : wpLinkL10n.noTitle;
|
||||
list += '</span><span class="item-info">' + this.info + '</span></li>';
|
||||
alt = ! alt;
|
||||
});
|
||||
}
|
||||
|
||||
this.ul[ firstPage ? 'html' : 'append' ]( list );
|
||||
},
|
||||
maybeLoad: function() {
|
||||
var self = this,
|
||||
el = this.element,
|
||||
bottom = el.scrollTop() + el.height();
|
||||
|
||||
if ( ! this.query.ready() || bottom < this.contentHeight.height() - wpLink.riverBottomThreshold )
|
||||
return;
|
||||
|
||||
setTimeout(function() {
|
||||
var newTop = el.scrollTop(),
|
||||
newBottom = newTop + el.height();
|
||||
|
||||
if ( ! self.query.ready() || newBottom < self.contentHeight.height() - wpLink.riverBottomThreshold )
|
||||
return;
|
||||
|
||||
self.waiting.addClass( 'is-active' );
|
||||
el.scrollTop( newTop + self.waiting.outerHeight() );
|
||||
|
||||
self.ajax( function() {
|
||||
self.waiting.removeClass( 'is-active' );
|
||||
});
|
||||
}, wpLink.timeToTriggerRiver );
|
||||
}
|
||||
});
|
||||
|
||||
Query = function( search ) {
|
||||
this.page = 1;
|
||||
this.allLoaded = false;
|
||||
this.querying = false;
|
||||
this.search = search;
|
||||
};
|
||||
|
||||
$.extend( Query.prototype, {
|
||||
ready: function() {
|
||||
return ! ( this.querying || this.allLoaded );
|
||||
},
|
||||
ajax: function( callback ) {
|
||||
var self = this,
|
||||
query = {
|
||||
action : 'wp-link-ajax',
|
||||
page : this.page,
|
||||
'_ajax_linking_nonce' : inputs.nonce.val()
|
||||
};
|
||||
|
||||
if ( this.search )
|
||||
query.search = this.search;
|
||||
|
||||
this.querying = true;
|
||||
|
||||
$.post( window.ajaxurl, query, function( r ) {
|
||||
self.page++;
|
||||
self.querying = false;
|
||||
self.allLoaded = ! r;
|
||||
callback( r, query );
|
||||
}, 'json' );
|
||||
}
|
||||
});
|
||||
|
||||
$( document ).ready( wpLink.init );
|
||||
})( jQuery, window.wpLinkL10n, window.wp );
|
||||
@@ -0,0 +1,24 @@
|
||||
(function(w) {
|
||||
var init = function() {
|
||||
var pr = document.getElementById('post-revisions'),
|
||||
inputs = pr ? pr.getElementsByTagName('input') : [];
|
||||
pr.onclick = function() {
|
||||
var i, checkCount = 0, side;
|
||||
for ( i = 0; i < inputs.length; i++ ) {
|
||||
checkCount += inputs[i].checked ? 1 : 0;
|
||||
side = inputs[i].getAttribute('name');
|
||||
if ( ! inputs[i].checked &&
|
||||
( 'left' == side && 1 > checkCount || 'right' == side && 1 < checkCount && ( ! inputs[i-1] || ! inputs[i-1].checked ) ) &&
|
||||
! ( inputs[i+1] && inputs[i+1].checked && 'right' == inputs[i+1].getAttribute('name') ) )
|
||||
inputs[i].style.visibility = 'hidden';
|
||||
else if ( 'left' == side || 'right' == side )
|
||||
inputs[i].style.visibility = 'visible';
|
||||
}
|
||||
};
|
||||
pr.onclick();
|
||||
};
|
||||
if ( w && w.addEventListener )
|
||||
w.addEventListener('load', init, false);
|
||||
else if ( w && w.attachEvent )
|
||||
w.attachEvent('onload', init);
|
||||
})(window);
|
||||
@@ -0,0 +1,854 @@
|
||||
/* global ajaxurl, wpAjax */
|
||||
|
||||
/**
|
||||
* @param {jQuery} $ jQuery object.
|
||||
*/
|
||||
( function( $ ) {
|
||||
var functions = {
|
||||
add: 'ajaxAdd',
|
||||
del: 'ajaxDel',
|
||||
dim: 'ajaxDim',
|
||||
process: 'process',
|
||||
recolor: 'recolor'
|
||||
}, wpList;
|
||||
|
||||
/**
|
||||
* @namespace
|
||||
*/
|
||||
wpList = {
|
||||
|
||||
/**
|
||||
* @member {object}
|
||||
*/
|
||||
settings: {
|
||||
|
||||
/**
|
||||
* URL for Ajax requests.
|
||||
*
|
||||
* @member {string}
|
||||
*/
|
||||
url: ajaxurl,
|
||||
|
||||
/**
|
||||
* The HTTP method to use for Ajax requests.
|
||||
*
|
||||
* @member {string}
|
||||
*/
|
||||
type: 'POST',
|
||||
|
||||
/**
|
||||
* ID of the element the parsed Ajax response will be stored in.
|
||||
*
|
||||
* @member {string}
|
||||
*/
|
||||
response: 'ajax-response',
|
||||
|
||||
/**
|
||||
* The type of list.
|
||||
*
|
||||
* @member {string}
|
||||
*/
|
||||
what: '',
|
||||
|
||||
/**
|
||||
* CSS class name for alternate styling.
|
||||
*
|
||||
* @member {string}
|
||||
*/
|
||||
alt: 'alternate',
|
||||
|
||||
/**
|
||||
* Offset to start alternate styling from.
|
||||
*
|
||||
* @member {number}
|
||||
*/
|
||||
altOffset: 0,
|
||||
|
||||
/**
|
||||
* Color used in animation when adding an element.
|
||||
*
|
||||
* Can be 'none' to disable the animation.
|
||||
*
|
||||
* @member {string}
|
||||
*/
|
||||
addColor: '#ffff33',
|
||||
|
||||
/**
|
||||
* Color used in animation when deleting an element.
|
||||
*
|
||||
* Can be 'none' to disable the animation.
|
||||
*
|
||||
* @member {string}
|
||||
*/
|
||||
delColor: '#faafaa',
|
||||
|
||||
/**
|
||||
* Color used in dim add animation.
|
||||
*
|
||||
* Can be 'none' to disable the animation.
|
||||
*
|
||||
* @member {string}
|
||||
*/
|
||||
dimAddColor: '#ffff33',
|
||||
|
||||
/**
|
||||
* Color used in dim delete animation.
|
||||
*
|
||||
* Can be 'none' to disable the animation.
|
||||
*
|
||||
* @member {string}
|
||||
*/
|
||||
dimDelColor: '#ff3333',
|
||||
|
||||
/**
|
||||
* Callback that's run before a request is made.
|
||||
*
|
||||
* @callback wpList~confirm
|
||||
* @param {object} this
|
||||
* @param {HTMLElement} list The list DOM element.
|
||||
* @param {object} settings Settings for the current list.
|
||||
* @param {string} action The type of action to perform: 'add', 'delete', or 'dim'.
|
||||
* @param {string} backgroundColor Background color of the list's DOM element.
|
||||
* @returns {boolean} Whether to proceed with the action or not.
|
||||
*/
|
||||
confirm: null,
|
||||
|
||||
/**
|
||||
* Callback that's run before an item gets added to the list.
|
||||
*
|
||||
* Allows to cancel the request.
|
||||
*
|
||||
* @callback wpList~addBefore
|
||||
* @param {object} settings Settings for the Ajax request.
|
||||
* @returns {object|boolean} Settings for the Ajax request or false to abort.
|
||||
*/
|
||||
addBefore: null,
|
||||
|
||||
/**
|
||||
* Callback that's run after an item got added to the list.
|
||||
*
|
||||
* @callback wpList~addAfter
|
||||
* @param {XML} returnedResponse Raw response returned from the server.
|
||||
* @param {object} settings Settings for the Ajax request.
|
||||
* @param {jqXHR} settings.xml jQuery XMLHttpRequest object.
|
||||
* @param {string} settings.status Status of the request: 'success', 'notmodified', 'nocontent', 'error',
|
||||
* 'timeout', 'abort', or 'parsererror'.
|
||||
* @param {object} settings.parsed Parsed response object.
|
||||
*/
|
||||
addAfter: null,
|
||||
|
||||
/**
|
||||
* Callback that's run before an item gets deleted from the list.
|
||||
*
|
||||
* Allows to cancel the request.
|
||||
*
|
||||
* @callback wpList~delBefore
|
||||
* @param {object} settings Settings for the Ajax request.
|
||||
* @param {HTMLElement} list The list DOM element.
|
||||
* @returns {object|boolean} Settings for the Ajax request or false to abort.
|
||||
*/
|
||||
delBefore: null,
|
||||
|
||||
/**
|
||||
* Callback that's run after an item got deleted from the list.
|
||||
*
|
||||
* @callback wpList~delAfter
|
||||
* @param {XML} returnedResponse Raw response returned from the server.
|
||||
* @param {object} settings Settings for the Ajax request.
|
||||
* @param {jqXHR} settings.xml jQuery XMLHttpRequest object.
|
||||
* @param {string} settings.status Status of the request: 'success', 'notmodified', 'nocontent', 'error',
|
||||
* 'timeout', 'abort', or 'parsererror'.
|
||||
* @param {object} settings.parsed Parsed response object.
|
||||
*/
|
||||
delAfter: null,
|
||||
|
||||
/**
|
||||
* Callback that's run before an item gets dim'd.
|
||||
*
|
||||
* Allows to cancel the request.
|
||||
*
|
||||
* @callback wpList~dimBefore
|
||||
* @param {object} settings Settings for the Ajax request.
|
||||
* @returns {object|boolean} Settings for the Ajax request or false to abort.
|
||||
*/
|
||||
dimBefore: null,
|
||||
|
||||
/**
|
||||
* Callback that's run after an item got dim'd.
|
||||
*
|
||||
* @callback wpList~dimAfter
|
||||
* @param {XML} returnedResponse Raw response returned from the server.
|
||||
* @param {object} settings Settings for the Ajax request.
|
||||
* @param {jqXHR} settings.xml jQuery XMLHttpRequest object.
|
||||
* @param {string} settings.status Status of the request: 'success', 'notmodified', 'nocontent', 'error',
|
||||
* 'timeout', 'abort', or 'parsererror'.
|
||||
* @param {object} settings.parsed Parsed response object.
|
||||
*/
|
||||
dimAfter: null
|
||||
},
|
||||
|
||||
/**
|
||||
* Finds a nonce.
|
||||
*
|
||||
* 1. Nonce in settings.
|
||||
* 2. `_ajax_nonce` value in element's href attribute.
|
||||
* 3. `_ajax_nonce` input field that is a descendant of element.
|
||||
* 4. `_wpnonce` value in element's href attribute.
|
||||
* 5. `_wpnonce` input field that is a descendant of element.
|
||||
* 6. 0 if none can be found.
|
||||
*
|
||||
* @param {jQuery} element Element that triggered the request.
|
||||
* @param {object} settings Settings for the Ajax request.
|
||||
* @returns {string|number} Nonce
|
||||
*/
|
||||
nonce: function( element, settings ) {
|
||||
var url = wpAjax.unserialize( element.attr( 'href' ) ),
|
||||
$element = $( '#' + settings.element );
|
||||
|
||||
return settings.nonce || url._ajax_nonce || $element.find( 'input[name="_ajax_nonce"]' ).val() || url._wpnonce || $element.find( 'input[name="_wpnonce"]' ).val() || 0;
|
||||
},
|
||||
|
||||
/**
|
||||
* Extract list item data from a DOM element.
|
||||
*
|
||||
* Example 1: data-wp-lists="delete:the-comment-list:comment-{comment_ID}:66cc66:unspam=1"
|
||||
* Example 2: data-wp-lists="dim:the-comment-list:comment-{comment_ID}:unapproved:e7e7d3:e7e7d3:new=approved"
|
||||
*
|
||||
* Returns an unassociated array with the following data:
|
||||
* data[0] - Data identifier: 'list', 'add', 'delete', or 'dim'.
|
||||
* data[1] - ID of the corresponding list. If data[0] is 'list', the type of list ('comment', 'category', etc).
|
||||
* data[2] - ID of the parent element of all inputs necessary for the request.
|
||||
* data[3] - Hex color to be used in this request. If data[0] is 'dim', dim class.
|
||||
* data[4] - Additional arguments in query syntax that are added to the request. Example: 'post_id=1234'.
|
||||
* If data[0] is 'dim', dim add color.
|
||||
* data[5] - Only available if data[0] is 'dim', dim delete color.
|
||||
* data[6] - Only available if data[0] is 'dim', additional arguments in query syntax that are added to the request.
|
||||
*
|
||||
* Result for Example 1:
|
||||
* data[0] - delete
|
||||
* data[1] - the-comment-list
|
||||
* data[2] - comment-{comment_ID}
|
||||
* data[3] - 66cc66
|
||||
* data[4] - unspam=1
|
||||
*
|
||||
* @param {HTMLElement} element The DOM element.
|
||||
* @param {string} type The type of data to look for: 'list', 'add', 'delete', or 'dim'.
|
||||
* @returns {Array} Extracted list item data.
|
||||
*/
|
||||
parseData: function( element, type ) {
|
||||
var data = [], wpListsData;
|
||||
|
||||
try {
|
||||
wpListsData = $( element ).data( 'wp-lists' ) || '';
|
||||
wpListsData = wpListsData.match( new RegExp( type + ':[\\S]+' ) );
|
||||
|
||||
if ( wpListsData ) {
|
||||
data = wpListsData[0].split( ':' );
|
||||
}
|
||||
} catch ( error ) {}
|
||||
|
||||
return data;
|
||||
},
|
||||
|
||||
/**
|
||||
* Calls a confirm callback to verify the action that is about to be performed.
|
||||
*
|
||||
* @param {HTMLElement} list The DOM element.
|
||||
* @param {object} settings Settings for this list.
|
||||
* @param {string} action The type of action to perform: 'add', 'delete', or 'dim'.
|
||||
* @returns {object|boolean} Settings if confirmed, false if not.
|
||||
*/
|
||||
pre: function( list, settings, action ) {
|
||||
var $element, backgroundColor, confirmed;
|
||||
|
||||
settings = $.extend( {}, this.wpList.settings, {
|
||||
element: null,
|
||||
nonce: 0,
|
||||
target: list.get( 0 )
|
||||
}, settings || {} );
|
||||
|
||||
if ( $.isFunction( settings.confirm ) ) {
|
||||
$element = $( '#' + settings.element );
|
||||
|
||||
if ( 'add' !== action ) {
|
||||
backgroundColor = $element.css( 'backgroundColor' );
|
||||
$element.css( 'backgroundColor', '#ff9966' );
|
||||
}
|
||||
|
||||
confirmed = settings.confirm.call( this, list, settings, action, backgroundColor );
|
||||
|
||||
if ( 'add' !== action ) {
|
||||
$element.css( 'backgroundColor', backgroundColor );
|
||||
}
|
||||
|
||||
if ( ! confirmed ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return settings;
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds an item to the list via AJAX.
|
||||
*
|
||||
* @param {HTMLElement} element The DOM element.
|
||||
* @param {object} settings Settings for this list.
|
||||
* @returns {boolean} Whether the item was added.
|
||||
*/
|
||||
ajaxAdd: function( element, settings ) {
|
||||
var list = this,
|
||||
$element = $( element ),
|
||||
data = wpList.parseData( $element, 'add' ),
|
||||
formValues, formData, parsedResponse, returnedResponse;
|
||||
|
||||
settings = settings || {};
|
||||
settings = wpList.pre.call( list, $element, settings, 'add' );
|
||||
|
||||
settings.element = data[2] || $element.prop( 'id' ) || settings.element || null;
|
||||
settings.addColor = data[3] ? '#' + data[3] : settings.addColor;
|
||||
|
||||
if ( ! settings ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! $element.is( '[id="' + settings.element + '-submit"]' ) ) {
|
||||
return ! wpList.add.call( list, $element, settings );
|
||||
}
|
||||
|
||||
if ( ! settings.element ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
settings.action = 'add-' + settings.what;
|
||||
settings.nonce = wpList.nonce( $element, settings );
|
||||
|
||||
if ( ! wpAjax.validateForm( '#' + settings.element ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
settings.data = $.param( $.extend( {
|
||||
_ajax_nonce: settings.nonce,
|
||||
action: settings.action
|
||||
}, wpAjax.unserialize( data[4] || '' ) ) );
|
||||
|
||||
formValues = $( '#' + settings.element + ' :input' ).not( '[name="_ajax_nonce"], [name="_wpnonce"], [name="action"]' );
|
||||
formData = $.isFunction( formValues.fieldSerialize ) ? formValues.fieldSerialize() : formValues.serialize();
|
||||
|
||||
if ( formData ) {
|
||||
settings.data += '&' + formData;
|
||||
}
|
||||
|
||||
if ( $.isFunction( settings.addBefore ) ) {
|
||||
settings = settings.addBefore( settings );
|
||||
|
||||
if ( ! settings ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! settings.data.match( /_ajax_nonce=[a-f0-9]+/ ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
settings.success = function( response ) {
|
||||
parsedResponse = wpAjax.parseAjaxResponse( response, settings.response, settings.element );
|
||||
returnedResponse = response;
|
||||
|
||||
if ( ! parsedResponse || parsedResponse.errors ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( true === parsedResponse ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$.each( parsedResponse.responses, function() {
|
||||
wpList.add.call( list, this.data, $.extend( {}, settings, { // this.firstChild.nodevalue
|
||||
position: this.position || 0,
|
||||
id: this.id || 0,
|
||||
oldId: this.oldId || null
|
||||
} ) );
|
||||
} );
|
||||
|
||||
list.wpList.recolor();
|
||||
$( list ).trigger( 'wpListAddEnd', [ settings, list.wpList ] );
|
||||
wpList.clear.call( list, '#' + settings.element );
|
||||
};
|
||||
|
||||
settings.complete = function( jqXHR, status ) {
|
||||
if ( $.isFunction( settings.addAfter ) ) {
|
||||
settings.addAfter( returnedResponse, $.extend( {
|
||||
xml: jqXHR,
|
||||
status: status,
|
||||
parsed: parsedResponse
|
||||
}, settings ) );
|
||||
}
|
||||
};
|
||||
|
||||
$.ajax( settings );
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Delete an item in the list via AJAX.
|
||||
*
|
||||
* @param {HTMLElement} element A DOM element containing item data.
|
||||
* @param {object} settings Settings for this list.
|
||||
* @returns {boolean} Whether the item was deleted.
|
||||
*/
|
||||
ajaxDel: function( element, settings ) {
|
||||
var list = this,
|
||||
$element = $( element ),
|
||||
data = wpList.parseData( $element, 'delete' ),
|
||||
$eventTarget, parsedResponse, returnedResponse;
|
||||
|
||||
settings = settings || {};
|
||||
settings = wpList.pre.call( list, $element, settings, 'delete' );
|
||||
|
||||
settings.element = data[2] || settings.element || null;
|
||||
settings.delColor = data[3] ? '#' + data[3] : settings.delColor;
|
||||
|
||||
if ( ! settings || ! settings.element ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
settings.action = 'delete-' + settings.what;
|
||||
settings.nonce = wpList.nonce( $element, settings );
|
||||
|
||||
settings.data = $.extend( {
|
||||
_ajax_nonce: settings.nonce,
|
||||
action: settings.action,
|
||||
id: settings.element.split( '-' ).pop()
|
||||
}, wpAjax.unserialize( data[4] || '' ) );
|
||||
|
||||
if ( $.isFunction( settings.delBefore ) ) {
|
||||
settings = settings.delBefore( settings, list );
|
||||
|
||||
if ( ! settings ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! settings.data._ajax_nonce ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$eventTarget = $( '#' + settings.element );
|
||||
|
||||
if ( 'none' !== settings.delColor ) {
|
||||
$eventTarget.css( 'backgroundColor', settings.delColor ).fadeOut( 350, function() {
|
||||
list.wpList.recolor();
|
||||
$( list ).trigger( 'wpListDelEnd', [ settings, list.wpList ] );
|
||||
} );
|
||||
} else {
|
||||
list.wpList.recolor();
|
||||
$( list ).trigger( 'wpListDelEnd', [ settings, list.wpList ] );
|
||||
}
|
||||
|
||||
settings.success = function( response ) {
|
||||
parsedResponse = wpAjax.parseAjaxResponse( response, settings.response, settings.element );
|
||||
returnedResponse = response;
|
||||
|
||||
if ( ! parsedResponse || parsedResponse.errors ) {
|
||||
$eventTarget.stop().stop().css( 'backgroundColor', '#faa' ).show().queue( function() {
|
||||
list.wpList.recolor();
|
||||
$( this ).dequeue();
|
||||
} );
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
settings.complete = function( jqXHR, status ) {
|
||||
if ( $.isFunction( settings.delAfter ) ) {
|
||||
$eventTarget.queue( function() {
|
||||
settings.delAfter( returnedResponse, $.extend( {
|
||||
xml: jqXHR,
|
||||
status: status,
|
||||
parsed: parsedResponse
|
||||
}, settings ) );
|
||||
} ).dequeue();
|
||||
}
|
||||
};
|
||||
|
||||
$.ajax( settings );
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Dim an item in the list via AJAX.
|
||||
*
|
||||
* @param {HTMLElement} element A DOM element containing item data.
|
||||
* @param {object} settings Settings for this list.
|
||||
* @returns {boolean} Whether the item was dim'ed.
|
||||
*/
|
||||
ajaxDim: function( element, settings ) {
|
||||
var list = this,
|
||||
$element = $( element ),
|
||||
data = wpList.parseData( $element, 'dim' ),
|
||||
$eventTarget, isClass, color, dimColor, parsedResponse, returnedResponse;
|
||||
|
||||
// Prevent hidden links from being clicked by hotkeys.
|
||||
if ( 'none' === $element.parent().css( 'display' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
settings = settings || {};
|
||||
settings = wpList.pre.call( list, $element, settings, 'dim' );
|
||||
|
||||
settings.element = data[2] || settings.element || null;
|
||||
settings.dimClass = data[3] || settings.dimClass || null;
|
||||
settings.dimAddColor = data[4] ? '#' + data[4] : settings.dimAddColor;
|
||||
settings.dimDelColor = data[5] ? '#' + data[5] : settings.dimDelColor;
|
||||
|
||||
if ( ! settings || ! settings.element || ! settings.dimClass ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
settings.action = 'dim-' + settings.what;
|
||||
settings.nonce = wpList.nonce( $element, settings );
|
||||
|
||||
settings.data = $.extend( {
|
||||
_ajax_nonce: settings.nonce,
|
||||
action: settings.action,
|
||||
id: settings.element.split( '-' ).pop(),
|
||||
dimClass: settings.dimClass
|
||||
}, wpAjax.unserialize( data[6] || '' ) );
|
||||
|
||||
if ( $.isFunction( settings.dimBefore ) ) {
|
||||
settings = settings.dimBefore( settings );
|
||||
|
||||
if ( ! settings ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
$eventTarget = $( '#' + settings.element );
|
||||
isClass = $eventTarget.toggleClass( settings.dimClass ).is( '.' + settings.dimClass );
|
||||
color = wpList.getColor( $eventTarget );
|
||||
dimColor = isClass ? settings.dimAddColor : settings.dimDelColor;
|
||||
$eventTarget.toggleClass( settings.dimClass );
|
||||
|
||||
if ( 'none' !== dimColor ) {
|
||||
$eventTarget
|
||||
.animate( { backgroundColor: dimColor }, 'fast' )
|
||||
.queue( function() {
|
||||
$eventTarget.toggleClass( settings.dimClass );
|
||||
$( this ).dequeue();
|
||||
} )
|
||||
.animate( { backgroundColor: color }, {
|
||||
complete: function() {
|
||||
$( this ).css( 'backgroundColor', '' );
|
||||
$( list ).trigger( 'wpListDimEnd', [ settings, list.wpList ] );
|
||||
}
|
||||
} );
|
||||
} else {
|
||||
$( list ).trigger( 'wpListDimEnd', [ settings, list.wpList ] );
|
||||
}
|
||||
|
||||
if ( ! settings.data._ajax_nonce ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
settings.success = function( response ) {
|
||||
parsedResponse = wpAjax.parseAjaxResponse( response, settings.response, settings.element );
|
||||
returnedResponse = response;
|
||||
|
||||
if ( true === parsedResponse ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( ! parsedResponse || parsedResponse.errors ) {
|
||||
$eventTarget.stop().stop().css( 'backgroundColor', '#ff3333' )[isClass ? 'removeClass' : 'addClass']( settings.dimClass ).show().queue( function() {
|
||||
list.wpList.recolor();
|
||||
$( this ).dequeue();
|
||||
} );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @property {string} comment_link Link of the comment to be dimmed. */
|
||||
if ( 'undefined' !== typeof parsedResponse.responses[0].supplemental.comment_link ) {
|
||||
var $submittedOn = $element.find( '.submitted-on' ),
|
||||
$commentLink = $submittedOn.find( 'a' );
|
||||
|
||||
// Comment is approved; link the date field.
|
||||
if ( '' !== parsedResponse.responses[0].supplemental.comment_link ) {
|
||||
$submittedOn.html( $('<a></a>').text( $submittedOn.text() ).prop( 'href', parsedResponse.responses[0].supplemental.comment_link ) );
|
||||
|
||||
// Comment is not approved; unlink the date field.
|
||||
} else if ( $commentLink.length ) {
|
||||
$submittedOn.text( $commentLink.text() );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
settings.complete = function( jqXHR, status ) {
|
||||
if ( $.isFunction( settings.dimAfter ) ) {
|
||||
$eventTarget.queue( function() {
|
||||
settings.dimAfter( returnedResponse, $.extend( {
|
||||
xml: jqXHR,
|
||||
status: status,
|
||||
parsed: parsedResponse
|
||||
}, settings ) );
|
||||
} ).dequeue();
|
||||
}
|
||||
};
|
||||
|
||||
$.ajax( settings );
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the background color of the passed element.
|
||||
*
|
||||
* @param {jQuery|string} element Element to check.
|
||||
* @returns {string} Background color value in HEX. Default: '#ffffff'.
|
||||
*/
|
||||
getColor: function( element ) {
|
||||
return $( element ).css( 'backgroundColor' ) || '#ffffff';
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds something.
|
||||
*
|
||||
* @param {HTMLElement} element A DOM element containing item data.
|
||||
* @param {object} settings Settings for this list.
|
||||
* @returns {boolean} Whether the item was added.
|
||||
*/
|
||||
add: function( element, settings ) {
|
||||
var $list = $( this ),
|
||||
$element = $( element ),
|
||||
old = false,
|
||||
position, reference;
|
||||
|
||||
if ( 'string' === typeof settings ) {
|
||||
settings = { what: settings };
|
||||
}
|
||||
|
||||
settings = $.extend( { position: 0, id: 0, oldId: null }, this.wpList.settings, settings );
|
||||
|
||||
if ( ! $element.length || ! settings.what ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( settings.oldId ) {
|
||||
old = $( '#' + settings.what + '-' + settings.oldId );
|
||||
}
|
||||
|
||||
if ( settings.id && ( settings.id !== settings.oldId || ! old || ! old.length ) ) {
|
||||
$( '#' + settings.what + '-' + settings.id ).remove();
|
||||
}
|
||||
|
||||
if ( old && old.length ) {
|
||||
old.before( $element );
|
||||
old.remove();
|
||||
|
||||
} else if ( isNaN( settings.position ) ) {
|
||||
position = 'after';
|
||||
|
||||
if ( '-' === settings.position.substr( 0, 1 ) ) {
|
||||
settings.position = settings.position.substr( 1 );
|
||||
position = 'before';
|
||||
}
|
||||
|
||||
reference = $list.find( '#' + settings.position );
|
||||
|
||||
if ( 1 === reference.length ) {
|
||||
reference[position]( $element );
|
||||
} else {
|
||||
$list.append( $element );
|
||||
}
|
||||
|
||||
} else if ( 'comment' !== settings.what || 0 === $( '#' + settings.element ).length ) {
|
||||
if ( settings.position < 0 ) {
|
||||
$list.prepend( $element );
|
||||
} else {
|
||||
$list.append( $element );
|
||||
}
|
||||
}
|
||||
|
||||
if ( settings.alt ) {
|
||||
$element.toggleClass( settings.alt, ( $list.children( ':visible' ).index( $element[0] ) + settings.altOffset ) % 2 );
|
||||
}
|
||||
|
||||
if ( 'none' !== settings.addColor ) {
|
||||
$element.css( 'backgroundColor', settings.addColor ).animate( { backgroundColor: wpList.getColor( $element ) }, {
|
||||
complete: function() {
|
||||
$( this ).css( 'backgroundColor', '' );
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
// Add event handlers.
|
||||
$list.each( function( index, list ) {
|
||||
list.wpList.process( $element );
|
||||
} );
|
||||
|
||||
return $element;
|
||||
},
|
||||
|
||||
/**
|
||||
* Clears all input fields within the element passed.
|
||||
*
|
||||
* @param {string} elementId ID of the element to check, including leading #.
|
||||
*/
|
||||
clear: function( elementId ) {
|
||||
var list = this,
|
||||
$element = $( elementId ),
|
||||
type, tagName;
|
||||
|
||||
// Bail if we're within the list.
|
||||
if ( list.wpList && $element.parents( '#' + list.id ).length ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check each input field.
|
||||
$element.find( ':input' ).each( function( index, input ) {
|
||||
|
||||
// Bail if the form was marked to not to be cleared.
|
||||
if ( $( input ).parents( '.form-no-clear' ).length ) {
|
||||
return;
|
||||
}
|
||||
|
||||
type = input.type.toLowerCase();
|
||||
tagName = input.tagName.toLowerCase();
|
||||
|
||||
if ( 'text' === type || 'password' === type || 'textarea' === tagName ) {
|
||||
input.value = '';
|
||||
|
||||
} else if ( 'checkbox' === type || 'radio' === type ) {
|
||||
input.checked = false;
|
||||
|
||||
} else if ( 'select' === tagName ) {
|
||||
input.selectedIndex = null;
|
||||
}
|
||||
} );
|
||||
},
|
||||
|
||||
/**
|
||||
* Registers event handlers to add, delete, and dim items.
|
||||
*
|
||||
* @param {string} elementId
|
||||
*/
|
||||
process: function( elementId ) {
|
||||
var list = this,
|
||||
$element = $( elementId || document );
|
||||
|
||||
$element.on( 'submit', 'form[data-wp-lists^="add:' + list.id + ':"]', function() {
|
||||
return list.wpList.add( this );
|
||||
} );
|
||||
|
||||
$element.on( 'click', 'a[data-wp-lists^="add:' + list.id + ':"], input[data-wp-lists^="add:' + list.id + ':"]', function() {
|
||||
return list.wpList.add( this );
|
||||
} );
|
||||
|
||||
$element.on( 'click', '[data-wp-lists^="delete:' + list.id + ':"]', function() {
|
||||
return list.wpList.del( this );
|
||||
} );
|
||||
|
||||
$element.on( 'click', '[data-wp-lists^="dim:' + list.id + ':"]', function() {
|
||||
return list.wpList.dim( this );
|
||||
} );
|
||||
},
|
||||
|
||||
/**
|
||||
* Updates list item background colors.
|
||||
*/
|
||||
recolor: function() {
|
||||
var list = this,
|
||||
evenOdd = [':even', ':odd'],
|
||||
items;
|
||||
|
||||
// Bail if there is no alternate class name specified.
|
||||
if ( ! list.wpList.settings.alt ) {
|
||||
return;
|
||||
}
|
||||
|
||||
items = $( '.list-item:visible', list );
|
||||
|
||||
if ( ! items.length ) {
|
||||
items = $( list ).children( ':visible' );
|
||||
}
|
||||
|
||||
if ( list.wpList.settings.altOffset % 2 ) {
|
||||
evenOdd.reverse();
|
||||
}
|
||||
|
||||
items.filter( evenOdd[0] ).addClass( list.wpList.settings.alt ).end();
|
||||
items.filter( evenOdd[1] ).removeClass( list.wpList.settings.alt );
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets up `process()` and `recolor()` functions.
|
||||
*/
|
||||
init: function() {
|
||||
var $list = this;
|
||||
|
||||
$list.wpList.process = function( element ) {
|
||||
$list.each( function() {
|
||||
this.wpList.process( element );
|
||||
} );
|
||||
};
|
||||
|
||||
$list.wpList.recolor = function() {
|
||||
$list.each( function() {
|
||||
this.wpList.recolor();
|
||||
} );
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Initializes wpList object.
|
||||
*
|
||||
* @param {Object} settings
|
||||
* @param {string} settings.url URL for ajax calls. Default: ajaxurl.
|
||||
* @param {string} settings.type The HTTP method to use for Ajax requests. Default: 'POST'.
|
||||
* @param {string} settings.response ID of the element the parsed ajax response will be stored in.
|
||||
* Default: 'ajax-response'.
|
||||
*
|
||||
* @param {string} settings.what Default: ''.
|
||||
* @param {string} settings.alt CSS class name for alternate styling. Default: 'alternate'.
|
||||
* @param {number} settings.altOffset Offset to start alternate styling from. Default: 0.
|
||||
* @param {string} settings.addColor Hex code or 'none' to disable animation. Default: '#ffff33'.
|
||||
* @param {string} settings.delColor Hex code or 'none' to disable animation. Default: '#faafaa'.
|
||||
* @param {string} settings.dimAddColor Hex code or 'none' to disable animation. Default: '#ffff33'.
|
||||
* @param {string} settings.dimDelColor Hex code or 'none' to disable animation. Default: '#ff3333'.
|
||||
*
|
||||
* @param {wpList~confirm} settings.confirm Callback that's run before a request is made. Default: null.
|
||||
* @param {wpList~addBefore} settings.addBefore Callback that's run before an item gets added to the list.
|
||||
* Default: null.
|
||||
* @param {wpList~addAfter} settings.addAfter Callback that's run after an item got added to the list.
|
||||
* Default: null.
|
||||
* @param {wpList~delBefore} settings.delBefore Callback that's run before an item gets deleted from the list.
|
||||
* Default: null.
|
||||
* @param {wpList~delAfter} settings.delAfter Callback that's run after an item got deleted from the list.
|
||||
* Default: null.
|
||||
* @param {wpList~dimBefore} settings.dimBefore Callback that's run before an item gets dim'd. Default: null.
|
||||
* @param {wpList~dimAfter} settings.dimAfter Callback that's run after an item got dim'd. Default: null.
|
||||
* @returns {$.fn} wpList API function.
|
||||
*/
|
||||
$.fn.wpList = function( settings ) {
|
||||
this.each( function( index, list ) {
|
||||
list.wpList = {
|
||||
settings: $.extend( {}, wpList.settings, { what: wpList.parseData( list, 'list' )[1] || '' }, settings )
|
||||
};
|
||||
|
||||
$.each( functions, function( func, callback ) {
|
||||
list.wpList[func] = function( element, setting ) {
|
||||
return wpList[callback].call( list, element, setting );
|
||||
};
|
||||
} );
|
||||
} );
|
||||
|
||||
wpList.init.call( this );
|
||||
this.wpList.process();
|
||||
|
||||
return this;
|
||||
};
|
||||
} ) ( jQuery );
|
||||
@@ -0,0 +1,285 @@
|
||||
/* global wpPointerL10n */
|
||||
/**
|
||||
* Pointer jQuery widget.
|
||||
*/
|
||||
(function($){
|
||||
var identifier = 0,
|
||||
zindex = 9999;
|
||||
|
||||
/**
|
||||
* @class $.widget.wp.pointer
|
||||
*/
|
||||
$.widget('wp.pointer',/** @lends $.widget.wp.pointer.prototype */{
|
||||
options: {
|
||||
pointerClass: 'wp-pointer',
|
||||
pointerWidth: 320,
|
||||
content: function() {
|
||||
return $(this).text();
|
||||
},
|
||||
buttons: function( event, t ) {
|
||||
var close = ( wpPointerL10n ) ? wpPointerL10n.dismiss : 'Dismiss',
|
||||
button = $('<a class="close" href="#">' + close + '</a>');
|
||||
|
||||
return button.bind( 'click.pointer', function(e) {
|
||||
e.preventDefault();
|
||||
t.element.pointer('close');
|
||||
});
|
||||
},
|
||||
position: 'top',
|
||||
show: function( event, t ) {
|
||||
t.pointer.show();
|
||||
t.opened();
|
||||
},
|
||||
hide: function( event, t ) {
|
||||
t.pointer.hide();
|
||||
t.closed();
|
||||
},
|
||||
document: document
|
||||
},
|
||||
|
||||
_create: function() {
|
||||
var positioning,
|
||||
family;
|
||||
|
||||
this.content = $('<div class="wp-pointer-content"></div>');
|
||||
this.arrow = $('<div class="wp-pointer-arrow"><div class="wp-pointer-arrow-inner"></div></div>');
|
||||
|
||||
family = this.element.parents().add( this.element );
|
||||
positioning = 'absolute';
|
||||
|
||||
if ( family.filter(function(){ return 'fixed' === $(this).css('position'); }).length )
|
||||
positioning = 'fixed';
|
||||
|
||||
this.pointer = $('<div />')
|
||||
.append( this.content )
|
||||
.append( this.arrow )
|
||||
.attr('id', 'wp-pointer-' + identifier++)
|
||||
.addClass( this.options.pointerClass )
|
||||
.css({'position': positioning, 'width': this.options.pointerWidth+'px', 'display': 'none'})
|
||||
.appendTo( this.options.document.body );
|
||||
},
|
||||
|
||||
_setOption: function( key, value ) {
|
||||
var o = this.options,
|
||||
tip = this.pointer;
|
||||
|
||||
// Handle document transfer
|
||||
if ( key === 'document' && value !== o.document ) {
|
||||
tip.detach().appendTo( value.body );
|
||||
|
||||
// Handle class change
|
||||
} else if ( key === 'pointerClass' ) {
|
||||
tip.removeClass( o.pointerClass ).addClass( value );
|
||||
}
|
||||
|
||||
// Call super method.
|
||||
$.Widget.prototype._setOption.apply( this, arguments );
|
||||
|
||||
// Reposition automatically
|
||||
if ( key === 'position' ) {
|
||||
this.reposition();
|
||||
|
||||
// Update content automatically if pointer is open
|
||||
} else if ( key === 'content' && this.active ) {
|
||||
this.update();
|
||||
}
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
this.pointer.remove();
|
||||
$.Widget.prototype.destroy.call( this );
|
||||
},
|
||||
|
||||
widget: function() {
|
||||
return this.pointer;
|
||||
},
|
||||
|
||||
update: function( event ) {
|
||||
var self = this,
|
||||
o = this.options,
|
||||
dfd = $.Deferred(),
|
||||
content;
|
||||
|
||||
if ( o.disabled )
|
||||
return;
|
||||
|
||||
dfd.done( function( content ) {
|
||||
self._update( event, content );
|
||||
});
|
||||
|
||||
// Either o.content is a string...
|
||||
if ( typeof o.content === 'string' ) {
|
||||
content = o.content;
|
||||
|
||||
// ...or o.content is a callback.
|
||||
} else {
|
||||
content = o.content.call( this.element[0], dfd.resolve, event, this._handoff() );
|
||||
}
|
||||
|
||||
// If content is set, then complete the update.
|
||||
if ( content )
|
||||
dfd.resolve( content );
|
||||
|
||||
return dfd.promise();
|
||||
},
|
||||
|
||||
/**
|
||||
* Update is separated into two functions to allow events to defer
|
||||
* updating the pointer (e.g. fetch content with ajax, etc).
|
||||
*/
|
||||
_update: function( event, content ) {
|
||||
var buttons,
|
||||
o = this.options;
|
||||
|
||||
if ( ! content )
|
||||
return;
|
||||
|
||||
this.pointer.stop(); // Kill any animations on the pointer.
|
||||
this.content.html( content );
|
||||
|
||||
buttons = o.buttons.call( this.element[0], event, this._handoff() );
|
||||
if ( buttons ) {
|
||||
buttons.wrap('<div class="wp-pointer-buttons" />').parent().appendTo( this.content );
|
||||
}
|
||||
|
||||
this.reposition();
|
||||
},
|
||||
|
||||
reposition: function() {
|
||||
var position;
|
||||
|
||||
if ( this.options.disabled )
|
||||
return;
|
||||
|
||||
position = this._processPosition( this.options.position );
|
||||
|
||||
// Reposition pointer.
|
||||
this.pointer.css({
|
||||
top: 0,
|
||||
left: 0,
|
||||
zIndex: zindex++ // Increment the z-index so that it shows above other opened pointers.
|
||||
}).show().position($.extend({
|
||||
of: this.element,
|
||||
collision: 'fit none'
|
||||
}, position )); // the object comes before this.options.position so the user can override position.of.
|
||||
|
||||
this.repoint();
|
||||
},
|
||||
|
||||
repoint: function() {
|
||||
var o = this.options,
|
||||
edge;
|
||||
|
||||
if ( o.disabled )
|
||||
return;
|
||||
|
||||
edge = ( typeof o.position == 'string' ) ? o.position : o.position.edge;
|
||||
|
||||
// Remove arrow classes.
|
||||
this.pointer[0].className = this.pointer[0].className.replace( /wp-pointer-[^\s'"]*/, '' );
|
||||
|
||||
// Add arrow class.
|
||||
this.pointer.addClass( 'wp-pointer-' + edge );
|
||||
},
|
||||
|
||||
_processPosition: function( position ) {
|
||||
var opposite = {
|
||||
top: 'bottom',
|
||||
bottom: 'top',
|
||||
left: 'right',
|
||||
right: 'left'
|
||||
},
|
||||
result;
|
||||
|
||||
// If the position object is a string, it is shorthand for position.edge.
|
||||
if ( typeof position == 'string' ) {
|
||||
result = {
|
||||
edge: position + ''
|
||||
};
|
||||
} else {
|
||||
result = $.extend( {}, position );
|
||||
}
|
||||
|
||||
if ( ! result.edge )
|
||||
return result;
|
||||
|
||||
if ( result.edge == 'top' || result.edge == 'bottom' ) {
|
||||
result.align = result.align || 'left';
|
||||
|
||||
result.at = result.at || result.align + ' ' + opposite[ result.edge ];
|
||||
result.my = result.my || result.align + ' ' + result.edge;
|
||||
} else {
|
||||
result.align = result.align || 'top';
|
||||
|
||||
result.at = result.at || opposite[ result.edge ] + ' ' + result.align;
|
||||
result.my = result.my || result.edge + ' ' + result.align;
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
|
||||
open: function( event ) {
|
||||
var self = this,
|
||||
o = this.options;
|
||||
|
||||
if ( this.active || o.disabled || this.element.is(':hidden') )
|
||||
return;
|
||||
|
||||
this.update().done( function() {
|
||||
self._open( event );
|
||||
});
|
||||
},
|
||||
|
||||
_open: function( event ) {
|
||||
var self = this,
|
||||
o = this.options;
|
||||
|
||||
if ( this.active || o.disabled || this.element.is(':hidden') )
|
||||
return;
|
||||
|
||||
this.active = true;
|
||||
|
||||
this._trigger( 'open', event, this._handoff() );
|
||||
|
||||
this._trigger( 'show', event, this._handoff({
|
||||
opened: function() {
|
||||
self._trigger( 'opened', event, self._handoff() );
|
||||
}
|
||||
}));
|
||||
},
|
||||
|
||||
close: function( event ) {
|
||||
if ( !this.active || this.options.disabled )
|
||||
return;
|
||||
|
||||
var self = this;
|
||||
this.active = false;
|
||||
|
||||
this._trigger( 'close', event, this._handoff() );
|
||||
this._trigger( 'hide', event, this._handoff({
|
||||
closed: function() {
|
||||
self._trigger( 'closed', event, self._handoff() );
|
||||
}
|
||||
}));
|
||||
},
|
||||
|
||||
sendToTop: function() {
|
||||
if ( this.active )
|
||||
this.pointer.css( 'z-index', zindex++ );
|
||||
},
|
||||
|
||||
toggle: function( event ) {
|
||||
if ( this.pointer.is(':hidden') )
|
||||
this.open( event );
|
||||
else
|
||||
this.close( event );
|
||||
},
|
||||
|
||||
_handoff: function( extend ) {
|
||||
return $.extend({
|
||||
pointer: this.pointer,
|
||||
element: this.element
|
||||
}, extend);
|
||||
}
|
||||
});
|
||||
})(jQuery);
|
||||
@@ -0,0 +1,747 @@
|
||||
/* global adminpage, wpActiveEditor, quicktagsL10n, wpLink, prompt */
|
||||
/*
|
||||
* Quicktags
|
||||
*
|
||||
* This is the HTML editor in WordPress. It can be attached to any textarea and will
|
||||
* append a toolbar above it. This script is self-contained (does not require external libraries).
|
||||
*
|
||||
* Run quicktags(settings) to initialize it, where settings is an object containing up to 3 properties:
|
||||
* settings = {
|
||||
* id : 'my_id', the HTML ID of the textarea, required
|
||||
* buttons: '' Comma separated list of the names of the default buttons to show. Optional.
|
||||
* Current list of default button names: 'strong,em,link,block,del,ins,img,ul,ol,li,code,more,close';
|
||||
* }
|
||||
*
|
||||
* The settings can also be a string quicktags_id.
|
||||
*
|
||||
* quicktags_id string The ID of the textarea that will be the editor canvas
|
||||
* buttons string Comma separated list of the default buttons names that will be shown in that instance.
|
||||
*/
|
||||
|
||||
// new edit toolbar used with permission
|
||||
// by Alex King
|
||||
// http://www.alexking.org/
|
||||
|
||||
var QTags, edCanvas,
|
||||
edButtons = [];
|
||||
|
||||
/* jshint ignore:start */
|
||||
|
||||
/**
|
||||
* Back-compat
|
||||
*
|
||||
* Define all former global functions so plugins that hack quicktags.js directly don't cause fatal errors.
|
||||
*/
|
||||
var edAddTag = function(){},
|
||||
edCheckOpenTags = function(){},
|
||||
edCloseAllTags = function(){},
|
||||
edInsertImage = function(){},
|
||||
edInsertLink = function(){},
|
||||
edInsertTag = function(){},
|
||||
edLink = function(){},
|
||||
edQuickLink = function(){},
|
||||
edRemoveTag = function(){},
|
||||
edShowButton = function(){},
|
||||
edShowLinks = function(){},
|
||||
edSpell = function(){},
|
||||
edToolbar = function(){};
|
||||
|
||||
/**
|
||||
* Initialize new instance of the Quicktags editor
|
||||
*/
|
||||
function quicktags(settings) {
|
||||
return new QTags(settings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts content at the caret in the active editor (textarea)
|
||||
*
|
||||
* Added for back compatibility
|
||||
* @see QTags.insertContent()
|
||||
*/
|
||||
function edInsertContent(bah, txt) {
|
||||
return QTags.insertContent(txt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a button to all instances of the editor
|
||||
*
|
||||
* Added for back compatibility, use QTags.addButton() as it gives more flexibility like type of button, button placement, etc.
|
||||
* @see QTags.addButton()
|
||||
*/
|
||||
function edButton(id, display, tagStart, tagEnd, access) {
|
||||
return QTags.addButton( id, display, tagStart, tagEnd, access, '', -1 );
|
||||
}
|
||||
|
||||
/* jshint ignore:end */
|
||||
|
||||
(function(){
|
||||
// private stuff is prefixed with an underscore
|
||||
var _domReady = function(func) {
|
||||
var t, i, DOMContentLoaded, _tryReady;
|
||||
|
||||
if ( typeof jQuery !== 'undefined' ) {
|
||||
jQuery(document).ready(func);
|
||||
} else {
|
||||
t = _domReady;
|
||||
t.funcs = [];
|
||||
|
||||
t.ready = function() {
|
||||
if ( ! t.isReady ) {
|
||||
t.isReady = true;
|
||||
for ( i = 0; i < t.funcs.length; i++ ) {
|
||||
t.funcs[i]();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if ( t.isReady ) {
|
||||
func();
|
||||
} else {
|
||||
t.funcs.push(func);
|
||||
}
|
||||
|
||||
if ( ! t.eventAttached ) {
|
||||
if ( document.addEventListener ) {
|
||||
DOMContentLoaded = function(){document.removeEventListener('DOMContentLoaded', DOMContentLoaded, false);t.ready();};
|
||||
document.addEventListener('DOMContentLoaded', DOMContentLoaded, false);
|
||||
window.addEventListener('load', t.ready, false);
|
||||
} else if ( document.attachEvent ) {
|
||||
DOMContentLoaded = function(){if (document.readyState === 'complete'){ document.detachEvent('onreadystatechange', DOMContentLoaded);t.ready();}};
|
||||
document.attachEvent('onreadystatechange', DOMContentLoaded);
|
||||
window.attachEvent('onload', t.ready);
|
||||
|
||||
_tryReady = function() {
|
||||
try {
|
||||
document.documentElement.doScroll('left');
|
||||
} catch(e) {
|
||||
setTimeout(_tryReady, 50);
|
||||
return;
|
||||
}
|
||||
|
||||
t.ready();
|
||||
};
|
||||
_tryReady();
|
||||
}
|
||||
|
||||
t.eventAttached = true;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_datetime = (function() {
|
||||
var now = new Date(), zeroise;
|
||||
|
||||
zeroise = function(number) {
|
||||
var str = number.toString();
|
||||
|
||||
if ( str.length < 2 ) {
|
||||
str = '0' + str;
|
||||
}
|
||||
|
||||
return str;
|
||||
};
|
||||
|
||||
return now.getUTCFullYear() + '-' +
|
||||
zeroise( now.getUTCMonth() + 1 ) + '-' +
|
||||
zeroise( now.getUTCDate() ) + 'T' +
|
||||
zeroise( now.getUTCHours() ) + ':' +
|
||||
zeroise( now.getUTCMinutes() ) + ':' +
|
||||
zeroise( now.getUTCSeconds() ) +
|
||||
'+00:00';
|
||||
})(),
|
||||
qt;
|
||||
|
||||
qt = QTags = function(settings) {
|
||||
if ( typeof(settings) === 'string' ) {
|
||||
settings = {id: settings};
|
||||
} else if ( typeof(settings) !== 'object' ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var t = this,
|
||||
id = settings.id,
|
||||
canvas = document.getElementById(id),
|
||||
name = 'qt_' + id,
|
||||
tb, onclick, toolbar_id, wrap, setActiveEditor;
|
||||
|
||||
if ( !id || !canvas ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
t.name = name;
|
||||
t.id = id;
|
||||
t.canvas = canvas;
|
||||
t.settings = settings;
|
||||
|
||||
if ( id === 'content' && typeof(adminpage) === 'string' && ( adminpage === 'post-new-php' || adminpage === 'post-php' ) ) {
|
||||
// back compat hack :-(
|
||||
edCanvas = canvas;
|
||||
toolbar_id = 'ed_toolbar';
|
||||
} else {
|
||||
toolbar_id = name + '_toolbar';
|
||||
}
|
||||
|
||||
tb = document.getElementById( toolbar_id );
|
||||
|
||||
if ( ! tb ) {
|
||||
tb = document.createElement('div');
|
||||
tb.id = toolbar_id;
|
||||
tb.className = 'quicktags-toolbar';
|
||||
}
|
||||
|
||||
canvas.parentNode.insertBefore(tb, canvas);
|
||||
t.toolbar = tb;
|
||||
|
||||
// listen for click events
|
||||
onclick = function(e) {
|
||||
e = e || window.event;
|
||||
var target = e.target || e.srcElement, visible = target.clientWidth || target.offsetWidth, i;
|
||||
|
||||
// don't call the callback on pressing the accesskey when the button is not visible
|
||||
if ( !visible ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// as long as it has the class ed_button, execute the callback
|
||||
if ( / ed_button /.test(' ' + target.className + ' ') ) {
|
||||
// we have to reassign canvas here
|
||||
t.canvas = canvas = document.getElementById(id);
|
||||
i = target.id.replace(name + '_', '');
|
||||
|
||||
if ( t.theButtons[i] ) {
|
||||
t.theButtons[i].callback.call(t.theButtons[i], target, canvas, t);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
setActiveEditor = function() {
|
||||
window.wpActiveEditor = id;
|
||||
};
|
||||
|
||||
wrap = document.getElementById( 'wp-' + id + '-wrap' );
|
||||
|
||||
if ( tb.addEventListener ) {
|
||||
tb.addEventListener( 'click', onclick, false );
|
||||
|
||||
if ( wrap ) {
|
||||
wrap.addEventListener( 'click', setActiveEditor, false );
|
||||
}
|
||||
} else if ( tb.attachEvent ) {
|
||||
tb.attachEvent( 'onclick', onclick );
|
||||
|
||||
if ( wrap ) {
|
||||
wrap.attachEvent( 'onclick', setActiveEditor );
|
||||
}
|
||||
}
|
||||
|
||||
t.getButton = function(id) {
|
||||
return t.theButtons[id];
|
||||
};
|
||||
|
||||
t.getButtonElement = function(id) {
|
||||
return document.getElementById(name + '_' + id);
|
||||
};
|
||||
|
||||
t.init = function() {
|
||||
_domReady( function(){ qt._buttonsInit( id ); } );
|
||||
};
|
||||
|
||||
t.remove = function() {
|
||||
delete qt.instances[id];
|
||||
|
||||
if ( tb && tb.parentNode ) {
|
||||
tb.parentNode.removeChild( tb );
|
||||
}
|
||||
};
|
||||
|
||||
qt.instances[id] = t;
|
||||
t.init();
|
||||
};
|
||||
|
||||
function _escape( text ) {
|
||||
text = text || '';
|
||||
text = text.replace( /&([^#])(?![a-z1-4]{1,8};)/gi, '&$1' );
|
||||
return text.replace( /</g, '<' ).replace( />/g, '>' ).replace( /"/g, '"' ).replace( /'/g, ''' );
|
||||
}
|
||||
|
||||
qt.instances = {};
|
||||
|
||||
qt.getInstance = function(id) {
|
||||
return qt.instances[id];
|
||||
};
|
||||
|
||||
qt._buttonsInit = function( id ) {
|
||||
var t = this;
|
||||
|
||||
function _init( instanceId ) {
|
||||
var canvas, name, settings, theButtons, html, ed, id, i, use,
|
||||
defaults = ',strong,em,link,block,del,ins,img,ul,ol,li,code,more,close,';
|
||||
|
||||
ed = t.instances[instanceId];
|
||||
canvas = ed.canvas;
|
||||
name = ed.name;
|
||||
settings = ed.settings;
|
||||
html = '';
|
||||
theButtons = {};
|
||||
use = '';
|
||||
|
||||
// set buttons
|
||||
if ( settings.buttons ) {
|
||||
use = ','+settings.buttons+',';
|
||||
}
|
||||
|
||||
for ( i in edButtons ) {
|
||||
if ( ! edButtons[i] ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
id = edButtons[i].id;
|
||||
if ( use && defaults.indexOf( ',' + id + ',' ) !== -1 && use.indexOf( ',' + id + ',' ) === -1 ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( ! edButtons[i].instance || edButtons[i].instance === instanceId ) {
|
||||
theButtons[id] = edButtons[i];
|
||||
|
||||
if ( edButtons[i].html ) {
|
||||
html += edButtons[i].html( name + '_' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( use && use.indexOf(',dfw,') !== -1 ) {
|
||||
theButtons.dfw = new qt.DFWButton();
|
||||
html += theButtons.dfw.html( name + '_' );
|
||||
}
|
||||
|
||||
if ( 'rtl' === document.getElementsByTagName( 'html' )[0].dir ) {
|
||||
theButtons.textdirection = new qt.TextDirectionButton();
|
||||
html += theButtons.textdirection.html( name + '_' );
|
||||
}
|
||||
|
||||
ed.toolbar.innerHTML = html;
|
||||
ed.theButtons = theButtons;
|
||||
|
||||
if ( typeof jQuery !== 'undefined' ) {
|
||||
jQuery( document ).triggerHandler( 'quicktags-init', [ ed ] );
|
||||
}
|
||||
}
|
||||
|
||||
if ( id ) {
|
||||
_init( id );
|
||||
} else {
|
||||
for ( id in t.instances ) {
|
||||
_init( id );
|
||||
}
|
||||
}
|
||||
|
||||
t.buttonsInitDone = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Main API function for adding a button to Quicktags
|
||||
*
|
||||
* Adds qt.Button or qt.TagButton depending on the args. The first three args are always required.
|
||||
* To be able to add button(s) to Quicktags, your script should be enqueued as dependent
|
||||
* on "quicktags" and outputted in the footer. If you are echoing JS directly from PHP,
|
||||
* use add_action( 'admin_print_footer_scripts', 'output_my_js', 100 ) or add_action( 'wp_footer', 'output_my_js', 100 )
|
||||
*
|
||||
* Minimum required to add a button that calls an external function:
|
||||
* QTags.addButton( 'my_id', 'my button', my_callback );
|
||||
* function my_callback() { alert('yeah!'); }
|
||||
*
|
||||
* Minimum required to add a button that inserts a tag:
|
||||
* QTags.addButton( 'my_id', 'my button', '<span>', '</span>' );
|
||||
* QTags.addButton( 'my_id2', 'my button', '<br />' );
|
||||
*
|
||||
* @param string id Required. Button HTML ID
|
||||
* @param string display Required. Button's value="..."
|
||||
* @param string|function arg1 Required. Either a starting tag to be inserted like "<span>" or a callback that is executed when the button is clicked.
|
||||
* @param string arg2 Optional. Ending tag like "</span>"
|
||||
* @param string access_key Deprecated Not used
|
||||
* @param string title Optional. Button's title="..."
|
||||
* @param int priority Optional. Number representing the desired position of the button in the toolbar. 1 - 9 = first, 11 - 19 = second, 21 - 29 = third, etc.
|
||||
* @param string instance Optional. Limit the button to a specific instance of Quicktags, add to all instances if not present.
|
||||
* @param attr object Optional. Used to pass additional attributes. Currently supports `ariaLabel` and `ariaLabelClose` (for "close tag" state)
|
||||
* @return mixed null or the button object that is needed for back-compat.
|
||||
*/
|
||||
qt.addButton = function( id, display, arg1, arg2, access_key, title, priority, instance, attr ) {
|
||||
var btn;
|
||||
|
||||
if ( !id || !display ) {
|
||||
return;
|
||||
}
|
||||
|
||||
priority = priority || 0;
|
||||
arg2 = arg2 || '';
|
||||
attr = attr || {};
|
||||
|
||||
if ( typeof(arg1) === 'function' ) {
|
||||
btn = new qt.Button( id, display, access_key, title, instance, attr );
|
||||
btn.callback = arg1;
|
||||
} else if ( typeof(arg1) === 'string' ) {
|
||||
btn = new qt.TagButton( id, display, arg1, arg2, access_key, title, instance, attr );
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( priority === -1 ) { // back-compat
|
||||
return btn;
|
||||
}
|
||||
|
||||
if ( priority > 0 ) {
|
||||
while ( typeof(edButtons[priority]) !== 'undefined' ) {
|
||||
priority++;
|
||||
}
|
||||
|
||||
edButtons[priority] = btn;
|
||||
} else {
|
||||
edButtons[edButtons.length] = btn;
|
||||
}
|
||||
|
||||
if ( this.buttonsInitDone ) {
|
||||
this._buttonsInit(); // add the button HTML to all instances toolbars if addButton() was called too late
|
||||
}
|
||||
};
|
||||
|
||||
qt.insertContent = function(content) {
|
||||
var sel, startPos, endPos, scrollTop, text, canvas = document.getElementById(wpActiveEditor), event;
|
||||
|
||||
if ( !canvas ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( document.selection ) { //IE
|
||||
canvas.focus();
|
||||
sel = document.selection.createRange();
|
||||
sel.text = content;
|
||||
canvas.focus();
|
||||
} else if ( canvas.selectionStart || canvas.selectionStart === 0 ) { // FF, WebKit, Opera
|
||||
text = canvas.value;
|
||||
startPos = canvas.selectionStart;
|
||||
endPos = canvas.selectionEnd;
|
||||
scrollTop = canvas.scrollTop;
|
||||
|
||||
canvas.value = text.substring(0, startPos) + content + text.substring(endPos, text.length);
|
||||
|
||||
canvas.selectionStart = startPos + content.length;
|
||||
canvas.selectionEnd = startPos + content.length;
|
||||
canvas.scrollTop = scrollTop;
|
||||
canvas.focus();
|
||||
} else {
|
||||
canvas.value += content;
|
||||
canvas.focus();
|
||||
}
|
||||
|
||||
if ( document.createEvent ) {
|
||||
event = document.createEvent( 'HTMLEvents' );
|
||||
event.initEvent( 'change', false, true );
|
||||
canvas.dispatchEvent( event );
|
||||
} else if ( canvas.fireEvent ) {
|
||||
canvas.fireEvent( 'onchange' );
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
// a plain, dumb button
|
||||
qt.Button = function( id, display, access, title, instance, attr ) {
|
||||
this.id = id;
|
||||
this.display = display;
|
||||
this.access = '';
|
||||
this.title = title || '';
|
||||
this.instance = instance || '';
|
||||
this.attr = attr || {};
|
||||
};
|
||||
qt.Button.prototype.html = function(idPrefix) {
|
||||
var active, on, wp,
|
||||
title = this.title ? ' title="' + _escape( this.title ) + '"' : '',
|
||||
ariaLabel = this.attr && this.attr.ariaLabel ? ' aria-label="' + _escape( this.attr.ariaLabel ) + '"' : '',
|
||||
val = this.display ? ' value="' + _escape( this.display ) + '"' : '',
|
||||
id = this.id ? ' id="' + _escape( idPrefix + this.id ) + '"' : '',
|
||||
dfw = ( wp = window.wp ) && wp.editor && wp.editor.dfw;
|
||||
|
||||
if ( this.id === 'fullscreen' ) {
|
||||
return '<button type="button"' + id + ' class="ed_button qt-dfw qt-fullscreen"' + title + ariaLabel + '></button>';
|
||||
} else if ( this.id === 'dfw' ) {
|
||||
active = dfw && dfw.isActive() ? '' : ' disabled="disabled"';
|
||||
on = dfw && dfw.isOn() ? ' active' : '';
|
||||
|
||||
return '<button type="button"' + id + ' class="ed_button qt-dfw' + on + '"' + title + ariaLabel + active + '></button>';
|
||||
}
|
||||
|
||||
return '<input type="button"' + id + ' class="ed_button button button-small"' + title + ariaLabel + val + ' />';
|
||||
};
|
||||
qt.Button.prototype.callback = function(){};
|
||||
|
||||
// a button that inserts HTML tag
|
||||
qt.TagButton = function( id, display, tagStart, tagEnd, access, title, instance, attr ) {
|
||||
var t = this;
|
||||
qt.Button.call( t, id, display, access, title, instance, attr );
|
||||
t.tagStart = tagStart;
|
||||
t.tagEnd = tagEnd;
|
||||
};
|
||||
qt.TagButton.prototype = new qt.Button();
|
||||
qt.TagButton.prototype.openTag = function( element, ed ) {
|
||||
if ( ! ed.openTags ) {
|
||||
ed.openTags = [];
|
||||
}
|
||||
|
||||
if ( this.tagEnd ) {
|
||||
ed.openTags.push( this.id );
|
||||
element.value = '/' + element.value;
|
||||
|
||||
if ( this.attr.ariaLabelClose ) {
|
||||
element.setAttribute( 'aria-label', this.attr.ariaLabelClose );
|
||||
}
|
||||
}
|
||||
};
|
||||
qt.TagButton.prototype.closeTag = function( element, ed ) {
|
||||
var i = this.isOpen(ed);
|
||||
|
||||
if ( i !== false ) {
|
||||
ed.openTags.splice( i, 1 );
|
||||
}
|
||||
|
||||
element.value = this.display;
|
||||
|
||||
if ( this.attr.ariaLabel ) {
|
||||
element.setAttribute( 'aria-label', this.attr.ariaLabel );
|
||||
}
|
||||
};
|
||||
// whether a tag is open or not. Returns false if not open, or current open depth of the tag
|
||||
qt.TagButton.prototype.isOpen = function (ed) {
|
||||
var t = this, i = 0, ret = false;
|
||||
if ( ed.openTags ) {
|
||||
while ( ret === false && i < ed.openTags.length ) {
|
||||
ret = ed.openTags[i] === t.id ? i : false;
|
||||
i ++;
|
||||
}
|
||||
} else {
|
||||
ret = false;
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
qt.TagButton.prototype.callback = function(element, canvas, ed) {
|
||||
var t = this, startPos, endPos, cursorPos, scrollTop, v = canvas.value, l, r, i, sel, endTag = v ? t.tagEnd : '', event;
|
||||
|
||||
if ( document.selection ) { // IE
|
||||
canvas.focus();
|
||||
sel = document.selection.createRange();
|
||||
if ( sel.text.length > 0 ) {
|
||||
if ( !t.tagEnd ) {
|
||||
sel.text = sel.text + t.tagStart;
|
||||
} else {
|
||||
sel.text = t.tagStart + sel.text + endTag;
|
||||
}
|
||||
} else {
|
||||
if ( !t.tagEnd ) {
|
||||
sel.text = t.tagStart;
|
||||
} else if ( t.isOpen(ed) === false ) {
|
||||
sel.text = t.tagStart;
|
||||
t.openTag(element, ed);
|
||||
} else {
|
||||
sel.text = endTag;
|
||||
t.closeTag(element, ed);
|
||||
}
|
||||
}
|
||||
canvas.focus();
|
||||
} else if ( canvas.selectionStart || canvas.selectionStart === 0 ) { // FF, WebKit, Opera
|
||||
startPos = canvas.selectionStart;
|
||||
endPos = canvas.selectionEnd;
|
||||
|
||||
if ( startPos < endPos && v.charAt( endPos - 1 ) === '\n' ) {
|
||||
endPos -= 1;
|
||||
}
|
||||
|
||||
cursorPos = endPos;
|
||||
scrollTop = canvas.scrollTop;
|
||||
l = v.substring(0, startPos); // left of the selection
|
||||
r = v.substring(endPos, v.length); // right of the selection
|
||||
i = v.substring(startPos, endPos); // inside the selection
|
||||
if ( startPos !== endPos ) {
|
||||
if ( !t.tagEnd ) {
|
||||
canvas.value = l + i + t.tagStart + r; // insert self closing tags after the selection
|
||||
cursorPos += t.tagStart.length;
|
||||
} else {
|
||||
canvas.value = l + t.tagStart + i + endTag + r;
|
||||
cursorPos += t.tagStart.length + endTag.length;
|
||||
}
|
||||
} else {
|
||||
if ( !t.tagEnd ) {
|
||||
canvas.value = l + t.tagStart + r;
|
||||
cursorPos = startPos + t.tagStart.length;
|
||||
} else if ( t.isOpen(ed) === false ) {
|
||||
canvas.value = l + t.tagStart + r;
|
||||
t.openTag(element, ed);
|
||||
cursorPos = startPos + t.tagStart.length;
|
||||
} else {
|
||||
canvas.value = l + endTag + r;
|
||||
cursorPos = startPos + endTag.length;
|
||||
t.closeTag(element, ed);
|
||||
}
|
||||
}
|
||||
|
||||
canvas.selectionStart = cursorPos;
|
||||
canvas.selectionEnd = cursorPos;
|
||||
canvas.scrollTop = scrollTop;
|
||||
canvas.focus();
|
||||
} else { // other browsers?
|
||||
if ( !endTag ) {
|
||||
canvas.value += t.tagStart;
|
||||
} else if ( t.isOpen(ed) !== false ) {
|
||||
canvas.value += t.tagStart;
|
||||
t.openTag(element, ed);
|
||||
} else {
|
||||
canvas.value += endTag;
|
||||
t.closeTag(element, ed);
|
||||
}
|
||||
canvas.focus();
|
||||
}
|
||||
|
||||
if ( document.createEvent ) {
|
||||
event = document.createEvent( 'HTMLEvents' );
|
||||
event.initEvent( 'change', false, true );
|
||||
canvas.dispatchEvent( event );
|
||||
} else if ( canvas.fireEvent ) {
|
||||
canvas.fireEvent( 'onchange' );
|
||||
}
|
||||
};
|
||||
|
||||
// removed
|
||||
qt.SpellButton = function() {};
|
||||
|
||||
// the close tags button
|
||||
qt.CloseButton = function() {
|
||||
qt.Button.call( this, 'close', quicktagsL10n.closeTags, '', quicktagsL10n.closeAllOpenTags );
|
||||
};
|
||||
|
||||
qt.CloseButton.prototype = new qt.Button();
|
||||
|
||||
qt._close = function(e, c, ed) {
|
||||
var button, element, tbo = ed.openTags;
|
||||
|
||||
if ( tbo ) {
|
||||
while ( tbo.length > 0 ) {
|
||||
button = ed.getButton(tbo[tbo.length - 1]);
|
||||
element = document.getElementById(ed.name + '_' + button.id);
|
||||
|
||||
if ( e ) {
|
||||
button.callback.call(button, element, c, ed);
|
||||
} else {
|
||||
button.closeTag(element, ed);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
qt.CloseButton.prototype.callback = qt._close;
|
||||
|
||||
qt.closeAllTags = function( editor_id ) {
|
||||
var ed = this.getInstance( editor_id );
|
||||
|
||||
if ( ed ) {
|
||||
qt._close( '', ed.canvas, ed );
|
||||
}
|
||||
};
|
||||
|
||||
// the link button
|
||||
qt.LinkButton = function() {
|
||||
var attr = {
|
||||
ariaLabel: quicktagsL10n.link
|
||||
};
|
||||
|
||||
qt.TagButton.call( this, 'link', 'link', '', '</a>', '', '', '', attr );
|
||||
};
|
||||
qt.LinkButton.prototype = new qt.TagButton();
|
||||
qt.LinkButton.prototype.callback = function(e, c, ed, defaultValue) {
|
||||
var URL, t = this;
|
||||
|
||||
if ( typeof wpLink !== 'undefined' ) {
|
||||
wpLink.open( ed.id );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! defaultValue ) {
|
||||
defaultValue = 'http://';
|
||||
}
|
||||
|
||||
if ( t.isOpen(ed) === false ) {
|
||||
URL = prompt( quicktagsL10n.enterURL, defaultValue );
|
||||
if ( URL ) {
|
||||
t.tagStart = '<a href="' + URL + '">';
|
||||
qt.TagButton.prototype.callback.call(t, e, c, ed);
|
||||
}
|
||||
} else {
|
||||
qt.TagButton.prototype.callback.call(t, e, c, ed);
|
||||
}
|
||||
};
|
||||
|
||||
// the img button
|
||||
qt.ImgButton = function() {
|
||||
var attr = {
|
||||
ariaLabel: quicktagsL10n.image
|
||||
};
|
||||
|
||||
qt.TagButton.call( this, 'img', 'img', '', '', '', '', '', attr );
|
||||
};
|
||||
qt.ImgButton.prototype = new qt.TagButton();
|
||||
qt.ImgButton.prototype.callback = function(e, c, ed, defaultValue) {
|
||||
if ( ! defaultValue ) {
|
||||
defaultValue = 'http://';
|
||||
}
|
||||
var src = prompt(quicktagsL10n.enterImageURL, defaultValue), alt;
|
||||
if ( src ) {
|
||||
alt = prompt(quicktagsL10n.enterImageDescription, '');
|
||||
this.tagStart = '<img src="' + src + '" alt="' + alt + '" />';
|
||||
qt.TagButton.prototype.callback.call(this, e, c, ed);
|
||||
}
|
||||
};
|
||||
|
||||
qt.DFWButton = function() {
|
||||
qt.Button.call( this, 'dfw', '', 'f', quicktagsL10n.dfw );
|
||||
};
|
||||
qt.DFWButton.prototype = new qt.Button();
|
||||
qt.DFWButton.prototype.callback = function() {
|
||||
var wp;
|
||||
|
||||
if ( ! ( wp = window.wp ) || ! wp.editor || ! wp.editor.dfw ) {
|
||||
return;
|
||||
}
|
||||
|
||||
window.wp.editor.dfw.toggle();
|
||||
};
|
||||
|
||||
qt.TextDirectionButton = function() {
|
||||
qt.Button.call( this, 'textdirection', quicktagsL10n.textdirection, '', quicktagsL10n.toggleTextdirection );
|
||||
};
|
||||
qt.TextDirectionButton.prototype = new qt.Button();
|
||||
qt.TextDirectionButton.prototype.callback = function(e, c) {
|
||||
var isRTL = ( 'rtl' === document.getElementsByTagName('html')[0].dir ),
|
||||
currentDirection = c.style.direction;
|
||||
|
||||
if ( ! currentDirection ) {
|
||||
currentDirection = ( isRTL ) ? 'rtl' : 'ltr';
|
||||
}
|
||||
|
||||
c.style.direction = ( 'rtl' === currentDirection ) ? 'ltr' : 'rtl';
|
||||
c.focus();
|
||||
};
|
||||
|
||||
// ensure backward compatibility
|
||||
edButtons[10] = new qt.TagButton( 'strong', 'b', '<strong>', '</strong>', '', '', '', { ariaLabel: quicktagsL10n.strong, ariaLabelClose: quicktagsL10n.strongClose } );
|
||||
edButtons[20] = new qt.TagButton( 'em', 'i', '<em>', '</em>', '', '', '', { ariaLabel: quicktagsL10n.em, ariaLabelClose: quicktagsL10n.emClose } );
|
||||
edButtons[30] = new qt.LinkButton(); // special case
|
||||
edButtons[40] = new qt.TagButton( 'block', 'b-quote', '\n\n<blockquote>', '</blockquote>\n\n', '', '', '', { ariaLabel: quicktagsL10n.blockquote, ariaLabelClose: quicktagsL10n.blockquoteClose } );
|
||||
edButtons[50] = new qt.TagButton( 'del', 'del', '<del datetime="' + _datetime + '">', '</del>', '', '', '', { ariaLabel: quicktagsL10n.del, ariaLabelClose: quicktagsL10n.delClose } );
|
||||
edButtons[60] = new qt.TagButton( 'ins', 'ins', '<ins datetime="' + _datetime + '">', '</ins>', '', '', '', { ariaLabel: quicktagsL10n.ins, ariaLabelClose: quicktagsL10n.insClose } );
|
||||
edButtons[70] = new qt.ImgButton(); // special case
|
||||
edButtons[80] = new qt.TagButton( 'ul', 'ul', '<ul>\n', '</ul>\n\n', '', '', '', { ariaLabel: quicktagsL10n.ul, ariaLabelClose: quicktagsL10n.ulClose } );
|
||||
edButtons[90] = new qt.TagButton( 'ol', 'ol', '<ol>\n', '</ol>\n\n', '', '', '', { ariaLabel: quicktagsL10n.ol, ariaLabelClose: quicktagsL10n.olClose } );
|
||||
edButtons[100] = new qt.TagButton( 'li', 'li', '\t<li>', '</li>\n', '', '', '', { ariaLabel: quicktagsL10n.li, ariaLabelClose: quicktagsL10n.liClose } );
|
||||
edButtons[110] = new qt.TagButton( 'code', 'code', '<code>', '</code>', '', '', '', { ariaLabel: quicktagsL10n.code, ariaLabelClose: quicktagsL10n.codeClose } );
|
||||
edButtons[120] = new qt.TagButton( 'more', 'more', '<!--more-->\n\n', '', '', '', '', { ariaLabel: quicktagsL10n.more } );
|
||||
edButtons[140] = new qt.CloseButton();
|
||||
|
||||
})();
|
||||
@@ -0,0 +1,62 @@
|
||||
/* global ajaxurl, current_site_id, isRtl */
|
||||
/**
|
||||
* Suggests users in a multisite environment.
|
||||
*
|
||||
* For input fields where the admin can select a user based on email or
|
||||
* username, this script shows an autocompletion menu for these inputs. Should
|
||||
* only be used in a multisite environment. Only users in the currently active
|
||||
* site are shown.
|
||||
*
|
||||
* @since 3.4.0
|
||||
*/
|
||||
|
||||
(function( $ ) {
|
||||
var id = ( typeof current_site_id !== 'undefined' ) ? '&site_id=' + current_site_id : '';
|
||||
$(document).ready( function() {
|
||||
var position = { offset: '0, -1' };
|
||||
if ( typeof isRtl !== 'undefined' && isRtl ) {
|
||||
position.my = 'right top';
|
||||
position.at = 'right bottom';
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an autocomplete function to input fields marked with the class
|
||||
* 'wp-suggest-user'.
|
||||
*
|
||||
* A minimum of two characters is required to trigger the suggestions. The
|
||||
* autocompletion menu is shown at the left bottom of the input field. On
|
||||
* RTL installations, it is shown at the right top. Adds the class 'open' to
|
||||
* the input field when the autocompletion menu is shown.
|
||||
*
|
||||
* Does a backend call to retrieve the users.
|
||||
*
|
||||
* Optional data-attributes:
|
||||
* - data-autocomplete-type (add, search)
|
||||
* The action that is going to be performed: search for existing users
|
||||
* or add a new one. Default: add
|
||||
* - data-autocomplete-field (user_login, user_email)
|
||||
* The field that is returned as the value for the suggestion.
|
||||
* Default: user_login
|
||||
*
|
||||
* @see wp-admin/includes/admin-actions.php:wp_ajax_autocomplete_user()
|
||||
*/
|
||||
$( '.wp-suggest-user' ).each( function(){
|
||||
var $this = $( this ),
|
||||
autocompleteType = ( typeof $this.data( 'autocompleteType' ) !== 'undefined' ) ? $this.data( 'autocompleteType' ) : 'add',
|
||||
autocompleteField = ( typeof $this.data( 'autocompleteField' ) !== 'undefined' ) ? $this.data( 'autocompleteField' ) : 'user_login';
|
||||
|
||||
$this.autocomplete({
|
||||
source: ajaxurl + '?action=autocomplete-user&autocomplete_type=' + autocompleteType + '&autocomplete_field=' + autocompleteField + id,
|
||||
delay: 500,
|
||||
minLength: 2,
|
||||
position: position,
|
||||
open: function() {
|
||||
$( this ).addClass( 'open' );
|
||||
},
|
||||
close: function() {
|
||||
$( this ).removeClass( 'open' );
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
})( jQuery );
|
||||
@@ -0,0 +1,18 @@
|
||||
/* global _zxcvbnSettings */
|
||||
(function() {
|
||||
var async_load = function() {
|
||||
var first, s;
|
||||
s = document.createElement('script');
|
||||
s.src = _zxcvbnSettings.src;
|
||||
s.type = 'text/javascript';
|
||||
s.async = true;
|
||||
first = document.getElementsByTagName('script')[0];
|
||||
return first.parentNode.insertBefore(s, first);
|
||||
};
|
||||
|
||||
if (window.attachEvent != null) {
|
||||
window.attachEvent('onload', async_load);
|
||||
} else {
|
||||
window.addEventListener('load', async_load, false);
|
||||
}
|
||||
}).call(this);
|
||||
@@ -0,0 +1,34 @@
|
||||
# src/js/enqueues/vendor
|
||||
|
||||
In this directory you'll find vendor JavaScript packages that cannot be installed through NPM, but are included in WordPress. Below we've documented the sources for those packages.
|
||||
|
||||
## Folder dependencies
|
||||
|
||||
- codemirror: https://github.com/codemirror/CodeMirror
|
||||
- crop: http://www.defusion.org.uk/code/javascript-image-cropper-ui-using-prototype-scriptaculous/download-zip/
|
||||
- imgareaselect: https://github.com/odyniec/imgareaselect
|
||||
- jcrop: https://github.com/tapmodo/Jcrop
|
||||
- mediaelement: https://github.com/mediaelement/mediaelement
|
||||
- plupload: https://github.com/moxiecode/plupload
|
||||
- swfupload: https://github.com/WordPress/secure-swfupload
|
||||
- thickbox: http://codylindley.com/thickbox/
|
||||
- tinymce: https://github.com/tinymce/tinymce
|
||||
|
||||
## Single file dependencies
|
||||
|
||||
- colorpicker: http://www.mattkruse.com/javascript/colorpicker/
|
||||
- deprecated/suggest: Patched by Mark Jaquith with Alexander Dick's "multiple items" patch to allow for auto-suggesting of more than one tag before submitting. See documentation in `suggest.js`.
|
||||
- farbtastic: https://github.com/mattfarina/farbtastic
|
||||
- iris: https://github.com/Automattic/Iris
|
||||
- json2: https://github.com/douglascrockford/JSON-js
|
||||
- jquery/jquery.color: https://github.com/jquery/jquery-color. Package is on NPM but not published by maintainer.
|
||||
- jquery/jquery.hotkeys: https://github.com/tzuryby/jquery.hotkeys
|
||||
- jquery/jquery.masonry: Old version for BC purposes, can't include two versions with NPM. The newer version is included through NPM and built to `wp-includes/js/masonry.min.js`
|
||||
- jquery/jquery.query: https://github.com/blairmitchelmore/jquery.plugins/blob/master/jquery.query.js
|
||||
- jquery/jquery.schedule: https://github.com/rse/jquery-schedule
|
||||
- jquery/jquery.serializeobject: https://github.com/cowboy/jquery-misc/blob/master/jquery.ba-serializeobject.js
|
||||
- jquery/jquery.table-hotkeys: WP version can be downloaded at https://code.google.com/archive/p/js-hotkeys/downloads?page=2. A newer version is available at https://github.com/jeresig/jquery.hotkeys.
|
||||
- jquery/jquery.ui.touch-punch.js https://github.com/furf/jquery-ui-touch-punch/blob/master/jquery.ui.touch-punch.js
|
||||
- swfobject: https://github.com/swfobject/swfobject
|
||||
- tw-sack: https://github.com/abritinthebay/simpleajaxcodekit
|
||||
- zxcvbn: https://github.com/dropbox/zxcvbn cannot automatically be installed as the frequency lists need to be manually ROT13 transformed.
|
||||
@@ -0,0 +1,43 @@
|
||||
// JSHINT has some GPL Compatability issues, so we are faking it out and using esprima for validation
|
||||
// Based on https://github.com/jquery/esprima/blob/gh-pages/demo/validate.js which is MIT licensed
|
||||
|
||||
var fakeJSHINT = new function() {
|
||||
var syntax, errors;
|
||||
var that = this;
|
||||
this.data = [];
|
||||
this.convertError = function( error ){
|
||||
return {
|
||||
line: error.lineNumber,
|
||||
character: error.column,
|
||||
reason: error.description,
|
||||
code: 'E'
|
||||
};
|
||||
};
|
||||
this.parse = function( code ){
|
||||
try {
|
||||
syntax = window.esprima.parse(code, { tolerant: true, loc: true });
|
||||
errors = syntax.errors;
|
||||
if ( errors.length > 0 ) {
|
||||
for ( var i = 0; i < errors.length; i++) {
|
||||
var error = errors[i];
|
||||
that.data.push( that.convertError( error ) );
|
||||
}
|
||||
} else {
|
||||
that.data = [];
|
||||
}
|
||||
} catch (e) {
|
||||
that.data.push( that.convertError( e ) );
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
window.JSHINT = function( text ){
|
||||
fakeJSHINT.parse( text );
|
||||
};
|
||||
window.JSHINT.data = function(){
|
||||
return {
|
||||
errors: fakeJSHINT.data
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/* global HTMLHint */
|
||||
/* eslint no-magic-numbers: ["error", { "ignore": [0, 1] }] */
|
||||
HTMLHint.addRule({
|
||||
id: 'kses',
|
||||
description: 'Element or attribute cannot be used.',
|
||||
init: function( parser, reporter, options ) {
|
||||
'use strict';
|
||||
|
||||
var self = this;
|
||||
parser.addListener( 'tagstart', function( event ) {
|
||||
var attr, col, attrName, allowedAttributes, i, len, tagName;
|
||||
|
||||
tagName = event.tagName.toLowerCase();
|
||||
if ( ! options[ tagName ] ) {
|
||||
reporter.error( 'Tag <' + event.tagName + '> is not allowed.', event.line, event.col, self, event.raw );
|
||||
return;
|
||||
}
|
||||
|
||||
allowedAttributes = options[ tagName ];
|
||||
col = event.col + event.tagName.length + 1;
|
||||
for ( i = 0, len = event.attrs.length; i < len; i++ ) {
|
||||
attr = event.attrs[ i ];
|
||||
attrName = attr.name.toLowerCase();
|
||||
if ( ! allowedAttributes[ attrName ] ) {
|
||||
reporter.error( 'Tag attribute [' + attr.raw + ' ] is not allowed.', event.line, col + attr.index, self, attr.raw );
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,432 @@
|
||||
/* Jison generated parser */
|
||||
var jsonlint = (function(){
|
||||
var parser = {trace: function trace() { },
|
||||
yy: {},
|
||||
symbols_: {"error":2,"JSONString":3,"STRING":4,"JSONNumber":5,"NUMBER":6,"JSONNullLiteral":7,"NULL":8,"JSONBooleanLiteral":9,"TRUE":10,"FALSE":11,"JSONText":12,"JSONValue":13,"EOF":14,"JSONObject":15,"JSONArray":16,"{":17,"}":18,"JSONMemberList":19,"JSONMember":20,":":21,",":22,"[":23,"]":24,"JSONElementList":25,"$accept":0,"$end":1},
|
||||
terminals_: {2:"error",4:"STRING",6:"NUMBER",8:"NULL",10:"TRUE",11:"FALSE",14:"EOF",17:"{",18:"}",21:":",22:",",23:"[",24:"]"},
|
||||
productions_: [0,[3,1],[5,1],[7,1],[9,1],[9,1],[12,2],[13,1],[13,1],[13,1],[13,1],[13,1],[13,1],[15,2],[15,3],[20,3],[19,1],[19,3],[16,2],[16,3],[25,1],[25,3]],
|
||||
performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) {
|
||||
|
||||
var $0 = $$.length - 1;
|
||||
switch (yystate) {
|
||||
case 1: // replace escaped characters with actual character
|
||||
this.$ = yytext.replace(/\\(\\|")/g, "$"+"1")
|
||||
.replace(/\\n/g,'\n')
|
||||
.replace(/\\r/g,'\r')
|
||||
.replace(/\\t/g,'\t')
|
||||
.replace(/\\v/g,'\v')
|
||||
.replace(/\\f/g,'\f')
|
||||
.replace(/\\b/g,'\b');
|
||||
|
||||
break;
|
||||
case 2:this.$ = Number(yytext);
|
||||
break;
|
||||
case 3:this.$ = null;
|
||||
break;
|
||||
case 4:this.$ = true;
|
||||
break;
|
||||
case 5:this.$ = false;
|
||||
break;
|
||||
case 6:return this.$ = $$[$0-1];
|
||||
break;
|
||||
case 13:this.$ = {};
|
||||
break;
|
||||
case 14:this.$ = $$[$0-1];
|
||||
break;
|
||||
case 15:this.$ = [$$[$0-2], $$[$0]];
|
||||
break;
|
||||
case 16:this.$ = {}; this.$[$$[$0][0]] = $$[$0][1];
|
||||
break;
|
||||
case 17:this.$ = $$[$0-2]; $$[$0-2][$$[$0][0]] = $$[$0][1];
|
||||
break;
|
||||
case 18:this.$ = [];
|
||||
break;
|
||||
case 19:this.$ = $$[$0-1];
|
||||
break;
|
||||
case 20:this.$ = [$$[$0]];
|
||||
break;
|
||||
case 21:this.$ = $$[$0-2]; $$[$0-2].push($$[$0]);
|
||||
break;
|
||||
}
|
||||
},
|
||||
table: [{3:5,4:[1,12],5:6,6:[1,13],7:3,8:[1,9],9:4,10:[1,10],11:[1,11],12:1,13:2,15:7,16:8,17:[1,14],23:[1,15]},{1:[3]},{14:[1,16]},{14:[2,7],18:[2,7],22:[2,7],24:[2,7]},{14:[2,8],18:[2,8],22:[2,8],24:[2,8]},{14:[2,9],18:[2,9],22:[2,9],24:[2,9]},{14:[2,10],18:[2,10],22:[2,10],24:[2,10]},{14:[2,11],18:[2,11],22:[2,11],24:[2,11]},{14:[2,12],18:[2,12],22:[2,12],24:[2,12]},{14:[2,3],18:[2,3],22:[2,3],24:[2,3]},{14:[2,4],18:[2,4],22:[2,4],24:[2,4]},{14:[2,5],18:[2,5],22:[2,5],24:[2,5]},{14:[2,1],18:[2,1],21:[2,1],22:[2,1],24:[2,1]},{14:[2,2],18:[2,2],22:[2,2],24:[2,2]},{3:20,4:[1,12],18:[1,17],19:18,20:19},{3:5,4:[1,12],5:6,6:[1,13],7:3,8:[1,9],9:4,10:[1,10],11:[1,11],13:23,15:7,16:8,17:[1,14],23:[1,15],24:[1,21],25:22},{1:[2,6]},{14:[2,13],18:[2,13],22:[2,13],24:[2,13]},{18:[1,24],22:[1,25]},{18:[2,16],22:[2,16]},{21:[1,26]},{14:[2,18],18:[2,18],22:[2,18],24:[2,18]},{22:[1,28],24:[1,27]},{22:[2,20],24:[2,20]},{14:[2,14],18:[2,14],22:[2,14],24:[2,14]},{3:20,4:[1,12],20:29},{3:5,4:[1,12],5:6,6:[1,13],7:3,8:[1,9],9:4,10:[1,10],11:[1,11],13:30,15:7,16:8,17:[1,14],23:[1,15]},{14:[2,19],18:[2,19],22:[2,19],24:[2,19]},{3:5,4:[1,12],5:6,6:[1,13],7:3,8:[1,9],9:4,10:[1,10],11:[1,11],13:31,15:7,16:8,17:[1,14],23:[1,15]},{18:[2,17],22:[2,17]},{18:[2,15],22:[2,15]},{22:[2,21],24:[2,21]}],
|
||||
defaultActions: {16:[2,6]},
|
||||
parseError: function parseError(str, hash) {
|
||||
throw new Error(str);
|
||||
},
|
||||
parse: function parse(input) {
|
||||
var self = this,
|
||||
stack = [0],
|
||||
vstack = [null], // semantic value stack
|
||||
lstack = [], // location stack
|
||||
table = this.table,
|
||||
yytext = '',
|
||||
yylineno = 0,
|
||||
yyleng = 0,
|
||||
recovering = 0,
|
||||
TERROR = 2,
|
||||
EOF = 1;
|
||||
|
||||
//this.reductionCount = this.shiftCount = 0;
|
||||
|
||||
this.lexer.setInput(input);
|
||||
this.lexer.yy = this.yy;
|
||||
this.yy.lexer = this.lexer;
|
||||
if (typeof this.lexer.yylloc == 'undefined')
|
||||
this.lexer.yylloc = {};
|
||||
var yyloc = this.lexer.yylloc;
|
||||
lstack.push(yyloc);
|
||||
|
||||
if (typeof this.yy.parseError === 'function')
|
||||
this.parseError = this.yy.parseError;
|
||||
|
||||
function popStack (n) {
|
||||
stack.length = stack.length - 2*n;
|
||||
vstack.length = vstack.length - n;
|
||||
lstack.length = lstack.length - n;
|
||||
}
|
||||
|
||||
function lex() {
|
||||
var token;
|
||||
token = self.lexer.lex() || 1; // $end = 1
|
||||
// if token isn't its numeric value, convert
|
||||
if (typeof token !== 'number') {
|
||||
token = self.symbols_[token] || token;
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
var symbol, preErrorSymbol, state, action, a, r, yyval={},p,len,newState, expected;
|
||||
while (true) {
|
||||
// retreive state number from top of stack
|
||||
state = stack[stack.length-1];
|
||||
|
||||
// use default actions if available
|
||||
if (this.defaultActions[state]) {
|
||||
action = this.defaultActions[state];
|
||||
} else {
|
||||
if (symbol == null)
|
||||
symbol = lex();
|
||||
// read action for current state and first input
|
||||
action = table[state] && table[state][symbol];
|
||||
}
|
||||
|
||||
// handle parse error
|
||||
_handle_error:
|
||||
if (typeof action === 'undefined' || !action.length || !action[0]) {
|
||||
|
||||
if (!recovering) {
|
||||
// Report error
|
||||
expected = [];
|
||||
for (p in table[state]) if (this.terminals_[p] && p > 2) {
|
||||
expected.push("'"+this.terminals_[p]+"'");
|
||||
}
|
||||
var errStr = '';
|
||||
if (this.lexer.showPosition) {
|
||||
errStr = 'Parse error on line '+(yylineno+1)+":\n"+this.lexer.showPosition()+"\nExpecting "+expected.join(', ') + ", got '" + this.terminals_[symbol]+ "'";
|
||||
} else {
|
||||
errStr = 'Parse error on line '+(yylineno+1)+": Unexpected " +
|
||||
(symbol == 1 /*EOF*/ ? "end of input" :
|
||||
("'"+(this.terminals_[symbol] || symbol)+"'"));
|
||||
}
|
||||
this.parseError(errStr,
|
||||
{text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected});
|
||||
}
|
||||
|
||||
// just recovered from another error
|
||||
if (recovering == 3) {
|
||||
if (symbol == EOF) {
|
||||
throw new Error(errStr || 'Parsing halted.');
|
||||
}
|
||||
|
||||
// discard current lookahead and grab another
|
||||
yyleng = this.lexer.yyleng;
|
||||
yytext = this.lexer.yytext;
|
||||
yylineno = this.lexer.yylineno;
|
||||
yyloc = this.lexer.yylloc;
|
||||
symbol = lex();
|
||||
}
|
||||
|
||||
// try to recover from error
|
||||
while (1) {
|
||||
// check for error recovery rule in this state
|
||||
if ((TERROR.toString()) in table[state]) {
|
||||
break;
|
||||
}
|
||||
if (state == 0) {
|
||||
throw new Error(errStr || 'Parsing halted.');
|
||||
}
|
||||
popStack(1);
|
||||
state = stack[stack.length-1];
|
||||
}
|
||||
|
||||
preErrorSymbol = symbol; // save the lookahead token
|
||||
symbol = TERROR; // insert generic error symbol as new lookahead
|
||||
state = stack[stack.length-1];
|
||||
action = table[state] && table[state][TERROR];
|
||||
recovering = 3; // allow 3 real symbols to be shifted before reporting a new error
|
||||
}
|
||||
|
||||
// this shouldn't happen, unless resolve defaults are off
|
||||
if (action[0] instanceof Array && action.length > 1) {
|
||||
throw new Error('Parse Error: multiple actions possible at state: '+state+', token: '+symbol);
|
||||
}
|
||||
|
||||
switch (action[0]) {
|
||||
|
||||
case 1: // shift
|
||||
//this.shiftCount++;
|
||||
|
||||
stack.push(symbol);
|
||||
vstack.push(this.lexer.yytext);
|
||||
lstack.push(this.lexer.yylloc);
|
||||
stack.push(action[1]); // push state
|
||||
symbol = null;
|
||||
if (!preErrorSymbol) { // normal execution/no error
|
||||
yyleng = this.lexer.yyleng;
|
||||
yytext = this.lexer.yytext;
|
||||
yylineno = this.lexer.yylineno;
|
||||
yyloc = this.lexer.yylloc;
|
||||
if (recovering > 0)
|
||||
recovering--;
|
||||
} else { // error just occurred, resume old lookahead f/ before error
|
||||
symbol = preErrorSymbol;
|
||||
preErrorSymbol = null;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: // reduce
|
||||
//this.reductionCount++;
|
||||
|
||||
len = this.productions_[action[1]][1];
|
||||
|
||||
// perform semantic action
|
||||
yyval.$ = vstack[vstack.length-len]; // default to $$ = $1
|
||||
// default location, uses first token for firsts, last for lasts
|
||||
yyval._$ = {
|
||||
first_line: lstack[lstack.length-(len||1)].first_line,
|
||||
last_line: lstack[lstack.length-1].last_line,
|
||||
first_column: lstack[lstack.length-(len||1)].first_column,
|
||||
last_column: lstack[lstack.length-1].last_column
|
||||
};
|
||||
r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack);
|
||||
|
||||
if (typeof r !== 'undefined') {
|
||||
return r;
|
||||
}
|
||||
|
||||
// pop off stack
|
||||
if (len) {
|
||||
stack = stack.slice(0,-1*len*2);
|
||||
vstack = vstack.slice(0, -1*len);
|
||||
lstack = lstack.slice(0, -1*len);
|
||||
}
|
||||
|
||||
stack.push(this.productions_[action[1]][0]); // push nonterminal (reduce)
|
||||
vstack.push(yyval.$);
|
||||
lstack.push(yyval._$);
|
||||
// goto new state = table[STATE][NONTERMINAL]
|
||||
newState = table[stack[stack.length-2]][stack[stack.length-1]];
|
||||
stack.push(newState);
|
||||
break;
|
||||
|
||||
case 3: // accept
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}};
|
||||
/* Jison generated lexer */
|
||||
var lexer = (function(){
|
||||
var lexer = ({EOF:1,
|
||||
parseError:function parseError(str, hash) {
|
||||
if (this.yy.parseError) {
|
||||
this.yy.parseError(str, hash);
|
||||
} else {
|
||||
throw new Error(str);
|
||||
}
|
||||
},
|
||||
setInput:function (input) {
|
||||
this._input = input;
|
||||
this._more = this._less = this.done = false;
|
||||
this.yylineno = this.yyleng = 0;
|
||||
this.yytext = this.matched = this.match = '';
|
||||
this.conditionStack = ['INITIAL'];
|
||||
this.yylloc = {first_line:1,first_column:0,last_line:1,last_column:0};
|
||||
return this;
|
||||
},
|
||||
input:function () {
|
||||
var ch = this._input[0];
|
||||
this.yytext+=ch;
|
||||
this.yyleng++;
|
||||
this.match+=ch;
|
||||
this.matched+=ch;
|
||||
var lines = ch.match(/\n/);
|
||||
if (lines) this.yylineno++;
|
||||
this._input = this._input.slice(1);
|
||||
return ch;
|
||||
},
|
||||
unput:function (ch) {
|
||||
this._input = ch + this._input;
|
||||
return this;
|
||||
},
|
||||
more:function () {
|
||||
this._more = true;
|
||||
return this;
|
||||
},
|
||||
less:function (n) {
|
||||
this._input = this.match.slice(n) + this._input;
|
||||
},
|
||||
pastInput:function () {
|
||||
var past = this.matched.substr(0, this.matched.length - this.match.length);
|
||||
return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, "");
|
||||
},
|
||||
upcomingInput:function () {
|
||||
var next = this.match;
|
||||
if (next.length < 20) {
|
||||
next += this._input.substr(0, 20-next.length);
|
||||
}
|
||||
return (next.substr(0,20)+(next.length > 20 ? '...':'')).replace(/\n/g, "");
|
||||
},
|
||||
showPosition:function () {
|
||||
var pre = this.pastInput();
|
||||
var c = new Array(pre.length + 1).join("-");
|
||||
return pre + this.upcomingInput() + "\n" + c+"^";
|
||||
},
|
||||
next:function () {
|
||||
if (this.done) {
|
||||
return this.EOF;
|
||||
}
|
||||
if (!this._input) this.done = true;
|
||||
|
||||
var token,
|
||||
match,
|
||||
tempMatch,
|
||||
index,
|
||||
col,
|
||||
lines;
|
||||
if (!this._more) {
|
||||
this.yytext = '';
|
||||
this.match = '';
|
||||
}
|
||||
var rules = this._currentRules();
|
||||
for (var i=0;i < rules.length; i++) {
|
||||
tempMatch = this._input.match(this.rules[rules[i]]);
|
||||
if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {
|
||||
match = tempMatch;
|
||||
index = i;
|
||||
if (!this.options.flex) break;
|
||||
}
|
||||
}
|
||||
if (match) {
|
||||
lines = match[0].match(/\n.*/g);
|
||||
if (lines) this.yylineno += lines.length;
|
||||
this.yylloc = {first_line: this.yylloc.last_line,
|
||||
last_line: this.yylineno+1,
|
||||
first_column: this.yylloc.last_column,
|
||||
last_column: lines ? lines[lines.length-1].length-1 : this.yylloc.last_column + match[0].length}
|
||||
this.yytext += match[0];
|
||||
this.match += match[0];
|
||||
this.yyleng = this.yytext.length;
|
||||
this._more = false;
|
||||
this._input = this._input.slice(match[0].length);
|
||||
this.matched += match[0];
|
||||
token = this.performAction.call(this, this.yy, this, rules[index],this.conditionStack[this.conditionStack.length-1]);
|
||||
if (this.done && this._input) this.done = false;
|
||||
if (token) return token;
|
||||
else return;
|
||||
}
|
||||
if (this._input === "") {
|
||||
return this.EOF;
|
||||
} else {
|
||||
this.parseError('Lexical error on line '+(this.yylineno+1)+'. Unrecognized text.\n'+this.showPosition(),
|
||||
{text: "", token: null, line: this.yylineno});
|
||||
}
|
||||
},
|
||||
lex:function lex() {
|
||||
var r = this.next();
|
||||
if (typeof r !== 'undefined') {
|
||||
return r;
|
||||
} else {
|
||||
return this.lex();
|
||||
}
|
||||
},
|
||||
begin:function begin(condition) {
|
||||
this.conditionStack.push(condition);
|
||||
},
|
||||
popState:function popState() {
|
||||
return this.conditionStack.pop();
|
||||
},
|
||||
_currentRules:function _currentRules() {
|
||||
return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules;
|
||||
},
|
||||
topState:function () {
|
||||
return this.conditionStack[this.conditionStack.length-2];
|
||||
},
|
||||
pushState:function begin(condition) {
|
||||
this.begin(condition);
|
||||
}});
|
||||
lexer.options = {};
|
||||
lexer.performAction = function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {
|
||||
|
||||
var YYSTATE=YY_START
|
||||
switch($avoiding_name_collisions) {
|
||||
case 0:/* skip whitespace */
|
||||
break;
|
||||
case 1:return 6
|
||||
break;
|
||||
case 2:yy_.yytext = yy_.yytext.substr(1,yy_.yyleng-2); return 4
|
||||
break;
|
||||
case 3:return 17
|
||||
break;
|
||||
case 4:return 18
|
||||
break;
|
||||
case 5:return 23
|
||||
break;
|
||||
case 6:return 24
|
||||
break;
|
||||
case 7:return 22
|
||||
break;
|
||||
case 8:return 21
|
||||
break;
|
||||
case 9:return 10
|
||||
break;
|
||||
case 10:return 11
|
||||
break;
|
||||
case 11:return 8
|
||||
break;
|
||||
case 12:return 14
|
||||
break;
|
||||
case 13:return 'INVALID'
|
||||
break;
|
||||
}
|
||||
};
|
||||
lexer.rules = [/^(?:\s+)/,/^(?:(-?([0-9]|[1-9][0-9]+))(\.[0-9]+)?([eE][-+]?[0-9]+)?\b)/,/^(?:"(?:\\[\\"bfnrt/]|\\u[a-fA-F0-9]{4}|[^\\\0-\x09\x0a-\x1f"])*")/,/^(?:\{)/,/^(?:\})/,/^(?:\[)/,/^(?:\])/,/^(?:,)/,/^(?::)/,/^(?:true\b)/,/^(?:false\b)/,/^(?:null\b)/,/^(?:$)/,/^(?:.)/];
|
||||
lexer.conditions = {"INITIAL":{"rules":[0,1,2,3,4,5,6,7,8,9,10,11,12,13],"inclusive":true}};
|
||||
|
||||
|
||||
;
|
||||
return lexer;})()
|
||||
parser.lexer = lexer;
|
||||
return parser;
|
||||
})();
|
||||
if (typeof require !== 'undefined' && typeof exports !== 'undefined') {
|
||||
exports.parser = jsonlint;
|
||||
exports.parse = function () { return jsonlint.parse.apply(jsonlint, arguments); }
|
||||
exports.main = function commonjsMain(args) {
|
||||
if (!args[1])
|
||||
throw new Error('Usage: '+args[0]+' FILE');
|
||||
if (typeof process !== 'undefined') {
|
||||
var source = require('fs').readFileSync(require('path').join(process.cwd(), args[1]), "utf8");
|
||||
} else {
|
||||
var cwd = require("file").path(require("file").cwd());
|
||||
var source = cwd.join(args[1]).read({charset: "utf-8"});
|
||||
}
|
||||
return exports.parser.parse(source);
|
||||
}
|
||||
if (typeof module !== 'undefined' && require.main === module) {
|
||||
exports.main(typeof process !== 'undefined' ? process.argv.slice(1) : require("system").args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,707 @@
|
||||
// ===================================================================
|
||||
// Author: Matt Kruse <matt@mattkruse.com>
|
||||
// WWW: http://www.mattkruse.com/
|
||||
//
|
||||
// NOTICE: You may use this code for any purpose, commercial or
|
||||
// private, without any further permission from the author. You may
|
||||
// remove this notice from your final code if you wish, however it is
|
||||
// appreciated by the author if at least my web site address is kept.
|
||||
//
|
||||
// You may *NOT* re-distribute this code in any way except through its
|
||||
// use. That means, you can include it in your product, or your web
|
||||
// site, or any other form where the code is actually being used. You
|
||||
// may not put the plain javascript up on your site for download or
|
||||
// include it in your javascript libraries for download.
|
||||
// If you wish to share this code with others, please just point them
|
||||
// to the URL instead.
|
||||
// Please DO NOT link directly to my .js files from your site. Copy
|
||||
// the files to your server and use them there. Thank you.
|
||||
// ===================================================================
|
||||
|
||||
|
||||
/* SOURCE FILE: AnchorPosition.js */
|
||||
|
||||
/*
|
||||
AnchorPosition.js
|
||||
Author: Matt Kruse
|
||||
Last modified: 10/11/02
|
||||
|
||||
DESCRIPTION: These functions find the position of an <A> tag in a document,
|
||||
so other elements can be positioned relative to it.
|
||||
|
||||
COMPATABILITY: Netscape 4.x,6.x,Mozilla, IE 5.x,6.x on Windows. Some small
|
||||
positioning errors - usually with Window positioning - occur on the
|
||||
Macintosh platform.
|
||||
|
||||
FUNCTIONS:
|
||||
getAnchorPosition(anchorname)
|
||||
Returns an Object() having .x and .y properties of the pixel coordinates
|
||||
of the upper-left corner of the anchor. Position is relative to the PAGE.
|
||||
|
||||
getAnchorWindowPosition(anchorname)
|
||||
Returns an Object() having .x and .y properties of the pixel coordinates
|
||||
of the upper-left corner of the anchor, relative to the WHOLE SCREEN.
|
||||
|
||||
NOTES:
|
||||
|
||||
1) For popping up separate browser windows, use getAnchorWindowPosition.
|
||||
Otherwise, use getAnchorPosition
|
||||
|
||||
2) Your anchor tag MUST contain both NAME and ID attributes which are the
|
||||
same. For example:
|
||||
<A NAME="test" ID="test"> </A>
|
||||
|
||||
3) There must be at least a space between <A> </A> for IE5.5 to see the
|
||||
anchor tag correctly. Do not do <A></A> with no space.
|
||||
*/
|
||||
|
||||
// getAnchorPosition(anchorname)
|
||||
// This function returns an object having .x and .y properties which are the coordinates
|
||||
// of the named anchor, relative to the page.
|
||||
function getAnchorPosition(anchorname) {
|
||||
// This function will return an Object with x and y properties
|
||||
var useWindow=false;
|
||||
var coordinates=new Object();
|
||||
var x=0,y=0;
|
||||
// Browser capability sniffing
|
||||
var use_gebi=false, use_css=false, use_layers=false;
|
||||
if (document.getElementById) { use_gebi=true; }
|
||||
else if (document.all) { use_css=true; }
|
||||
else if (document.layers) { use_layers=true; }
|
||||
// Logic to find position
|
||||
if (use_gebi && document.all) {
|
||||
x=AnchorPosition_getPageOffsetLeft(document.all[anchorname]);
|
||||
y=AnchorPosition_getPageOffsetTop(document.all[anchorname]);
|
||||
}
|
||||
else if (use_gebi) {
|
||||
var o=document.getElementById(anchorname);
|
||||
x=AnchorPosition_getPageOffsetLeft(o);
|
||||
y=AnchorPosition_getPageOffsetTop(o);
|
||||
}
|
||||
else if (use_css) {
|
||||
x=AnchorPosition_getPageOffsetLeft(document.all[anchorname]);
|
||||
y=AnchorPosition_getPageOffsetTop(document.all[anchorname]);
|
||||
}
|
||||
else if (use_layers) {
|
||||
var found=0;
|
||||
for (var i=0; i<document.anchors.length; i++) {
|
||||
if (document.anchors[i].name==anchorname) { found=1; break; }
|
||||
}
|
||||
if (found==0) {
|
||||
coordinates.x=0; coordinates.y=0; return coordinates;
|
||||
}
|
||||
x=document.anchors[i].x;
|
||||
y=document.anchors[i].y;
|
||||
}
|
||||
else {
|
||||
coordinates.x=0; coordinates.y=0; return coordinates;
|
||||
}
|
||||
coordinates.x=x;
|
||||
coordinates.y=y;
|
||||
return coordinates;
|
||||
}
|
||||
|
||||
// getAnchorWindowPosition(anchorname)
|
||||
// This function returns an object having .x and .y properties which are the coordinates
|
||||
// of the named anchor, relative to the window
|
||||
function getAnchorWindowPosition(anchorname) {
|
||||
var coordinates=getAnchorPosition(anchorname);
|
||||
var x=0;
|
||||
var y=0;
|
||||
if (document.getElementById) {
|
||||
if (isNaN(window.screenX)) {
|
||||
x=coordinates.x-document.body.scrollLeft+window.screenLeft;
|
||||
y=coordinates.y-document.body.scrollTop+window.screenTop;
|
||||
}
|
||||
else {
|
||||
x=coordinates.x+window.screenX+(window.outerWidth-window.innerWidth)-window.pageXOffset;
|
||||
y=coordinates.y+window.screenY+(window.outerHeight-24-window.innerHeight)-window.pageYOffset;
|
||||
}
|
||||
}
|
||||
else if (document.all) {
|
||||
x=coordinates.x-document.body.scrollLeft+window.screenLeft;
|
||||
y=coordinates.y-document.body.scrollTop+window.screenTop;
|
||||
}
|
||||
else if (document.layers) {
|
||||
x=coordinates.x+window.screenX+(window.outerWidth-window.innerWidth)-window.pageXOffset;
|
||||
y=coordinates.y+window.screenY+(window.outerHeight-24-window.innerHeight)-window.pageYOffset;
|
||||
}
|
||||
coordinates.x=x;
|
||||
coordinates.y=y;
|
||||
return coordinates;
|
||||
}
|
||||
|
||||
// Functions for IE to get position of an object
|
||||
function AnchorPosition_getPageOffsetLeft (el) {
|
||||
var ol=el.offsetLeft;
|
||||
while ((el=el.offsetParent) != null) { ol += el.offsetLeft; }
|
||||
return ol;
|
||||
}
|
||||
function AnchorPosition_getWindowOffsetLeft (el) {
|
||||
return AnchorPosition_getPageOffsetLeft(el)-document.body.scrollLeft;
|
||||
}
|
||||
function AnchorPosition_getPageOffsetTop (el) {
|
||||
var ot=el.offsetTop;
|
||||
while((el=el.offsetParent) != null) { ot += el.offsetTop; }
|
||||
return ot;
|
||||
}
|
||||
function AnchorPosition_getWindowOffsetTop (el) {
|
||||
return AnchorPosition_getPageOffsetTop(el)-document.body.scrollTop;
|
||||
}
|
||||
|
||||
/* SOURCE FILE: PopupWindow.js */
|
||||
|
||||
/*
|
||||
PopupWindow.js
|
||||
Author: Matt Kruse
|
||||
Last modified: 02/16/04
|
||||
|
||||
DESCRIPTION: This object allows you to easily and quickly popup a window
|
||||
in a certain place. The window can either be a DIV or a separate browser
|
||||
window.
|
||||
|
||||
COMPATABILITY: Works with Netscape 4.x, 6.x, IE 5.x on Windows. Some small
|
||||
positioning errors - usually with Window positioning - occur on the
|
||||
Macintosh platform. Due to bugs in Netscape 4.x, populating the popup
|
||||
window with <STYLE> tags may cause errors.
|
||||
|
||||
USAGE:
|
||||
// Create an object for a WINDOW popup
|
||||
var win = new PopupWindow();
|
||||
|
||||
// Create an object for a DIV window using the DIV named 'mydiv'
|
||||
var win = new PopupWindow('mydiv');
|
||||
|
||||
// Set the window to automatically hide itself when the user clicks
|
||||
// anywhere else on the page except the popup
|
||||
win.autoHide();
|
||||
|
||||
// Show the window relative to the anchor name passed in
|
||||
win.showPopup(anchorname);
|
||||
|
||||
// Hide the popup
|
||||
win.hidePopup();
|
||||
|
||||
// Set the size of the popup window (only applies to WINDOW popups
|
||||
win.setSize(width,height);
|
||||
|
||||
// Populate the contents of the popup window that will be shown. If you
|
||||
// change the contents while it is displayed, you will need to refresh()
|
||||
win.populate(string);
|
||||
|
||||
// set the URL of the window, rather than populating its contents
|
||||
// manually
|
||||
win.setUrl("http://www.site.com/");
|
||||
|
||||
// Refresh the contents of the popup
|
||||
win.refresh();
|
||||
|
||||
// Specify how many pixels to the right of the anchor the popup will appear
|
||||
win.offsetX = 50;
|
||||
|
||||
// Specify how many pixels below the anchor the popup will appear
|
||||
win.offsetY = 100;
|
||||
|
||||
NOTES:
|
||||
1) Requires the functions in AnchorPosition.js
|
||||
|
||||
2) Your anchor tag MUST contain both NAME and ID attributes which are the
|
||||
same. For example:
|
||||
<A NAME="test" ID="test"> </A>
|
||||
|
||||
3) There must be at least a space between <A> </A> for IE5.5 to see the
|
||||
anchor tag correctly. Do not do <A></A> with no space.
|
||||
|
||||
4) When a PopupWindow object is created, a handler for 'onmouseup' is
|
||||
attached to any event handler you may have already defined. Do NOT define
|
||||
an event handler for 'onmouseup' after you define a PopupWindow object or
|
||||
the autoHide() will not work correctly.
|
||||
*/
|
||||
|
||||
// Set the position of the popup window based on the anchor
|
||||
function PopupWindow_getXYPosition(anchorname) {
|
||||
var coordinates;
|
||||
if (this.type == "WINDOW") {
|
||||
coordinates = getAnchorWindowPosition(anchorname);
|
||||
}
|
||||
else {
|
||||
coordinates = getAnchorPosition(anchorname);
|
||||
}
|
||||
this.x = coordinates.x;
|
||||
this.y = coordinates.y;
|
||||
}
|
||||
// Set width/height of DIV/popup window
|
||||
function PopupWindow_setSize(width,height) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
// Fill the window with contents
|
||||
function PopupWindow_populate(contents) {
|
||||
this.contents = contents;
|
||||
this.populated = false;
|
||||
}
|
||||
// Set the URL to go to
|
||||
function PopupWindow_setUrl(url) {
|
||||
this.url = url;
|
||||
}
|
||||
// Set the window popup properties
|
||||
function PopupWindow_setWindowProperties(props) {
|
||||
this.windowProperties = props;
|
||||
}
|
||||
// Refresh the displayed contents of the popup
|
||||
function PopupWindow_refresh() {
|
||||
if (this.divName != null) {
|
||||
// refresh the DIV object
|
||||
if (this.use_gebi) {
|
||||
document.getElementById(this.divName).innerHTML = this.contents;
|
||||
}
|
||||
else if (this.use_css) {
|
||||
document.all[this.divName].innerHTML = this.contents;
|
||||
}
|
||||
else if (this.use_layers) {
|
||||
var d = document.layers[this.divName];
|
||||
d.document.open();
|
||||
d.document.writeln(this.contents);
|
||||
d.document.close();
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (this.popupWindow != null && !this.popupWindow.closed) {
|
||||
if (this.url!="") {
|
||||
this.popupWindow.location.href=this.url;
|
||||
}
|
||||
else {
|
||||
this.popupWindow.document.open();
|
||||
this.popupWindow.document.writeln(this.contents);
|
||||
this.popupWindow.document.close();
|
||||
}
|
||||
this.popupWindow.focus();
|
||||
}
|
||||
}
|
||||
}
|
||||
// Position and show the popup, relative to an anchor object
|
||||
function PopupWindow_showPopup(anchorname) {
|
||||
this.getXYPosition(anchorname);
|
||||
this.x += this.offsetX;
|
||||
this.y += this.offsetY;
|
||||
if (!this.populated && (this.contents != "")) {
|
||||
this.populated = true;
|
||||
this.refresh();
|
||||
}
|
||||
if (this.divName != null) {
|
||||
// Show the DIV object
|
||||
if (this.use_gebi) {
|
||||
document.getElementById(this.divName).style.left = this.x + "px";
|
||||
document.getElementById(this.divName).style.top = this.y;
|
||||
document.getElementById(this.divName).style.visibility = "visible";
|
||||
}
|
||||
else if (this.use_css) {
|
||||
document.all[this.divName].style.left = this.x;
|
||||
document.all[this.divName].style.top = this.y;
|
||||
document.all[this.divName].style.visibility = "visible";
|
||||
}
|
||||
else if (this.use_layers) {
|
||||
document.layers[this.divName].left = this.x;
|
||||
document.layers[this.divName].top = this.y;
|
||||
document.layers[this.divName].visibility = "visible";
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (this.popupWindow == null || this.popupWindow.closed) {
|
||||
// If the popup window will go off-screen, move it so it doesn't
|
||||
if (this.x<0) { this.x=0; }
|
||||
if (this.y<0) { this.y=0; }
|
||||
if (screen && screen.availHeight) {
|
||||
if ((this.y + this.height) > screen.availHeight) {
|
||||
this.y = screen.availHeight - this.height;
|
||||
}
|
||||
}
|
||||
if (screen && screen.availWidth) {
|
||||
if ((this.x + this.width) > screen.availWidth) {
|
||||
this.x = screen.availWidth - this.width;
|
||||
}
|
||||
}
|
||||
var avoidAboutBlank = window.opera || ( document.layers && !navigator.mimeTypes['*'] ) || navigator.vendor == 'KDE' || ( document.childNodes && !document.all && !navigator.taintEnabled );
|
||||
this.popupWindow = window.open(avoidAboutBlank?"":"about:blank","window_"+anchorname,this.windowProperties+",width="+this.width+",height="+this.height+",screenX="+this.x+",left="+this.x+",screenY="+this.y+",top="+this.y+"");
|
||||
}
|
||||
this.refresh();
|
||||
}
|
||||
}
|
||||
// Hide the popup
|
||||
function PopupWindow_hidePopup() {
|
||||
if (this.divName != null) {
|
||||
if (this.use_gebi) {
|
||||
document.getElementById(this.divName).style.visibility = "hidden";
|
||||
}
|
||||
else if (this.use_css) {
|
||||
document.all[this.divName].style.visibility = "hidden";
|
||||
}
|
||||
else if (this.use_layers) {
|
||||
document.layers[this.divName].visibility = "hidden";
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (this.popupWindow && !this.popupWindow.closed) {
|
||||
this.popupWindow.close();
|
||||
this.popupWindow = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Pass an event and return whether or not it was the popup DIV that was clicked
|
||||
function PopupWindow_isClicked(e) {
|
||||
if (this.divName != null) {
|
||||
if (this.use_layers) {
|
||||
var clickX = e.pageX;
|
||||
var clickY = e.pageY;
|
||||
var t = document.layers[this.divName];
|
||||
if ((clickX > t.left) && (clickX < t.left+t.clip.width) && (clickY > t.top) && (clickY < t.top+t.clip.height)) {
|
||||
return true;
|
||||
}
|
||||
else { return false; }
|
||||
}
|
||||
else if (document.all) { // Need to hard-code this to trap IE for error-handling
|
||||
var t = window.event.srcElement;
|
||||
while (t.parentElement != null) {
|
||||
if (t.id==this.divName) {
|
||||
return true;
|
||||
}
|
||||
t = t.parentElement;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else if (this.use_gebi && e) {
|
||||
var t = e.originalTarget;
|
||||
while (t.parentNode != null) {
|
||||
if (t.id==this.divName) {
|
||||
return true;
|
||||
}
|
||||
t = t.parentNode;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check an onMouseDown event to see if we should hide
|
||||
function PopupWindow_hideIfNotClicked(e) {
|
||||
if (this.autoHideEnabled && !this.isClicked(e)) {
|
||||
this.hidePopup();
|
||||
}
|
||||
}
|
||||
// Call this to make the DIV disable automatically when mouse is clicked outside it
|
||||
function PopupWindow_autoHide() {
|
||||
this.autoHideEnabled = true;
|
||||
}
|
||||
// This global function checks all PopupWindow objects onmouseup to see if they should be hidden
|
||||
function PopupWindow_hidePopupWindows(e) {
|
||||
for (var i=0; i<popupWindowObjects.length; i++) {
|
||||
if (popupWindowObjects[i] != null) {
|
||||
var p = popupWindowObjects[i];
|
||||
p.hideIfNotClicked(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Run this immediately to attach the event listener
|
||||
function PopupWindow_attachListener() {
|
||||
if (document.layers) {
|
||||
document.captureEvents(Event.MOUSEUP);
|
||||
}
|
||||
window.popupWindowOldEventListener = document.onmouseup;
|
||||
if (window.popupWindowOldEventListener != null) {
|
||||
document.onmouseup = new Function("window.popupWindowOldEventListener(); PopupWindow_hidePopupWindows();");
|
||||
}
|
||||
else {
|
||||
document.onmouseup = PopupWindow_hidePopupWindows;
|
||||
}
|
||||
}
|
||||
// CONSTRUCTOR for the PopupWindow object
|
||||
// Pass it a DIV name to use a DHTML popup, otherwise will default to window popup
|
||||
function PopupWindow() {
|
||||
if (!window.popupWindowIndex) { window.popupWindowIndex = 0; }
|
||||
if (!window.popupWindowObjects) { window.popupWindowObjects = new Array(); }
|
||||
if (!window.listenerAttached) {
|
||||
window.listenerAttached = true;
|
||||
PopupWindow_attachListener();
|
||||
}
|
||||
this.index = popupWindowIndex++;
|
||||
popupWindowObjects[this.index] = this;
|
||||
this.divName = null;
|
||||
this.popupWindow = null;
|
||||
this.width=0;
|
||||
this.height=0;
|
||||
this.populated = false;
|
||||
this.visible = false;
|
||||
this.autoHideEnabled = false;
|
||||
|
||||
this.contents = "";
|
||||
this.url="";
|
||||
this.windowProperties="toolbar=no,location=no,status=no,menubar=no,scrollbars=auto,resizable,alwaysRaised,dependent,titlebar=no";
|
||||
if (arguments.length>0) {
|
||||
this.type="DIV";
|
||||
this.divName = arguments[0];
|
||||
}
|
||||
else {
|
||||
this.type="WINDOW";
|
||||
}
|
||||
this.use_gebi = false;
|
||||
this.use_css = false;
|
||||
this.use_layers = false;
|
||||
if (document.getElementById) { this.use_gebi = true; }
|
||||
else if (document.all) { this.use_css = true; }
|
||||
else if (document.layers) { this.use_layers = true; }
|
||||
else { this.type = "WINDOW"; }
|
||||
this.offsetX = 0;
|
||||
this.offsetY = 0;
|
||||
// Method mappings
|
||||
this.getXYPosition = PopupWindow_getXYPosition;
|
||||
this.populate = PopupWindow_populate;
|
||||
this.setUrl = PopupWindow_setUrl;
|
||||
this.setWindowProperties = PopupWindow_setWindowProperties;
|
||||
this.refresh = PopupWindow_refresh;
|
||||
this.showPopup = PopupWindow_showPopup;
|
||||
this.hidePopup = PopupWindow_hidePopup;
|
||||
this.setSize = PopupWindow_setSize;
|
||||
this.isClicked = PopupWindow_isClicked;
|
||||
this.autoHide = PopupWindow_autoHide;
|
||||
this.hideIfNotClicked = PopupWindow_hideIfNotClicked;
|
||||
}
|
||||
|
||||
/* SOURCE FILE: ColorPicker2.js */
|
||||
|
||||
/*
|
||||
Last modified: 02/24/2003
|
||||
|
||||
DESCRIPTION: This widget is used to select a color, in hexadecimal #RRGGBB
|
||||
form. It uses a color "swatch" to display the standard 216-color web-safe
|
||||
palette. The user can then click on a color to select it.
|
||||
|
||||
COMPATABILITY: See notes in AnchorPosition.js and PopupWindow.js.
|
||||
Only the latest DHTML-capable browsers will show the color and hex values
|
||||
at the bottom as your mouse goes over them.
|
||||
|
||||
USAGE:
|
||||
// Create a new ColorPicker object using DHTML popup
|
||||
var cp = new ColorPicker();
|
||||
|
||||
// Create a new ColorPicker object using Window Popup
|
||||
var cp = new ColorPicker('window');
|
||||
|
||||
// Add a link in your page to trigger the popup. For example:
|
||||
<A HREF="#" onClick="cp.show('pick');return false;" NAME="pick" ID="pick">Pick</A>
|
||||
|
||||
// Or use the built-in "select" function to do the dirty work for you:
|
||||
<A HREF="#" onClick="cp.select(document.forms[0].color,'pick');return false;" NAME="pick" ID="pick">Pick</A>
|
||||
|
||||
// If using DHTML popup, write out the required DIV tag near the bottom
|
||||
// of your page.
|
||||
<SCRIPT LANGUAGE="JavaScript">cp.writeDiv()</SCRIPT>
|
||||
|
||||
// Write the 'pickColor' function that will be called when the user clicks
|
||||
// a color and do something with the value. This is only required if you
|
||||
// want to do something other than simply populate a form field, which is
|
||||
// what the 'select' function will give you.
|
||||
function pickColor(color) {
|
||||
field.value = color;
|
||||
}
|
||||
|
||||
NOTES:
|
||||
1) Requires the functions in AnchorPosition.js and PopupWindow.js
|
||||
|
||||
2) Your anchor tag MUST contain both NAME and ID attributes which are the
|
||||
same. For example:
|
||||
<A NAME="test" ID="test"> </A>
|
||||
|
||||
3) There must be at least a space between <A> </A> for IE5.5 to see the
|
||||
anchor tag correctly. Do not do <A></A> with no space.
|
||||
|
||||
4) When a ColorPicker object is created, a handler for 'onmouseup' is
|
||||
attached to any event handler you may have already defined. Do NOT define
|
||||
an event handler for 'onmouseup' after you define a ColorPicker object or
|
||||
the color picker will not hide itself correctly.
|
||||
*/
|
||||
ColorPicker_targetInput = null;
|
||||
function ColorPicker_writeDiv() {
|
||||
document.writeln("<DIV ID=\"colorPickerDiv\" STYLE=\"position:absolute;visibility:hidden;\"> </DIV>");
|
||||
}
|
||||
|
||||
function ColorPicker_show(anchorname) {
|
||||
this.showPopup(anchorname);
|
||||
}
|
||||
|
||||
function ColorPicker_pickColor(color,obj) {
|
||||
obj.hidePopup();
|
||||
pickColor(color);
|
||||
}
|
||||
|
||||
// A Default "pickColor" function to accept the color passed back from popup.
|
||||
// User can over-ride this with their own function.
|
||||
function pickColor(color) {
|
||||
if (ColorPicker_targetInput==null) {
|
||||
alert("Target Input is null, which means you either didn't use the 'select' function or you have no defined your own 'pickColor' function to handle the picked color!");
|
||||
return;
|
||||
}
|
||||
ColorPicker_targetInput.value = color;
|
||||
}
|
||||
|
||||
// This function is the easiest way to popup the window, select a color, and
|
||||
// have the value populate a form field, which is what most people want to do.
|
||||
function ColorPicker_select(inputobj,linkname) {
|
||||
if (inputobj.type!="text" && inputobj.type!="hidden" && inputobj.type!="textarea") {
|
||||
alert("colorpicker.select: Input object passed is not a valid form input object");
|
||||
window.ColorPicker_targetInput=null;
|
||||
return;
|
||||
}
|
||||
window.ColorPicker_targetInput = inputobj;
|
||||
this.show(linkname);
|
||||
}
|
||||
|
||||
// This function runs when you move your mouse over a color block, if you have a newer browser
|
||||
function ColorPicker_highlightColor(c) {
|
||||
var thedoc = (arguments.length>1)?arguments[1]:window.document;
|
||||
var d = thedoc.getElementById("colorPickerSelectedColor");
|
||||
d.style.backgroundColor = c;
|
||||
d = thedoc.getElementById("colorPickerSelectedColorValue");
|
||||
d.innerHTML = c;
|
||||
}
|
||||
|
||||
function ColorPicker() {
|
||||
var windowMode = false;
|
||||
// Create a new PopupWindow object
|
||||
if (arguments.length==0) {
|
||||
var divname = "colorPickerDiv";
|
||||
}
|
||||
else if (arguments[0] == "window") {
|
||||
var divname = '';
|
||||
windowMode = true;
|
||||
}
|
||||
else {
|
||||
var divname = arguments[0];
|
||||
}
|
||||
|
||||
if (divname != "") {
|
||||
var cp = new PopupWindow(divname);
|
||||
}
|
||||
else {
|
||||
var cp = new PopupWindow();
|
||||
cp.setSize(225,250);
|
||||
}
|
||||
|
||||
// Object variables
|
||||
cp.currentValue = "#FFFFFF";
|
||||
|
||||
// Method Mappings
|
||||
cp.writeDiv = ColorPicker_writeDiv;
|
||||
cp.highlightColor = ColorPicker_highlightColor;
|
||||
cp.show = ColorPicker_show;
|
||||
cp.select = ColorPicker_select;
|
||||
|
||||
// Code to populate color picker window
|
||||
var colors = new Array( "#4180B6","#69AEE7","#000000","#000033","#000066","#000099","#0000CC","#0000FF","#330000","#330033","#330066","#330099",
|
||||
"#3300CC","#3300FF","#660000","#660033","#660066","#660099","#6600CC","#6600FF","#990000","#990033","#990066","#990099",
|
||||
"#9900CC","#9900FF","#CC0000","#CC0033","#CC0066","#CC0099","#CC00CC","#CC00FF","#FF0000","#FF0033","#FF0066","#FF0099",
|
||||
"#FF00CC","#FF00FF","#7FFFFF","#7FFFFF","#7FF7F7","#7FEFEF","#7FE7E7","#7FDFDF","#7FD7D7","#7FCFCF","#7FC7C7","#7FBFBF",
|
||||
"#7FB7B7","#7FAFAF","#7FA7A7","#7F9F9F","#7F9797","#7F8F8F","#7F8787","#7F7F7F","#7F7777","#7F6F6F","#7F6767","#7F5F5F",
|
||||
"#7F5757","#7F4F4F","#7F4747","#7F3F3F","#7F3737","#7F2F2F","#7F2727","#7F1F1F","#7F1717","#7F0F0F","#7F0707","#7F0000",
|
||||
|
||||
"#4180B6","#69AEE7","#003300","#003333","#003366","#003399","#0033CC","#0033FF","#333300","#333333","#333366","#333399",
|
||||
"#3333CC","#3333FF","#663300","#663333","#663366","#663399","#6633CC","#6633FF","#993300","#993333","#993366","#993399",
|
||||
"#9933CC","#9933FF","#CC3300","#CC3333","#CC3366","#CC3399","#CC33CC","#CC33FF","#FF3300","#FF3333","#FF3366","#FF3399",
|
||||
"#FF33CC","#FF33FF","#FF7FFF","#FF7FFF","#F77FF7","#EF7FEF","#E77FE7","#DF7FDF","#D77FD7","#CF7FCF","#C77FC7","#BF7FBF",
|
||||
"#B77FB7","#AF7FAF","#A77FA7","#9F7F9F","#977F97","#8F7F8F","#877F87","#7F7F7F","#777F77","#6F7F6F","#677F67","#5F7F5F",
|
||||
"#577F57","#4F7F4F","#477F47","#3F7F3F","#377F37","#2F7F2F","#277F27","#1F7F1F","#177F17","#0F7F0F","#077F07","#007F00",
|
||||
|
||||
"#4180B6","#69AEE7","#006600","#006633","#006666","#006699","#0066CC","#0066FF","#336600","#336633","#336666","#336699",
|
||||
"#3366CC","#3366FF","#666600","#666633","#666666","#666699","#6666CC","#6666FF","#996600","#996633","#996666","#996699",
|
||||
"#9966CC","#9966FF","#CC6600","#CC6633","#CC6666","#CC6699","#CC66CC","#CC66FF","#FF6600","#FF6633","#FF6666","#FF6699",
|
||||
"#FF66CC","#FF66FF","#FFFF7F","#FFFF7F","#F7F77F","#EFEF7F","#E7E77F","#DFDF7F","#D7D77F","#CFCF7F","#C7C77F","#BFBF7F",
|
||||
"#B7B77F","#AFAF7F","#A7A77F","#9F9F7F","#97977F","#8F8F7F","#87877F","#7F7F7F","#77777F","#6F6F7F","#67677F","#5F5F7F",
|
||||
"#57577F","#4F4F7F","#47477F","#3F3F7F","#37377F","#2F2F7F","#27277F","#1F1F7F","#17177F","#0F0F7F","#07077F","#00007F",
|
||||
|
||||
"#4180B6","#69AEE7","#009900","#009933","#009966","#009999","#0099CC","#0099FF","#339900","#339933","#339966","#339999",
|
||||
"#3399CC","#3399FF","#669900","#669933","#669966","#669999","#6699CC","#6699FF","#999900","#999933","#999966","#999999",
|
||||
"#9999CC","#9999FF","#CC9900","#CC9933","#CC9966","#CC9999","#CC99CC","#CC99FF","#FF9900","#FF9933","#FF9966","#FF9999",
|
||||
"#FF99CC","#FF99FF","#3FFFFF","#3FFFFF","#3FF7F7","#3FEFEF","#3FE7E7","#3FDFDF","#3FD7D7","#3FCFCF","#3FC7C7","#3FBFBF",
|
||||
"#3FB7B7","#3FAFAF","#3FA7A7","#3F9F9F","#3F9797","#3F8F8F","#3F8787","#3F7F7F","#3F7777","#3F6F6F","#3F6767","#3F5F5F",
|
||||
"#3F5757","#3F4F4F","#3F4747","#3F3F3F","#3F3737","#3F2F2F","#3F2727","#3F1F1F","#3F1717","#3F0F0F","#3F0707","#3F0000",
|
||||
|
||||
"#4180B6","#69AEE7","#00CC00","#00CC33","#00CC66","#00CC99","#00CCCC","#00CCFF","#33CC00","#33CC33","#33CC66","#33CC99",
|
||||
"#33CCCC","#33CCFF","#66CC00","#66CC33","#66CC66","#66CC99","#66CCCC","#66CCFF","#99CC00","#99CC33","#99CC66","#99CC99",
|
||||
"#99CCCC","#99CCFF","#CCCC00","#CCCC33","#CCCC66","#CCCC99","#CCCCCC","#CCCCFF","#FFCC00","#FFCC33","#FFCC66","#FFCC99",
|
||||
"#FFCCCC","#FFCCFF","#FF3FFF","#FF3FFF","#F73FF7","#EF3FEF","#E73FE7","#DF3FDF","#D73FD7","#CF3FCF","#C73FC7","#BF3FBF",
|
||||
"#B73FB7","#AF3FAF","#A73FA7","#9F3F9F","#973F97","#8F3F8F","#873F87","#7F3F7F","#773F77","#6F3F6F","#673F67","#5F3F5F",
|
||||
"#573F57","#4F3F4F","#473F47","#3F3F3F","#373F37","#2F3F2F","#273F27","#1F3F1F","#173F17","#0F3F0F","#073F07","#003F00",
|
||||
|
||||
"#4180B6","#69AEE7","#00FF00","#00FF33","#00FF66","#00FF99","#00FFCC","#00FFFF","#33FF00","#33FF33","#33FF66","#33FF99",
|
||||
"#33FFCC","#33FFFF","#66FF00","#66FF33","#66FF66","#66FF99","#66FFCC","#66FFFF","#99FF00","#99FF33","#99FF66","#99FF99",
|
||||
"#99FFCC","#99FFFF","#CCFF00","#CCFF33","#CCFF66","#CCFF99","#CCFFCC","#CCFFFF","#FFFF00","#FFFF33","#FFFF66","#FFFF99",
|
||||
"#FFFFCC","#FFFFFF","#FFFF3F","#FFFF3F","#F7F73F","#EFEF3F","#E7E73F","#DFDF3F","#D7D73F","#CFCF3F","#C7C73F","#BFBF3F",
|
||||
"#B7B73F","#AFAF3F","#A7A73F","#9F9F3F","#97973F","#8F8F3F","#87873F","#7F7F3F","#77773F","#6F6F3F","#67673F","#5F5F3F",
|
||||
"#57573F","#4F4F3F","#47473F","#3F3F3F","#37373F","#2F2F3F","#27273F","#1F1F3F","#17173F","#0F0F3F","#07073F","#00003F",
|
||||
|
||||
"#4180B6","#69AEE7","#FFFFFF","#FFEEEE","#FFDDDD","#FFCCCC","#FFBBBB","#FFAAAA","#FF9999","#FF8888","#FF7777","#FF6666",
|
||||
"#FF5555","#FF4444","#FF3333","#FF2222","#FF1111","#FF0000","#FF0000","#FF0000","#FF0000","#EE0000","#DD0000","#CC0000",
|
||||
"#BB0000","#AA0000","#990000","#880000","#770000","#660000","#550000","#440000","#330000","#220000","#110000","#000000",
|
||||
"#000000","#000000","#000000","#001111","#002222","#003333","#004444","#005555","#006666","#007777","#008888","#009999",
|
||||
"#00AAAA","#00BBBB","#00CCCC","#00DDDD","#00EEEE","#00FFFF","#00FFFF","#00FFFF","#00FFFF","#11FFFF","#22FFFF","#33FFFF",
|
||||
"#44FFFF","#55FFFF","#66FFFF","#77FFFF","#88FFFF","#99FFFF","#AAFFFF","#BBFFFF","#CCFFFF","#DDFFFF","#EEFFFF","#FFFFFF",
|
||||
|
||||
"#4180B6","#69AEE7","#FFFFFF","#EEFFEE","#DDFFDD","#CCFFCC","#BBFFBB","#AAFFAA","#99FF99","#88FF88","#77FF77","#66FF66",
|
||||
"#55FF55","#44FF44","#33FF33","#22FF22","#11FF11","#00FF00","#00FF00","#00FF00","#00FF00","#00EE00","#00DD00","#00CC00",
|
||||
"#00BB00","#00AA00","#009900","#008800","#007700","#006600","#005500","#004400","#003300","#002200","#001100","#000000",
|
||||
"#000000","#000000","#000000","#110011","#220022","#330033","#440044","#550055","#660066","#770077","#880088","#990099",
|
||||
"#AA00AA","#BB00BB","#CC00CC","#DD00DD","#EE00EE","#FF00FF","#FF00FF","#FF00FF","#FF00FF","#FF11FF","#FF22FF","#FF33FF",
|
||||
"#FF44FF","#FF55FF","#FF66FF","#FF77FF","#FF88FF","#FF99FF","#FFAAFF","#FFBBFF","#FFCCFF","#FFDDFF","#FFEEFF","#FFFFFF",
|
||||
|
||||
"#4180B6","#69AEE7","#FFFFFF","#EEEEFF","#DDDDFF","#CCCCFF","#BBBBFF","#AAAAFF","#9999FF","#8888FF","#7777FF","#6666FF",
|
||||
"#5555FF","#4444FF","#3333FF","#2222FF","#1111FF","#0000FF","#0000FF","#0000FF","#0000FF","#0000EE","#0000DD","#0000CC",
|
||||
"#0000BB","#0000AA","#000099","#000088","#000077","#000066","#000055","#000044","#000033","#000022","#000011","#000000",
|
||||
"#000000","#000000","#000000","#111100","#222200","#333300","#444400","#555500","#666600","#777700","#888800","#999900",
|
||||
"#AAAA00","#BBBB00","#CCCC00","#DDDD00","#EEEE00","#FFFF00","#FFFF00","#FFFF00","#FFFF00","#FFFF11","#FFFF22","#FFFF33",
|
||||
"#FFFF44","#FFFF55","#FFFF66","#FFFF77","#FFFF88","#FFFF99","#FFFFAA","#FFFFBB","#FFFFCC","#FFFFDD","#FFFFEE","#FFFFFF",
|
||||
|
||||
"#4180B6","#69AEE7","#FFFFFF","#FFFFFF","#FBFBFB","#F7F7F7","#F3F3F3","#EFEFEF","#EBEBEB","#E7E7E7","#E3E3E3","#DFDFDF",
|
||||
"#DBDBDB","#D7D7D7","#D3D3D3","#CFCFCF","#CBCBCB","#C7C7C7","#C3C3C3","#BFBFBF","#BBBBBB","#B7B7B7","#B3B3B3","#AFAFAF",
|
||||
"#ABABAB","#A7A7A7","#A3A3A3","#9F9F9F","#9B9B9B","#979797","#939393","#8F8F8F","#8B8B8B","#878787","#838383","#7F7F7F",
|
||||
"#7B7B7B","#777777","#737373","#6F6F6F","#6B6B6B","#676767","#636363","#5F5F5F","#5B5B5B","#575757","#535353","#4F4F4F",
|
||||
"#4B4B4B","#474747","#434343","#3F3F3F","#3B3B3B","#373737","#333333","#2F2F2F","#2B2B2B","#272727","#232323","#1F1F1F",
|
||||
"#1B1B1B","#171717","#131313","#0F0F0F","#0B0B0B","#070707","#030303","#000000","#000000","#000000","#000000","#000000");
|
||||
var total = colors.length;
|
||||
var width = 72;
|
||||
var cp_contents = "";
|
||||
var windowRef = (windowMode)?"window.opener.":"";
|
||||
if (windowMode) {
|
||||
cp_contents += "<html><head><title>Select Color</title></head>";
|
||||
cp_contents += "<body marginwidth=0 marginheight=0 leftmargin=0 topmargin=0><span style='text-align: center;'>";
|
||||
}
|
||||
cp_contents += "<table style='border: none;' cellspacing=0 cellpadding=0>";
|
||||
var use_highlight = (document.getElementById || document.all)?true:false;
|
||||
for (var i=0; i<total; i++) {
|
||||
if ((i % width) == 0) { cp_contents += "<tr>"; }
|
||||
if (use_highlight) { var mo = 'onMouseOver="'+windowRef+'ColorPicker_highlightColor(\''+colors[i]+'\',window.document)"'; }
|
||||
else { mo = ""; }
|
||||
cp_contents += '<td style="background-color: '+colors[i]+';"><a href="javascript:void()" onclick="'+windowRef+'ColorPicker_pickColor(\''+colors[i]+'\','+windowRef+'window.popupWindowObjects['+cp.index+']);return false;" '+mo+'> </a></td>';
|
||||
if ( ((i+1)>=total) || (((i+1) % width) == 0)) {
|
||||
cp_contents += "</tr>";
|
||||
}
|
||||
}
|
||||
// If the browser supports dynamically changing TD cells, add the fancy stuff
|
||||
if (document.getElementById) {
|
||||
var width1 = Math.floor(width/2);
|
||||
var width2 = width = width1;
|
||||
cp_contents += "<tr><td colspan='"+width1+"' style='background-color: #FFF;' ID='colorPickerSelectedColor'> </td><td colspan='"+width2+"' style='text-align: center;' id='colorPickerSelectedColorValue'>#FFFFFF</td></tr>";
|
||||
}
|
||||
cp_contents += "</table>";
|
||||
if (windowMode) {
|
||||
cp_contents += "</span></body></html>";
|
||||
}
|
||||
// end populate code
|
||||
|
||||
// Write the contents to the popup object
|
||||
cp.populate(cp_contents+"\n");
|
||||
// Move the table down a bit so you can see it
|
||||
cp.offsetY = 25;
|
||||
cp.autoHide();
|
||||
return cp;
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
.imgCrop_wrap {
|
||||
/* width: 500px; @done_in_js */
|
||||
/* height: 375px; @done_in_js */
|
||||
position: relative;
|
||||
cursor: crosshair;
|
||||
}
|
||||
|
||||
/* an extra classname is applied for Opera < 9.0 to fix its lack of opacity support */
|
||||
.imgCrop_wrap.opera8 .imgCrop_overlay,
|
||||
.imgCrop_wrap.opera8 .imgCrop_clickArea {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
/* fix for IE displaying all boxes at line-height by default, although they are still 1 pixel high until we combine them with the pointless span */
|
||||
.imgCrop_wrap,
|
||||
.imgCrop_wrap * {
|
||||
font-size: 0;
|
||||
}
|
||||
|
||||
.imgCrop_overlay {
|
||||
background-color: #000;
|
||||
opacity: 0.5;
|
||||
filter:alpha(opacity=50);
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.imgCrop_selArea {
|
||||
position: absolute;
|
||||
/* @done_in_js
|
||||
top: 20px;
|
||||
left: 20px;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
background: transparent url(castle.jpg) no-repeat -210px -110px;
|
||||
*/
|
||||
cursor: move;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
/* clickArea is all a fix for IE 5.5 & 6 to allow the user to click on the given area */
|
||||
.imgCrop_clickArea {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #FFF;
|
||||
opacity: 0.01;
|
||||
filter:alpha(opacity=01);
|
||||
}
|
||||
|
||||
.imgCrop_marqueeHoriz {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
background: transparent url(marqueeHoriz.gif) repeat-x 0 0;
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
.imgCrop_marqueeVert {
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 1px;
|
||||
background: transparent url(marqueeVert.gif) repeat-y 0 0;
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
.imgCrop_marqueeNorth { top: 0; left: 0; }
|
||||
.imgCrop_marqueeEast { top: 0; right: 0; }
|
||||
.imgCrop_marqueeSouth { bottom: 0px; left: 0; }
|
||||
.imgCrop_marqueeWest { top: 0; left: 0; }
|
||||
|
||||
|
||||
.imgCrop_handle {
|
||||
position: absolute;
|
||||
border: 1px solid #333;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
background: #FFF;
|
||||
opacity: 0.5;
|
||||
filter:alpha(opacity=50);
|
||||
z-index: 4;
|
||||
}
|
||||
|
||||
/* fix IE 5 box model */
|
||||
* html .imgCrop_handle {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
wid\th: 6px;
|
||||
hei\ght: 6px;
|
||||
}
|
||||
|
||||
.imgCrop_handleN {
|
||||
top: -3px;
|
||||
left: 0;
|
||||
/* margin-left: 49%; @done_in_js */
|
||||
cursor: n-resize;
|
||||
}
|
||||
|
||||
.imgCrop_handleNE {
|
||||
top: -3px;
|
||||
right: -3px;
|
||||
cursor: ne-resize;
|
||||
}
|
||||
|
||||
.imgCrop_handleE {
|
||||
top: 0;
|
||||
right: -3px;
|
||||
/* margin-top: 49%; @done_in_js */
|
||||
cursor: e-resize;
|
||||
}
|
||||
|
||||
.imgCrop_handleSE {
|
||||
right: -3px;
|
||||
bottom: -3px;
|
||||
cursor: se-resize;
|
||||
}
|
||||
|
||||
.imgCrop_handleS {
|
||||
right: 0;
|
||||
bottom: -3px;
|
||||
/* margin-right: 49%; @done_in_js */
|
||||
cursor: s-resize;
|
||||
}
|
||||
|
||||
.imgCrop_handleSW {
|
||||
left: -3px;
|
||||
bottom: -3px;
|
||||
cursor: sw-resize;
|
||||
}
|
||||
|
||||
.imgCrop_handleW {
|
||||
top: 0;
|
||||
left: -3px;
|
||||
/* margin-top: 49%; @done_in_js */
|
||||
cursor: e-resize;
|
||||
}
|
||||
|
||||
.imgCrop_handleNW {
|
||||
top: -3px;
|
||||
left: -3px;
|
||||
cursor: nw-resize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an area to click & drag around on as the default browser behaviour is to let you drag the image
|
||||
*/
|
||||
.imgCrop_dragArea {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 200;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.imgCrop_previewWrap {
|
||||
/* width: 200px; @done_in_js */
|
||||
/* height: 200px; @done_in_js */
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.imgCrop_previewWrap img {
|
||||
position: absolute;
|
||||
}
|
||||
@@ -0,0 +1,516 @@
|
||||
/**
|
||||
* Copyright (c) 2006, David Spurr (http://www.defusion.org.uk/)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the David Spurr nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
*
|
||||
* See scriptaculous.js for full scriptaculous licence
|
||||
*/
|
||||
|
||||
var CropDraggable=Class.create();
|
||||
Object.extend(Object.extend(CropDraggable.prototype,Draggable.prototype),{initialize:function(_1){
|
||||
this.options=Object.extend({drawMethod:function(){
|
||||
}},arguments[1]||{});
|
||||
this.element=$(_1);
|
||||
this.handle=this.element;
|
||||
this.delta=this.currentDelta();
|
||||
this.dragging=false;
|
||||
this.eventMouseDown=this.initDrag.bindAsEventListener(this);
|
||||
Event.observe(this.handle,"mousedown",this.eventMouseDown);
|
||||
Draggables.register(this);
|
||||
},draw:function(_2){
|
||||
var _3=Position.cumulativeOffset(this.element);
|
||||
var d=this.currentDelta();
|
||||
_3[0]-=d[0];
|
||||
_3[1]-=d[1];
|
||||
var p=[0,1].map(function(i){
|
||||
return (_2[i]-_3[i]-this.offset[i]);
|
||||
}.bind(this));
|
||||
this.options.drawMethod(p);
|
||||
}});
|
||||
var Cropper={};
|
||||
Cropper.Img=Class.create();
|
||||
Cropper.Img.prototype={initialize:function(_7,_8){
|
||||
this.options=Object.extend({ratioDim:{x:0,y:0},minWidth:0,minHeight:0,displayOnInit:false,onEndCrop:Prototype.emptyFunction,captureKeys:true},_8||{});
|
||||
if(this.options.minWidth>0&&this.options.minHeight>0){
|
||||
this.options.ratioDim.x=this.options.minWidth;
|
||||
this.options.ratioDim.y=this.options.minHeight;
|
||||
}
|
||||
this.img=$(_7);
|
||||
this.clickCoords={x:0,y:0};
|
||||
this.dragging=false;
|
||||
this.resizing=false;
|
||||
this.isWebKit=/Konqueror|Safari|KHTML/.test(navigator.userAgent);
|
||||
this.isIE=/MSIE/.test(navigator.userAgent);
|
||||
this.isOpera8=/Opera\s[1-8]/.test(navigator.userAgent);
|
||||
this.ratioX=0;
|
||||
this.ratioY=0;
|
||||
this.attached=false;
|
||||
$A(document.getElementsByTagName("script")).each(function(s){
|
||||
if(s.src.match(/cropper\.js/)){
|
||||
var _a=s.src.replace(/cropper\.js(.*)?/,"");
|
||||
var _b=document.createElement("link");
|
||||
_b.rel="stylesheet";
|
||||
_b.type="text/css";
|
||||
_b.href=_a+"cropper.css";
|
||||
_b.media="screen";
|
||||
document.getElementsByTagName("head")[0].appendChild(_b);
|
||||
}
|
||||
});
|
||||
if(this.options.ratioDim.x>0&&this.options.ratioDim.y>0){
|
||||
var _c=this.getGCD(this.options.ratioDim.x,this.options.ratioDim.y);
|
||||
this.ratioX=this.options.ratioDim.x/_c;
|
||||
this.ratioY=this.options.ratioDim.y/_c;
|
||||
}
|
||||
this.subInitialize();
|
||||
if(this.img.complete||this.isWebKit){
|
||||
this.onLoad();
|
||||
}else{
|
||||
Event.observe(this.img,"load",this.onLoad.bindAsEventListener(this));
|
||||
}
|
||||
},getGCD:function(a,b){return 1;
|
||||
if(b==0){
|
||||
return a;
|
||||
}
|
||||
return this.getGCD(b,a%b);
|
||||
},onLoad:function(){
|
||||
var _f="imgCrop_";
|
||||
var _10=this.img.parentNode;
|
||||
var _11="";
|
||||
if(this.isOpera8){
|
||||
_11=" opera8";
|
||||
}
|
||||
this.imgWrap=Builder.node("div",{"class":_f+"wrap"+_11});
|
||||
if(this.isIE){
|
||||
this.north=Builder.node("div",{"class":_f+"overlay "+_f+"north"},[Builder.node("span")]);
|
||||
this.east=Builder.node("div",{"class":_f+"overlay "+_f+"east"},[Builder.node("span")]);
|
||||
this.south=Builder.node("div",{"class":_f+"overlay "+_f+"south"},[Builder.node("span")]);
|
||||
this.west=Builder.node("div",{"class":_f+"overlay "+_f+"west"},[Builder.node("span")]);
|
||||
var _12=[this.north,this.east,this.south,this.west];
|
||||
}else{
|
||||
this.overlay=Builder.node("div",{"class":_f+"overlay"});
|
||||
var _12=[this.overlay];
|
||||
}
|
||||
this.dragArea=Builder.node("div",{"class":_f+"dragArea"},_12);
|
||||
this.handleN=Builder.node("div",{"class":_f+"handle "+_f+"handleN"});
|
||||
this.handleNE=Builder.node("div",{"class":_f+"handle "+_f+"handleNE"});
|
||||
this.handleE=Builder.node("div",{"class":_f+"handle "+_f+"handleE"});
|
||||
this.handleSE=Builder.node("div",{"class":_f+"handle "+_f+"handleSE"});
|
||||
this.handleS=Builder.node("div",{"class":_f+"handle "+_f+"handleS"});
|
||||
this.handleSW=Builder.node("div",{"class":_f+"handle "+_f+"handleSW"});
|
||||
this.handleW=Builder.node("div",{"class":_f+"handle "+_f+"handleW"});
|
||||
this.handleNW=Builder.node("div",{"class":_f+"handle "+_f+"handleNW"});
|
||||
this.selArea=Builder.node("div",{"class":_f+"selArea"},[Builder.node("div",{"class":_f+"marqueeHoriz "+_f+"marqueeNorth"},[Builder.node("span")]),Builder.node("div",{"class":_f+"marqueeVert "+_f+"marqueeEast"},[Builder.node("span")]),Builder.node("div",{"class":_f+"marqueeHoriz "+_f+"marqueeSouth"},[Builder.node("span")]),Builder.node("div",{"class":_f+"marqueeVert "+_f+"marqueeWest"},[Builder.node("span")]),this.handleN,this.handleNE,this.handleE,this.handleSE,this.handleS,this.handleSW,this.handleW,this.handleNW,Builder.node("div",{"class":_f+"clickArea"})]);
|
||||
Element.setStyle($(this.selArea),{backgroundColor:"transparent",backgroundRepeat:"no-repeat",backgroundPosition:"0 0"});
|
||||
this.imgWrap.appendChild(this.img);
|
||||
this.imgWrap.appendChild(this.dragArea);
|
||||
this.dragArea.appendChild(this.selArea);
|
||||
this.dragArea.appendChild(Builder.node("div",{"class":_f+"clickArea"}));
|
||||
_10.appendChild(this.imgWrap);
|
||||
Event.observe(this.dragArea,"mousedown",this.startDrag.bindAsEventListener(this));
|
||||
Event.observe(document,"mousemove",this.onDrag.bindAsEventListener(this));
|
||||
Event.observe(document,"mouseup",this.endCrop.bindAsEventListener(this));
|
||||
var _13=[this.handleN,this.handleNE,this.handleE,this.handleSE,this.handleS,this.handleSW,this.handleW,this.handleNW];
|
||||
for(var i=0;i<_13.length;i++){
|
||||
Event.observe(_13[i],"mousedown",this.startResize.bindAsEventListener(this));
|
||||
}
|
||||
if(this.options.captureKeys){
|
||||
Event.observe(document,"keydown",this.handleKeys.bindAsEventListener(this));
|
||||
}
|
||||
new CropDraggable(this.selArea,{drawMethod:this.moveArea.bindAsEventListener(this)});
|
||||
this.setParams();
|
||||
},setParams:function(){
|
||||
this.imgW=this.img.width;
|
||||
this.imgH=this.img.height;
|
||||
if(!this.isIE){
|
||||
Element.setStyle($(this.overlay),{width:this.imgW+"px",height:this.imgH+"px"});
|
||||
Element.hide($(this.overlay));
|
||||
Element.setStyle($(this.selArea),{backgroundImage:"url("+this.img.src+")"});
|
||||
}else{
|
||||
Element.setStyle($(this.north),{height:0});
|
||||
Element.setStyle($(this.east),{width:0,height:0});
|
||||
Element.setStyle($(this.south),{height:0});
|
||||
Element.setStyle($(this.west),{width:0,height:0});
|
||||
}
|
||||
Element.setStyle($(this.imgWrap),{"width":this.imgW+"px","height":this.imgH+"px"});
|
||||
Element.hide($(this.selArea));
|
||||
var _15=Position.positionedOffset(this.imgWrap);
|
||||
this.wrapOffsets={"top":_15[1],"left":_15[0]};
|
||||
var _16={x1:0,y1:0,x2:0,y2:0};
|
||||
this.setAreaCoords(_16);
|
||||
if(this.options.ratioDim.x>0&&this.options.ratioDim.y>0&&this.options.displayOnInit){
|
||||
_16.x1=Math.ceil((this.imgW-this.options.ratioDim.x)/2);
|
||||
_16.y1=Math.ceil((this.imgH-this.options.ratioDim.y)/2);
|
||||
_16.x2=_16.x1+this.options.ratioDim.x;
|
||||
_16.y2=_16.y1+this.options.ratioDim.y;
|
||||
Element.show(this.selArea);
|
||||
this.drawArea();
|
||||
this.endCrop();
|
||||
}
|
||||
this.attached=true;
|
||||
},remove:function(){
|
||||
this.attached=false;
|
||||
this.imgWrap.parentNode.insertBefore(this.img,this.imgWrap);
|
||||
this.imgWrap.parentNode.removeChild(this.imgWrap);
|
||||
Event.stopObserving(this.dragArea,"mousedown",this.startDrag.bindAsEventListener(this));
|
||||
Event.stopObserving(document,"mousemove",this.onDrag.bindAsEventListener(this));
|
||||
Event.stopObserving(document,"mouseup",this.endCrop.bindAsEventListener(this));
|
||||
var _17=[this.handleN,this.handleNE,this.handleE,this.handleSE,this.handleS,this.handleSW,this.handleW,this.handleNW];
|
||||
for(var i=0;i<_17.length;i++){
|
||||
Event.stopObserving(_17[i],"mousedown",this.startResize.bindAsEventListener(this));
|
||||
}
|
||||
if(this.options.captureKeys){
|
||||
Event.stopObserving(document,"keydown",this.handleKeys.bindAsEventListener(this));
|
||||
}
|
||||
},reset:function(){
|
||||
if(!this.attached){
|
||||
this.onLoad();
|
||||
}else{
|
||||
this.setParams();
|
||||
}
|
||||
this.endCrop();
|
||||
},handleKeys:function(e){
|
||||
var dir={x:0,y:0};
|
||||
if(!this.dragging){
|
||||
switch(e.keyCode){
|
||||
case (37):
|
||||
dir.x=-1;
|
||||
break;
|
||||
case (38):
|
||||
dir.y=-1;
|
||||
break;
|
||||
case (39):
|
||||
dir.x=1;
|
||||
break;
|
||||
case (40):
|
||||
dir.y=1;
|
||||
break;
|
||||
}
|
||||
if(dir.x!=0||dir.y!=0){
|
||||
if(e.shiftKey){
|
||||
dir.x*=10;
|
||||
dir.y*=10;
|
||||
}
|
||||
this.moveArea([this.areaCoords.x1+dir.x,this.areaCoords.y1+dir.y]);
|
||||
Event.stop(e);
|
||||
}
|
||||
}
|
||||
},calcW:function(){
|
||||
return (this.areaCoords.x2-this.areaCoords.x1);
|
||||
},calcH:function(){
|
||||
return (this.areaCoords.y2-this.areaCoords.y1);
|
||||
},moveArea:function(_1b){
|
||||
this.setAreaCoords({x1:_1b[0],y1:_1b[1],x2:_1b[0]+this.calcW(),y2:_1b[1]+this.calcH()},true);
|
||||
this.drawArea();
|
||||
},cloneCoords:function(_1c){
|
||||
return {x1:_1c.x1,y1:_1c.y1,x2:_1c.x2,y2:_1c.y2};
|
||||
},setAreaCoords:function(_1d,_1e,_1f,_20,_21){
|
||||
var _22=typeof _1e!="undefined"?_1e:false;
|
||||
var _23=typeof _1f!="undefined"?_1f:false;
|
||||
if(_1e){
|
||||
var _24=_1d.x2-_1d.x1;
|
||||
var _25=_1d.y2-_1d.y1;
|
||||
if(_1d.x1<0){
|
||||
_1d.x1=0;
|
||||
_1d.x2=_24;
|
||||
}
|
||||
if(_1d.y1<0){
|
||||
_1d.y1=0;
|
||||
_1d.y2=_25;
|
||||
}
|
||||
if(_1d.x2>this.imgW){
|
||||
_1d.x2=this.imgW;
|
||||
_1d.x1=this.imgW-_24;
|
||||
}
|
||||
if(_1d.y2>this.imgH){
|
||||
_1d.y2=this.imgH;
|
||||
_1d.y1=this.imgH-_25;
|
||||
}
|
||||
}else{
|
||||
if(_1d.x1<0){
|
||||
_1d.x1=0;
|
||||
}
|
||||
if(_1d.y1<0){
|
||||
_1d.y1=0;
|
||||
}
|
||||
if(_1d.x2>this.imgW){
|
||||
_1d.x2=this.imgW;
|
||||
}
|
||||
if(_1d.y2>this.imgH){
|
||||
_1d.y2=this.imgH;
|
||||
}
|
||||
if(typeof (_20)!="undefined"){
|
||||
if(this.ratioX>0){
|
||||
this.applyRatio(_1d,{x:this.ratioX,y:this.ratioY},_20,_21);
|
||||
}else{
|
||||
if(_23){
|
||||
this.applyRatio(_1d,{x:1,y:1},_20,_21);
|
||||
}
|
||||
}
|
||||
var _26={a1:_1d.x1,a2:_1d.x2};
|
||||
var _27={a1:_1d.y1,a2:_1d.y2};
|
||||
var _28=this.options.minWidth;
|
||||
var _29=this.options.minHeight;
|
||||
if((_28==0||_29==0)&&_23){
|
||||
if(_28>0){
|
||||
_29=_28;
|
||||
}else{
|
||||
if(_29>0){
|
||||
_28=_29;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.applyMinDimension(_26,_28,_20.x,{min:0,max:this.imgW});
|
||||
this.applyMinDimension(_27,_29,_20.y,{min:0,max:this.imgH});
|
||||
_1d={x1:_26.a1,y1:_27.a1,x2:_26.a2,y2:_27.a2};
|
||||
}
|
||||
}
|
||||
this.areaCoords=_1d;
|
||||
},applyMinDimension:function(_2a,_2b,_2c,_2d){
|
||||
if((_2a.a2-_2a.a1)<_2b){
|
||||
if(_2c==1){
|
||||
_2a.a2=_2a.a1+_2b;
|
||||
}else{
|
||||
_2a.a1=_2a.a2-_2b;
|
||||
}
|
||||
if(_2a.a1<_2d.min){
|
||||
_2a.a1=_2d.min;
|
||||
_2a.a2=_2b;
|
||||
}else{
|
||||
if(_2a.a2>_2d.max){
|
||||
_2a.a1=_2d.max-_2b;
|
||||
_2a.a2=_2d.max;
|
||||
}
|
||||
}
|
||||
}
|
||||
},applyRatio:function(_2e,_2f,_30,_31){
|
||||
var _32;
|
||||
if(_31=="N"||_31=="S"){
|
||||
_32=this.applyRatioToAxis({a1:_2e.y1,b1:_2e.x1,a2:_2e.y2,b2:_2e.x2},{a:_2f.y,b:_2f.x},{a:_30.y,b:_30.x},{min:0,max:this.imgW});
|
||||
_2e.x1=_32.b1;
|
||||
_2e.y1=_32.a1;
|
||||
_2e.x2=_32.b2;
|
||||
_2e.y2=_32.a2;
|
||||
}else{
|
||||
_32=this.applyRatioToAxis({a1:_2e.x1,b1:_2e.y1,a2:_2e.x2,b2:_2e.y2},{a:_2f.x,b:_2f.y},{a:_30.x,b:_30.y},{min:0,max:this.imgH});
|
||||
_2e.x1=_32.a1;
|
||||
_2e.y1=_32.b1;
|
||||
_2e.x2=_32.a2;
|
||||
_2e.y2=_32.b2;
|
||||
}
|
||||
},applyRatioToAxis:function(_33,_34,_35,_36){
|
||||
var _37=Object.extend(_33,{});
|
||||
var _38=_37.a2-_37.a1;
|
||||
var _3a=Math.floor(_38*_34.b/_34.a);
|
||||
var _3b;
|
||||
var _3c;
|
||||
var _3d=null;
|
||||
if(_35.b==1){
|
||||
_3b=_37.b1+_3a;
|
||||
if(_3b>_36.max){
|
||||
_3b=_36.max;
|
||||
_3d=_3b-_37.b1;
|
||||
}
|
||||
_37.b2=_3b;
|
||||
}else{
|
||||
_3b=_37.b2-_3a;
|
||||
if(_3b<_36.min){
|
||||
_3b=_36.min;
|
||||
_3d=_3b+_37.b2;
|
||||
}
|
||||
_37.b1=_3b;
|
||||
}
|
||||
if(_3d!=null){
|
||||
_3c=Math.floor(_3d*_34.a/_34.b);
|
||||
if(_35.a==1){
|
||||
_37.a2=_37.a1+_3c;
|
||||
}else{
|
||||
_37.a1=_37.a1=_37.a2-_3c;
|
||||
}
|
||||
}
|
||||
return _37;
|
||||
},drawArea:function(){
|
||||
if(!this.isIE){
|
||||
Element.show($(this.overlay));
|
||||
}
|
||||
var _3e=this.calcW();
|
||||
var _3f=this.calcH();
|
||||
var _40=this.areaCoords.x2;
|
||||
var _41=this.areaCoords.y2;
|
||||
var _42=this.selArea.style;
|
||||
_42.left=this.areaCoords.x1+"px";
|
||||
_42.top=this.areaCoords.y1+"px";
|
||||
_42.width=_3e+"px";
|
||||
_42.height=_3f+"px";
|
||||
var _43=Math.ceil((_3e-6)/2)+"px";
|
||||
var _44=Math.ceil((_3f-6)/2)+"px";
|
||||
this.handleN.style.left=_43;
|
||||
this.handleE.style.top=_44;
|
||||
this.handleS.style.left=_43;
|
||||
this.handleW.style.top=_44;
|
||||
if(this.isIE){
|
||||
this.north.style.height=this.areaCoords.y1+"px";
|
||||
var _45=this.east.style;
|
||||
_45.top=this.areaCoords.y1+"px";
|
||||
_45.height=_3f+"px";
|
||||
_45.left=_40+"px";
|
||||
_45.width=(this.img.width-_40)+"px";
|
||||
var _46=this.south.style;
|
||||
_46.top=_41+"px";
|
||||
_46.height=(this.img.height-_41)+"px";
|
||||
var _47=this.west.style;
|
||||
_47.top=this.areaCoords.y1+"px";
|
||||
_47.height=_3f+"px";
|
||||
_47.width=this.areaCoords.x1+"px";
|
||||
}else{
|
||||
_42.backgroundPosition="-"+this.areaCoords.x1+"px "+"-"+this.areaCoords.y1+"px";
|
||||
}
|
||||
this.subDrawArea();
|
||||
this.forceReRender();
|
||||
},forceReRender:function(){
|
||||
if(this.isIE||this.isWebKit){
|
||||
var n=document.createTextNode(" ");
|
||||
var d,el,fixEL,i;
|
||||
if(this.isIE){
|
||||
fixEl=this.selArea;
|
||||
}else{
|
||||
if(this.isWebKit){
|
||||
fixEl=document.getElementsByClassName("imgCrop_marqueeSouth",this.imgWrap)[0];
|
||||
d=Builder.node("div","");
|
||||
d.style.visibility="hidden";
|
||||
var _4a=["SE","S","SW"];
|
||||
for(i=0;i<_4a.length;i++){
|
||||
el=document.getElementsByClassName("imgCrop_handle"+_4a[i],this.selArea)[0];
|
||||
if(el.childNodes.length){
|
||||
el.removeChild(el.childNodes[0]);
|
||||
}
|
||||
el.appendChild(d);
|
||||
}
|
||||
}
|
||||
}
|
||||
fixEl.appendChild(n);
|
||||
fixEl.removeChild(n);
|
||||
}
|
||||
},startResize:function(e){
|
||||
this.startCoords=this.cloneCoords(this.areaCoords);
|
||||
this.resizing=true;
|
||||
this.resizeHandle=Element.classNames(Event.element(e)).toString().replace(/([^N|NE|E|SE|S|SW|W|NW])+/,"");
|
||||
Event.stop(e);
|
||||
},startDrag:function(e){
|
||||
Element.show(this.selArea);
|
||||
this.clickCoords=this.getCurPos(e);
|
||||
this.setAreaCoords({x1:this.clickCoords.x,y1:this.clickCoords.y,x2:this.clickCoords.x,y2:this.clickCoords.y});
|
||||
this.dragging=true;
|
||||
this.onDrag(e);
|
||||
Event.stop(e);
|
||||
},getCurPos:function(e){
|
||||
return curPos={x:Event.pointerX(e)-this.wrapOffsets.left,y:Event.pointerY(e)-this.wrapOffsets.top};
|
||||
},onDrag:function(e){
|
||||
var _4f=null;
|
||||
if(this.dragging||this.resizing){
|
||||
var _50=this.getCurPos(e);
|
||||
var _51=this.cloneCoords(this.areaCoords);
|
||||
var _52={x:1,y:1};
|
||||
}
|
||||
if(this.dragging){
|
||||
if(_50.x<this.clickCoords.x){
|
||||
_52.x=-1;
|
||||
}
|
||||
if(_50.y<this.clickCoords.y){
|
||||
_52.y=-1;
|
||||
}
|
||||
this.transformCoords(_50.x,this.clickCoords.x,_51,"x");
|
||||
this.transformCoords(_50.y,this.clickCoords.y,_51,"y");
|
||||
}else{
|
||||
if(this.resizing){
|
||||
_4f=this.resizeHandle;
|
||||
if(_4f.match(/E/)){
|
||||
this.transformCoords(_50.x,this.startCoords.x1,_51,"x");
|
||||
if(_50.x<this.startCoords.x1){
|
||||
_52.x=-1;
|
||||
}
|
||||
}else{
|
||||
if(_4f.match(/W/)){
|
||||
this.transformCoords(_50.x,this.startCoords.x2,_51,"x");
|
||||
if(_50.x<this.startCoords.x2){
|
||||
_52.x=-1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(_4f.match(/N/)){
|
||||
this.transformCoords(_50.y,this.startCoords.y2,_51,"y");
|
||||
if(_50.y<this.startCoords.y2){
|
||||
_52.y=-1;
|
||||
}
|
||||
}else{
|
||||
if(_4f.match(/S/)){
|
||||
this.transformCoords(_50.y,this.startCoords.y1,_51,"y");
|
||||
if(_50.y<this.startCoords.y1){
|
||||
_52.y=-1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(this.dragging||this.resizing){
|
||||
this.setAreaCoords(_51,false,e.shiftKey,_52,_4f);
|
||||
this.drawArea();
|
||||
Event.stop(e);
|
||||
}
|
||||
},transformCoords:function(_53,_54,_55,_56){
|
||||
var _57=new Array();
|
||||
if(_53<_54){
|
||||
_57[0]=_53;
|
||||
_57[1]=_54;
|
||||
}else{
|
||||
_57[0]=_54;
|
||||
_57[1]=_53;
|
||||
}
|
||||
if(_56=="x"){
|
||||
_55.x1=_57[0];
|
||||
_55.x2=_57[1];
|
||||
}else{
|
||||
_55.y1=_57[0];
|
||||
_55.y2=_57[1];
|
||||
}
|
||||
},endCrop:function(){
|
||||
this.dragging=false;
|
||||
this.resizing=false;
|
||||
this.options.onEndCrop(this.areaCoords,{width:this.calcW(),height:this.calcH()});
|
||||
},subInitialize:function(){
|
||||
},subDrawArea:function(){
|
||||
}};
|
||||
Cropper.ImgWithPreview=Class.create();
|
||||
Object.extend(Object.extend(Cropper.ImgWithPreview.prototype,Cropper.Img.prototype),{subInitialize:function(){
|
||||
this.hasPreviewImg=false;
|
||||
if(typeof (this.options.previewWrap)!="undefined"&&this.options.minWidth>0&&this.options.minHeight>0){
|
||||
this.previewWrap=$(this.options.previewWrap);
|
||||
this.previewImg=this.img.cloneNode(false);
|
||||
this.options.displayOnInit=true;
|
||||
this.hasPreviewImg=true;
|
||||
Element.addClassName(this.previewWrap,"imgCrop_previewWrap");
|
||||
Element.setStyle(this.previewWrap,{width:this.options.minWidth+"px",height:this.options.minHeight+"px"});
|
||||
this.previewWrap.appendChild(this.previewImg);
|
||||
}
|
||||
},subDrawArea:function(){
|
||||
if(this.hasPreviewImg){
|
||||
var _58=this.calcW();
|
||||
var _59=this.calcH();
|
||||
var _5a={x:this.imgW/_58,y:this.imgH/_59};
|
||||
var _5b={x:_58/this.options.minWidth,y:_59/this.options.minHeight};
|
||||
var _5c={w:Math.ceil(this.options.minWidth*_5a.x)+"px",h:Math.ceil(this.options.minHeight*_5a.y)+"px",x:"-"+Math.ceil(this.areaCoords.x1/_5b.x)+"px",y:"-"+Math.ceil(this.areaCoords.y1/_5b.y)+"px"};
|
||||
var _5d=this.previewImg.style;
|
||||
_5d.width=_5c.w;
|
||||
_5d.height=_5c.h;
|
||||
_5d.left=_5c.x;
|
||||
_5d.top=_5c.y;
|
||||
}
|
||||
}});
|
||||
|
After Width: | Height: | Size: 277 B |
|
After Width: | Height: | Size: 293 B |
@@ -0,0 +1,316 @@
|
||||
/*
|
||||
* jquery.suggest 1.1b - 2007-08-06
|
||||
* Patched by Mark Jaquith with Alexander Dick's "multiple items" patch to allow for auto-suggesting of more than one tag before submitting
|
||||
* See: http://www.vulgarisoip.com/2007/06/29/jquerysuggest-an-alternative-jquery-based-autocomplete-library/#comment-7228
|
||||
*
|
||||
* Uses code and techniques from following libraries:
|
||||
* 1. http://www.dyve.net/jquery/?autocomplete
|
||||
* 2. http://dev.jquery.com/browser/trunk/plugins/interface/iautocompleter.js
|
||||
*
|
||||
* All the new stuff written by Peter Vulgaris (www.vulgarisoip.com)
|
||||
* Feel free to do whatever you want with this file
|
||||
*
|
||||
*/
|
||||
|
||||
(function($) {
|
||||
|
||||
$.suggest = function(input, options) {
|
||||
var $input, $results, timeout, prevLength, cache, cacheSize;
|
||||
|
||||
$input = $(input).attr("autocomplete", "off");
|
||||
$results = $("<ul/>");
|
||||
|
||||
timeout = false; // hold timeout ID for suggestion results to appear
|
||||
prevLength = 0; // last recorded length of $input.val()
|
||||
cache = []; // cache MRU list
|
||||
cacheSize = 0; // size of cache in chars (bytes?)
|
||||
|
||||
$results.addClass(options.resultsClass).appendTo('body');
|
||||
|
||||
|
||||
resetPosition();
|
||||
$(window)
|
||||
.on( 'load', resetPosition ) // just in case user is changing size of page while loading
|
||||
.on( 'resize', resetPosition );
|
||||
|
||||
$input.blur(function() {
|
||||
setTimeout(function() { $results.hide() }, 200);
|
||||
});
|
||||
|
||||
$input.keydown(processKey);
|
||||
|
||||
function resetPosition() {
|
||||
// requires jquery.dimension plugin
|
||||
var offset = $input.offset();
|
||||
$results.css({
|
||||
top: (offset.top + input.offsetHeight) + 'px',
|
||||
left: offset.left + 'px'
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function processKey(e) {
|
||||
|
||||
// handling up/down/escape requires results to be visible
|
||||
// handling enter/tab requires that AND a result to be selected
|
||||
if ((/27$|38$|40$/.test(e.keyCode) && $results.is(':visible')) ||
|
||||
(/^13$|^9$/.test(e.keyCode) && getCurrentResult())) {
|
||||
|
||||
if (e.preventDefault)
|
||||
e.preventDefault();
|
||||
if (e.stopPropagation)
|
||||
e.stopPropagation();
|
||||
|
||||
e.cancelBubble = true;
|
||||
e.returnValue = false;
|
||||
|
||||
switch(e.keyCode) {
|
||||
|
||||
case 38: // up
|
||||
prevResult();
|
||||
break;
|
||||
|
||||
case 40: // down
|
||||
nextResult();
|
||||
break;
|
||||
|
||||
case 9: // tab
|
||||
case 13: // return
|
||||
selectCurrentResult();
|
||||
break;
|
||||
|
||||
case 27: // escape
|
||||
$results.hide();
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
} else if ($input.val().length != prevLength) {
|
||||
|
||||
if (timeout)
|
||||
clearTimeout(timeout);
|
||||
timeout = setTimeout(suggest, options.delay);
|
||||
prevLength = $input.val().length;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
function suggest() {
|
||||
|
||||
var q = $.trim($input.val()), multipleSepPos, items;
|
||||
|
||||
if ( options.multiple ) {
|
||||
multipleSepPos = q.lastIndexOf(options.multipleSep);
|
||||
if ( multipleSepPos != -1 ) {
|
||||
q = $.trim(q.substr(multipleSepPos + options.multipleSep.length));
|
||||
}
|
||||
}
|
||||
if (q.length >= options.minchars) {
|
||||
|
||||
cached = checkCache(q);
|
||||
|
||||
if (cached) {
|
||||
|
||||
displayItems(cached['items']);
|
||||
|
||||
} else {
|
||||
|
||||
$.get(options.source, {q: q}, function(txt) {
|
||||
|
||||
$results.hide();
|
||||
|
||||
items = parseTxt(txt, q);
|
||||
|
||||
displayItems(items);
|
||||
addToCache(q, items, txt.length);
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
$results.hide();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
function checkCache(q) {
|
||||
var i;
|
||||
for (i = 0; i < cache.length; i++)
|
||||
if (cache[i]['q'] == q) {
|
||||
cache.unshift(cache.splice(i, 1)[0]);
|
||||
return cache[0];
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
function addToCache(q, items, size) {
|
||||
var cached;
|
||||
while (cache.length && (cacheSize + size > options.maxCacheSize)) {
|
||||
cached = cache.pop();
|
||||
cacheSize -= cached['size'];
|
||||
}
|
||||
|
||||
cache.push({
|
||||
q: q,
|
||||
size: size,
|
||||
items: items
|
||||
});
|
||||
|
||||
cacheSize += size;
|
||||
|
||||
}
|
||||
|
||||
function displayItems(items) {
|
||||
var html = '', i;
|
||||
if (!items)
|
||||
return;
|
||||
|
||||
if (!items.length) {
|
||||
$results.hide();
|
||||
return;
|
||||
}
|
||||
|
||||
resetPosition(); // when the form moves after the page has loaded
|
||||
|
||||
for (i = 0; i < items.length; i++)
|
||||
html += '<li>' + items[i] + '</li>';
|
||||
|
||||
$results.html(html).show();
|
||||
|
||||
$results
|
||||
.children('li')
|
||||
.mouseover(function() {
|
||||
$results.children('li').removeClass(options.selectClass);
|
||||
$(this).addClass(options.selectClass);
|
||||
})
|
||||
.click(function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
selectCurrentResult();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function parseTxt(txt, q) {
|
||||
|
||||
var items = [], tokens = txt.split(options.delimiter), i, token;
|
||||
|
||||
// parse returned data for non-empty items
|
||||
for (i = 0; i < tokens.length; i++) {
|
||||
token = $.trim(tokens[i]);
|
||||
if (token) {
|
||||
token = token.replace(
|
||||
new RegExp(q, 'ig'),
|
||||
function(q) { return '<span class="' + options.matchClass + '">' + q + '</span>' }
|
||||
);
|
||||
items[items.length] = token;
|
||||
}
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
function getCurrentResult() {
|
||||
var $currentResult;
|
||||
if (!$results.is(':visible'))
|
||||
return false;
|
||||
|
||||
$currentResult = $results.children('li.' + options.selectClass);
|
||||
|
||||
if (!$currentResult.length)
|
||||
$currentResult = false;
|
||||
|
||||
return $currentResult;
|
||||
|
||||
}
|
||||
|
||||
function selectCurrentResult() {
|
||||
|
||||
$currentResult = getCurrentResult();
|
||||
|
||||
if ($currentResult) {
|
||||
if ( options.multiple ) {
|
||||
if ( $input.val().indexOf(options.multipleSep) != -1 ) {
|
||||
$currentVal = $input.val().substr( 0, ( $input.val().lastIndexOf(options.multipleSep) + options.multipleSep.length ) ) + ' ';
|
||||
} else {
|
||||
$currentVal = "";
|
||||
}
|
||||
$input.val( $currentVal + $currentResult.text() + options.multipleSep + ' ' );
|
||||
$input.focus();
|
||||
} else {
|
||||
$input.val($currentResult.text());
|
||||
}
|
||||
$results.hide();
|
||||
$input.trigger('change');
|
||||
|
||||
if (options.onSelect)
|
||||
options.onSelect.apply($input[0]);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function nextResult() {
|
||||
|
||||
$currentResult = getCurrentResult();
|
||||
|
||||
if ($currentResult)
|
||||
$currentResult
|
||||
.removeClass(options.selectClass)
|
||||
.next()
|
||||
.addClass(options.selectClass);
|
||||
else
|
||||
$results.children('li:first-child').addClass(options.selectClass);
|
||||
|
||||
}
|
||||
|
||||
function prevResult() {
|
||||
var $currentResult = getCurrentResult();
|
||||
|
||||
if ($currentResult)
|
||||
$currentResult
|
||||
.removeClass(options.selectClass)
|
||||
.prev()
|
||||
.addClass(options.selectClass);
|
||||
else
|
||||
$results.children('li:last-child').addClass(options.selectClass);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
$.fn.suggest = function(source, options) {
|
||||
|
||||
if (!source)
|
||||
return;
|
||||
|
||||
options = options || {};
|
||||
options.multiple = options.multiple || false;
|
||||
options.multipleSep = options.multipleSep || ",";
|
||||
options.source = source;
|
||||
options.delay = options.delay || 100;
|
||||
options.resultsClass = options.resultsClass || 'ac_results';
|
||||
options.selectClass = options.selectClass || 'ac_over';
|
||||
options.matchClass = options.matchClass || 'ac_match';
|
||||
options.minchars = options.minchars || 2;
|
||||
options.delimiter = options.delimiter || '\n';
|
||||
options.onSelect = options.onSelect || false;
|
||||
options.maxCacheSize = options.maxCacheSize || 65536;
|
||||
|
||||
this.each(function() {
|
||||
new $.suggest(this, options);
|
||||
});
|
||||
|
||||
return this;
|
||||
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
@@ -0,0 +1 @@
|
||||
!function(a){a.suggest=function(b,c){function d(){var a=o.offset();p.css({top:a.top+b.offsetHeight+"px",left:a.left+"px"})}function e(a){if(/27$|38$|40$/.test(a.keyCode)&&p.is(":visible")||/^13$|^9$/.test(a.keyCode)&&k())switch(a.preventDefault&&a.preventDefault(),a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0,a.returnValue=!1,a.keyCode){case 38:n();break;case 40:m();break;case 9:case 13:l();break;case 27:p.hide()}else o.val().length!=r&&(q&&clearTimeout(q),q=setTimeout(f,c.delay),r=o.val().length)}function f(){var b,d,e=a.trim(o.val());c.multiple&&(b=e.lastIndexOf(c.multipleSep),-1!=b&&(e=a.trim(e.substr(b+c.multipleSep.length)))),e.length>=c.minchars?(cached=g(e),cached?i(cached.items):a.get(c.source,{q:e},function(a){p.hide(),d=j(a,e),i(d),h(e,d,a.length)})):p.hide()}function g(a){var b;for(b=0;b<s.length;b++)if(s[b].q==a)return s.unshift(s.splice(b,1)[0]),s[0];return!1}function h(a,b,d){for(var e;s.length&&t+d>c.maxCacheSize;)e=s.pop(),t-=e.size;s.push({q:a,size:d,items:b}),t+=d}function i(b){var e,f="";if(b){if(!b.length)return void p.hide();for(d(),e=0;e<b.length;e++)f+="<li>"+b[e]+"</li>";p.html(f).show(),p.children("li").mouseover(function(){p.children("li").removeClass(c.selectClass),a(this).addClass(c.selectClass)}).click(function(a){a.preventDefault(),a.stopPropagation(),l()})}}function j(b,d){var e,f,g=[],h=b.split(c.delimiter);for(e=0;e<h.length;e++)f=a.trim(h[e]),f&&(f=f.replace(new RegExp(d,"ig"),function(a){return'<span class="'+c.matchClass+'">'+a+"</span>"}),g[g.length]=f);return g}function k(){var a;return p.is(":visible")?(a=p.children("li."+c.selectClass),a.length||(a=!1),a):!1}function l(){$currentResult=k(),$currentResult&&(c.multiple?(-1!=o.val().indexOf(c.multipleSep)?$currentVal=o.val().substr(0,o.val().lastIndexOf(c.multipleSep)+c.multipleSep.length)+" ":$currentVal="",o.val($currentVal+$currentResult.text()+c.multipleSep+" "),o.focus()):o.val($currentResult.text()),p.hide(),o.trigger("change"),c.onSelect&&c.onSelect.apply(o[0]))}function m(){$currentResult=k(),$currentResult?$currentResult.removeClass(c.selectClass).next().addClass(c.selectClass):p.children("li:first-child").addClass(c.selectClass)}function n(){var a=k();a?a.removeClass(c.selectClass).prev().addClass(c.selectClass):p.children("li:last-child").addClass(c.selectClass)}var o,p,q,r,s,t;o=a(b).attr("autocomplete","off"),p=a("<ul/>"),q=!1,r=0,s=[],t=0,p.addClass(c.resultsClass).appendTo("body"),d(),a(window).on("load",d).on("resize",d),o.blur(function(){setTimeout(function(){p.hide()},200)}),o.keydown(e)},a.fn.suggest=function(b,c){return b?(c=c||{},c.multiple=c.multiple||!1,c.multipleSep=c.multipleSep||",",c.source=b,c.delay=c.delay||100,c.resultsClass=c.resultsClass||"ac_results",c.selectClass=c.selectClass||"ac_over",c.matchClass=c.matchClass||"ac_match",c.minchars=c.minchars||2,c.delimiter=c.delimiter||"\n",c.onSelect=c.onSelect||!1,c.maxCacheSize=c.maxCacheSize||65536,this.each(function(){new a.suggest(this,c)}),this):void 0}}(jQuery);
|
||||
@@ -0,0 +1,276 @@
|
||||
/*!
|
||||
* Farbtastic: jQuery color picker plug-in v1.3u
|
||||
*
|
||||
* Licensed under the GPL license:
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*/
|
||||
(function($) {
|
||||
|
||||
$.fn.farbtastic = function (options) {
|
||||
$.farbtastic(this, options);
|
||||
return this;
|
||||
};
|
||||
|
||||
$.farbtastic = function (container, callback) {
|
||||
var container = $(container).get(0);
|
||||
return container.farbtastic || (container.farbtastic = new $._farbtastic(container, callback));
|
||||
};
|
||||
|
||||
$._farbtastic = function (container, callback) {
|
||||
// Store farbtastic object
|
||||
var fb = this;
|
||||
|
||||
// Insert markup
|
||||
$(container).html('<div class="farbtastic"><div class="color"></div><div class="wheel"></div><div class="overlay"></div><div class="h-marker marker"></div><div class="sl-marker marker"></div></div>');
|
||||
var e = $('.farbtastic', container);
|
||||
fb.wheel = $('.wheel', container).get(0);
|
||||
// Dimensions
|
||||
fb.radius = 84;
|
||||
fb.square = 100;
|
||||
fb.width = 194;
|
||||
|
||||
// Fix background PNGs in IE6
|
||||
if (navigator.appVersion.match(/MSIE [0-6]\./)) {
|
||||
$('*', e).each(function () {
|
||||
if (this.currentStyle.backgroundImage != 'none') {
|
||||
var image = this.currentStyle.backgroundImage;
|
||||
image = this.currentStyle.backgroundImage.substring(5, image.length - 2);
|
||||
$(this).css({
|
||||
'backgroundImage': 'none',
|
||||
'filter': "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src='" + image + "')"
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Link to the given element(s) or callback.
|
||||
*/
|
||||
fb.linkTo = function (callback) {
|
||||
// Unbind previous nodes
|
||||
if (typeof fb.callback == 'object') {
|
||||
$(fb.callback).unbind('keyup', fb.updateValue);
|
||||
}
|
||||
|
||||
// Reset color
|
||||
fb.color = null;
|
||||
|
||||
// Bind callback or elements
|
||||
if (typeof callback == 'function') {
|
||||
fb.callback = callback;
|
||||
}
|
||||
else if (typeof callback == 'object' || typeof callback == 'string') {
|
||||
fb.callback = $(callback);
|
||||
fb.callback.bind('keyup', fb.updateValue);
|
||||
if (fb.callback.get(0).value) {
|
||||
fb.setColor(fb.callback.get(0).value);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
};
|
||||
fb.updateValue = function (event) {
|
||||
if (this.value && this.value != fb.color) {
|
||||
fb.setColor(this.value);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Change color with HTML syntax #123456
|
||||
*/
|
||||
fb.setColor = function (color) {
|
||||
var unpack = fb.unpack(color);
|
||||
if (fb.color != color && unpack) {
|
||||
fb.color = color;
|
||||
fb.rgb = unpack;
|
||||
fb.hsl = fb.RGBToHSL(fb.rgb);
|
||||
fb.updateDisplay();
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Change color with HSL triplet [0..1, 0..1, 0..1]
|
||||
*/
|
||||
fb.setHSL = function (hsl) {
|
||||
fb.hsl = hsl;
|
||||
fb.rgb = fb.HSLToRGB(hsl);
|
||||
fb.color = fb.pack(fb.rgb);
|
||||
fb.updateDisplay();
|
||||
return this;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Retrieve the coordinates of the given event relative to the center
|
||||
* of the widget.
|
||||
*/
|
||||
fb.widgetCoords = function (event) {
|
||||
var offset = $(fb.wheel).offset();
|
||||
return { x: (event.pageX - offset.left) - fb.width / 2, y: (event.pageY - offset.top) - fb.width / 2 };
|
||||
};
|
||||
|
||||
/**
|
||||
* Mousedown handler
|
||||
*/
|
||||
fb.mousedown = function (event) {
|
||||
// Capture mouse
|
||||
if (!document.dragging) {
|
||||
$(document).bind('mousemove', fb.mousemove).bind('mouseup', fb.mouseup);
|
||||
document.dragging = true;
|
||||
}
|
||||
|
||||
// Check which area is being dragged
|
||||
var pos = fb.widgetCoords(event);
|
||||
fb.circleDrag = Math.max(Math.abs(pos.x), Math.abs(pos.y)) * 2 > fb.square;
|
||||
|
||||
// Process
|
||||
fb.mousemove(event);
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Mousemove handler
|
||||
*/
|
||||
fb.mousemove = function (event) {
|
||||
// Get coordinates relative to color picker center
|
||||
var pos = fb.widgetCoords(event);
|
||||
|
||||
// Set new HSL parameters
|
||||
if (fb.circleDrag) {
|
||||
var hue = Math.atan2(pos.x, -pos.y) / 6.28;
|
||||
if (hue < 0) hue += 1;
|
||||
fb.setHSL([hue, fb.hsl[1], fb.hsl[2]]);
|
||||
}
|
||||
else {
|
||||
var sat = Math.max(0, Math.min(1, -(pos.x / fb.square) + .5));
|
||||
var lum = Math.max(0, Math.min(1, -(pos.y / fb.square) + .5));
|
||||
fb.setHSL([fb.hsl[0], sat, lum]);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Mouseup handler
|
||||
*/
|
||||
fb.mouseup = function () {
|
||||
// Uncapture mouse
|
||||
$(document).unbind('mousemove', fb.mousemove);
|
||||
$(document).unbind('mouseup', fb.mouseup);
|
||||
document.dragging = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Update the markers and styles
|
||||
*/
|
||||
fb.updateDisplay = function () {
|
||||
// Markers
|
||||
var angle = fb.hsl[0] * 6.28;
|
||||
$('.h-marker', e).css({
|
||||
left: Math.round(Math.sin(angle) * fb.radius + fb.width / 2) + 'px',
|
||||
top: Math.round(-Math.cos(angle) * fb.radius + fb.width / 2) + 'px'
|
||||
});
|
||||
|
||||
$('.sl-marker', e).css({
|
||||
left: Math.round(fb.square * (.5 - fb.hsl[1]) + fb.width / 2) + 'px',
|
||||
top: Math.round(fb.square * (.5 - fb.hsl[2]) + fb.width / 2) + 'px'
|
||||
});
|
||||
|
||||
// Saturation/Luminance gradient
|
||||
$('.color', e).css('backgroundColor', fb.pack(fb.HSLToRGB([fb.hsl[0], 1, 0.5])));
|
||||
|
||||
// Linked elements or callback
|
||||
if (typeof fb.callback == 'object') {
|
||||
// Set background/foreground color
|
||||
$(fb.callback).css({
|
||||
backgroundColor: fb.color,
|
||||
color: fb.hsl[2] > 0.5 ? '#000' : '#fff'
|
||||
});
|
||||
|
||||
// Change linked value
|
||||
$(fb.callback).each(function() {
|
||||
if (this.value && this.value != fb.color) {
|
||||
this.value = fb.color;
|
||||
}
|
||||
});
|
||||
}
|
||||
else if (typeof fb.callback == 'function') {
|
||||
fb.callback.call(fb, fb.color);
|
||||
}
|
||||
};
|
||||
|
||||
/* Various color utility functions */
|
||||
fb.pack = function (rgb) {
|
||||
var r = Math.round(rgb[0] * 255);
|
||||
var g = Math.round(rgb[1] * 255);
|
||||
var b = Math.round(rgb[2] * 255);
|
||||
return '#' + (r < 16 ? '0' : '') + r.toString(16) +
|
||||
(g < 16 ? '0' : '') + g.toString(16) +
|
||||
(b < 16 ? '0' : '') + b.toString(16);
|
||||
};
|
||||
|
||||
fb.unpack = function (color) {
|
||||
if (color.length == 7) {
|
||||
return [parseInt('0x' + color.substring(1, 3)) / 255,
|
||||
parseInt('0x' + color.substring(3, 5)) / 255,
|
||||
parseInt('0x' + color.substring(5, 7)) / 255];
|
||||
}
|
||||
else if (color.length == 4) {
|
||||
return [parseInt('0x' + color.substring(1, 2)) / 15,
|
||||
parseInt('0x' + color.substring(2, 3)) / 15,
|
||||
parseInt('0x' + color.substring(3, 4)) / 15];
|
||||
}
|
||||
};
|
||||
|
||||
fb.HSLToRGB = function (hsl) {
|
||||
var m1, m2, r, g, b;
|
||||
var h = hsl[0], s = hsl[1], l = hsl[2];
|
||||
m2 = (l <= 0.5) ? l * (s + 1) : l + s - l*s;
|
||||
m1 = l * 2 - m2;
|
||||
return [this.hueToRGB(m1, m2, h+0.33333),
|
||||
this.hueToRGB(m1, m2, h),
|
||||
this.hueToRGB(m1, m2, h-0.33333)];
|
||||
};
|
||||
|
||||
fb.hueToRGB = function (m1, m2, h) {
|
||||
h = (h < 0) ? h + 1 : ((h > 1) ? h - 1 : h);
|
||||
if (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
|
||||
if (h * 2 < 1) return m2;
|
||||
if (h * 3 < 2) return m1 + (m2 - m1) * (0.66666 - h) * 6;
|
||||
return m1;
|
||||
};
|
||||
|
||||
fb.RGBToHSL = function (rgb) {
|
||||
var min, max, delta, h, s, l;
|
||||
var r = rgb[0], g = rgb[1], b = rgb[2];
|
||||
min = Math.min(r, Math.min(g, b));
|
||||
max = Math.max(r, Math.max(g, b));
|
||||
delta = max - min;
|
||||
l = (min + max) / 2;
|
||||
s = 0;
|
||||
if (l > 0 && l < 1) {
|
||||
s = delta / (l < 0.5 ? (2 * l) : (2 - 2 * l));
|
||||
}
|
||||
h = 0;
|
||||
if (delta > 0) {
|
||||
if (max == r && max != g) h += (g - b) / delta;
|
||||
if (max == g && max != b) h += (2 + (b - r) / delta);
|
||||
if (max == b && max != r) h += (4 + (r - g) / delta);
|
||||
h /= 6;
|
||||
}
|
||||
return [h, s, l];
|
||||
};
|
||||
|
||||
// Install mousedown handler (the others are set on the document on-demand)
|
||||
$('*', e).mousedown(fb.mousedown);
|
||||
|
||||
// Init color
|
||||
fb.setColor('#000000');
|
||||
|
||||
// Set linked elements/callback
|
||||
if (callback) {
|
||||
fb.linkTo(callback);
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
|
After Width: | Height: | Size: 178 B |
|
After Width: | Height: | Size: 178 B |
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* imgAreaSelect animated border style
|
||||
*/
|
||||
|
||||
.imgareaselect-border1 {
|
||||
background: url(border-anim-v.gif) repeat-y left top;
|
||||
}
|
||||
|
||||
.imgareaselect-border2 {
|
||||
background: url(border-anim-h.gif) repeat-x left top;
|
||||
}
|
||||
|
||||
.imgareaselect-border3 {
|
||||
background: url(border-anim-v.gif) repeat-y right top;
|
||||
}
|
||||
|
||||
.imgareaselect-border4 {
|
||||
background: url(border-anim-h.gif) repeat-x left bottom;
|
||||
}
|
||||
|
||||
.imgareaselect-border1, .imgareaselect-border2,
|
||||
.imgareaselect-border3, .imgareaselect-border4 {
|
||||
filter: alpha(opacity=50);
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.imgareaselect-handle {
|
||||
background-color: #fff;
|
||||
border: solid 1px #000;
|
||||
filter: alpha(opacity=50);
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.imgareaselect-outer {
|
||||
background-color: #000;
|
||||
filter: alpha(opacity=50);
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.imgareaselect-selection {
|
||||
}
|
||||
|
After Width: | Height: | Size: 323 B |
@@ -0,0 +1,29 @@
|
||||
/* jquery.Jcrop.min.css v0.9.12 (build:20130521) */
|
||||
.jcrop-holder{-ms-touch-action:none;direction:ltr;text-align:left;}
|
||||
.jcrop-vline,.jcrop-hline{background:#FFF url(Jcrop.gif);font-size:0;position:absolute;}
|
||||
.jcrop-vline{height:100%;width:1px!important;}
|
||||
.jcrop-vline.right{right:0;}
|
||||
.jcrop-hline{height:1px!important;width:100%;}
|
||||
.jcrop-hline.bottom{bottom:0;}
|
||||
.jcrop-tracker{-webkit-tap-highlight-color:transparent;-webkit-touch-callout:none;-webkit-user-select:none;height:100%;width:100%;}
|
||||
.jcrop-handle{background-color:#333;border:1px #EEE solid;font-size:1px;height:7px;width:7px;}
|
||||
.jcrop-handle.ord-n{left:50%;margin-left:-4px;margin-top:-4px;top:0;}
|
||||
.jcrop-handle.ord-s{bottom:0;left:50%;margin-bottom:-4px;margin-left:-4px;}
|
||||
.jcrop-handle.ord-e{margin-right:-4px;margin-top:-4px;right:0;top:50%;}
|
||||
.jcrop-handle.ord-w{left:0;margin-left:-4px;margin-top:-4px;top:50%;}
|
||||
.jcrop-handle.ord-nw{left:0;margin-left:-4px;margin-top:-4px;top:0;}
|
||||
.jcrop-handle.ord-ne{margin-right:-4px;margin-top:-4px;right:0;top:0;}
|
||||
.jcrop-handle.ord-se{bottom:0;margin-bottom:-4px;margin-right:-4px;right:0;}
|
||||
.jcrop-handle.ord-sw{bottom:0;left:0;margin-bottom:-4px;margin-left:-4px;}
|
||||
.jcrop-dragbar.ord-n,.jcrop-dragbar.ord-s{height:7px;width:100%;}
|
||||
.jcrop-dragbar.ord-e,.jcrop-dragbar.ord-w{height:100%;width:7px;}
|
||||
.jcrop-dragbar.ord-n{margin-top:-4px;}
|
||||
.jcrop-dragbar.ord-s{bottom:0;margin-bottom:-4px;}
|
||||
.jcrop-dragbar.ord-e{margin-right:-4px;right:0;}
|
||||
.jcrop-dragbar.ord-w{margin-left:-4px;}
|
||||
.jcrop-light .jcrop-vline,.jcrop-light .jcrop-hline{background:#FFF;filter:alpha(opacity=70)!important;opacity:.70!important;}
|
||||
.jcrop-light .jcrop-handle{-moz-border-radius:3px;-webkit-border-radius:3px;background-color:#000;border-color:#FFF;border-radius:3px;}
|
||||
.jcrop-dark .jcrop-vline,.jcrop-dark .jcrop-hline{background:#000;filter:alpha(opacity=70)!important;opacity:.7!important;}
|
||||
.jcrop-dark .jcrop-handle{-moz-border-radius:3px;-webkit-border-radius:3px;background-color:#FFF;border-color:#000;border-radius:3px;}
|
||||
.solid-line .jcrop-vline,.solid-line .jcrop-hline{background:#FFF;}
|
||||
.jcrop-holder img,img.jcrop-preview{max-width:none;}
|
||||
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* jquery.Jcrop.min.js v0.9.12 (build:20130202)
|
||||
* jQuery Image Cropping Plugin - released under MIT License
|
||||
* Copyright (c) 2008-2013 Tapmodo Interactive LLC
|
||||
* https://github.com/tapmodo/Jcrop
|
||||
*/
|
||||
(function(a){a.Jcrop=function(b,c){function i(a){return Math.round(a)+"px"}function j(a){return d.baseClass+"-"+a}function k(){return a.fx.step.hasOwnProperty("backgroundColor")}function l(b){var c=a(b).offset();return[c.left,c.top]}function m(a){return[a.pageX-e[0],a.pageY-e[1]]}function n(b){typeof b!="object"&&(b={}),d=a.extend(d,b),a.each(["onChange","onSelect","onRelease","onDblClick"],function(a,b){typeof d[b]!="function"&&(d[b]=function(){})})}function o(a,b,c){e=l(D),bc.setCursor(a==="move"?a:a+"-resize");if(a==="move")return bc.activateHandlers(q(b),v,c);var d=_.getFixed(),f=r(a),g=_.getCorner(r(f));_.setPressed(_.getCorner(f)),_.setCurrent(g),bc.activateHandlers(p(a,d),v,c)}function p(a,b){return function(c){if(!d.aspectRatio)switch(a){case"e":c[1]=b.y2;break;case"w":c[1]=b.y2;break;case"n":c[0]=b.x2;break;case"s":c[0]=b.x2}else switch(a){case"e":c[1]=b.y+1;break;case"w":c[1]=b.y+1;break;case"n":c[0]=b.x+1;break;case"s":c[0]=b.x+1}_.setCurrent(c),bb.update()}}function q(a){var b=a;return bd.watchKeys
|
||||
(),function(a){_.moveOffset([a[0]-b[0],a[1]-b[1]]),b=a,bb.update()}}function r(a){switch(a){case"n":return"sw";case"s":return"nw";case"e":return"nw";case"w":return"ne";case"ne":return"sw";case"nw":return"se";case"se":return"nw";case"sw":return"ne"}}function s(a){return function(b){return d.disabled?!1:a==="move"&&!d.allowMove?!1:(e=l(D),W=!0,o(a,m(b)),b.stopPropagation(),b.preventDefault(),!1)}}function t(a,b,c){var d=a.width(),e=a.height();d>b&&b>0&&(d=b,e=b/a.width()*a.height()),e>c&&c>0&&(e=c,d=c/a.height()*a.width()),T=a.width()/d,U=a.height()/e,a.width(d).height(e)}function u(a){return{x:a.x*T,y:a.y*U,x2:a.x2*T,y2:a.y2*U,w:a.w*T,h:a.h*U}}function v(a){var b=_.getFixed();b.w>d.minSelect[0]&&b.h>d.minSelect[1]?(bb.enableHandles(),bb.done()):bb.release(),bc.setCursor(d.allowSelect?"crosshair":"default")}function w(a){if(d.disabled)return!1;if(!d.allowSelect)return!1;W=!0,e=l(D),bb.disableHandles(),bc.setCursor("crosshair");var b=m(a);return _.setPressed(b),bb.update(),bc.activateHandlers(x,v,a.type.substring
|
||||
(0,5)==="touch"),bd.watchKeys(),a.stopPropagation(),a.preventDefault(),!1}function x(a){_.setCurrent(a),bb.update()}function y(){var b=a("<div></div>").addClass(j("tracker"));return g&&b.css({opacity:0,backgroundColor:"white"}),b}function be(a){G.removeClass().addClass(j("holder")).addClass(a)}function bf(a,b){function t(){window.setTimeout(u,l)}var c=a[0]/T,e=a[1]/U,f=a[2]/T,g=a[3]/U;if(X)return;var h=_.flipCoords(c,e,f,g),i=_.getFixed(),j=[i.x,i.y,i.x2,i.y2],k=j,l=d.animationDelay,m=h[0]-j[0],n=h[1]-j[1],o=h[2]-j[2],p=h[3]-j[3],q=0,r=d.swingSpeed;c=k[0],e=k[1],f=k[2],g=k[3],bb.animMode(!0);var s,u=function(){return function(){q+=(100-q)/r,k[0]=Math.round(c+q/100*m),k[1]=Math.round(e+q/100*n),k[2]=Math.round(f+q/100*o),k[3]=Math.round(g+q/100*p),q>=99.8&&(q=100),q<100?(bh(k),t()):(bb.done(),bb.animMode(!1),typeof b=="function"&&b.call(bs))}}();t()}function bg(a){bh([a[0]/T,a[1]/U,a[2]/T,a[3]/U]),d.onSelect.call(bs,u(_.getFixed())),bb.enableHandles()}function bh(a){_.setPressed([a[0],a[1]]),_.setCurrent([a[2],
|
||||
a[3]]),bb.update()}function bi(){return u(_.getFixed())}function bj(){return _.getFixed()}function bk(a){n(a),br()}function bl(){d.disabled=!0,bb.disableHandles(),bb.setCursor("default"),bc.setCursor("default")}function bm(){d.disabled=!1,br()}function bn(){bb.done(),bc.activateHandlers(null,null)}function bo(){G.remove(),A.show(),A.css("visibility","visible"),a(b).removeData("Jcrop")}function bp(a,b){bb.release(),bl();var c=new Image;c.onload=function(){var e=c.width,f=c.height,g=d.boxWidth,h=d.boxHeight;D.width(e).height(f),D.attr("src",a),H.attr("src",a),t(D,g,h),E=D.width(),F=D.height(),H.width(E).height(F),M.width(E+L*2).height(F+L*2),G.width(E).height(F),ba.resize(E,F),bm(),typeof b=="function"&&b.call(bs)},c.src=a}function bq(a,b,c){var e=b||d.bgColor;d.bgFade&&k()&&d.fadeTime&&!c?a.animate({backgroundColor:e},{queue:!1,duration:d.fadeTime}):a.css("backgroundColor",e)}function br(a){d.allowResize?a?bb.enableOnly():bb.enableHandles():bb.disableHandles(),bc.setCursor(d.allowSelect?"crosshair":"default"),bb
|
||||
.setCursor(d.allowMove?"move":"default"),d.hasOwnProperty("trueSize")&&(T=d.trueSize[0]/E,U=d.trueSize[1]/F),d.hasOwnProperty("setSelect")&&(bg(d.setSelect),bb.done(),delete d.setSelect),ba.refresh(),d.bgColor!=N&&(bq(d.shade?ba.getShades():G,d.shade?d.shadeColor||d.bgColor:d.bgColor),N=d.bgColor),O!=d.bgOpacity&&(O=d.bgOpacity,d.shade?ba.refresh():bb.setBgOpacity(O)),P=d.maxSize[0]||0,Q=d.maxSize[1]||0,R=d.minSize[0]||0,S=d.minSize[1]||0,d.hasOwnProperty("outerImage")&&(D.attr("src",d.outerImage),delete d.outerImage),bb.refresh()}var d=a.extend({},a.Jcrop.defaults),e,f=navigator.userAgent.toLowerCase(),g=/msie/.test(f),h=/msie [1-6]\./.test(f);typeof b!="object"&&(b=a(b)[0]),typeof c!="object"&&(c={}),n(c);var z={border:"none",visibility:"visible",margin:0,padding:0,position:"absolute",top:0,left:0},A=a(b),B=!0;if(b.tagName=="IMG"){if(A[0].width!=0&&A[0].height!=0)A.width(A[0].width),A.height(A[0].height);else{var C=new Image;C.src=A[0].src,A.width(C.width),A.height(C.height)}var D=A.clone().removeAttr("id").
|
||||
css(z).show();D.width(A.width()),D.height(A.height()),A.after(D).hide()}else D=A.css(z).show(),B=!1,d.shade===null&&(d.shade=!0);t(D,d.boxWidth,d.boxHeight);var E=D.width(),F=D.height(),G=a("<div />").width(E).height(F).addClass(j("holder")).css({position:"relative",backgroundColor:d.bgColor}).insertAfter(A).append(D);d.addClass&&G.addClass(d.addClass);var H=a("<div />"),I=a("<div />").width("100%").height("100%").css({zIndex:310,position:"absolute",overflow:"hidden"}),J=a("<div />").width("100%").height("100%").css("zIndex",320),K=a("<div />").css({position:"absolute",zIndex:600}).dblclick(function(){var a=_.getFixed();d.onDblClick.call(bs,a)}).insertBefore(D).append(I,J);B&&(H=a("<img />").attr("src",D.attr("src")).css(z).width(E).height(F),I.append(H)),h&&K.css({overflowY:"hidden"});var L=d.boundary,M=y().width(E+L*2).height(F+L*2).css({position:"absolute",top:i(-L),left:i(-L),zIndex:290}).mousedown(w),N=d.bgColor,O=d.bgOpacity,P,Q,R,S,T,U,V=!0,W,X,Y;e=l(D);var Z=function(){function a(){var a={},b=["touchstart"
|
||||
,"touchmove","touchend"],c=document.createElement("div"),d;try{for(d=0;d<b.length;d++){var e=b[d];e="on"+e;var f=e in c;f||(c.setAttribute(e,"return;"),f=typeof c[e]=="function"),a[b[d]]=f}return a.touchstart&&a.touchend&&a.touchmove}catch(g){return!1}}function b(){return d.touchSupport===!0||d.touchSupport===!1?d.touchSupport:a()}return{createDragger:function(a){return function(b){return d.disabled?!1:a==="move"&&!d.allowMove?!1:(e=l(D),W=!0,o(a,m(Z.cfilter(b)),!0),b.stopPropagation(),b.preventDefault(),!1)}},newSelection:function(a){return w(Z.cfilter(a))},cfilter:function(a){return a.pageX=a.originalEvent.changedTouches[0].pageX,a.pageY=a.originalEvent.changedTouches[0].pageY,a},isSupported:a,support:b()}}(),_=function(){function h(d){d=n(d),c=a=d[0],e=b=d[1]}function i(a){a=n(a),f=a[0]-c,g=a[1]-e,c=a[0],e=a[1]}function j(){return[f,g]}function k(d){var f=d[0],g=d[1];0>a+f&&(f-=f+a),0>b+g&&(g-=g+b),F<e+g&&(g+=F-(e+g)),E<c+f&&(f+=E-(c+f)),a+=f,c+=f,b+=g,e+=g}function l(a){var b=m();switch(a){case"ne":return[
|
||||
b.x2,b.y];case"nw":return[b.x,b.y];case"se":return[b.x2,b.y2];case"sw":return[b.x,b.y2]}}function m(){if(!d.aspectRatio)return p();var f=d.aspectRatio,g=d.minSize[0]/T,h=d.maxSize[0]/T,i=d.maxSize[1]/U,j=c-a,k=e-b,l=Math.abs(j),m=Math.abs(k),n=l/m,r,s,t,u;return h===0&&(h=E*10),i===0&&(i=F*10),n<f?(s=e,t=m*f,r=j<0?a-t:t+a,r<0?(r=0,u=Math.abs((r-a)/f),s=k<0?b-u:u+b):r>E&&(r=E,u=Math.abs((r-a)/f),s=k<0?b-u:u+b)):(r=c,u=l/f,s=k<0?b-u:b+u,s<0?(s=0,t=Math.abs((s-b)*f),r=j<0?a-t:t+a):s>F&&(s=F,t=Math.abs(s-b)*f,r=j<0?a-t:t+a)),r>a?(r-a<g?r=a+g:r-a>h&&(r=a+h),s>b?s=b+(r-a)/f:s=b-(r-a)/f):r<a&&(a-r<g?r=a-g:a-r>h&&(r=a-h),s>b?s=b+(a-r)/f:s=b-(a-r)/f),r<0?(a-=r,r=0):r>E&&(a-=r-E,r=E),s<0?(b-=s,s=0):s>F&&(b-=s-F,s=F),q(o(a,b,r,s))}function n(a){return a[0]<0&&(a[0]=0),a[1]<0&&(a[1]=0),a[0]>E&&(a[0]=E),a[1]>F&&(a[1]=F),[Math.round(a[0]),Math.round(a[1])]}function o(a,b,c,d){var e=a,f=c,g=b,h=d;return c<a&&(e=c,f=a),d<b&&(g=d,h=b),[e,g,f,h]}function p(){var d=c-a,f=e-b,g;return P&&Math.abs(d)>P&&(c=d>0?a+P:a-P),Q&&Math.abs
|
||||
(f)>Q&&(e=f>0?b+Q:b-Q),S/U&&Math.abs(f)<S/U&&(e=f>0?b+S/U:b-S/U),R/T&&Math.abs(d)<R/T&&(c=d>0?a+R/T:a-R/T),a<0&&(c-=a,a-=a),b<0&&(e-=b,b-=b),c<0&&(a-=c,c-=c),e<0&&(b-=e,e-=e),c>E&&(g=c-E,a-=g,c-=g),e>F&&(g=e-F,b-=g,e-=g),a>E&&(g=a-F,e-=g,b-=g),b>F&&(g=b-F,e-=g,b-=g),q(o(a,b,c,e))}function q(a){return{x:a[0],y:a[1],x2:a[2],y2:a[3],w:a[2]-a[0],h:a[3]-a[1]}}var a=0,b=0,c=0,e=0,f,g;return{flipCoords:o,setPressed:h,setCurrent:i,getOffset:j,moveOffset:k,getCorner:l,getFixed:m}}(),ba=function(){function f(a,b){e.left.css({height:i(b)}),e.right.css({height:i(b)})}function g(){return h(_.getFixed())}function h(a){e.top.css({left:i(a.x),width:i(a.w),height:i(a.y)}),e.bottom.css({top:i(a.y2),left:i(a.x),width:i(a.w),height:i(F-a.y2)}),e.right.css({left:i(a.x2),width:i(E-a.x2)}),e.left.css({width:i(a.x)})}function j(){return a("<div />").css({position:"absolute",backgroundColor:d.shadeColor||d.bgColor}).appendTo(c)}function k(){b||(b=!0,c.insertBefore(D),g(),bb.setBgOpacity(1,0,1),H.hide(),l(d.shadeColor||d.bgColor,1),bb.
|
||||
isAwake()?n(d.bgOpacity,1):n(1,1))}function l(a,b){bq(p(),a,b)}function m(){b&&(c.remove(),H.show(),b=!1,bb.isAwake()?bb.setBgOpacity(d.bgOpacity,1,1):(bb.setBgOpacity(1,1,1),bb.disableHandles()),bq(G,0,1))}function n(a,e){b&&(d.bgFade&&!e?c.animate({opacity:1-a},{queue:!1,duration:d.fadeTime}):c.css({opacity:1-a}))}function o(){d.shade?k():m(),bb.isAwake()&&n(d.bgOpacity)}function p(){return c.children()}var b=!1,c=a("<div />").css({position:"absolute",zIndex:240,opacity:0}),e={top:j(),left:j().height(F),right:j().height(F),bottom:j()};return{update:g,updateRaw:h,getShades:p,setBgColor:l,enable:k,disable:m,resize:f,refresh:o,opacity:n}}(),bb=function(){function k(b){var c=a("<div />").css({position:"absolute",opacity:d.borderOpacity}).addClass(j(b));return I.append(c),c}function l(b,c){var d=a("<div />").mousedown(s(b)).css({cursor:b+"-resize",position:"absolute",zIndex:c}).addClass("ord-"+b);return Z.support&&d.bind("touchstart.jcrop",Z.createDragger(b)),J.append(d),d}function m(a){var b=d.handleSize,e=l(a,c++
|
||||
).css({opacity:d.handleOpacity}).addClass(j("handle"));return b&&e.width(b).height(b),e}function n(a){return l(a,c++).addClass("jcrop-dragbar")}function o(a){var b;for(b=0;b<a.length;b++)g[a[b]]=n(a[b])}function p(a){var b,c;for(c=0;c<a.length;c++){switch(a[c]){case"n":b="hline";break;case"s":b="hline bottom";break;case"e":b="vline right";break;case"w":b="vline"}e[a[c]]=k(b)}}function q(a){var b;for(b=0;b<a.length;b++)f[a[b]]=m(a[b])}function r(a,b){d.shade||H.css({top:i(-b),left:i(-a)}),K.css({top:i(b),left:i(a)})}function t(a,b){K.width(Math.round(a)).height(Math.round(b))}function v(){var a=_.getFixed();_.setPressed([a.x,a.y]),_.setCurrent([a.x2,a.y2]),w()}function w(a){if(b)return x(a)}function x(a){var c=_.getFixed();t(c.w,c.h),r(c.x,c.y),d.shade&&ba.updateRaw(c),b||A(),a?d.onSelect.call(bs,u(c)):d.onChange.call(bs,u(c))}function z(a,c,e){if(!b&&!c)return;d.bgFade&&!e?D.animate({opacity:a},{queue:!1,duration:d.fadeTime}):D.css("opacity",a)}function A(){K.show(),d.shade?ba.opacity(O):z(O,!0),b=!0}function B
|
||||
(){F(),K.hide(),d.shade?ba.opacity(1):z(1),b=!1,d.onRelease.call(bs)}function C(){h&&J.show()}function E(){h=!0;if(d.allowResize)return J.show(),!0}function F(){h=!1,J.hide()}function G(a){a?(X=!0,F()):(X=!1,E())}function L(){G(!1),v()}var b,c=370,e={},f={},g={},h=!1;d.dragEdges&&a.isArray(d.createDragbars)&&o(d.createDragbars),a.isArray(d.createHandles)&&q(d.createHandles),d.drawBorders&&a.isArray(d.createBorders)&&p(d.createBorders),a(document).bind("touchstart.jcrop-ios",function(b){a(b.currentTarget).hasClass("jcrop-tracker")&&b.stopPropagation()});var M=y().mousedown(s("move")).css({cursor:"move",position:"absolute",zIndex:360});return Z.support&&M.bind("touchstart.jcrop",Z.createDragger("move")),I.append(M),F(),{updateVisible:w,update:x,release:B,refresh:v,isAwake:function(){return b},setCursor:function(a){M.css("cursor",a)},enableHandles:E,enableOnly:function(){h=!0},showHandles:C,disableHandles:F,animMode:G,setBgOpacity:z,done:L}}(),bc=function(){function f(b){M.css({zIndex:450}),b?a(document).bind("touchmove.jcrop"
|
||||
,k).bind("touchend.jcrop",l):e&&a(document).bind("mousemove.jcrop",h).bind("mouseup.jcrop",i)}function g(){M.css({zIndex:290}),a(document).unbind(".jcrop")}function h(a){return b(m(a)),!1}function i(a){return a.preventDefault(),a.stopPropagation(),W&&(W=!1,c(m(a)),bb.isAwake()&&d.onSelect.call(bs,u(_.getFixed())),g(),b=function(){},c=function(){}),!1}function j(a,d,e){return W=!0,b=a,c=d,f(e),!1}function k(a){return b(m(Z.cfilter(a))),!1}function l(a){return i(Z.cfilter(a))}function n(a){M.css("cursor",a)}var b=function(){},c=function(){},e=d.trackDocument;return e||M.mousemove(h).mouseup(i).mouseout(i),D.before(M),{activateHandlers:j,setCursor:n}}(),bd=function(){function e(){d.keySupport&&(b.show(),b.focus())}function f(a){b.hide()}function g(a,b,c){d.allowMove&&(_.moveOffset([b,c]),bb.updateVisible(!0)),a.preventDefault(),a.stopPropagation()}function i(a){if(a.ctrlKey||a.metaKey)return!0;Y=a.shiftKey?!0:!1;var b=Y?10:1;switch(a.keyCode){case 37:g(a,-b,0);break;case 39:g(a,b,0);break;case 38:g(a,0,-b);break;
|
||||
case 40:g(a,0,b);break;case 27:d.allowSelect&&bb.release();break;case 9:return!0}return!1}var b=a('<input type="radio" />').css({position:"fixed",left:"-120px",width:"12px"}).addClass("jcrop-keymgr"),c=a("<div />").css({position:"absolute",overflow:"hidden"}).append(b);return d.keySupport&&(b.keydown(i).blur(f),h||!d.fixedSupport?(b.css({position:"absolute",left:"-20px"}),c.append(b).insertBefore(D)):b.insertBefore(D)),{watchKeys:e}}();Z.support&&M.bind("touchstart.jcrop",Z.newSelection),J.hide(),br(!0);var bs={setImage:bp,animateTo:bf,setSelect:bg,setOptions:bk,tellSelect:bi,tellScaled:bj,setClass:be,disable:bl,enable:bm,cancel:bn,release:bb.release,destroy:bo,focus:bd.watchKeys,getBounds:function(){return[E*T,F*U]},getWidgetSize:function(){return[E,F]},getScaleFactor:function(){return[T,U]},getOptions:function(){return d},ui:{holder:G,selection:K}};return g&&G.bind("selectstart",function(){return!1}),A.data("Jcrop",bs),bs},a.fn.Jcrop=function(b,c){var d;return this.each(function(){if(a(this).data("Jcrop")){if(
|
||||
b==="api")return a(this).data("Jcrop");a(this).data("Jcrop").setOptions(b)}else this.tagName=="IMG"?a.Jcrop.Loader(this,function(){a(this).css({display:"block",visibility:"hidden"}),d=a.Jcrop(this,b),a.isFunction(c)&&c.call(d)}):(a(this).css({display:"block",visibility:"hidden"}),d=a.Jcrop(this,b),a.isFunction(c)&&c.call(d))}),this},a.Jcrop.Loader=function(b,c,d){function g(){f.complete?(e.unbind(".jcloader"),a.isFunction(c)&&c.call(f)):window.setTimeout(g,50)}var e=a(b),f=e[0];e.bind("load.jcloader",g).bind("error.jcloader",function(b){e.unbind(".jcloader"),a.isFunction(d)&&d.call(f)}),f.complete&&a.isFunction(c)&&(e.unbind(".jcloader"),c.call(f))},a.Jcrop.defaults={allowSelect:!0,allowMove:!0,allowResize:!0,trackDocument:!0,baseClass:"jcrop",addClass:null,bgColor:"black",bgOpacity:.6,bgFade:!1,borderOpacity:.4,handleOpacity:.5,handleSize:null,aspectRatio:0,keySupport:!0,createHandles:["n","s","e","w","nw","ne","se","sw"],createDragbars:["n","s","e","w"],createBorders:["n","s","e","w"],drawBorders:!0,dragEdges
|
||||
:!0,fixedSupport:!0,touchSupport:null,shade:null,boxWidth:0,boxHeight:0,boundary:2,fadeTime:400,animationDelay:20,swingSpeed:3,minSelect:[0,0],maxSize:[0,0],minSize:[0,0],onChange:function(){},onSelect:function(){},onDblClick:function(){},onRelease:function(){}}})(jQuery);
|
||||
@@ -0,0 +1,134 @@
|
||||
/******************************************************************************************************************************
|
||||
|
||||
* @ Original idea by by Binny V A, Original version: 2.00.A
|
||||
* @ http://www.openjs.com/scripts/events/keyboard_shortcuts/
|
||||
* @ Original License : BSD
|
||||
|
||||
* @ jQuery Plugin by Tzury Bar Yochay
|
||||
mail: tzury.by@gmail.com
|
||||
blog: evalinux.wordpress.com
|
||||
face: facebook.com/profile.php?id=513676303
|
||||
|
||||
(c) Copyrights 2007
|
||||
|
||||
* @ jQuery Plugin version Beta (0.0.2)
|
||||
* @ License: jQuery-License.
|
||||
|
||||
TODO:
|
||||
add queue support (as in gmail) e.g. 'x' then 'y', etc.
|
||||
add mouse + mouse wheel events.
|
||||
|
||||
USAGE:
|
||||
$.hotkeys.add('Ctrl+c', function(){ alert('copy anyone?');});
|
||||
$.hotkeys.add('Ctrl+c', {target:'div#editor', type:'keyup', propagate: true},function(){ alert('copy anyone?');});>
|
||||
$.hotkeys.remove('Ctrl+c');
|
||||
$.hotkeys.remove('Ctrl+c', {target:'div#editor', type:'keypress'});
|
||||
|
||||
******************************************************************************************************************************/
|
||||
(function (jQuery){
|
||||
this.version = '(beta)(0.0.3)';
|
||||
this.all = {};
|
||||
this.special_keys = {
|
||||
27: 'esc', 9: 'tab', 32:'space', 13: 'return', 8:'backspace', 145: 'scroll', 20: 'capslock',
|
||||
144: 'numlock', 19:'pause', 45:'insert', 36:'home', 46:'del',35:'end', 33: 'pageup',
|
||||
34:'pagedown', 37:'left', 38:'up', 39:'right',40:'down', 112:'f1',113:'f2', 114:'f3',
|
||||
115:'f4', 116:'f5', 117:'f6', 118:'f7', 119:'f8', 120:'f9', 121:'f10', 122:'f11', 123:'f12'};
|
||||
|
||||
this.shift_nums = { "`":"~", "1":"!", "2":"@", "3":"#", "4":"$", "5":"%", "6":"^", "7":"&",
|
||||
"8":"*", "9":"(", "0":")", "-":"_", "=":"+", ";":":", "'":"\"", ",":"<",
|
||||
".":">", "/":"?", "\\":"|" };
|
||||
|
||||
this.add = function(combi, options, callback) {
|
||||
if (jQuery.isFunction(options)){
|
||||
callback = options;
|
||||
options = {};
|
||||
}
|
||||
var opt = {},
|
||||
defaults = {type: 'keydown', propagate: false, disableInInput: false, target: jQuery('html')[0]},
|
||||
that = this;
|
||||
opt = jQuery.extend( opt , defaults, options || {} );
|
||||
combi = combi.toLowerCase();
|
||||
|
||||
// inspect if keystroke matches
|
||||
var inspector = function(event) {
|
||||
// WP: not needed with newer jQuery
|
||||
// event = jQuery.event.fix(event); // jQuery event normalization.
|
||||
var element = event.target;
|
||||
// @ TextNode -> nodeType == 3
|
||||
// WP: not needed with newer jQuery
|
||||
// element = (element.nodeType==3) ? element.parentNode : element;
|
||||
|
||||
if ( opt['disableInInput'] ) { // Disable shortcut keys in Input, Textarea fields
|
||||
var target = jQuery(element);
|
||||
|
||||
if ( ( target.is('input') || target.is('textarea') ) &&
|
||||
( ! opt.noDisable || ! target.is( opt.noDisable ) ) ) {
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
var code = event.which,
|
||||
type = event.type,
|
||||
character = String.fromCharCode(code).toLowerCase(),
|
||||
special = that.special_keys[code],
|
||||
shift = event.shiftKey,
|
||||
ctrl = event.ctrlKey,
|
||||
alt= event.altKey,
|
||||
meta = event.metaKey,
|
||||
propagate = true, // default behaivour
|
||||
mapPoint = null;
|
||||
|
||||
// in opera + safari, the event.target is unpredictable.
|
||||
// for example: 'keydown' might be associated with HtmlBodyElement
|
||||
// or the element where you last clicked with your mouse.
|
||||
// WP: needed for all browsers
|
||||
// if (jQuery.browser.opera || jQuery.browser.safari){
|
||||
while (!that.all[element] && element.parentNode){
|
||||
element = element.parentNode;
|
||||
}
|
||||
// }
|
||||
var cbMap = that.all[element].events[type].callbackMap;
|
||||
if(!shift && !ctrl && !alt && !meta) { // No Modifiers
|
||||
mapPoint = cbMap[special] || cbMap[character]
|
||||
}
|
||||
// deals with combinaitons (alt|ctrl|shift+anything)
|
||||
else{
|
||||
var modif = '';
|
||||
if(alt) modif +='alt+';
|
||||
if(ctrl) modif+= 'ctrl+';
|
||||
if(shift) modif += 'shift+';
|
||||
if(meta) modif += 'meta+';
|
||||
// modifiers + special keys or modifiers + characters or modifiers + shift characters
|
||||
mapPoint = cbMap[modif+special] || cbMap[modif+character] || cbMap[modif+that.shift_nums[character]]
|
||||
}
|
||||
if (mapPoint){
|
||||
mapPoint.cb(event);
|
||||
if(!mapPoint.propagate) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
// first hook for this element
|
||||
if (!this.all[opt.target]){
|
||||
this.all[opt.target] = {events:{}};
|
||||
}
|
||||
if (!this.all[opt.target].events[opt.type]){
|
||||
this.all[opt.target].events[opt.type] = {callbackMap: {}}
|
||||
jQuery.event.add(opt.target, opt.type, inspector);
|
||||
}
|
||||
this.all[opt.target].events[opt.type].callbackMap[combi] = {cb: callback, propagate:opt.propagate};
|
||||
return jQuery;
|
||||
};
|
||||
this.remove = function(exp, opt) {
|
||||
opt = opt || {};
|
||||
target = opt.target || jQuery('html')[0];
|
||||
type = opt.type || 'keydown';
|
||||
exp = exp.toLowerCase();
|
||||
delete this.all[target].events[type].callbackMap[exp]
|
||||
return jQuery;
|
||||
};
|
||||
jQuery.hotkeys = this;
|
||||
return jQuery;
|
||||
})(jQuery);
|
||||
@@ -0,0 +1 @@
|
||||
(function(a){this.version="(beta)(0.0.3)";this.all={};this.special_keys={27:"esc",9:"tab",32:"space",13:"return",8:"backspace",145:"scroll",20:"capslock",144:"numlock",19:"pause",45:"insert",36:"home",46:"del",35:"end",33:"pageup",34:"pagedown",37:"left",38:"up",39:"right",40:"down",112:"f1",113:"f2",114:"f3",115:"f4",116:"f5",117:"f6",118:"f7",119:"f8",120:"f9",121:"f10",122:"f11",123:"f12"};this.shift_nums={"`":"~","1":"!","2":"@","3":"#","4":"$","5":"%","6":"^","7":"&","8":"*","9":"(","0":")","-":"_","=":"+",";":":","'":'"',",":"<",".":">","/":"?","\\":"|"};this.add=function(c,b,h){if(a.isFunction(b)){h=b;b={}}var d={},f={type:"keydown",propagate:false,disableInInput:false,target:a("html")[0]},e=this;d=a.extend(d,f,b||{});c=c.toLowerCase();var g=function(j){var o=j.target;if(d.disableInInput){var s=a(o);if(s.is("input")||s.is("textarea")){return}}var l=j.which,u=j.type,r=String.fromCharCode(l).toLowerCase(),t=e.special_keys[l],m=j.shiftKey,i=j.ctrlKey,p=j.altKey,w=j.metaKey,q=true,k=null;while(!e.all[o]&&o.parentNode){o=o.parentNode}var v=e.all[o].events[u].callbackMap;if(!m&&!i&&!p&&!w){k=v[t]||v[r]}else{var n="";if(p){n+="alt+"}if(i){n+="ctrl+"}if(m){n+="shift+"}if(w){n+="meta+"}k=v[n+t]||v[n+r]||v[n+e.shift_nums[r]]}if(k){k.cb(j);if(!k.propagate){j.stopPropagation();j.preventDefault();return false}}};if(!this.all[d.target]){this.all[d.target]={events:{}}}if(!this.all[d.target].events[d.type]){this.all[d.target].events[d.type]={callbackMap:{}};a.event.add(d.target,d.type,g)}this.all[d.target].events[d.type].callbackMap[c]={cb:h,propagate:d.propagate};return a};this.remove=function(c,b){b=b||{};target=b.target||a("html")[0];type=b.type||"keydown";c=c.toLowerCase();delete this.all[target].events[type].callbackMap[c];return a};a.hotkeys=this;return a})(jQuery);
|
||||
@@ -0,0 +1,105 @@
|
||||
/*!
|
||||
* Masonry v2 shim
|
||||
* to maintain backwards compatibility
|
||||
* as of Masonry v3.1.2
|
||||
*
|
||||
* Cascading grid layout library
|
||||
* http://masonry.desandro.com
|
||||
* MIT License
|
||||
* by David DeSandro
|
||||
*/
|
||||
( function( window ) {
|
||||
|
||||
'use strict';
|
||||
|
||||
var Masonry = window.Masonry;
|
||||
|
||||
Masonry.prototype._remapV2Options = function() {
|
||||
// map v2 options to v3 equivalents
|
||||
this._remapOption( 'gutterWidth', 'gutter' );
|
||||
this._remapOption( 'isResizable', 'isResizeBound' );
|
||||
this._remapOption( 'isRTL', 'isOriginLeft', function( opt ) {
|
||||
return !opt;
|
||||
});
|
||||
|
||||
// override transitionDuration with isAnimated
|
||||
var isAniOption = this.options.isAnimated;
|
||||
if ( isAniOption !== undefined ) {
|
||||
this.options.transitionDuration = isAniOption ?
|
||||
this.options.transitionDuration : 0;
|
||||
}
|
||||
|
||||
if ( isAniOption === undefined || isAniOption ) {
|
||||
// use animation Duration option in place of transitionDuration
|
||||
var aniOptions = this.options.animationOptions;
|
||||
var aniDuration = aniOptions && aniOptions.duration;
|
||||
if ( aniDuration ) {
|
||||
this.options.transitionDuration = typeof aniDuration === 'string' ?
|
||||
aniDuration : aniDuration + 'ms';
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Masonry.prototype._remapOption = function( from, to, munge ) {
|
||||
var fromOption = this.options[ from ];
|
||||
if ( fromOption !== undefined ) {
|
||||
this.options[ to ] = munge ? munge( fromOption ) : fromOption;
|
||||
}
|
||||
};
|
||||
|
||||
// remap v2 options for necessary methods
|
||||
|
||||
var __create = Masonry.prototype._create;
|
||||
Masonry.prototype._create = function() {
|
||||
var that = this;
|
||||
this._remapV2Options();
|
||||
__create.apply( this, arguments );
|
||||
setTimeout( function() {
|
||||
jQuery( that.element ).addClass( 'masonry' );
|
||||
}, 0 );
|
||||
};
|
||||
|
||||
var _layout = Masonry.prototype.layout;
|
||||
Masonry.prototype.layout = function() {
|
||||
this._remapV2Options();
|
||||
_layout.apply( this, arguments );
|
||||
};
|
||||
|
||||
var _option = Masonry.prototype.option;
|
||||
Masonry.prototype.option = function() {
|
||||
_option.apply( this, arguments );
|
||||
this._remapV2Options();
|
||||
};
|
||||
|
||||
var __itemize = Masonry.prototype._itemize;
|
||||
Masonry.prototype._itemize = function( elements ) {
|
||||
var items = __itemize.apply( this, arguments );
|
||||
jQuery( elements ).addClass( 'masonry-brick' );
|
||||
return items;
|
||||
};
|
||||
|
||||
// re-enable using function for columnWidth
|
||||
var _measureColumns = Masonry.prototype.measureColumns;
|
||||
Masonry.prototype.measureColumns = function() {
|
||||
var colWOpt = this.options.columnWidth;
|
||||
if ( colWOpt && typeof colWOpt === 'function' ) {
|
||||
this.getContainerWidth();
|
||||
this.columnWidth = colWOpt( this.containerWidth );
|
||||
}
|
||||
_measureColumns.apply( this, arguments );
|
||||
};
|
||||
|
||||
Masonry.prototype.reload = function() {
|
||||
this.reloadItems.apply( this, arguments );
|
||||
this.layout.apply( this );
|
||||
};
|
||||
|
||||
var _destroy = Masonry.prototype.destroy;
|
||||
Masonry.prototype.destroy = function() {
|
||||
var items = this.getItemElements();
|
||||
jQuery( this.element ).removeClass( 'masonry' );
|
||||
jQuery( items ).removeClass( 'masonry-brick' );
|
||||
_destroy.apply( this, arguments );
|
||||
};
|
||||
|
||||
})( window );
|
||||
@@ -0,0 +1,11 @@
|
||||
/*!
|
||||
* Masonry v2 shim
|
||||
* to maintain backwards compatibility
|
||||
* as of Masonry v3.1.2
|
||||
*
|
||||
* Cascading grid layout library
|
||||
* http://masonry.desandro.com
|
||||
* MIT License
|
||||
* by David DeSandro
|
||||
*/
|
||||
!function(a){"use strict";var b=a.Masonry;b.prototype._remapV2Options=function(){this._remapOption("gutterWidth","gutter"),this._remapOption("isResizable","isResizeBound"),this._remapOption("isRTL","isOriginLeft",function(a){return!a});var a=this.options.isAnimated;if(void 0!==a&&(this.options.transitionDuration=a?this.options.transitionDuration:0),void 0===a||a){var b=this.options.animationOptions,c=b&&b.duration;c&&(this.options.transitionDuration="string"==typeof c?c:c+"ms")}},b.prototype._remapOption=function(a,b,c){var d=this.options[a];void 0!==d&&(this.options[b]=c?c(d):d)};var c=b.prototype._create;b.prototype._create=function(){var a=this;this._remapV2Options(),c.apply(this,arguments),setTimeout(function(){jQuery(a.element).addClass("masonry")},0)};var d=b.prototype.layout;b.prototype.layout=function(){this._remapV2Options(),d.apply(this,arguments)};var e=b.prototype.option;b.prototype.option=function(){e.apply(this,arguments),this._remapV2Options()};var f=b.prototype._itemize;b.prototype._itemize=function(a){var b=f.apply(this,arguments);return jQuery(a).addClass("masonry-brick"),b};var g=b.prototype.measureColumns;b.prototype.measureColumns=function(){var a=this.options.columnWidth;a&&"function"==typeof a&&(this.getContainerWidth(),this.columnWidth=a(this.containerWidth)),g.apply(this,arguments)},b.prototype.reload=function(){this.reloadItems.apply(this,arguments),this.layout.apply(this)};var h=b.prototype.destroy;b.prototype.destroy=function(){var a=this.getItemElements();jQuery(this.element).removeClass("masonry"),jQuery(a).removeClass("masonry-brick"),h.apply(this,arguments)}}(window);
|
||||
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* jQuery.query - Query String Modification and Creation for jQuery
|
||||
* Written by Blair Mitchelmore (blair DOT mitchelmore AT gmail DOT com)
|
||||
* Licensed under the WTFPL (http://sam.zoy.org/wtfpl/).
|
||||
* Date: 2009/8/13
|
||||
*
|
||||
* @author Blair Mitchelmore
|
||||
* @version 2.1.7
|
||||
*
|
||||
**/
|
||||
new function(e){var d=e.separator||"&";var c=e.spaces===false?false:true;var a=e.suffix===false?"":"[]";var g=e.prefix===false?false:true;var b=g?e.hash===true?"#":"?":"";var f=e.numbers===false?false:true;jQuery.query=new function(){var h=function(m,l){return m!=undefined&&m!==null&&(!!l?m.constructor==l:true)};var i=function(r){var l,q=/\[([^[]*)\]/g,n=/^([^[]+)(\[.*\])?$/.exec(r),o=n[1],p=[];while(l=q.exec(n[2])){p.push(l[1])}return[o,p]};var k=function(s,r,q){var t,p=r.shift();if(typeof s!="object"){s=null}if(p===""){if(!s){s=[]}if(h(s,Array)){s.push(r.length==0?q:k(null,r.slice(0),q))}else{if(h(s,Object)){var n=0;while(s[n++]!=null){}s[--n]=r.length==0?q:k(s[n],r.slice(0),q)}else{s=[];s.push(r.length==0?q:k(null,r.slice(0),q))}}}else{if(p&&p.match(/^\s*[0-9]+\s*$/)){var m=parseInt(p,10);if(!s){s=[]}s[m]=r.length==0?q:k(s[m],r.slice(0),q)}else{if(p){var m=p.replace(/^\s*|\s*$/g,"");if(!s){s={}}if(h(s,Array)){var l={};for(var n=0;n<s.length;++n){l[n]=s[n]}s=l}s[m]=r.length==0?q:k(s[m],r.slice(0),q)}else{return q}}}return s};var j=function(l){var m=this;m.keys={};if(l.queryObject){jQuery.each(l.get(),function(n,o){m.SET(n,o)})}else{jQuery.each(arguments,function(){var n=""+this;n=n.replace(/^[?#]/,"");n=n.replace(/[;&]$/,"");if(c){n=n.replace(/[+]/g," ")}jQuery.each(n.split(/[&;]/),function(){var o=decodeURIComponent(this.split("=")[0]||"");var p=decodeURIComponent(this.split("=")[1]||"");if(!o){return}if(f){if(/^[+-]?[0-9]+\.[0-9]*$/.test(p)){p=parseFloat(p)}else{if(/^[+-]?[0-9]+$/.test(p)){p=parseInt(p,10)}}}p=(!p&&p!==0)?true:p;if(p!==false&&p!==true&&typeof p!="number"){p=p}m.SET(o,p)})})}return m};j.prototype={queryObject:true,has:function(l,m){var n=this.get(l);return h(n,m)},GET:function(m){if(!h(m)){return this.keys}var l=i(m),n=l[0],p=l[1];var o=this.keys[n];while(o!=null&&p.length!=0){o=o[p.shift()]}return typeof o=="number"?o:o||""},get:function(l){var m=this.GET(l);if(h(m,Object)){return jQuery.extend(true,{},m)}else{if(h(m,Array)){return m.slice(0)}}return m},SET:function(m,r){var o=!h(r)?null:r;var l=i(m),n=l[0],q=l[1];var p=this.keys[n];this.keys[n]=k(p,q.slice(0),o);return this},set:function(l,m){return this.copy().SET(l,m)},REMOVE:function(l){return this.SET(l,null).COMPACT()},remove:function(l){return this.copy().REMOVE(l)},EMPTY:function(){var l=this;jQuery.each(l.keys,function(m,n){delete l.keys[m]});return l},load:function(l){var n=l.replace(/^.*?[#](.+?)(?:\?.+)?$/,"$1");var m=l.replace(/^.*?[?](.+?)(?:#.+)?$/,"$1");return new j(l.length==m.length?"":m,l.length==n.length?"":n)},empty:function(){return this.copy().EMPTY()},copy:function(){return new j(this)},COMPACT:function(){function l(o){var n=typeof o=="object"?h(o,Array)?[]:{}:o;if(typeof o=="object"){function m(r,p,q){if(h(r,Array)){r.push(q)}else{r[p]=q}}jQuery.each(o,function(p,q){if(!h(q)){return true}m(n,p,l(q))})}return n}this.keys=l(this.keys);return this},compact:function(){return this.copy().COMPACT()},toString:function(){var n=0,r=[],q=[],m=this;var o=function(s){s=s+"";if(c){s=s.replace(/ /g,"+")}return encodeURIComponent(s)};var l=function(s,t,u){if(!h(u)||u===false){return}var v=[o(t)];if(u!==true){v.push("=");v.push(o(u))}s.push(v.join(""))};var p=function(t,s){var u=function(v){return !s||s==""?[v].join(""):[s,"[",v,"]"].join("")};jQuery.each(t,function(v,w){if(typeof w=="object"){p(w,u(v))}else{l(q,u(v),w)}})};p(this.keys);if(q.length>0){r.push(b)}r.push(q.join(d));return r.join("")}};return new j(location.search,location.hash)}}(jQuery.query||{});
|
||||
@@ -0,0 +1,36 @@
|
||||
|
||||
(function($){$.scheduler=function(){this.bucket={};return;};$.scheduler.prototype={schedule:function(){var ctx={"id":null,"time":1000,"repeat":false,"protect":false,"obj":null,"func":function(){},"args":[]};function _isfn(fn){return(!!fn&&typeof fn!="string"&&typeof fn[0]=="undefined"&&RegExp("function","i").test(fn+""));};var i=0;var override=false;if(typeof arguments[i]=="object"&&arguments.length>1){override=true;i++;}
|
||||
if(typeof arguments[i]=="object"){for(var option in arguments[i])
|
||||
if(typeof ctx[option]!="undefined")
|
||||
ctx[option]=arguments[i][option];i++;}
|
||||
if(typeof arguments[i]=="number"||(typeof arguments[i]=="string"&&arguments[i].match(RegExp("^[0-9]+[smhdw]$"))))
|
||||
ctx["time"]=arguments[i++];if(typeof arguments[i]=="boolean")
|
||||
ctx["repeat"]=arguments[i++];if(typeof arguments[i]=="boolean")
|
||||
ctx["protect"]=arguments[i++];if(typeof arguments[i]=="object"&&typeof arguments[i+1]=="string"&&_isfn(arguments[i][arguments[i+1]])){ctx["obj"]=arguments[i++];ctx["func"]=arguments[i++];}
|
||||
else if(typeof arguments[i]!="undefined"&&(_isfn(arguments[i])||typeof arguments[i]=="string"))
|
||||
ctx["func"]=arguments[i++];while(typeof arguments[i]!="undefined")
|
||||
ctx["args"].push(arguments[i++]);if(override){if(typeof arguments[1]=="object"){for(var option in arguments[0])
|
||||
if(typeof ctx[option]!="undefined"&&typeof arguments[1][option]=="undefined")
|
||||
ctx[option]=arguments[0][option];}
|
||||
else{for(var option in arguments[0])
|
||||
if(typeof ctx[option]!="undefined")
|
||||
ctx[option]=arguments[0][option];}
|
||||
i++;}
|
||||
ctx["_scheduler"]=this;ctx["_handle"]=null;var match=String(ctx["time"]).match(RegExp("^([0-9]+)([smhdw])$"));if(match&&match[0]!="undefined"&&match[1]!="undefined")
|
||||
ctx["time"]=String(parseInt(match[1])*{s:1000,m:1000*60,h:1000*60*60,d:1000*60*60*24,w:1000*60*60*24*7}[match[2]]);if(ctx["id"]==null)
|
||||
ctx["id"]=(String(ctx["repeat"])+":"
|
||||
+String(ctx["protect"])+":"
|
||||
+String(ctx["time"])+":"
|
||||
+String(ctx["obj"])+":"
|
||||
+String(ctx["func"])+":"
|
||||
+String(ctx["args"]));if(ctx["protect"])
|
||||
if(typeof this.bucket[ctx["id"]]!="undefined")
|
||||
return this.bucket[ctx["id"]];if(!_isfn(ctx["func"])){if(ctx["obj"]!=null&&typeof ctx["obj"]=="object"&&typeof ctx["func"]=="string"&&_isfn(ctx["obj"][ctx["func"]]))
|
||||
ctx["func"]=ctx["obj"][ctx["func"]];else
|
||||
ctx["func"]=eval("function () { "+ctx["func"]+" }");}
|
||||
ctx["_handle"]=this._schedule(ctx);this.bucket[ctx["id"]]=ctx;return ctx;},reschedule:function(ctx){if(typeof ctx=="string")
|
||||
ctx=this.bucket[ctx];ctx["_handle"]=this._schedule(ctx);return ctx;},_schedule:function(ctx){var trampoline=function(){var obj=(ctx["obj"]!=null?ctx["obj"]:ctx);(ctx["func"]).apply(obj,ctx["args"]);if(typeof(ctx["_scheduler"]).bucket[ctx["id"]]!="undefined"&&ctx["repeat"])
|
||||
(ctx["_scheduler"])._schedule(ctx);else
|
||||
delete(ctx["_scheduler"]).bucket[ctx["id"]];};return setTimeout(trampoline,ctx["time"]);},cancel:function(ctx){if(typeof ctx=="string")
|
||||
ctx=this.bucket[ctx];if(typeof ctx=="object"){clearTimeout(ctx["_handle"]);delete this.bucket[ctx["id"]];}}};$.extend({scheduler$:new $.scheduler(),schedule:function(){return $.scheduler$.schedule.apply($.scheduler$,arguments)},reschedule:function(){return $.scheduler$.reschedule.apply($.scheduler$,arguments)},cancel:function(){return $.scheduler$.cancel.apply($.scheduler$,arguments)}});$.fn.extend({schedule:function(){var a=[{}];for(var i=0;i<arguments.length;i++)
|
||||
a.push(arguments[i]);return this.each(function(){a[0]={"id":this,"obj":this};return $.schedule.apply($,a);});}});})(jQuery);
|
||||
@@ -0,0 +1,31 @@
|
||||
/*!
|
||||
* jQuery serializeObject - v0.2 - 1/20/2010
|
||||
* http://benalman.com/projects/jquery-misc-plugins/
|
||||
*
|
||||
* Copyright (c) 2010 "Cowboy" Ben Alman
|
||||
* Dual licensed under the MIT and GPL licenses.
|
||||
* http://benalman.com/about/license/
|
||||
*/
|
||||
|
||||
// Whereas .serializeArray() serializes a form into an array, .serializeObject()
|
||||
// serializes a form into an (arguably more useful) object.
|
||||
|
||||
(function($,undefined){
|
||||
'$:nomunge'; // Used by YUI compressor.
|
||||
|
||||
$.fn.serializeObject = function(){
|
||||
var obj = {};
|
||||
|
||||
$.each( this.serializeArray(), function(i,o){
|
||||
var n = o.name,
|
||||
v = o.value;
|
||||
|
||||
obj[n] = obj[n] === undefined ? v
|
||||
: $.isArray( obj[n] ) ? obj[n].concat( v )
|
||||
: [ obj[n], v ];
|
||||
});
|
||||
|
||||
return obj;
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
@@ -0,0 +1,99 @@
|
||||
(function($){
|
||||
$.fn.filter_visible = function(depth) {
|
||||
depth = depth || 3;
|
||||
var is_visible = function() {
|
||||
var p = $(this), i;
|
||||
for(i=0; i<depth-1; ++i) {
|
||||
if (!p.is(':visible')) return false;
|
||||
p = p.parent();
|
||||
}
|
||||
return true;
|
||||
};
|
||||
return this.filter(is_visible);
|
||||
};
|
||||
$.table_hotkeys = function(table, keys, opts) {
|
||||
opts = $.extend($.table_hotkeys.defaults, opts);
|
||||
var selected_class, destructive_class, set_current_row, adjacent_row_callback, get_adjacent_row, adjacent_row, prev_row, next_row, check, get_first_row, get_last_row, make_key_callback, first_row;
|
||||
|
||||
selected_class = opts.class_prefix + opts.selected_suffix;
|
||||
destructive_class = opts.class_prefix + opts.destructive_suffix;
|
||||
set_current_row = function (tr) {
|
||||
if ($.table_hotkeys.current_row) $.table_hotkeys.current_row.removeClass(selected_class);
|
||||
tr.addClass(selected_class);
|
||||
tr[0].scrollIntoView(false);
|
||||
$.table_hotkeys.current_row = tr;
|
||||
};
|
||||
adjacent_row_callback = function(which) {
|
||||
if (!adjacent_row(which) && $.isFunction(opts[which+'_page_link_cb'])) {
|
||||
opts[which+'_page_link_cb']();
|
||||
}
|
||||
};
|
||||
get_adjacent_row = function(which) {
|
||||
var first_row, method;
|
||||
|
||||
if (!$.table_hotkeys.current_row) {
|
||||
first_row = get_first_row();
|
||||
$.table_hotkeys.current_row = first_row;
|
||||
return first_row[0];
|
||||
}
|
||||
method = 'prev' == which? $.fn.prevAll : $.fn.nextAll;
|
||||
return method.call($.table_hotkeys.current_row, opts.cycle_expr).filter_visible()[0];
|
||||
};
|
||||
adjacent_row = function(which) {
|
||||
var adj = get_adjacent_row(which);
|
||||
if (!adj) return false;
|
||||
set_current_row($(adj));
|
||||
return true;
|
||||
};
|
||||
prev_row = function() { return adjacent_row('prev'); };
|
||||
next_row = function() { return adjacent_row('next'); };
|
||||
check = function() {
|
||||
$(opts.checkbox_expr, $.table_hotkeys.current_row).each(function() {
|
||||
this.checked = !this.checked;
|
||||
});
|
||||
};
|
||||
get_first_row = function() {
|
||||
return $(opts.cycle_expr, table).filter_visible().eq(opts.start_row_index);
|
||||
};
|
||||
get_last_row = function() {
|
||||
var rows = $(opts.cycle_expr, table).filter_visible();
|
||||
return rows.eq(rows.length-1);
|
||||
};
|
||||
make_key_callback = function(expr) {
|
||||
return function() {
|
||||
if ( null == $.table_hotkeys.current_row ) return false;
|
||||
var clickable = $(expr, $.table_hotkeys.current_row);
|
||||
if (!clickable.length) return false;
|
||||
if (clickable.is('.'+destructive_class)) next_row() || prev_row();
|
||||
clickable.click();
|
||||
};
|
||||
};
|
||||
first_row = get_first_row();
|
||||
if (!first_row.length) return;
|
||||
if (opts.highlight_first)
|
||||
set_current_row(first_row);
|
||||
else if (opts.highlight_last)
|
||||
set_current_row(get_last_row());
|
||||
$.hotkeys.add(opts.prev_key, opts.hotkeys_opts, function() {return adjacent_row_callback('prev');});
|
||||
$.hotkeys.add(opts.next_key, opts.hotkeys_opts, function() {return adjacent_row_callback('next');});
|
||||
$.hotkeys.add(opts.mark_key, opts.hotkeys_opts, check);
|
||||
$.each(keys, function() {
|
||||
var callback, key;
|
||||
|
||||
if ($.isFunction(this[1])) {
|
||||
callback = this[1];
|
||||
key = this[0];
|
||||
$.hotkeys.add(key, opts.hotkeys_opts, function(event) { return callback(event, $.table_hotkeys.current_row); });
|
||||
} else {
|
||||
key = this;
|
||||
$.hotkeys.add(key, opts.hotkeys_opts, make_key_callback('.'+opts.class_prefix+key));
|
||||
}
|
||||
});
|
||||
|
||||
};
|
||||
$.table_hotkeys.current_row = null;
|
||||
$.table_hotkeys.defaults = {cycle_expr: 'tr', class_prefix: 'vim-', selected_suffix: 'current',
|
||||
destructive_suffix: 'destructive', hotkeys_opts: {disableInInput: true, type: 'keypress'},
|
||||
checkbox_expr: ':checkbox', next_key: 'j', prev_key: 'k', mark_key: 'x',
|
||||
start_row_index: 2, highlight_first: false, highlight_last: false, next_page_link_cb: false, prev_page_link_cb: false};
|
||||
})(jQuery);
|
||||
@@ -0,0 +1 @@
|
||||
(function(a){a.fn.filter_visible=function(c){c=c||3;var b=function(){var e=a(this),d;for(d=0;d<c-1;++d){if(!e.is(":visible")){return false}e=e.parent()}return true};return this.filter(b)};a.table_hotkeys=function(p,q,b){b=a.extend(a.table_hotkeys.defaults,b);var i,l,e,f,m,d,k,o,c,h,g,n,j;i=b.class_prefix+b.selected_suffix;l=b.class_prefix+b.destructive_suffix;e=function(r){if(a.table_hotkeys.current_row){a.table_hotkeys.current_row.removeClass(i)}r.addClass(i);r[0].scrollIntoView(false);a.table_hotkeys.current_row=r};f=function(r){if(!d(r)&&a.isFunction(b[r+"_page_link_cb"])){b[r+"_page_link_cb"]()}};m=function(s){var r,t;if(!a.table_hotkeys.current_row){r=h();a.table_hotkeys.current_row=r;return r[0]}t="prev"==s?a.fn.prevAll:a.fn.nextAll;return t.call(a.table_hotkeys.current_row,b.cycle_expr).filter_visible()[0]};d=function(s){var r=m(s);if(!r){return false}e(a(r));return true};k=function(){return d("prev")};o=function(){return d("next")};c=function(){a(b.checkbox_expr,a.table_hotkeys.current_row).each(function(){this.checked=!this.checked})};h=function(){return a(b.cycle_expr,p).filter_visible().eq(b.start_row_index)};g=function(){var r=a(b.cycle_expr,p).filter_visible();return r.eq(r.length-1)};n=function(r){return function(){if(null==a.table_hotkeys.current_row){return false}var s=a(r,a.table_hotkeys.current_row);if(!s.length){return false}if(s.is("."+l)){o()||k()}s.click()}};j=h();if(!j.length){return}if(b.highlight_first){e(j)}else{if(b.highlight_last){e(g())}}a.hotkeys.add(b.prev_key,b.hotkeys_opts,function(){return f("prev")});a.hotkeys.add(b.next_key,b.hotkeys_opts,function(){return f("next")});a.hotkeys.add(b.mark_key,b.hotkeys_opts,c);a.each(q,function(){var s,r;if(a.isFunction(this[1])){s=this[1];r=this[0];a.hotkeys.add(r,b.hotkeys_opts,function(t){return s(t,a.table_hotkeys.current_row)})}else{r=this;a.hotkeys.add(r,b.hotkeys_opts,n("."+b.class_prefix+r))}})};a.table_hotkeys.current_row=null;a.table_hotkeys.defaults={cycle_expr:"tr",class_prefix:"vim-",selected_suffix:"current",destructive_suffix:"destructive",hotkeys_opts:{disableInInput:true,type:"keypress"},checkbox_expr:":checkbox",next_key:"j",prev_key:"k",mark_key:"x",start_row_index:2,highlight_first:false,highlight_last:false,next_page_link_cb:false,prev_page_link_cb:false}})(jQuery);
|
||||
@@ -0,0 +1,11 @@
|
||||
/*!
|
||||
* jQuery UI Touch Punch 0.2.2
|
||||
*
|
||||
* Copyright 2011, Dave Furfero
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
*
|
||||
* Depends:
|
||||
* jquery.ui.widget.js
|
||||
* jquery.ui.mouse.js
|
||||
*/
|
||||
(function(b){b.support.touch="ontouchend" in document;if(!b.support.touch){return}var c=b.ui.mouse.prototype,e=c._mouseInit,a;function d(g,h){if(g.originalEvent.touches.length>1){return}g.preventDefault();var i=g.originalEvent.changedTouches[0],f=document.createEvent("MouseEvents");f.initMouseEvent(h,true,true,window,1,i.screenX,i.screenY,i.clientX,i.clientY,false,false,false,false,0,null);g.target.dispatchEvent(f)}c._touchStart=function(g){var f=this;if(a||!f._mouseCapture(g.originalEvent.changedTouches[0])){return}a=true;f._touchMoved=false;d(g,"mouseover");d(g,"mousemove");d(g,"mousedown")};c._touchMove=function(f){if(!a){return}this._touchMoved=true;d(f,"mousemove")};c._touchEnd=function(f){if(!a){return}d(f,"mouseup");d(f,"mouseout");if(!this._touchMoved){d(f,"click")}a=false};c._mouseInit=function(){var f=this;f.element.bind("touchstart",b.proxy(f,"_touchStart")).bind("touchmove",b.proxy(f,"_touchMove")).bind("touchend",b.proxy(f,"_touchEnd"));e.call(f)}})(jQuery);
|
||||
@@ -0,0 +1,519 @@
|
||||
/*
|
||||
json2.js
|
||||
2015-05-03
|
||||
|
||||
Public Domain.
|
||||
|
||||
NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
|
||||
|
||||
See http://www.JSON.org/js.html
|
||||
|
||||
|
||||
This code should be minified before deployment.
|
||||
See http://javascript.crockford.com/jsmin.html
|
||||
|
||||
USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
|
||||
NOT CONTROL.
|
||||
|
||||
|
||||
This file creates a global JSON object containing two methods: stringify
|
||||
and parse. This file is provides the ES5 JSON capability to ES3 systems.
|
||||
If a project might run on IE8 or earlier, then this file should be included.
|
||||
This file does nothing on ES5 systems.
|
||||
|
||||
JSON.stringify(value, replacer, space)
|
||||
value any JavaScript value, usually an object or array.
|
||||
|
||||
replacer an optional parameter that determines how object
|
||||
values are stringified for objects. It can be a
|
||||
function or an array of strings.
|
||||
|
||||
space an optional parameter that specifies the indentation
|
||||
of nested structures. If it is omitted, the text will
|
||||
be packed without extra whitespace. If it is a number,
|
||||
it will specify the number of spaces to indent at each
|
||||
level. If it is a string (such as '\t' or ' '),
|
||||
it contains the characters used to indent at each level.
|
||||
|
||||
This method produces a JSON text from a JavaScript value.
|
||||
|
||||
When an object value is found, if the object contains a toJSON
|
||||
method, its toJSON method will be called and the result will be
|
||||
stringified. A toJSON method does not serialize: it returns the
|
||||
value represented by the name/value pair that should be serialized,
|
||||
or undefined if nothing should be serialized. The toJSON method
|
||||
will be passed the key associated with the value, and this will be
|
||||
bound to the value
|
||||
|
||||
For example, this would serialize Dates as ISO strings.
|
||||
|
||||
Date.prototype.toJSON = function (key) {
|
||||
function f(n) {
|
||||
// Format integers to have at least two digits.
|
||||
return n < 10
|
||||
? '0' + n
|
||||
: n;
|
||||
}
|
||||
|
||||
return this.getUTCFullYear() + '-' +
|
||||
f(this.getUTCMonth() + 1) + '-' +
|
||||
f(this.getUTCDate()) + 'T' +
|
||||
f(this.getUTCHours()) + ':' +
|
||||
f(this.getUTCMinutes()) + ':' +
|
||||
f(this.getUTCSeconds()) + 'Z';
|
||||
};
|
||||
|
||||
You can provide an optional replacer method. It will be passed the
|
||||
key and value of each member, with this bound to the containing
|
||||
object. The value that is returned from your method will be
|
||||
serialized. If your method returns undefined, then the member will
|
||||
be excluded from the serialization.
|
||||
|
||||
If the replacer parameter is an array of strings, then it will be
|
||||
used to select the members to be serialized. It filters the results
|
||||
such that only members with keys listed in the replacer array are
|
||||
stringified.
|
||||
|
||||
Values that do not have JSON representations, such as undefined or
|
||||
functions, will not be serialized. Such values in objects will be
|
||||
dropped; in arrays they will be replaced with null. You can use
|
||||
a replacer function to replace those with JSON values.
|
||||
JSON.stringify(undefined) returns undefined.
|
||||
|
||||
The optional space parameter produces a stringification of the
|
||||
value that is filled with line breaks and indentation to make it
|
||||
easier to read.
|
||||
|
||||
If the space parameter is a non-empty string, then that string will
|
||||
be used for indentation. If the space parameter is a number, then
|
||||
the indentation will be that many spaces.
|
||||
|
||||
Example:
|
||||
|
||||
text = JSON.stringify(['e', {pluribus: 'unum'}]);
|
||||
// text is '["e",{"pluribus":"unum"}]'
|
||||
|
||||
|
||||
text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
|
||||
// text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
|
||||
|
||||
text = JSON.stringify([new Date()], function (key, value) {
|
||||
return this[key] instanceof Date
|
||||
? 'Date(' + this[key] + ')'
|
||||
: value;
|
||||
});
|
||||
// text is '["Date(---current time---)"]'
|
||||
|
||||
|
||||
JSON.parse(text, reviver)
|
||||
This method parses a JSON text to produce an object or array.
|
||||
It can throw a SyntaxError exception.
|
||||
|
||||
The optional reviver parameter is a function that can filter and
|
||||
transform the results. It receives each of the keys and values,
|
||||
and its return value is used instead of the original value.
|
||||
If it returns what it received, then the structure is not modified.
|
||||
If it returns undefined then the member is deleted.
|
||||
|
||||
Example:
|
||||
|
||||
// Parse the text. Values that look like ISO date strings will
|
||||
// be converted to Date objects.
|
||||
|
||||
myData = JSON.parse(text, function (key, value) {
|
||||
var a;
|
||||
if (typeof value === 'string') {
|
||||
a =
|
||||
/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
|
||||
if (a) {
|
||||
return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
|
||||
+a[5], +a[6]));
|
||||
}
|
||||
}
|
||||
return value;
|
||||
});
|
||||
|
||||
myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
|
||||
var d;
|
||||
if (typeof value === 'string' &&
|
||||
value.slice(0, 5) === 'Date(' &&
|
||||
value.slice(-1) === ')') {
|
||||
d = new Date(value.slice(5, -1));
|
||||
if (d) {
|
||||
return d;
|
||||
}
|
||||
}
|
||||
return value;
|
||||
});
|
||||
|
||||
|
||||
This is a reference implementation. You are free to copy, modify, or
|
||||
redistribute.
|
||||
*/
|
||||
|
||||
/*jslint
|
||||
eval, for, this
|
||||
*/
|
||||
|
||||
/*property
|
||||
JSON, apply, call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
|
||||
getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
|
||||
lastIndex, length, parse, prototype, push, replace, slice, stringify,
|
||||
test, toJSON, toString, valueOf
|
||||
*/
|
||||
|
||||
|
||||
// Create a JSON object only if one does not already exist. We create the
|
||||
// methods in a closure to avoid creating global variables.
|
||||
|
||||
if (typeof JSON !== 'object') {
|
||||
JSON = {};
|
||||
}
|
||||
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
var rx_one = /^[\],:{}\s]*$/,
|
||||
rx_two = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,
|
||||
rx_three = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
|
||||
rx_four = /(?:^|:|,)(?:\s*\[)+/g,
|
||||
rx_escapable = /[\\\"\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
|
||||
rx_dangerous = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
|
||||
|
||||
function f(n) {
|
||||
// Format integers to have at least two digits.
|
||||
return n < 10
|
||||
? '0' + n
|
||||
: n;
|
||||
}
|
||||
|
||||
function this_value() {
|
||||
return this.valueOf();
|
||||
}
|
||||
|
||||
if (typeof Date.prototype.toJSON !== 'function') {
|
||||
|
||||
Date.prototype.toJSON = function () {
|
||||
|
||||
return isFinite(this.valueOf())
|
||||
? this.getUTCFullYear() + '-' +
|
||||
f(this.getUTCMonth() + 1) + '-' +
|
||||
f(this.getUTCDate()) + 'T' +
|
||||
f(this.getUTCHours()) + ':' +
|
||||
f(this.getUTCMinutes()) + ':' +
|
||||
f(this.getUTCSeconds()) + 'Z'
|
||||
: null;
|
||||
};
|
||||
|
||||
Boolean.prototype.toJSON = this_value;
|
||||
Number.prototype.toJSON = this_value;
|
||||
String.prototype.toJSON = this_value;
|
||||
}
|
||||
|
||||
var gap,
|
||||
indent,
|
||||
meta,
|
||||
rep;
|
||||
|
||||
|
||||
function quote(string) {
|
||||
|
||||
// If the string contains no control characters, no quote characters, and no
|
||||
// backslash characters, then we can safely slap some quotes around it.
|
||||
// Otherwise we must also replace the offending characters with safe escape
|
||||
// sequences.
|
||||
|
||||
rx_escapable.lastIndex = 0;
|
||||
return rx_escapable.test(string)
|
||||
? '"' + string.replace(rx_escapable, function (a) {
|
||||
var c = meta[a];
|
||||
return typeof c === 'string'
|
||||
? c
|
||||
: '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
|
||||
}) + '"'
|
||||
: '"' + string + '"';
|
||||
}
|
||||
|
||||
|
||||
function str(key, holder) {
|
||||
|
||||
// Produce a string from holder[key].
|
||||
|
||||
var i, // The loop counter.
|
||||
k, // The member key.
|
||||
v, // The member value.
|
||||
length,
|
||||
mind = gap,
|
||||
partial,
|
||||
value = holder[key];
|
||||
|
||||
// If the value has a toJSON method, call it to obtain a replacement value.
|
||||
|
||||
if (value && typeof value === 'object' &&
|
||||
typeof value.toJSON === 'function') {
|
||||
value = value.toJSON(key);
|
||||
}
|
||||
|
||||
// If we were called with a replacer function, then call the replacer to
|
||||
// obtain a replacement value.
|
||||
|
||||
if (typeof rep === 'function') {
|
||||
value = rep.call(holder, key, value);
|
||||
}
|
||||
|
||||
// What happens next depends on the value's type.
|
||||
|
||||
switch (typeof value) {
|
||||
case 'string':
|
||||
return quote(value);
|
||||
|
||||
case 'number':
|
||||
|
||||
// JSON numbers must be finite. Encode non-finite numbers as null.
|
||||
|
||||
return isFinite(value)
|
||||
? String(value)
|
||||
: 'null';
|
||||
|
||||
case 'boolean':
|
||||
case 'null':
|
||||
|
||||
// If the value is a boolean or null, convert it to a string. Note:
|
||||
// typeof null does not produce 'null'. The case is included here in
|
||||
// the remote chance that this gets fixed someday.
|
||||
|
||||
return String(value);
|
||||
|
||||
// If the type is 'object', we might be dealing with an object or an array or
|
||||
// null.
|
||||
|
||||
case 'object':
|
||||
|
||||
// Due to a specification blunder in ECMAScript, typeof null is 'object',
|
||||
// so watch out for that case.
|
||||
|
||||
if (!value) {
|
||||
return 'null';
|
||||
}
|
||||
|
||||
// Make an array to hold the partial results of stringifying this object value.
|
||||
|
||||
gap += indent;
|
||||
partial = [];
|
||||
|
||||
// Is the value an array?
|
||||
|
||||
if (Object.prototype.toString.apply(value) === '[object Array]') {
|
||||
|
||||
// The value is an array. Stringify every element. Use null as a placeholder
|
||||
// for non-JSON values.
|
||||
|
||||
length = value.length;
|
||||
for (i = 0; i < length; i += 1) {
|
||||
partial[i] = str(i, value) || 'null';
|
||||
}
|
||||
|
||||
// Join all of the elements together, separated with commas, and wrap them in
|
||||
// brackets.
|
||||
|
||||
v = partial.length === 0
|
||||
? '[]'
|
||||
: gap
|
||||
? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']'
|
||||
: '[' + partial.join(',') + ']';
|
||||
gap = mind;
|
||||
return v;
|
||||
}
|
||||
|
||||
// If the replacer is an array, use it to select the members to be stringified.
|
||||
|
||||
if (rep && typeof rep === 'object') {
|
||||
length = rep.length;
|
||||
for (i = 0; i < length; i += 1) {
|
||||
if (typeof rep[i] === 'string') {
|
||||
k = rep[i];
|
||||
v = str(k, value);
|
||||
if (v) {
|
||||
partial.push(quote(k) + (
|
||||
gap
|
||||
? ': '
|
||||
: ':'
|
||||
) + v);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
// Otherwise, iterate through all of the keys in the object.
|
||||
|
||||
for (k in value) {
|
||||
if (Object.prototype.hasOwnProperty.call(value, k)) {
|
||||
v = str(k, value);
|
||||
if (v) {
|
||||
partial.push(quote(k) + (
|
||||
gap
|
||||
? ': '
|
||||
: ':'
|
||||
) + v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Join all of the member texts together, separated with commas,
|
||||
// and wrap them in braces.
|
||||
|
||||
v = partial.length === 0
|
||||
? '{}'
|
||||
: gap
|
||||
? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}'
|
||||
: '{' + partial.join(',') + '}';
|
||||
gap = mind;
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
// If the JSON object does not yet have a stringify method, give it one.
|
||||
|
||||
if (typeof JSON.stringify !== 'function') {
|
||||
meta = { // table of character substitutions
|
||||
'\b': '\\b',
|
||||
'\t': '\\t',
|
||||
'\n': '\\n',
|
||||
'\f': '\\f',
|
||||
'\r': '\\r',
|
||||
'"': '\\"',
|
||||
'\\': '\\\\'
|
||||
};
|
||||
JSON.stringify = function (value, replacer, space) {
|
||||
|
||||
// The stringify method takes a value and an optional replacer, and an optional
|
||||
// space parameter, and returns a JSON text. The replacer can be a function
|
||||
// that can replace values, or an array of strings that will select the keys.
|
||||
// A default replacer method can be provided. Use of the space parameter can
|
||||
// produce text that is more easily readable.
|
||||
|
||||
var i;
|
||||
gap = '';
|
||||
indent = '';
|
||||
|
||||
// If the space parameter is a number, make an indent string containing that
|
||||
// many spaces.
|
||||
|
||||
if (typeof space === 'number') {
|
||||
for (i = 0; i < space; i += 1) {
|
||||
indent += ' ';
|
||||
}
|
||||
|
||||
// If the space parameter is a string, it will be used as the indent string.
|
||||
|
||||
} else if (typeof space === 'string') {
|
||||
indent = space;
|
||||
}
|
||||
|
||||
// If there is a replacer, it must be a function or an array.
|
||||
// Otherwise, throw an error.
|
||||
|
||||
rep = replacer;
|
||||
if (replacer && typeof replacer !== 'function' &&
|
||||
(typeof replacer !== 'object' ||
|
||||
typeof replacer.length !== 'number')) {
|
||||
throw new Error('JSON.stringify');
|
||||
}
|
||||
|
||||
// Make a fake root object containing our value under the key of ''.
|
||||
// Return the result of stringifying the value.
|
||||
|
||||
return str('', {'': value});
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
// If the JSON object does not yet have a parse method, give it one.
|
||||
|
||||
if (typeof JSON.parse !== 'function') {
|
||||
JSON.parse = function (text, reviver) {
|
||||
|
||||
// The parse method takes a text and an optional reviver function, and returns
|
||||
// a JavaScript value if the text is a valid JSON text.
|
||||
|
||||
var j;
|
||||
|
||||
function walk(holder, key) {
|
||||
|
||||
// The walk method is used to recursively walk the resulting structure so
|
||||
// that modifications can be made.
|
||||
|
||||
var k, v, value = holder[key];
|
||||
if (value && typeof value === 'object') {
|
||||
for (k in value) {
|
||||
if (Object.prototype.hasOwnProperty.call(value, k)) {
|
||||
v = walk(value, k);
|
||||
if (v !== undefined) {
|
||||
value[k] = v;
|
||||
} else {
|
||||
delete value[k];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return reviver.call(holder, key, value);
|
||||
}
|
||||
|
||||
|
||||
// Parsing happens in four stages. In the first stage, we replace certain
|
||||
// Unicode characters with escape sequences. JavaScript handles many characters
|
||||
// incorrectly, either silently deleting them, or treating them as line endings.
|
||||
|
||||
text = String(text);
|
||||
rx_dangerous.lastIndex = 0;
|
||||
if (rx_dangerous.test(text)) {
|
||||
text = text.replace(rx_dangerous, function (a) {
|
||||
return '\\u' +
|
||||
('0000' + a.charCodeAt(0).toString(16)).slice(-4);
|
||||
});
|
||||
}
|
||||
|
||||
// In the second stage, we run the text against regular expressions that look
|
||||
// for non-JSON patterns. We are especially concerned with '()' and 'new'
|
||||
// because they can cause invocation, and '=' because it can cause mutation.
|
||||
// But just to be safe, we want to reject all unexpected forms.
|
||||
|
||||
// We split the second stage into 4 regexp operations in order to work around
|
||||
// crippling inefficiencies in IE's and Safari's regexp engines. First we
|
||||
// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
|
||||
// replace all simple value tokens with ']' characters. Third, we delete all
|
||||
// open brackets that follow a colon or comma or that begin the text. Finally,
|
||||
// we look to see that the remaining characters are only whitespace or ']' or
|
||||
// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
|
||||
|
||||
if (
|
||||
rx_one.test(
|
||||
text
|
||||
.replace(rx_two, '@')
|
||||
.replace(rx_three, ']')
|
||||
.replace(rx_four, '')
|
||||
)
|
||||
) {
|
||||
|
||||
// In the third stage we use the eval function to compile the text into a
|
||||
// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
|
||||
// in JavaScript: it can begin a block or an object literal. We wrap the text
|
||||
// in parens to eliminate the ambiguity.
|
||||
|
||||
j = eval('(' + text + ')');
|
||||
|
||||
// In the optional fourth stage, we recursively walk the new structure, passing
|
||||
// each name/value pair to a reviver function for possible transformation.
|
||||
|
||||
return typeof reviver === 'function'
|
||||
? walk({'': j}, '')
|
||||
: j;
|
||||
}
|
||||
|
||||
// If the text is not JSON parseable, then a SyntaxError is thrown.
|
||||
|
||||
throw new SyntaxError('JSON.parse');
|
||||
};
|
||||
}
|
||||
}());
|
||||
@@ -0,0 +1,84 @@
|
||||
/* global console, MediaElementPlayer, mejs */
|
||||
(function ( window, $ ) {
|
||||
// Reintegrate `plugins` since they don't exist in MEJS anymore; it won't affect anything in the player
|
||||
if (mejs.plugins === undefined) {
|
||||
mejs.plugins = {};
|
||||
mejs.plugins.silverlight = [];
|
||||
mejs.plugins.silverlight.push({
|
||||
types: []
|
||||
});
|
||||
}
|
||||
|
||||
// Inclusion of old `HtmlMediaElementShim` if it doesn't exist
|
||||
mejs.HtmlMediaElementShim = mejs.HtmlMediaElementShim || {
|
||||
getTypeFromFile: mejs.Utils.getTypeFromFile
|
||||
};
|
||||
|
||||
// Add missing global variables for backward compatibility
|
||||
if (mejs.MediaFeatures === undefined) {
|
||||
mejs.MediaFeatures = mejs.Features;
|
||||
}
|
||||
if (mejs.Utility === undefined) {
|
||||
mejs.Utility = mejs.Utils;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create missing variables and have default `classPrefix` overridden to avoid issues.
|
||||
*
|
||||
* `media` is now a fake wrapper needed to simplify manipulation of various media types,
|
||||
* so in order to access the `video` or `audio` tag, use `media.originalNode` or `player.node`;
|
||||
* `player.container` used to be jQuery but now is a HTML element, and many elements inside
|
||||
* the player rely on it being a HTML now, so its conversion is difficult; however, a
|
||||
* `player.$container` new variable has been added to be used as jQuery object
|
||||
*/
|
||||
var init = MediaElementPlayer.prototype.init;
|
||||
MediaElementPlayer.prototype.init = function () {
|
||||
this.options.classPrefix = 'mejs-';
|
||||
this.$media = this.$node = $( this.node );
|
||||
init.call( this );
|
||||
};
|
||||
|
||||
var ready = MediaElementPlayer.prototype._meReady;
|
||||
MediaElementPlayer.prototype._meReady = function () {
|
||||
this.container = $( this.container) ;
|
||||
this.controls = $( this.controls );
|
||||
this.layers = $( this.layers );
|
||||
ready.apply( this, arguments );
|
||||
};
|
||||
|
||||
// Override method so certain elements can be called with jQuery
|
||||
MediaElementPlayer.prototype.getElement = function ( el ) {
|
||||
return $ !== undefined && el instanceof $ ? el[0] : el;
|
||||
};
|
||||
|
||||
// Add jQuery ONLY to most of custom features' arguments for backward compatibility; default features rely 100%
|
||||
// on the arguments being HTML elements to work properly
|
||||
MediaElementPlayer.prototype.buildfeatures = function ( player, controls, layers, media ) {
|
||||
var defaultFeatures = [
|
||||
'playpause',
|
||||
'current',
|
||||
'progress',
|
||||
'duration',
|
||||
'tracks',
|
||||
'volume',
|
||||
'fullscreen'
|
||||
];
|
||||
for (var i = 0, total = this.options.features.length; i < total; i++) {
|
||||
var feature = this.options.features[i];
|
||||
if (this['build' + feature]) {
|
||||
try {
|
||||
// Use jQuery for non-default features
|
||||
if (defaultFeatures.indexOf(feature) === -1) {
|
||||
this['build' + feature]( player, $(controls), $(layers), media );
|
||||
} else {
|
||||
this['build' + feature]( player, controls, layers, media );
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
console.error( 'error building ' + feature, e );
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
})( window, jQuery );
|
||||
@@ -0,0 +1,772 @@
|
||||
/* Accessibility: hide screen reader texts (and prefer "top" for RTL languages).
|
||||
Reference: http://blog.rrwd.nl/2015/04/04/the-screen-reader-text-class-why-and-how/ */
|
||||
.mejs-offscreen {
|
||||
border: 0;
|
||||
clip: rect( 1px, 1px, 1px, 1px );
|
||||
-webkit-clip-path: inset( 50% );
|
||||
clip-path: inset( 50% );
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
word-wrap: normal;
|
||||
}
|
||||
|
||||
.mejs-container {
|
||||
background: #000;
|
||||
box-sizing: border-box;
|
||||
font-family: 'Helvetica', Arial, serif;
|
||||
position: relative;
|
||||
text-align: left;
|
||||
text-indent: 0;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.mejs-container * {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* Hide native play button and control bar from iOS to favor plugin button */
|
||||
.mejs-container video::-webkit-media-controls,
|
||||
.mejs-container video::-webkit-media-controls-panel,
|
||||
.mejs-container video::-webkit-media-controls-panel-container,
|
||||
.mejs-container video::-webkit-media-controls-start-playback-button {
|
||||
-webkit-appearance: none;
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.mejs-fill-container,
|
||||
.mejs-fill-container .mejs-container {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mejs-fill-container {
|
||||
background: transparent;
|
||||
margin: 0 auto;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.mejs-container:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.mejs-iframe-overlay {
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mejs-embed,
|
||||
.mejs-embed body {
|
||||
background: #000;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mejs-fullscreen {
|
||||
overflow: hidden !important;
|
||||
}
|
||||
|
||||
.mejs-container-fullscreen {
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
overflow: hidden;
|
||||
position: fixed;
|
||||
right: 0;
|
||||
top: 0;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.mejs-container-fullscreen .mejs-mediaelement,
|
||||
.mejs-container-fullscreen video {
|
||||
height: 100% !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
/* Start: LAYERS */
|
||||
.mejs-background {
|
||||
left: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.mejs-mediaelement {
|
||||
height: 100%;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.mejs-poster {
|
||||
background-position: 50% 50%;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
:root .mejs-poster-img {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.mejs-poster-img {
|
||||
border: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.mejs-overlay {
|
||||
-webkit-box-align: center;
|
||||
-webkit-align-items: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-pack: center;
|
||||
-webkit-justify-content: center;
|
||||
-ms-flex-pack: center;
|
||||
justify-content: center;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.mejs-layer {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.mejs-overlay-play {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mejs-overlay-button {
|
||||
background: url('mejs-controls.svg') no-repeat;
|
||||
background-position: 0 -39px;
|
||||
height: 80px;
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
.mejs-overlay:hover > .mejs-overlay-button {
|
||||
background-position: -80px -39px;
|
||||
}
|
||||
|
||||
.mejs-overlay-loading {
|
||||
height: 80px;
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
.mejs-overlay-loading-bg-img {
|
||||
-webkit-animation: mejs-loading-spinner 1s linear infinite;
|
||||
animation: mejs-loading-spinner 1s linear infinite;
|
||||
background: transparent url('mejs-controls.svg') -160px -40px no-repeat;
|
||||
display: block;
|
||||
height: 80px;
|
||||
width: 80px;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
@-webkit-keyframes mejs-loading-spinner {
|
||||
100% {
|
||||
-webkit-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes mejs-loading-spinner {
|
||||
100% {
|
||||
-webkit-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
/* End: LAYERS */
|
||||
|
||||
/* Start: CONTROL BAR */
|
||||
.mejs-controls {
|
||||
bottom: 0;
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
height: 40px;
|
||||
left: 0;
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
padding: 0 10px;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
.mejs-controls:not([style*='display: none']) {
|
||||
background: rgba(255, 0, 0, 0.7);
|
||||
background: -webkit-linear-gradient(transparent, rgba(0, 0, 0, 0.35));
|
||||
background: linear-gradient(transparent, rgba(0, 0, 0, 0.35));
|
||||
}
|
||||
|
||||
.mejs-button,
|
||||
.mejs-time,
|
||||
.mejs-time-rail {
|
||||
font-size: 10px;
|
||||
height: 40px;
|
||||
line-height: 10px;
|
||||
margin: 0;
|
||||
width: 32px;
|
||||
}
|
||||
|
||||
.mejs-button > button {
|
||||
background: transparent url('mejs-controls.svg');
|
||||
border: 0;
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
font-size: 0;
|
||||
height: 20px;
|
||||
line-height: 0;
|
||||
margin: 10px 6px;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
text-decoration: none;
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
/* :focus for accessibility */
|
||||
.mejs-button > button:focus {
|
||||
outline: dotted 1px #999;
|
||||
}
|
||||
|
||||
.mejs-container-keyboard-inactive a,
|
||||
.mejs-container-keyboard-inactive a:focus,
|
||||
.mejs-container-keyboard-inactive button,
|
||||
.mejs-container-keyboard-inactive button:focus,
|
||||
.mejs-container-keyboard-inactive [role=slider],
|
||||
.mejs-container-keyboard-inactive [role=slider]:focus {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
/* End: CONTROL BAR */
|
||||
|
||||
/* Start: Time (Current / Duration) */
|
||||
.mejs-time {
|
||||
box-sizing: content-box;
|
||||
color: #fff;
|
||||
font-size: 11px;
|
||||
font-weight: bold;
|
||||
height: 24px;
|
||||
overflow: hidden;
|
||||
padding: 16px 6px 0;
|
||||
text-align: center;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
/* End: Time (Current / Duration) */
|
||||
|
||||
/* Start: Play/Pause/Stop */
|
||||
.mejs-play > button {
|
||||
background-position: 0 0;
|
||||
}
|
||||
|
||||
.mejs-pause > button {
|
||||
background-position: -20px 0;
|
||||
}
|
||||
|
||||
.mejs-replay > button {
|
||||
background-position: -160px 0;
|
||||
}
|
||||
|
||||
/* End: Play/Pause/Stop */
|
||||
|
||||
/* Start: Progress Bar */
|
||||
.mejs-time-rail {
|
||||
direction: ltr;
|
||||
-webkit-box-flex: 1;
|
||||
-webkit-flex-grow: 1;
|
||||
-ms-flex-positive: 1;
|
||||
flex-grow: 1;
|
||||
height: 40px;
|
||||
margin: 0 10px;
|
||||
padding-top: 10px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.mejs-time-total,
|
||||
.mejs-time-buffering,
|
||||
.mejs-time-loaded,
|
||||
.mejs-time-current,
|
||||
.mejs-time-float,
|
||||
.mejs-time-hovered,
|
||||
.mejs-time-float-current,
|
||||
.mejs-time-float-corner,
|
||||
.mejs-time-marker {
|
||||
border-radius: 2px;
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
height: 10px;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.mejs-time-total {
|
||||
background: rgba(255, 255, 255, 0.3);
|
||||
margin: 5px 0 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mejs-time-buffering {
|
||||
-webkit-animation: buffering-stripes 2s linear infinite;
|
||||
animation: buffering-stripes 2s linear infinite;
|
||||
background: -webkit-linear-gradient(135deg, rgba(255, 255, 255, 0.4) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.4) 50%, rgba(255, 255, 255, 0.4) 75%, transparent 75%, transparent);
|
||||
background: linear-gradient(-45deg, rgba(255, 255, 255, 0.4) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.4) 50%, rgba(255, 255, 255, 0.4) 75%, transparent 75%, transparent);
|
||||
background-size: 15px 15px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@-webkit-keyframes buffering-stripes {
|
||||
from {
|
||||
background-position: 0 0;
|
||||
}
|
||||
to {
|
||||
background-position: 30px 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes buffering-stripes {
|
||||
from {
|
||||
background-position: 0 0;
|
||||
}
|
||||
to {
|
||||
background-position: 30px 0;
|
||||
}
|
||||
}
|
||||
|
||||
.mejs-time-loaded {
|
||||
background: rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
|
||||
.mejs-time-current,
|
||||
.mejs-time-handle-content {
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
}
|
||||
|
||||
.mejs-time-hovered {
|
||||
background: rgba(255, 255, 255, 0.5);
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.mejs-time-hovered.negative {
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.mejs-time-current,
|
||||
.mejs-time-buffering,
|
||||
.mejs-time-loaded,
|
||||
.mejs-time-hovered {
|
||||
left: 0;
|
||||
-webkit-transform: scaleX(0);
|
||||
-ms-transform: scaleX(0);
|
||||
transform: scaleX(0);
|
||||
-webkit-transform-origin: 0 0;
|
||||
-ms-transform-origin: 0 0;
|
||||
transform-origin: 0 0;
|
||||
-webkit-transition: 0.15s ease-in all;
|
||||
transition: 0.15s ease-in all;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mejs-time-buffering {
|
||||
-webkit-transform: scaleX(1);
|
||||
-ms-transform: scaleX(1);
|
||||
transform: scaleX(1);
|
||||
}
|
||||
|
||||
.mejs-time-hovered {
|
||||
-webkit-transition: height 0.1s cubic-bezier(0.44, 0, 1, 1);
|
||||
transition: height 0.1s cubic-bezier(0.44, 0, 1, 1);
|
||||
}
|
||||
|
||||
.mejs-time-hovered.no-hover {
|
||||
-webkit-transform: scaleX(0) !important;
|
||||
-ms-transform: scaleX(0) !important;
|
||||
transform: scaleX(0) !important;
|
||||
}
|
||||
|
||||
.mejs-time-handle,
|
||||
.mejs-time-handle-content {
|
||||
border: 4px solid transparent;
|
||||
cursor: pointer;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
-webkit-transform: translateX(0);
|
||||
-ms-transform: translateX(0);
|
||||
transform: translateX(0);
|
||||
z-index: 11;
|
||||
}
|
||||
|
||||
.mejs-time-handle-content {
|
||||
border: 4px solid rgba(255, 255, 255, 0.9);
|
||||
border-radius: 50%;
|
||||
height: 10px;
|
||||
left: -7px;
|
||||
top: -4px;
|
||||
-webkit-transform: scale(0);
|
||||
-ms-transform: scale(0);
|
||||
transform: scale(0);
|
||||
width: 10px;
|
||||
}
|
||||
|
||||
.mejs-time-rail:hover .mejs-time-handle-content,
|
||||
.mejs-time-rail .mejs-time-handle-content:focus,
|
||||
.mejs-time-rail .mejs-time-handle-content:active {
|
||||
-webkit-transform: scale(1);
|
||||
-ms-transform: scale(1);
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
.mejs-time-float {
|
||||
background: #eee;
|
||||
border: solid 1px #333;
|
||||
bottom: 100%;
|
||||
color: #111;
|
||||
display: none;
|
||||
height: 17px;
|
||||
margin-bottom: 9px;
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
-webkit-transform: translateX(-50%);
|
||||
-ms-transform: translateX(-50%);
|
||||
transform: translateX(-50%);
|
||||
width: 36px;
|
||||
}
|
||||
|
||||
.mejs-time-float-current {
|
||||
display: block;
|
||||
left: 0;
|
||||
margin: 2px;
|
||||
text-align: center;
|
||||
width: 30px;
|
||||
}
|
||||
|
||||
.mejs-time-float-corner {
|
||||
border: solid 5px #eee;
|
||||
border-color: #eee transparent transparent;
|
||||
border-radius: 0;
|
||||
display: block;
|
||||
height: 0;
|
||||
left: 50%;
|
||||
line-height: 0;
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
-webkit-transform: translateX(-50%);
|
||||
-ms-transform: translateX(-50%);
|
||||
transform: translateX(-50%);
|
||||
width: 0;
|
||||
}
|
||||
|
||||
.mejs-long-video .mejs-time-float {
|
||||
margin-left: -23px;
|
||||
width: 64px;
|
||||
}
|
||||
|
||||
.mejs-long-video .mejs-time-float-current {
|
||||
width: 60px;
|
||||
}
|
||||
|
||||
.mejs-broadcast {
|
||||
color: #fff;
|
||||
height: 10px;
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* End: Progress Bar */
|
||||
|
||||
/* Start: Fullscreen */
|
||||
.mejs-fullscreen-button > button {
|
||||
background-position: -80px 0;
|
||||
}
|
||||
|
||||
.mejs-unfullscreen > button {
|
||||
background-position: -100px 0;
|
||||
}
|
||||
|
||||
/* End: Fullscreen */
|
||||
|
||||
/* Start: Mute/Volume */
|
||||
.mejs-mute > button {
|
||||
background-position: -60px 0;
|
||||
}
|
||||
|
||||
.mejs-unmute > button {
|
||||
background-position: -40px 0;
|
||||
}
|
||||
|
||||
.mejs-volume-button {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.mejs-volume-button > .mejs-volume-slider {
|
||||
-webkit-backface-visibility: hidden;
|
||||
background: rgba(50, 50, 50, 0.7);
|
||||
border-radius: 0;
|
||||
bottom: 100%;
|
||||
display: none;
|
||||
height: 115px;
|
||||
left: 50%;
|
||||
margin: 0;
|
||||
position: absolute;
|
||||
-webkit-transform: translateX(-50%);
|
||||
-ms-transform: translateX(-50%);
|
||||
transform: translateX(-50%);
|
||||
width: 25px;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.mejs-volume-button:hover {
|
||||
border-radius: 0 0 4px 4px;
|
||||
}
|
||||
|
||||
.mejs-volume-total {
|
||||
background: rgba(255, 255, 255, 0.5);
|
||||
height: 100px;
|
||||
left: 50%;
|
||||
margin: 0;
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
-webkit-transform: translateX(-50%);
|
||||
-ms-transform: translateX(-50%);
|
||||
transform: translateX(-50%);
|
||||
width: 2px;
|
||||
}
|
||||
|
||||
.mejs-volume-current {
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
left: 0;
|
||||
margin: 0;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mejs-volume-handle {
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
border-radius: 1px;
|
||||
cursor: ns-resize;
|
||||
height: 6px;
|
||||
left: 50%;
|
||||
position: absolute;
|
||||
-webkit-transform: translateX(-50%);
|
||||
-ms-transform: translateX(-50%);
|
||||
transform: translateX(-50%);
|
||||
width: 16px;
|
||||
}
|
||||
|
||||
.mejs-horizontal-volume-slider {
|
||||
display: block;
|
||||
height: 36px;
|
||||
position: relative;
|
||||
vertical-align: middle;
|
||||
width: 56px;
|
||||
}
|
||||
|
||||
.mejs-horizontal-volume-total {
|
||||
background: rgba(50, 50, 50, 0.8);
|
||||
border-radius: 2px;
|
||||
font-size: 1px;
|
||||
height: 8px;
|
||||
left: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
top: 16px;
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
.mejs-horizontal-volume-current {
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
border-radius: 2px;
|
||||
font-size: 1px;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mejs-horizontal-volume-handle {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* End: Mute/Volume */
|
||||
|
||||
/* Start: Track (Captions and Chapters) */
|
||||
.mejs-captions-button,
|
||||
.mejs-chapters-button {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.mejs-captions-button > button {
|
||||
background-position: -140px 0;
|
||||
}
|
||||
|
||||
.mejs-chapters-button > button {
|
||||
background-position: -180px 0;
|
||||
}
|
||||
|
||||
.mejs-captions-button > .mejs-captions-selector,
|
||||
.mejs-chapters-button > .mejs-chapters-selector {
|
||||
background: rgba(50, 50, 50, 0.7);
|
||||
border: solid 1px transparent;
|
||||
border-radius: 0;
|
||||
bottom: 100%;
|
||||
margin-right: -43px;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
right: 50%;
|
||||
visibility: visible;
|
||||
width: 86px;
|
||||
}
|
||||
|
||||
.mejs-chapters-button > .mejs-chapters-selector {
|
||||
margin-right: -55px;
|
||||
width: 110px;
|
||||
}
|
||||
|
||||
.mejs-captions-selector-list,
|
||||
.mejs-chapters-selector-list {
|
||||
list-style-type: none !important;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.mejs-captions-selector-list-item,
|
||||
.mejs-chapters-selector-list-item {
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
list-style-type: none !important;
|
||||
margin: 0 0 6px;
|
||||
overflow: hidden;
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
.mejs-captions-selector-list-item:hover,
|
||||
.mejs-chapters-selector-list-item:hover {
|
||||
background-color: rgb(200, 200, 200) !important;
|
||||
background-color: rgba(255, 255, 255, 0.4) !important;
|
||||
}
|
||||
|
||||
.mejs-captions-selector-input,
|
||||
.mejs-chapters-selector-input {
|
||||
clear: both;
|
||||
float: left;
|
||||
left: -1000px;
|
||||
margin: 3px 3px 0 5px;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.mejs-captions-selector-label,
|
||||
.mejs-chapters-selector-label {
|
||||
cursor: pointer;
|
||||
float: left;
|
||||
font-size: 10px;
|
||||
line-height: 15px;
|
||||
padding: 4px 0 0;
|
||||
}
|
||||
|
||||
.mejs-captions-selected,
|
||||
.mejs-chapters-selected {
|
||||
color: rgba(33, 248, 248, 1);
|
||||
}
|
||||
|
||||
.mejs-captions-translations {
|
||||
font-size: 10px;
|
||||
margin: 0 0 5px;
|
||||
}
|
||||
|
||||
.mejs-captions-layer {
|
||||
bottom: 0;
|
||||
color: #fff;
|
||||
font-size: 16px;
|
||||
left: 0;
|
||||
line-height: 20px;
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.mejs-captions-layer a {
|
||||
color: #fff;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.mejs-captions-layer[lang=ar] {
|
||||
font-size: 20px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.mejs-captions-position {
|
||||
bottom: 15px;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mejs-captions-position-hover {
|
||||
bottom: 35px;
|
||||
}
|
||||
|
||||
.mejs-captions-text,
|
||||
.mejs-captions-text * {
|
||||
background: rgba(20, 20, 20, 0.5);
|
||||
box-shadow: 5px 0 0 rgba(20, 20, 20, 0.5), -5px 0 0 rgba(20, 20, 20, 0.5);
|
||||
padding: 0;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.mejs-container.mejs-hide-cues video::-webkit-media-text-track-container {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* End: Track (Captions and Chapters) */
|
||||
|
||||
/* Start: Error */
|
||||
.mejs-overlay-error {
|
||||
position: relative;
|
||||
}
|
||||
.mejs-overlay-error > img {
|
||||
left: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
z-index: -1;
|
||||
}
|
||||
.mejs-cannotplay,
|
||||
.mejs-cannotplay a {
|
||||
color: #fff;
|
||||
font-size: 0.8em;
|
||||
}
|
||||
|
||||
.mejs-cannotplay {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.mejs-cannotplay p,
|
||||
.mejs-cannotplay a {
|
||||
display: inline-block;
|
||||
padding: 0 15px;
|
||||
width: 100%;
|
||||
}
|
||||
/* End: Error */
|
||||
@@ -0,0 +1,772 @@
|
||||
/* Accessibility: hide screen reader texts (and prefer "top" for RTL languages).
|
||||
Reference: http://blog.rrwd.nl/2015/04/04/the-screen-reader-text-class-why-and-how/ */
|
||||
.mejs__offscreen {
|
||||
border: 0;
|
||||
clip: rect( 1px, 1px, 1px, 1px );
|
||||
-webkit-clip-path: inset( 50% );
|
||||
clip-path: inset( 50% );
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
word-wrap: normal;
|
||||
}
|
||||
|
||||
.mejs__container {
|
||||
background: #000;
|
||||
box-sizing: border-box;
|
||||
font-family: 'Helvetica', Arial, serif;
|
||||
position: relative;
|
||||
text-align: left;
|
||||
text-indent: 0;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.mejs__container * {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* Hide native play button and control bar from iOS to favor plugin button */
|
||||
.mejs__container video::-webkit-media-controls,
|
||||
.mejs__container video::-webkit-media-controls-panel,
|
||||
.mejs__container video::-webkit-media-controls-panel-container,
|
||||
.mejs__container video::-webkit-media-controls-start-playback-button {
|
||||
-webkit-appearance: none;
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.mejs__fill-container,
|
||||
.mejs__fill-container .mejs__container {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mejs__fill-container {
|
||||
background: transparent;
|
||||
margin: 0 auto;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.mejs__container:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.mejs__iframe-overlay {
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mejs__embed,
|
||||
.mejs__embed body {
|
||||
background: #000;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mejs__fullscreen {
|
||||
overflow: hidden !important;
|
||||
}
|
||||
|
||||
.mejs__container-fullscreen {
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
overflow: hidden;
|
||||
position: fixed;
|
||||
right: 0;
|
||||
top: 0;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.mejs__container-fullscreen .mejs__mediaelement,
|
||||
.mejs__container-fullscreen video {
|
||||
height: 100% !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
/* Start: LAYERS */
|
||||
.mejs__background {
|
||||
left: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.mejs__mediaelement {
|
||||
height: 100%;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.mejs__poster {
|
||||
background-position: 50% 50%;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
:root .mejs__poster-img {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.mejs__poster-img {
|
||||
border: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.mejs__overlay {
|
||||
-webkit-box-align: center;
|
||||
-webkit-align-items: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-pack: center;
|
||||
-webkit-justify-content: center;
|
||||
-ms-flex-pack: center;
|
||||
justify-content: center;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.mejs__layer {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.mejs__overlay-play {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mejs__overlay-button {
|
||||
background: url('mejs-controls.svg') no-repeat;
|
||||
background-position: 0 -39px;
|
||||
height: 80px;
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
.mejs__overlay:hover > .mejs__overlay-button {
|
||||
background-position: -80px -39px;
|
||||
}
|
||||
|
||||
.mejs__overlay-loading {
|
||||
height: 80px;
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
.mejs__overlay-loading-bg-img {
|
||||
-webkit-animation: mejs__loading-spinner 1s linear infinite;
|
||||
animation: mejs__loading-spinner 1s linear infinite;
|
||||
background: transparent url('mejs-controls.svg') -160px -40px no-repeat;
|
||||
display: block;
|
||||
height: 80px;
|
||||
width: 80px;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
@-webkit-keyframes mejs__loading-spinner {
|
||||
100% {
|
||||
-webkit-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes mejs__loading-spinner {
|
||||
100% {
|
||||
-webkit-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
/* End: LAYERS */
|
||||
|
||||
/* Start: CONTROL BAR */
|
||||
.mejs__controls {
|
||||
bottom: 0;
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
height: 40px;
|
||||
left: 0;
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
padding: 0 10px;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
.mejs__controls:not([style*='display: none']) {
|
||||
background: rgba(255, 0, 0, 0.7);
|
||||
background: -webkit-linear-gradient(transparent, rgba(0, 0, 0, 0.35));
|
||||
background: linear-gradient(transparent, rgba(0, 0, 0, 0.35));
|
||||
}
|
||||
|
||||
.mejs__button,
|
||||
.mejs__time,
|
||||
.mejs__time-rail {
|
||||
font-size: 10px;
|
||||
height: 40px;
|
||||
line-height: 10px;
|
||||
margin: 0;
|
||||
width: 32px;
|
||||
}
|
||||
|
||||
.mejs__button > button {
|
||||
background: transparent url('mejs-controls.svg');
|
||||
border: 0;
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
font-size: 0;
|
||||
height: 20px;
|
||||
line-height: 0;
|
||||
margin: 10px 6px;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
text-decoration: none;
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
/* :focus for accessibility */
|
||||
.mejs__button > button:focus {
|
||||
outline: dotted 1px #999;
|
||||
}
|
||||
|
||||
.mejs__container-keyboard-inactive a,
|
||||
.mejs__container-keyboard-inactive a:focus,
|
||||
.mejs__container-keyboard-inactive button,
|
||||
.mejs__container-keyboard-inactive button:focus,
|
||||
.mejs__container-keyboard-inactive [role=slider],
|
||||
.mejs__container-keyboard-inactive [role=slider]:focus {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
/* End: CONTROL BAR */
|
||||
|
||||
/* Start: Time (Current / Duration) */
|
||||
.mejs__time {
|
||||
box-sizing: content-box;
|
||||
color: #fff;
|
||||
font-size: 11px;
|
||||
font-weight: bold;
|
||||
height: 24px;
|
||||
overflow: hidden;
|
||||
padding: 16px 6px 0;
|
||||
text-align: center;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
/* End: Time (Current / Duration) */
|
||||
|
||||
/* Start: Play/Pause/Stop */
|
||||
.mejs__play > button {
|
||||
background-position: 0 0;
|
||||
}
|
||||
|
||||
.mejs__pause > button {
|
||||
background-position: -20px 0;
|
||||
}
|
||||
|
||||
.mejs__replay > button {
|
||||
background-position: -160px 0;
|
||||
}
|
||||
|
||||
/* End: Play/Pause/Stop */
|
||||
|
||||
/* Start: Progress Bar */
|
||||
.mejs__time-rail {
|
||||
direction: ltr;
|
||||
-webkit-box-flex: 1;
|
||||
-webkit-flex-grow: 1;
|
||||
-ms-flex-positive: 1;
|
||||
flex-grow: 1;
|
||||
height: 40px;
|
||||
margin: 0 10px;
|
||||
padding-top: 10px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.mejs__time-total,
|
||||
.mejs__time-buffering,
|
||||
.mejs__time-loaded,
|
||||
.mejs__time-current,
|
||||
.mejs__time-float,
|
||||
.mejs__time-hovered,
|
||||
.mejs__time-float-current,
|
||||
.mejs__time-float-corner,
|
||||
.mejs__time-marker {
|
||||
border-radius: 2px;
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
height: 10px;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.mejs__time-total {
|
||||
background: rgba(255, 255, 255, 0.3);
|
||||
margin: 5px 0 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mejs__time-buffering {
|
||||
-webkit-animation: buffering-stripes 2s linear infinite;
|
||||
animation: buffering-stripes 2s linear infinite;
|
||||
background: -webkit-linear-gradient(135deg, rgba(255, 255, 255, 0.4) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.4) 50%, rgba(255, 255, 255, 0.4) 75%, transparent 75%, transparent);
|
||||
background: linear-gradient(-45deg, rgba(255, 255, 255, 0.4) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.4) 50%, rgba(255, 255, 255, 0.4) 75%, transparent 75%, transparent);
|
||||
background-size: 15px 15px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@-webkit-keyframes buffering-stripes {
|
||||
from {
|
||||
background-position: 0 0;
|
||||
}
|
||||
to {
|
||||
background-position: 30px 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes buffering-stripes {
|
||||
from {
|
||||
background-position: 0 0;
|
||||
}
|
||||
to {
|
||||
background-position: 30px 0;
|
||||
}
|
||||
}
|
||||
|
||||
.mejs__time-loaded {
|
||||
background: rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
|
||||
.mejs__time-current,
|
||||
.mejs__time-handle-content {
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
}
|
||||
|
||||
.mejs__time-hovered {
|
||||
background: rgba(255, 255, 255, 0.5);
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.mejs__time-hovered.negative {
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.mejs__time-current,
|
||||
.mejs__time-buffering,
|
||||
.mejs__time-loaded,
|
||||
.mejs__time-hovered {
|
||||
left: 0;
|
||||
-webkit-transform: scaleX(0);
|
||||
-ms-transform: scaleX(0);
|
||||
transform: scaleX(0);
|
||||
-webkit-transform-origin: 0 0;
|
||||
-ms-transform-origin: 0 0;
|
||||
transform-origin: 0 0;
|
||||
-webkit-transition: 0.15s ease-in all;
|
||||
transition: 0.15s ease-in all;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mejs__time-buffering {
|
||||
-webkit-transform: scaleX(1);
|
||||
-ms-transform: scaleX(1);
|
||||
transform: scaleX(1);
|
||||
}
|
||||
|
||||
.mejs__time-hovered {
|
||||
-webkit-transition: height 0.1s cubic-bezier(0.44, 0, 1, 1);
|
||||
transition: height 0.1s cubic-bezier(0.44, 0, 1, 1);
|
||||
}
|
||||
|
||||
.mejs__time-hovered.no-hover {
|
||||
-webkit-transform: scaleX(0) !important;
|
||||
-ms-transform: scaleX(0) !important;
|
||||
transform: scaleX(0) !important;
|
||||
}
|
||||
|
||||
.mejs__time-handle,
|
||||
.mejs__time-handle-content {
|
||||
border: 4px solid transparent;
|
||||
cursor: pointer;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
-webkit-transform: translateX(0);
|
||||
-ms-transform: translateX(0);
|
||||
transform: translateX(0);
|
||||
z-index: 11;
|
||||
}
|
||||
|
||||
.mejs__time-handle-content {
|
||||
border: 4px solid rgba(255, 255, 255, 0.9);
|
||||
border-radius: 50%;
|
||||
height: 10px;
|
||||
left: -7px;
|
||||
top: -4px;
|
||||
-webkit-transform: scale(0);
|
||||
-ms-transform: scale(0);
|
||||
transform: scale(0);
|
||||
width: 10px;
|
||||
}
|
||||
|
||||
.mejs__time-rail:hover .mejs__time-handle-content,
|
||||
.mejs__time-rail .mejs__time-handle-content:focus,
|
||||
.mejs__time-rail .mejs__time-handle-content:active {
|
||||
-webkit-transform: scale(1);
|
||||
-ms-transform: scale(1);
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
.mejs__time-float {
|
||||
background: #eee;
|
||||
border: solid 1px #333;
|
||||
bottom: 100%;
|
||||
color: #111;
|
||||
display: none;
|
||||
height: 17px;
|
||||
margin-bottom: 9px;
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
-webkit-transform: translateX(-50%);
|
||||
-ms-transform: translateX(-50%);
|
||||
transform: translateX(-50%);
|
||||
width: 36px;
|
||||
}
|
||||
|
||||
.mejs__time-float-current {
|
||||
display: block;
|
||||
left: 0;
|
||||
margin: 2px;
|
||||
text-align: center;
|
||||
width: 30px;
|
||||
}
|
||||
|
||||
.mejs__time-float-corner {
|
||||
border: solid 5px #eee;
|
||||
border-color: #eee transparent transparent;
|
||||
border-radius: 0;
|
||||
display: block;
|
||||
height: 0;
|
||||
left: 50%;
|
||||
line-height: 0;
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
-webkit-transform: translateX(-50%);
|
||||
-ms-transform: translateX(-50%);
|
||||
transform: translateX(-50%);
|
||||
width: 0;
|
||||
}
|
||||
|
||||
.mejs__long-video .mejs__time-float {
|
||||
margin-left: -23px;
|
||||
width: 64px;
|
||||
}
|
||||
|
||||
.mejs__long-video .mejs__time-float-current {
|
||||
width: 60px;
|
||||
}
|
||||
|
||||
.mejs__broadcast {
|
||||
color: #fff;
|
||||
height: 10px;
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* End: Progress Bar */
|
||||
|
||||
/* Start: Fullscreen */
|
||||
.mejs__fullscreen-button > button {
|
||||
background-position: -80px 0;
|
||||
}
|
||||
|
||||
.mejs__unfullscreen > button {
|
||||
background-position: -100px 0;
|
||||
}
|
||||
|
||||
/* End: Fullscreen */
|
||||
|
||||
/* Start: Mute/Volume */
|
||||
.mejs__mute > button {
|
||||
background-position: -60px 0;
|
||||
}
|
||||
|
||||
.mejs__unmute > button {
|
||||
background-position: -40px 0;
|
||||
}
|
||||
|
||||
.mejs__volume-button {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.mejs__volume-button > .mejs__volume-slider {
|
||||
-webkit-backface-visibility: hidden;
|
||||
background: rgba(50, 50, 50, 0.7);
|
||||
border-radius: 0;
|
||||
bottom: 100%;
|
||||
display: none;
|
||||
height: 115px;
|
||||
left: 50%;
|
||||
margin: 0;
|
||||
position: absolute;
|
||||
-webkit-transform: translateX(-50%);
|
||||
-ms-transform: translateX(-50%);
|
||||
transform: translateX(-50%);
|
||||
width: 25px;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.mejs__volume-button:hover {
|
||||
border-radius: 0 0 4px 4px;
|
||||
}
|
||||
|
||||
.mejs__volume-total {
|
||||
background: rgba(255, 255, 255, 0.5);
|
||||
height: 100px;
|
||||
left: 50%;
|
||||
margin: 0;
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
-webkit-transform: translateX(-50%);
|
||||
-ms-transform: translateX(-50%);
|
||||
transform: translateX(-50%);
|
||||
width: 2px;
|
||||
}
|
||||
|
||||
.mejs__volume-current {
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
left: 0;
|
||||
margin: 0;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mejs__volume-handle {
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
border-radius: 1px;
|
||||
cursor: ns-resize;
|
||||
height: 6px;
|
||||
left: 50%;
|
||||
position: absolute;
|
||||
-webkit-transform: translateX(-50%);
|
||||
-ms-transform: translateX(-50%);
|
||||
transform: translateX(-50%);
|
||||
width: 16px;
|
||||
}
|
||||
|
||||
.mejs__horizontal-volume-slider {
|
||||
display: block;
|
||||
height: 36px;
|
||||
position: relative;
|
||||
vertical-align: middle;
|
||||
width: 56px;
|
||||
}
|
||||
|
||||
.mejs__horizontal-volume-total {
|
||||
background: rgba(50, 50, 50, 0.8);
|
||||
border-radius: 2px;
|
||||
font-size: 1px;
|
||||
height: 8px;
|
||||
left: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
top: 16px;
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
.mejs__horizontal-volume-current {
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
border-radius: 2px;
|
||||
font-size: 1px;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mejs__horizontal-volume-handle {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* End: Mute/Volume */
|
||||
|
||||
/* Start: Track (Captions and Chapters) */
|
||||
.mejs__captions-button,
|
||||
.mejs__chapters-button {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.mejs__captions-button > button {
|
||||
background-position: -140px 0;
|
||||
}
|
||||
|
||||
.mejs__chapters-button > button {
|
||||
background-position: -180px 0;
|
||||
}
|
||||
|
||||
.mejs__captions-button > .mejs__captions-selector,
|
||||
.mejs__chapters-button > .mejs__chapters-selector {
|
||||
background: rgba(50, 50, 50, 0.7);
|
||||
border: solid 1px transparent;
|
||||
border-radius: 0;
|
||||
bottom: 100%;
|
||||
margin-right: -43px;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
right: 50%;
|
||||
visibility: visible;
|
||||
width: 86px;
|
||||
}
|
||||
|
||||
.mejs__chapters-button > .mejs__chapters-selector {
|
||||
margin-right: -55px;
|
||||
width: 110px;
|
||||
}
|
||||
|
||||
.mejs__captions-selector-list,
|
||||
.mejs__chapters-selector-list {
|
||||
list-style-type: none !important;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.mejs__captions-selector-list-item,
|
||||
.mejs__chapters-selector-list-item {
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
list-style-type: none !important;
|
||||
margin: 0 0 6px;
|
||||
overflow: hidden;
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
.mejs__captions-selector-list-item:hover,
|
||||
.mejs__chapters-selector-list-item:hover {
|
||||
background-color: rgb(200, 200, 200) !important;
|
||||
background-color: rgba(255, 255, 255, 0.4) !important;
|
||||
}
|
||||
|
||||
.mejs__captions-selector-input,
|
||||
.mejs__chapters-selector-input {
|
||||
clear: both;
|
||||
float: left;
|
||||
left: -1000px;
|
||||
margin: 3px 3px 0 5px;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.mejs__captions-selector-label,
|
||||
.mejs__chapters-selector-label {
|
||||
cursor: pointer;
|
||||
float: left;
|
||||
font-size: 10px;
|
||||
line-height: 15px;
|
||||
padding: 4px 0 0;
|
||||
}
|
||||
|
||||
.mejs__captions-selected,
|
||||
.mejs__chapters-selected {
|
||||
color: rgba(33, 248, 248, 1);
|
||||
}
|
||||
|
||||
.mejs__captions-translations {
|
||||
font-size: 10px;
|
||||
margin: 0 0 5px;
|
||||
}
|
||||
|
||||
.mejs__captions-layer {
|
||||
bottom: 0;
|
||||
color: #fff;
|
||||
font-size: 16px;
|
||||
left: 0;
|
||||
line-height: 20px;
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.mejs__captions-layer a {
|
||||
color: #fff;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.mejs__captions-layer[lang=ar] {
|
||||
font-size: 20px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.mejs__captions-position {
|
||||
bottom: 15px;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mejs__captions-position-hover {
|
||||
bottom: 35px;
|
||||
}
|
||||
|
||||
.mejs__captions-text,
|
||||
.mejs__captions-text * {
|
||||
background: rgba(20, 20, 20, 0.5);
|
||||
box-shadow: 5px 0 0 rgba(20, 20, 20, 0.5), -5px 0 0 rgba(20, 20, 20, 0.5);
|
||||
padding: 0;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.mejs__container.mejs__hide-cues video::-webkit-media-text-track-container {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* End: Track (Captions and Chapters) */
|
||||
|
||||
/* Start: Error */
|
||||
.mejs__overlay-error {
|
||||
position: relative;
|
||||
}
|
||||
.mejs__overlay-error > img {
|
||||
left: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
z-index: -1;
|
||||
}
|
||||
.mejs__cannotplay,
|
||||
.mejs__cannotplay a {
|
||||
color: #fff;
|
||||
font-size: 0.8em;
|
||||
}
|
||||
|
||||
.mejs__cannotplay {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.mejs__cannotplay p,
|
||||
.mejs__cannotplay a {
|
||||
display: inline-block;
|
||||
padding: 0 15px;
|
||||
width: 100%;
|
||||
}
|
||||
/* End: Error */
|
||||
|
After Width: | Height: | Size: 2.8 KiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="120" viewBox="0 0 400 120"><style>.st0{fill:#FFFFFF;width:16px;height:16px} .st1{fill:none;stroke:#FFFFFF;stroke-width:1.5;stroke-linecap:round;} .st2{fill:none;stroke:#FFFFFF;stroke-width:2;stroke-linecap:round;} .st3{fill:none;stroke:#FFFFFF;} .st4{fill:#231F20;} .st5{opacity:0.75;fill:none;stroke:#FFFFFF;stroke-width:5;enable-background:new;} .st6{fill:none;stroke:#FFFFFF;stroke-width:5;} .st7{opacity:0.4;fill:#FFFFFF;enable-background:new;} .st8{opacity:0.6;fill:#FFFFFF;enable-background:new;} .st9{opacity:0.8;fill:#FFFFFF;enable-background:new;} .st10{opacity:0.9;fill:#FFFFFF;enable-background:new;} .st11{opacity:0.3;fill:#FFFFFF;enable-background:new;} .st12{opacity:0.5;fill:#FFFFFF;enable-background:new;} .st13{opacity:0.7;fill:#FFFFFF;enable-background:new;}</style><path class="st0" d="M16.5 8.5c.3.1.4.5.2.8-.1.1-.1.2-.2.2l-11.4 7c-.5.3-.8.1-.8-.5V2c0-.5.4-.8.8-.5l11.4 7z"/><path class="st0" d="M24 1h2.2c.6 0 1 .4 1 1v14c0 .6-.4 1-1 1H24c-.6 0-1-.4-1-1V2c0-.5.4-1 1-1zm9.8 0H36c.6 0 1 .4 1 1v14c0 .6-.4 1-1 1h-2.2c-.6 0-1-.4-1-1V2c0-.5.4-1 1-1z"/><path class="st0" d="M81 1.4c0-.6.4-1 1-1h5.4c.6 0 .7.3.3.7l-6 6c-.4.4-.7.3-.7-.3V1.4zm0 15.8c0 .6.4 1 1 1h5.4c.6 0 .7-.3.3-.7l-6-6c-.4-.4-.7-.3-.7.3v5.4zM98.8 1.4c0-.6-.4-1-1-1h-5.4c-.6 0-.7.3-.3.7l6 6c.4.4.7.3.7-.3V1.4zm0 15.8c0 .6-.4 1-1 1h-5.4c-.6 0-.7-.3-.3-.7l6-6c.4-.4.7-.3.7.3v5.4z"/><path class="st0" d="M112.7 5c0 .6.4 1 1 1h4.1c.6 0 .7-.3.3-.7L113.4.6c-.4-.4-.7-.3-.7.3V5zm-7.1 1c.6 0 1-.4 1-1V.9c0-.6-.3-.7-.7-.3l-4.7 4.7c-.4.4-.3.7.3.7h4.1zm1 7.1c0-.6-.4-1-1-1h-4.1c-.6 0-.7.3-.3.7l4.7 4.7c.4.4.7.3.7-.3v-4.1zm7.1-1c-.6 0-1 .4-1 1v4.1c0 .5.3.7.7.3l4.7-4.7c.4-.4.3-.7-.3-.7h-4.1z"/><path class="st0" d="M67 5.8c-.5.4-1.2.6-1.8.6H62c-.6 0-1 .4-1 1v5.7c0 .6.4 1 1 1h4.2c.3.2.5.4.8.6l3.5 2.6c.4.3.8.1.8-.4V3.5c0-.5-.4-.7-.8-.4L67 5.8z"/><path class="st1" d="M73.9 2.5s3.9-.8 3.9 7.7-3.9 7.8-3.9 7.8"/><path class="st1" d="M72.6 6.4s2.6-.4 2.6 3.8-2.6 3.9-2.6 3.9"/><path class="st0" d="M47 5.8c-.5.4-1.2.6-1.8.6H42c-.6 0-1 .4-1 1v5.7c0 .6.4 1 1 1h4.2c.3.2.5.4.8.6l3.5 2.6c.4.3.8.1.8-.4V3.5c0-.5-.4-.7-.8-.4L47 5.8z"/><path class="st2" d="M52.8 7l5.4 5.4m-5.4 0L58.2 7"/><path class="st3" d="M128.7 8.6c-6.2-4.2-6.5 7.8 0 3.9m6.5-3.9c-6.2-4.2-6.5 7.8 0 3.9"/><path class="st0" d="M122.2 3.4h15.7v13.1h-15.7V3.4zM120.8 2v15.7h18.3V2h-18.3z"/><path class="st0" d="M143.2 3h14c1.1 0 2 .9 2 2v10c0 1.1-.9 2-2 2h-14c-1.1 0-2-.9-2-2V5c0-1.1.9-2 2-2z"/><path class="st4" d="M146.4 13.8c-.8 0-1.6-.4-2.1-1-1.1-1.4-1-3.4.1-4.8.5-.6 2-1.7 4.6.2l-.6.8c-1.4-1-2.6-1.1-3.3-.3-.8 1-.8 2.4-.1 3.5.7.9 1.9.8 3.4-.1l.5.9c-.7.5-1.6.7-2.5.8zm7.5 0c-.8 0-1.6-.4-2.1-1-1.1-1.4-1-3.4.1-4.8.5-.6 2-1.7 4.6.2l-.5.8c-1.4-1-2.6-1.1-3.3-.3-.8 1-.8 2.4-.1 3.5.7.9 1.9.8 3.4-.1l.5.9c-.8.5-1.7.7-2.6.8z"/><path class="st0" d="M60.3 77c.6.2.8.8.6 1.4-.1.3-.3.5-.6.6L30 96.5c-1 .6-1.7.1-1.7-1v-35c0-1.1.8-1.5 1.7-1L60.3 77z"/><path class="st5" d="M2.5 79c0-20.7 16.8-37.5 37.5-37.5S77.5 58.3 77.5 79 60.7 116.5 40 116.5 2.5 99.7 2.5 79z"/><path class="st0" d="M140.3 77c.6.2.8.8.6 1.4-.1.3-.3.5-.6.6L110 96.5c-1 .6-1.7.1-1.7-1v-35c0-1.1.8-1.5 1.7-1L140.3 77z"/><path class="st6" d="M82.5 79c0-20.7 16.8-37.5 37.5-37.5s37.5 16.8 37.5 37.5-16.8 37.5-37.5 37.5S82.5 99.7 82.5 79z"/><circle class="st0" cx="201.9" cy="47.1" r="8.1"/><circle class="st7" cx="233.9" cy="79" r="5"/><circle class="st8" cx="201.9" cy="110.9" r="6"/><circle class="st9" cx="170.1" cy="79" r="7"/><circle class="st10" cx="178.2" cy="56.3" r="7.5"/><circle class="st11" cx="226.3" cy="56.1" r="4.5"/><circle class="st12" cx="225.8" cy="102.8" r="5.5"/><circle class="st13" cx="178.2" cy="102.8" r="6.5"/><path class="st0" d="M178 9.4c0 .4-.4.7-.9.7-.1 0-.2 0-.2-.1L172 8.2c-.5-.2-.6-.6-.1-.8l6.2-3.6c.5-.3.8-.1.7.5l-.8 5.1z"/><path class="st0" d="M169.4 15.9c-1 0-2-.2-2.9-.7-2-1-3.2-3-3.2-5.2.1-3.4 2.9-6 6.3-6 2.5.1 4.8 1.7 5.6 4.1l.1-.1 2.1 1.1c-.6-4.4-4.7-7.5-9.1-6.9-3.9.6-6.9 3.9-7 7.9 0 2.9 1.7 5.6 4.3 7 1.2.6 2.5.9 3.8 1 2.6 0 5-1.2 6.6-3.3l-1.8-.9c-1.2 1.2-3 2-4.8 2z"/><path class="st0" d="M183.4 3.2c.8 0 1.5.7 1.5 1.5s-.7 1.5-1.5 1.5-1.5-.7-1.5-1.5c0-.9.7-1.5 1.5-1.5zm5.1 0h8.5c.9 0 1.5.7 1.5 1.5s-.7 1.5-1.5 1.5h-8.5c-.9 0-1.5-.7-1.5-1.5-.1-.9.6-1.5 1.5-1.5zm-5.1 5c.8 0 1.5.7 1.5 1.5s-.7 1.5-1.5 1.5-1.5-.7-1.5-1.5c0-.9.7-1.5 1.5-1.5zm5.1 0h8.5c.9 0 1.5.7 1.5 1.5s-.7 1.5-1.5 1.5h-8.5c-.9 0-1.5-.7-1.5-1.5-.1-.9.6-1.5 1.5-1.5zm-5.1 5c.8 0 1.5.7 1.5 1.5s-.7 1.5-1.5 1.5-1.5-.7-1.5-1.5c0-.9.7-1.5 1.5-1.5zm5.1 0h8.5c.9 0 1.5.7 1.5 1.5s-.7 1.5-1.5 1.5h-8.5c-.9 0-1.5-.7-1.5-1.5-.1-.9.6-1.5 1.5-1.5z"/></svg>
|
||||
|
After Width: | Height: | Size: 4.5 KiB |
@@ -0,0 +1,416 @@
|
||||
/*!
|
||||
* MediaElement.js
|
||||
* http://www.mediaelementjs.com/
|
||||
*
|
||||
* Wrapper that mimics native HTML5 MediaElement (audio and video)
|
||||
* using a variety of technologies (pure JavaScript, Flash, iframe)
|
||||
*
|
||||
* Copyright 2010-2017, John Dyer (http://j.hn/)
|
||||
* License: MIT
|
||||
*
|
||||
*/(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
|
||||
'use strict';
|
||||
|
||||
var VimeoApi = {
|
||||
|
||||
promise: null,
|
||||
|
||||
load: function load(settings) {
|
||||
|
||||
if (typeof Vimeo !== 'undefined') {
|
||||
VimeoApi._createPlayer(settings);
|
||||
} else {
|
||||
VimeoApi.promise = VimeoApi.promise || mejs.Utils.loadScript('https://player.vimeo.com/api/player.js');
|
||||
VimeoApi.promise.then(function () {
|
||||
VimeoApi._createPlayer(settings);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
_createPlayer: function _createPlayer(settings) {
|
||||
var player = new Vimeo.Player(settings.iframe);
|
||||
window['__ready__' + settings.id](player);
|
||||
},
|
||||
|
||||
getVimeoId: function getVimeoId(url) {
|
||||
if (url === undefined || url === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var parts = url.split('?');
|
||||
url = parts[0];
|
||||
return parseInt(url.substring(url.lastIndexOf('/') + 1), 10);
|
||||
}
|
||||
};
|
||||
|
||||
var vimeoIframeRenderer = {
|
||||
|
||||
name: 'vimeo_iframe',
|
||||
options: {
|
||||
prefix: 'vimeo_iframe'
|
||||
},
|
||||
|
||||
canPlayType: function canPlayType(type) {
|
||||
return ~['video/vimeo', 'video/x-vimeo'].indexOf(type.toLowerCase());
|
||||
},
|
||||
|
||||
create: function create(mediaElement, options, mediaFiles) {
|
||||
var apiStack = [],
|
||||
vimeo = {},
|
||||
readyState = 4;
|
||||
|
||||
var paused = true,
|
||||
volume = 1,
|
||||
oldVolume = volume,
|
||||
currentTime = 0,
|
||||
bufferedTime = 0,
|
||||
ended = false,
|
||||
duration = 0,
|
||||
vimeoPlayer = null,
|
||||
url = '';
|
||||
|
||||
vimeo.options = options;
|
||||
vimeo.id = mediaElement.id + '_' + options.prefix;
|
||||
vimeo.mediaElement = mediaElement;
|
||||
|
||||
var errorHandler = function errorHandler(error, target) {
|
||||
var event = mejs.Utils.createEvent('error', target);
|
||||
event.message = error.name + ': ' + error.message;
|
||||
mediaElement.dispatchEvent(event);
|
||||
};
|
||||
|
||||
var props = mejs.html5media.properties,
|
||||
assignGettersSetters = function assignGettersSetters(propName) {
|
||||
|
||||
var capName = '' + propName.substring(0, 1).toUpperCase() + propName.substring(1);
|
||||
|
||||
vimeo['get' + capName] = function () {
|
||||
if (vimeoPlayer !== null) {
|
||||
var value = null;
|
||||
|
||||
switch (propName) {
|
||||
case 'currentTime':
|
||||
return currentTime;
|
||||
|
||||
case 'duration':
|
||||
return duration;
|
||||
|
||||
case 'volume':
|
||||
return volume;
|
||||
case 'muted':
|
||||
return volume === 0;
|
||||
case 'paused':
|
||||
return paused;
|
||||
case 'ended':
|
||||
return ended;
|
||||
|
||||
case 'src':
|
||||
vimeoPlayer.getVideoUrl().then(function (_url) {
|
||||
url = _url;
|
||||
});
|
||||
|
||||
return url;
|
||||
case 'buffered':
|
||||
return {
|
||||
start: function start() {
|
||||
return 0;
|
||||
},
|
||||
end: function end() {
|
||||
return bufferedTime * duration;
|
||||
},
|
||||
length: 1
|
||||
};
|
||||
case 'readyState':
|
||||
return readyState;
|
||||
}
|
||||
return value;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
vimeo['set' + capName] = function (value) {
|
||||
if (vimeoPlayer !== null) {
|
||||
switch (propName) {
|
||||
case 'src':
|
||||
var _url2 = typeof value === 'string' ? value : value[0].src,
|
||||
videoId = VimeoApi.getVimeoId(_url2);
|
||||
|
||||
vimeoPlayer.loadVideo(videoId).then(function () {
|
||||
if (mediaElement.originalNode.autoplay) {
|
||||
vimeoPlayer.play();
|
||||
}
|
||||
}).catch(function (error) {
|
||||
errorHandler(error, vimeo);
|
||||
});
|
||||
break;
|
||||
case 'currentTime':
|
||||
vimeoPlayer.setCurrentTime(value).then(function () {
|
||||
currentTime = value;
|
||||
setTimeout(function () {
|
||||
var event = mejs.Utils.createEvent('timeupdate', vimeo);
|
||||
mediaElement.dispatchEvent(event);
|
||||
}, 50);
|
||||
}).catch(function (error) {
|
||||
errorHandler(error, vimeo);
|
||||
});
|
||||
break;
|
||||
case 'volume':
|
||||
vimeoPlayer.setVolume(value).then(function () {
|
||||
volume = value;
|
||||
oldVolume = volume;
|
||||
setTimeout(function () {
|
||||
var event = mejs.Utils.createEvent('volumechange', vimeo);
|
||||
mediaElement.dispatchEvent(event);
|
||||
}, 50);
|
||||
}).catch(function (error) {
|
||||
errorHandler(error, vimeo);
|
||||
});
|
||||
break;
|
||||
case 'loop':
|
||||
vimeoPlayer.setLoop(value).catch(function (error) {
|
||||
errorHandler(error, vimeo);
|
||||
});
|
||||
break;
|
||||
case 'muted':
|
||||
if (value) {
|
||||
vimeoPlayer.setVolume(0).then(function () {
|
||||
volume = 0;
|
||||
setTimeout(function () {
|
||||
var event = mejs.Utils.createEvent('volumechange', vimeo);
|
||||
mediaElement.dispatchEvent(event);
|
||||
}, 50);
|
||||
}).catch(function (error) {
|
||||
errorHandler(error, vimeo);
|
||||
});
|
||||
} else {
|
||||
vimeoPlayer.setVolume(oldVolume).then(function () {
|
||||
volume = oldVolume;
|
||||
setTimeout(function () {
|
||||
var event = mejs.Utils.createEvent('volumechange', vimeo);
|
||||
mediaElement.dispatchEvent(event);
|
||||
}, 50);
|
||||
}).catch(function (error) {
|
||||
errorHandler(error, vimeo);
|
||||
});
|
||||
}
|
||||
break;
|
||||
case 'readyState':
|
||||
var event = mejs.Utils.createEvent('canplay', vimeo);
|
||||
mediaElement.dispatchEvent(event);
|
||||
break;
|
||||
default:
|
||||
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
apiStack.push({ type: 'set', propName: propName, value: value });
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
for (var i = 0, total = props.length; i < total; i++) {
|
||||
assignGettersSetters(props[i]);
|
||||
}
|
||||
|
||||
var methods = mejs.html5media.methods,
|
||||
assignMethods = function assignMethods(methodName) {
|
||||
vimeo[methodName] = function () {
|
||||
if (vimeoPlayer !== null) {
|
||||
switch (methodName) {
|
||||
case 'play':
|
||||
paused = false;
|
||||
return vimeoPlayer.play();
|
||||
case 'pause':
|
||||
paused = true;
|
||||
return vimeoPlayer.pause();
|
||||
case 'load':
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
apiStack.push({ type: 'call', methodName: methodName });
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
for (var _i = 0, _total = methods.length; _i < _total; _i++) {
|
||||
assignMethods(methods[_i]);
|
||||
}
|
||||
|
||||
window['__ready__' + vimeo.id] = function (_vimeoPlayer) {
|
||||
|
||||
mediaElement.vimeoPlayer = vimeoPlayer = _vimeoPlayer;
|
||||
|
||||
if (apiStack.length) {
|
||||
for (var _i2 = 0, _total2 = apiStack.length; _i2 < _total2; _i2++) {
|
||||
var stackItem = apiStack[_i2];
|
||||
|
||||
if (stackItem.type === 'set') {
|
||||
var propName = stackItem.propName,
|
||||
capName = '' + propName.substring(0, 1).toUpperCase() + propName.substring(1);
|
||||
|
||||
vimeo['set' + capName](stackItem.value);
|
||||
} else if (stackItem.type === 'call') {
|
||||
vimeo[stackItem.methodName]();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mediaElement.originalNode.muted) {
|
||||
vimeoPlayer.setVolume(0);
|
||||
volume = 0;
|
||||
}
|
||||
|
||||
var vimeoIframe = document.getElementById(vimeo.id);
|
||||
var events = void 0;
|
||||
|
||||
events = ['mouseover', 'mouseout'];
|
||||
|
||||
var assignEvents = function assignEvents(e) {
|
||||
var event = mejs.Utils.createEvent(e.type, vimeo);
|
||||
mediaElement.dispatchEvent(event);
|
||||
};
|
||||
|
||||
for (var _i3 = 0, _total3 = events.length; _i3 < _total3; _i3++) {
|
||||
vimeoIframe.addEventListener(events[_i3], assignEvents, false);
|
||||
}
|
||||
|
||||
vimeoPlayer.on('loaded', function () {
|
||||
vimeoPlayer.getDuration().then(function (loadProgress) {
|
||||
duration = loadProgress;
|
||||
if (duration > 0) {
|
||||
bufferedTime = duration * loadProgress;
|
||||
if (mediaElement.originalNode.autoplay) {
|
||||
paused = false;
|
||||
ended = false;
|
||||
var event = mejs.Utils.createEvent('play', vimeo);
|
||||
mediaElement.dispatchEvent(event);
|
||||
}
|
||||
}
|
||||
}).catch(function (error) {
|
||||
errorHandler(error, vimeo);
|
||||
});
|
||||
});
|
||||
vimeoPlayer.on('progress', function () {
|
||||
vimeoPlayer.getDuration().then(function (loadProgress) {
|
||||
duration = loadProgress;
|
||||
|
||||
if (duration > 0) {
|
||||
bufferedTime = duration * loadProgress;
|
||||
if (mediaElement.originalNode.autoplay) {
|
||||
var initEvent = mejs.Utils.createEvent('play', vimeo);
|
||||
mediaElement.dispatchEvent(initEvent);
|
||||
|
||||
var playingEvent = mejs.Utils.createEvent('playing', vimeo);
|
||||
mediaElement.dispatchEvent(playingEvent);
|
||||
}
|
||||
}
|
||||
|
||||
var event = mejs.Utils.createEvent('progress', vimeo);
|
||||
mediaElement.dispatchEvent(event);
|
||||
}).catch(function (error) {
|
||||
errorHandler(error, vimeo);
|
||||
});
|
||||
});
|
||||
vimeoPlayer.on('timeupdate', function () {
|
||||
vimeoPlayer.getCurrentTime().then(function (seconds) {
|
||||
currentTime = seconds;
|
||||
|
||||
var event = mejs.Utils.createEvent('timeupdate', vimeo);
|
||||
mediaElement.dispatchEvent(event);
|
||||
}).catch(function (error) {
|
||||
errorHandler(error, vimeo);
|
||||
});
|
||||
});
|
||||
vimeoPlayer.on('play', function () {
|
||||
paused = false;
|
||||
ended = false;
|
||||
var event = mejs.Utils.createEvent('play', vimeo);
|
||||
mediaElement.dispatchEvent(event);
|
||||
|
||||
var playingEvent = mejs.Utils.createEvent('playing', vimeo);
|
||||
mediaElement.dispatchEvent(playingEvent);
|
||||
});
|
||||
vimeoPlayer.on('pause', function () {
|
||||
paused = true;
|
||||
ended = false;
|
||||
|
||||
var event = mejs.Utils.createEvent('pause', vimeo);
|
||||
mediaElement.dispatchEvent(event);
|
||||
});
|
||||
vimeoPlayer.on('ended', function () {
|
||||
paused = false;
|
||||
ended = true;
|
||||
|
||||
var event = mejs.Utils.createEvent('ended', vimeo);
|
||||
mediaElement.dispatchEvent(event);
|
||||
});
|
||||
|
||||
events = ['rendererready', 'loadedmetadata', 'loadeddata', 'canplay'];
|
||||
|
||||
for (var _i4 = 0, _total4 = events.length; _i4 < _total4; _i4++) {
|
||||
var event = mejs.Utils.createEvent(events[_i4], vimeo);
|
||||
mediaElement.dispatchEvent(event);
|
||||
}
|
||||
};
|
||||
|
||||
var height = mediaElement.originalNode.height,
|
||||
width = mediaElement.originalNode.width,
|
||||
vimeoContainer = document.createElement('iframe'),
|
||||
standardUrl = 'https://player.vimeo.com/video/' + VimeoApi.getVimeoId(mediaFiles[0].src);
|
||||
|
||||
var queryArgs = ~mediaFiles[0].src.indexOf('?') ? '?' + mediaFiles[0].src.slice(mediaFiles[0].src.indexOf('?') + 1) : '';
|
||||
if (queryArgs && mediaElement.originalNode.autoplay && queryArgs.indexOf('autoplay') === -1) {
|
||||
queryArgs += '&autoplay=1';
|
||||
}
|
||||
if (queryArgs && mediaElement.originalNode.loop && queryArgs.indexOf('loop') === -1) {
|
||||
queryArgs += '&loop=1';
|
||||
}
|
||||
|
||||
vimeoContainer.setAttribute('id', vimeo.id);
|
||||
vimeoContainer.setAttribute('width', width);
|
||||
vimeoContainer.setAttribute('height', height);
|
||||
vimeoContainer.setAttribute('frameBorder', '0');
|
||||
vimeoContainer.setAttribute('src', '' + standardUrl + queryArgs);
|
||||
vimeoContainer.setAttribute('webkitallowfullscreen', '');
|
||||
vimeoContainer.setAttribute('mozallowfullscreen', '');
|
||||
vimeoContainer.setAttribute('allowfullscreen', '');
|
||||
|
||||
mediaElement.originalNode.parentNode.insertBefore(vimeoContainer, mediaElement.originalNode);
|
||||
mediaElement.originalNode.style.display = 'none';
|
||||
|
||||
VimeoApi.load({
|
||||
iframe: vimeoContainer,
|
||||
id: vimeo.id
|
||||
});
|
||||
|
||||
vimeo.hide = function () {
|
||||
vimeo.pause();
|
||||
if (vimeoPlayer) {
|
||||
vimeoContainer.style.display = 'none';
|
||||
}
|
||||
};
|
||||
vimeo.setSize = function (width, height) {
|
||||
vimeoContainer.setAttribute('width', width);
|
||||
vimeoContainer.setAttribute('height', height);
|
||||
};
|
||||
vimeo.show = function () {
|
||||
if (vimeoPlayer) {
|
||||
vimeoContainer.style.display = '';
|
||||
}
|
||||
};
|
||||
|
||||
vimeo.destroy = function () {};
|
||||
|
||||
return vimeo;
|
||||
}
|
||||
};
|
||||
|
||||
mejs.Utils.typeChecks.push(function (url) {
|
||||
return (/(\/\/player\.vimeo|vimeo\.com)/i.test(url) ? 'video/x-vimeo' : null
|
||||
);
|
||||
});
|
||||
|
||||
mejs.Renderers.add(vimeoIframeRenderer);
|
||||
|
||||
},{}]},{},[1]);
|
||||
@@ -0,0 +1,293 @@
|
||||
.mejs-container {
|
||||
clear: both;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.mejs-container * {
|
||||
font-family: Helvetica, Arial;
|
||||
}
|
||||
|
||||
.mejs-container,
|
||||
.mejs-embed,
|
||||
.mejs-embed body,
|
||||
.mejs-container .mejs-controls {
|
||||
background: #222;
|
||||
}
|
||||
|
||||
.mejs-time {
|
||||
font-weight: normal;
|
||||
word-wrap: normal;
|
||||
}
|
||||
|
||||
.mejs-controls a.mejs-horizontal-volume-slider {
|
||||
display: table;
|
||||
}
|
||||
|
||||
.mejs-controls .mejs-time-rail .mejs-time-loaded,
|
||||
.mejs-controls .mejs-horizontal-volume-slider .mejs-horizontal-volume-current {
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.mejs-controls .mejs-time-rail .mejs-time-current {
|
||||
background: #0073aa;
|
||||
}
|
||||
|
||||
.mejs-controls .mejs-time-rail .mejs-time-total,
|
||||
.mejs-controls .mejs-horizontal-volume-slider .mejs-horizontal-volume-total {
|
||||
background: rgba(255, 255, 255, .33);
|
||||
}
|
||||
|
||||
.mejs-controls .mejs-time-rail span,
|
||||
.mejs-controls .mejs-horizontal-volume-slider .mejs-horizontal-volume-total,
|
||||
.mejs-controls .mejs-horizontal-volume-slider .mejs-horizontal-volume-current {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.mejs-overlay-loading {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
/* Override theme styles that may conflict with controls. */
|
||||
.mejs-controls button:hover {
|
||||
border: none;
|
||||
-webkit-box-shadow: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.me-cannotplay {
|
||||
width: auto !important;
|
||||
}
|
||||
|
||||
.media-embed-details .wp-audio-shortcode {
|
||||
display: inline-block;
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
.audio-details .embed-media-settings {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.media-embed-details .embed-media-settings .setting span {
|
||||
max-width: 400px;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.media-embed-details .embed-media-settings .checkbox-setting span {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.media-embed-details .embed-media-settings {
|
||||
padding-top: 0;
|
||||
top: 28px;
|
||||
}
|
||||
|
||||
.media-embed-details .instructions {
|
||||
padding: 16px 0;
|
||||
max-width: 600px;
|
||||
}
|
||||
|
||||
.media-embed-details .setting p,
|
||||
.media-embed-details .setting .remove-setting {
|
||||
color: #a00;
|
||||
font-size: 10px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.media-embed-details .setting .remove-setting {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.media-embed-details .setting a:hover {
|
||||
color: #dc3232;
|
||||
}
|
||||
|
||||
.media-embed-details .embed-media-settings .checkbox-setting {
|
||||
float: none;
|
||||
margin: 0 0 10px;
|
||||
}
|
||||
|
||||
.wp-video {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.wp_attachment_holder .wp-video,
|
||||
.wp_attachment_holder .wp-audio-shortcode {
|
||||
margin-top: 18px;
|
||||
}
|
||||
|
||||
video.wp-video-shortcode,
|
||||
.wp-video-shortcode video {
|
||||
max-width: 100%;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.video-details .wp-video-holder {
|
||||
width: 100%;
|
||||
max-width: 640px;
|
||||
}
|
||||
|
||||
.wp-playlist {
|
||||
border: 1px solid #ccc;
|
||||
padding: 10px;
|
||||
margin: 12px 0 18px;
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.wp-admin .wp-playlist {
|
||||
margin: 0 0 18px;
|
||||
}
|
||||
|
||||
.wp-playlist video {
|
||||
display: inline-block;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.wp-playlist audio {
|
||||
display: none;
|
||||
max-width: 100%;
|
||||
width: 400px;
|
||||
}
|
||||
|
||||
.wp-playlist .mejs-container {
|
||||
margin: 0;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.wp-playlist .mejs-controls .mejs-button button {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.wp-playlist-light {
|
||||
background: #fff;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.wp-playlist-dark {
|
||||
color: #fff;
|
||||
background: #000;
|
||||
}
|
||||
|
||||
.wp-playlist-caption {
|
||||
display: block;
|
||||
max-width: 88%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.wp-playlist-item .wp-playlist-caption {
|
||||
text-decoration: none;
|
||||
color: #000;
|
||||
max-width: -webkit-calc(100% - 40px);
|
||||
max-width: calc(100% - 40px);
|
||||
}
|
||||
|
||||
.wp-playlist-item-meta {
|
||||
display: block;
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.wp-playlist-item-title {
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.wp-playlist-item-album {
|
||||
font-style: italic;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.wp-playlist-item-artist {
|
||||
font-size: 12px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.wp-playlist-item-length {
|
||||
position: absolute;
|
||||
right: 3px;
|
||||
top: 0;
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.rtl .wp-playlist-item-length {
|
||||
left: 3px;
|
||||
right: auto;
|
||||
}
|
||||
|
||||
.wp-playlist-tracks {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.wp-playlist-item {
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
padding: 0 3px;
|
||||
border-bottom: 1px solid #ccc;
|
||||
}
|
||||
|
||||
.wp-playlist-item:last-child {
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
.wp-playlist-light .wp-playlist-caption {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.wp-playlist-dark .wp-playlist-caption {
|
||||
color: #ddd;
|
||||
}
|
||||
|
||||
.wp-playlist-playing {
|
||||
font-weight: bold;
|
||||
background: #f7f7f7;
|
||||
}
|
||||
|
||||
.wp-playlist-light .wp-playlist-playing {
|
||||
background: #fff;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.wp-playlist-dark .wp-playlist-playing {
|
||||
background: #000;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.wp-playlist-current-item {
|
||||
overflow: hidden;
|
||||
margin-bottom: 10px;
|
||||
height: 60px;
|
||||
}
|
||||
|
||||
.wp-playlist .wp-playlist-current-item img {
|
||||
float: left;
|
||||
max-width: 60px;
|
||||
height: auto;
|
||||
margin-right: 10px;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.rtl .wp-playlist .wp-playlist-current-item img {
|
||||
float: right;
|
||||
margin-left: 10px;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.wp-playlist-current-item .wp-playlist-item-title,
|
||||
.wp-playlist-current-item .wp-playlist-item-artist {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.wp-audio-playlist .me-cannotplay span {
|
||||
padding: 5px 15px;
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/* global _wpmejsSettings, mejsL10n */
|
||||
(function( window, $ ) {
|
||||
|
||||
window.wp = window.wp || {};
|
||||
|
||||
function wpMediaElement() {
|
||||
var settings = {};
|
||||
|
||||
/**
|
||||
* Initialize media elements.
|
||||
*
|
||||
* Ensures media elements that have already been initialized won't be
|
||||
* processed again.
|
||||
*
|
||||
* @memberOf wp.mediaelement
|
||||
*
|
||||
* @since 4.4.0
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
function initialize() {
|
||||
if ( typeof _wpmejsSettings !== 'undefined' ) {
|
||||
settings = $.extend( true, {}, _wpmejsSettings );
|
||||
}
|
||||
settings.classPrefix = 'mejs-';
|
||||
settings.success = settings.success || function ( mejs ) {
|
||||
var autoplay, loop;
|
||||
|
||||
if ( mejs.rendererName && -1 !== mejs.rendererName.indexOf( 'flash' ) ) {
|
||||
autoplay = mejs.attributes.autoplay && 'false' !== mejs.attributes.autoplay;
|
||||
loop = mejs.attributes.loop && 'false' !== mejs.attributes.loop;
|
||||
|
||||
if ( autoplay ) {
|
||||
mejs.addEventListener( 'canplay', function() {
|
||||
mejs.play();
|
||||
}, false );
|
||||
}
|
||||
|
||||
if ( loop ) {
|
||||
mejs.addEventListener( 'ended', function() {
|
||||
mejs.play();
|
||||
}, false );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Custom error handler.
|
||||
*
|
||||
* Sets up a custom error handler in case a video render fails, and provides a download
|
||||
* link as the fallback.
|
||||
*
|
||||
* @since 4.9.3
|
||||
*
|
||||
* @param {object} media The wrapper that mimics all the native events/properties/methods for all renderers.
|
||||
* @param {object} node The original HTML video, audio, or iframe tag where the media was loaded.
|
||||
* @returns {string}
|
||||
*/
|
||||
settings.customError = function ( media, node ) {
|
||||
// Make sure we only fall back to a download link for flash files.
|
||||
if ( -1 !== media.rendererName.indexOf( 'flash' ) || -1 !== media.rendererName.indexOf( 'flv' ) ) {
|
||||
return '<a href="' + node.src + '">' + mejsL10n.strings['mejs.download-video'] + '</a>';
|
||||
}
|
||||
};
|
||||
|
||||
// Only initialize new media elements.
|
||||
$( '.wp-audio-shortcode, .wp-video-shortcode' )
|
||||
.not( '.mejs-container' )
|
||||
.filter(function () {
|
||||
return ! $( this ).parent().hasClass( 'mejs-mediaelement' );
|
||||
})
|
||||
.mediaelementplayer( settings );
|
||||
}
|
||||
|
||||
return {
|
||||
initialize: initialize
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @namespace wp.mediaelement
|
||||
* @memberOf wp
|
||||
*/
|
||||
window.wp.mediaelement = new wpMediaElement();
|
||||
|
||||
$( window.wp.mediaelement.initialize );
|
||||
|
||||
})( window, jQuery );
|
||||
@@ -0,0 +1,203 @@
|
||||
/* global _wpmejsSettings, MediaElementPlayer */
|
||||
|
||||
(function ($, _, Backbone) {
|
||||
'use strict';
|
||||
|
||||
/** @namespace wp */
|
||||
window.wp = window.wp || {};
|
||||
|
||||
var WPPlaylistView = Backbone.View.extend(/** @lends WPPlaylistView.prototype */{
|
||||
/**
|
||||
* @constructs
|
||||
*
|
||||
* @param {Object} options The options to create this playlist view with.
|
||||
* @param {Object} options.metadata The metadata
|
||||
*/
|
||||
initialize : function (options) {
|
||||
this.index = 0;
|
||||
this.settings = {};
|
||||
this.data = options.metadata || $.parseJSON( this.$('script.wp-playlist-script').html() );
|
||||
this.playerNode = this.$( this.data.type );
|
||||
|
||||
this.tracks = new Backbone.Collection( this.data.tracks );
|
||||
this.current = this.tracks.first();
|
||||
|
||||
if ( 'audio' === this.data.type ) {
|
||||
this.currentTemplate = wp.template( 'wp-playlist-current-item' );
|
||||
this.currentNode = this.$( '.wp-playlist-current-item' );
|
||||
}
|
||||
|
||||
this.renderCurrent();
|
||||
|
||||
if ( this.data.tracklist ) {
|
||||
this.itemTemplate = wp.template( 'wp-playlist-item' );
|
||||
this.playingClass = 'wp-playlist-playing';
|
||||
this.renderTracks();
|
||||
}
|
||||
|
||||
this.playerNode.attr( 'src', this.current.get( 'src' ) );
|
||||
|
||||
_.bindAll( this, 'bindPlayer', 'bindResetPlayer', 'setPlayer', 'ended', 'clickTrack' );
|
||||
|
||||
if ( ! _.isUndefined( window._wpmejsSettings ) ) {
|
||||
this.settings = _.clone( _wpmejsSettings );
|
||||
}
|
||||
this.settings.success = this.bindPlayer;
|
||||
this.setPlayer();
|
||||
},
|
||||
|
||||
bindPlayer : function (mejs) {
|
||||
this.mejs = mejs;
|
||||
this.mejs.addEventListener( 'ended', this.ended );
|
||||
},
|
||||
|
||||
bindResetPlayer : function (mejs) {
|
||||
this.bindPlayer( mejs );
|
||||
this.playCurrentSrc();
|
||||
},
|
||||
|
||||
setPlayer: function (force) {
|
||||
if ( this.player ) {
|
||||
this.player.pause();
|
||||
this.player.remove();
|
||||
this.playerNode = this.$( this.data.type );
|
||||
}
|
||||
|
||||
if (force) {
|
||||
this.playerNode.attr( 'src', this.current.get( 'src' ) );
|
||||
this.settings.success = this.bindResetPlayer;
|
||||
}
|
||||
|
||||
// This is also our bridge to the outside world.
|
||||
this.player = new MediaElementPlayer( this.playerNode.get(0), this.settings );
|
||||
},
|
||||
|
||||
playCurrentSrc : function () {
|
||||
this.renderCurrent();
|
||||
this.mejs.setSrc( this.playerNode.attr( 'src' ) );
|
||||
this.mejs.load();
|
||||
this.mejs.play();
|
||||
},
|
||||
|
||||
renderCurrent : function () {
|
||||
var dimensions, defaultImage = 'wp-includes/images/media/video.png';
|
||||
if ( 'video' === this.data.type ) {
|
||||
if ( this.data.images && this.current.get( 'image' ) && -1 === this.current.get( 'image' ).src.indexOf( defaultImage ) ) {
|
||||
this.playerNode.attr( 'poster', this.current.get( 'image' ).src );
|
||||
}
|
||||
dimensions = this.current.get( 'dimensions' ).resized;
|
||||
this.playerNode.attr( dimensions );
|
||||
} else {
|
||||
if ( ! this.data.images ) {
|
||||
this.current.set( 'image', false );
|
||||
}
|
||||
this.currentNode.html( this.currentTemplate( this.current.toJSON() ) );
|
||||
}
|
||||
},
|
||||
|
||||
renderTracks : function () {
|
||||
var self = this, i = 1, tracklist = $( '<div class="wp-playlist-tracks"></div>' );
|
||||
this.tracks.each(function (model) {
|
||||
if ( ! self.data.images ) {
|
||||
model.set( 'image', false );
|
||||
}
|
||||
model.set( 'artists', self.data.artists );
|
||||
model.set( 'index', self.data.tracknumbers ? i : false );
|
||||
tracklist.append( self.itemTemplate( model.toJSON() ) );
|
||||
i += 1;
|
||||
});
|
||||
this.$el.append( tracklist );
|
||||
|
||||
this.$( '.wp-playlist-item' ).eq(0).addClass( this.playingClass );
|
||||
},
|
||||
|
||||
events : {
|
||||
'click .wp-playlist-item' : 'clickTrack',
|
||||
'click .wp-playlist-next' : 'next',
|
||||
'click .wp-playlist-prev' : 'prev'
|
||||
},
|
||||
|
||||
clickTrack : function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
this.index = this.$( '.wp-playlist-item' ).index( e.currentTarget );
|
||||
this.setCurrent();
|
||||
},
|
||||
|
||||
ended : function () {
|
||||
if ( this.index + 1 < this.tracks.length ) {
|
||||
this.next();
|
||||
} else {
|
||||
this.index = 0;
|
||||
this.setCurrent();
|
||||
}
|
||||
},
|
||||
|
||||
next : function () {
|
||||
this.index = this.index + 1 >= this.tracks.length ? 0 : this.index + 1;
|
||||
this.setCurrent();
|
||||
},
|
||||
|
||||
prev : function () {
|
||||
this.index = this.index - 1 < 0 ? this.tracks.length - 1 : this.index - 1;
|
||||
this.setCurrent();
|
||||
},
|
||||
|
||||
loadCurrent : function () {
|
||||
var last = this.playerNode.attr( 'src' ) && this.playerNode.attr( 'src' ).split('.').pop(),
|
||||
current = this.current.get( 'src' ).split('.').pop();
|
||||
|
||||
this.mejs && this.mejs.pause();
|
||||
|
||||
if ( last !== current ) {
|
||||
this.setPlayer( true );
|
||||
} else {
|
||||
this.playerNode.attr( 'src', this.current.get( 'src' ) );
|
||||
this.playCurrentSrc();
|
||||
}
|
||||
},
|
||||
|
||||
setCurrent : function () {
|
||||
this.current = this.tracks.at( this.index );
|
||||
|
||||
if ( this.data.tracklist ) {
|
||||
this.$( '.wp-playlist-item' )
|
||||
.removeClass( this.playingClass )
|
||||
.eq( this.index )
|
||||
.addClass( this.playingClass );
|
||||
}
|
||||
|
||||
this.loadCurrent();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Initialize media playlists in the document.
|
||||
*
|
||||
* Only initializes new playlists not previously-initialized.
|
||||
*
|
||||
* @since 4.9.3
|
||||
* @returns {void}
|
||||
*/
|
||||
function initialize() {
|
||||
$( '.wp-playlist:not(:has(.mejs-container))' ).each( function() {
|
||||
new WPPlaylistView( { el: this } );
|
||||
} );
|
||||
}
|
||||
|
||||
/**
|
||||
* Expose the API publicly on window.wp.playlist.
|
||||
*
|
||||
* @namespace wp.playlist
|
||||
* @since 4.9.3
|
||||
* @type {object}
|
||||
*/
|
||||
window.wp.playlist = {
|
||||
initialize: initialize
|
||||
};
|
||||
|
||||
$( document ).ready( initialize );
|
||||
|
||||
window.WPPlaylistView = WPPlaylistView;
|
||||
|
||||
}(jQuery, _, Backbone));
|
||||
@@ -0,0 +1,506 @@
|
||||
/* global plupload, pluploadL10n, ajaxurl, post_id, wpUploaderInit, deleteUserSetting, setUserSetting, getUserSetting, shortform */
|
||||
var topWin = window.dialogArguments || opener || parent || top, uploader, uploader_init;
|
||||
|
||||
// progress and success handlers for media multi uploads
|
||||
function fileQueued(fileObj) {
|
||||
// Get rid of unused form
|
||||
jQuery('.media-blank').remove();
|
||||
|
||||
var items = jQuery('#media-items').children(), postid = post_id || 0;
|
||||
|
||||
// Collapse a single item
|
||||
if ( items.length == 1 ) {
|
||||
items.removeClass('open').find('.slidetoggle').slideUp(200);
|
||||
}
|
||||
// Create a progress bar containing the filename
|
||||
jQuery('<div class="media-item">')
|
||||
.attr( 'id', 'media-item-' + fileObj.id )
|
||||
.addClass('child-of-' + postid)
|
||||
.append('<div class="progress"><div class="percent">0%</div><div class="bar"></div></div>',
|
||||
jQuery('<div class="filename original">').text( ' ' + fileObj.name ))
|
||||
.appendTo( jQuery('#media-items' ) );
|
||||
|
||||
// Disable submit
|
||||
jQuery('#insert-gallery').prop('disabled', true);
|
||||
}
|
||||
|
||||
function uploadStart() {
|
||||
try {
|
||||
if ( typeof topWin.tb_remove != 'undefined' )
|
||||
topWin.jQuery('#TB_overlay').unbind('click', topWin.tb_remove);
|
||||
} catch(e){}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function uploadProgress(up, file) {
|
||||
var item = jQuery('#media-item-' + file.id);
|
||||
|
||||
jQuery('.bar', item).width( (200 * file.loaded) / file.size );
|
||||
jQuery('.percent', item).html( file.percent + '%' );
|
||||
}
|
||||
|
||||
// check to see if a large file failed to upload
|
||||
function fileUploading( up, file ) {
|
||||
var hundredmb = 100 * 1024 * 1024,
|
||||
max = parseInt( up.settings.max_file_size, 10 );
|
||||
|
||||
if ( max > hundredmb && file.size > hundredmb ) {
|
||||
setTimeout( function() {
|
||||
if ( file.status < 3 && file.loaded === 0 ) { // not uploading
|
||||
wpFileError( file, pluploadL10n.big_upload_failed.replace( '%1$s', '<a class="uploader-html" href="#">' ).replace( '%2$s', '</a>' ) );
|
||||
up.stop(); // stops the whole queue
|
||||
up.removeFile( file );
|
||||
up.start(); // restart the queue
|
||||
}
|
||||
}, 10000 ); // wait for 10 sec. for the file to start uploading
|
||||
}
|
||||
}
|
||||
|
||||
function updateMediaForm() {
|
||||
var items = jQuery('#media-items').children();
|
||||
|
||||
// Just one file, no need for collapsible part
|
||||
if ( items.length == 1 ) {
|
||||
items.addClass('open').find('.slidetoggle').show();
|
||||
jQuery('.insert-gallery').hide();
|
||||
} else if ( items.length > 1 ) {
|
||||
items.removeClass('open');
|
||||
// Only show Gallery/Playlist buttons when there are at least two files.
|
||||
jQuery('.insert-gallery').show();
|
||||
}
|
||||
|
||||
// Only show Save buttons when there is at least one file.
|
||||
if ( items.not('.media-blank').length > 0 )
|
||||
jQuery('.savebutton').show();
|
||||
else
|
||||
jQuery('.savebutton').hide();
|
||||
}
|
||||
|
||||
function uploadSuccess(fileObj, serverData) {
|
||||
var item = jQuery('#media-item-' + fileObj.id);
|
||||
|
||||
// on success serverData should be numeric, fix bug in html4 runtime returning the serverData wrapped in a <pre> tag
|
||||
serverData = serverData.replace(/^<pre>(\d+)<\/pre>$/, '$1');
|
||||
|
||||
// if async-upload returned an error message, place it in the media item div and return
|
||||
if ( serverData.match(/media-upload-error|error-div/) ) {
|
||||
item.html(serverData);
|
||||
return;
|
||||
} else {
|
||||
jQuery('.percent', item).html( pluploadL10n.crunching );
|
||||
}
|
||||
|
||||
prepareMediaItem(fileObj, serverData);
|
||||
updateMediaForm();
|
||||
|
||||
// Increment the counter.
|
||||
if ( post_id && item.hasClass('child-of-' + post_id) )
|
||||
jQuery('#attachments-count').text(1 * jQuery('#attachments-count').text() + 1);
|
||||
}
|
||||
|
||||
function setResize( arg ) {
|
||||
if ( arg ) {
|
||||
if ( window.resize_width && window.resize_height ) {
|
||||
uploader.settings.resize = {
|
||||
enabled: true,
|
||||
width: window.resize_width,
|
||||
height: window.resize_height,
|
||||
quality: 100
|
||||
};
|
||||
} else {
|
||||
uploader.settings.multipart_params.image_resize = true;
|
||||
}
|
||||
} else {
|
||||
delete( uploader.settings.multipart_params.image_resize );
|
||||
}
|
||||
}
|
||||
|
||||
function prepareMediaItem(fileObj, serverData) {
|
||||
var f = ( typeof shortform == 'undefined' ) ? 1 : 2, item = jQuery('#media-item-' + fileObj.id);
|
||||
if ( f == 2 && shortform > 2 )
|
||||
f = shortform;
|
||||
|
||||
try {
|
||||
if ( typeof topWin.tb_remove != 'undefined' )
|
||||
topWin.jQuery('#TB_overlay').click(topWin.tb_remove);
|
||||
} catch(e){}
|
||||
|
||||
if ( isNaN(serverData) || !serverData ) { // Old style: Append the HTML returned by the server -- thumbnail and form inputs
|
||||
item.append(serverData);
|
||||
prepareMediaItemInit(fileObj);
|
||||
} else { // New style: server data is just the attachment ID, fetch the thumbnail and form html from the server
|
||||
item.load('async-upload.php', {attachment_id:serverData, fetch:f}, function(){prepareMediaItemInit(fileObj);updateMediaForm();});
|
||||
}
|
||||
}
|
||||
|
||||
function prepareMediaItemInit(fileObj) {
|
||||
var item = jQuery('#media-item-' + fileObj.id);
|
||||
// Clone the thumbnail as a "pinkynail" -- a tiny image to the left of the filename
|
||||
jQuery('.thumbnail', item).clone().attr('class', 'pinkynail toggle').prependTo(item);
|
||||
|
||||
// Replace the original filename with the new (unique) one assigned during upload
|
||||
jQuery('.filename.original', item).replaceWith( jQuery('.filename.new', item) );
|
||||
|
||||
// Bind AJAX to the new Delete button
|
||||
jQuery('a.delete', item).click(function(){
|
||||
// Tell the server to delete it. TODO: handle exceptions
|
||||
jQuery.ajax({
|
||||
url: ajaxurl,
|
||||
type: 'post',
|
||||
success: deleteSuccess,
|
||||
error: deleteError,
|
||||
id: fileObj.id,
|
||||
data: {
|
||||
id : this.id.replace(/[^0-9]/g, ''),
|
||||
action : 'trash-post',
|
||||
_ajax_nonce : this.href.replace(/^.*wpnonce=/,'')
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
|
||||
// Bind AJAX to the new Undo button
|
||||
jQuery('a.undo', item).click(function(){
|
||||
// Tell the server to untrash it. TODO: handle exceptions
|
||||
jQuery.ajax({
|
||||
url: ajaxurl,
|
||||
type: 'post',
|
||||
id: fileObj.id,
|
||||
data: {
|
||||
id : this.id.replace(/[^0-9]/g,''),
|
||||
action: 'untrash-post',
|
||||
_ajax_nonce: this.href.replace(/^.*wpnonce=/,'')
|
||||
},
|
||||
success: function( ){
|
||||
var type,
|
||||
item = jQuery('#media-item-' + fileObj.id);
|
||||
|
||||
if ( type = jQuery('#type-of-' + fileObj.id).val() )
|
||||
jQuery('#' + type + '-counter').text(jQuery('#' + type + '-counter').text()-0+1);
|
||||
|
||||
if ( post_id && item.hasClass('child-of-'+post_id) )
|
||||
jQuery('#attachments-count').text(jQuery('#attachments-count').text()-0+1);
|
||||
|
||||
jQuery('.filename .trashnotice', item).remove();
|
||||
jQuery('.filename .title', item).css('font-weight','normal');
|
||||
jQuery('a.undo', item).addClass('hidden');
|
||||
jQuery('.menu_order_input', item).show();
|
||||
item.css( {backgroundColor:'#ceb'} ).animate( {backgroundColor: '#fff'}, { queue: false, duration: 500, complete: function(){ jQuery(this).css({backgroundColor:''}); } }).removeClass('undo');
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
|
||||
// Open this item if it says to start open (e.g. to display an error)
|
||||
jQuery('#media-item-' + fileObj.id + '.startopen').removeClass('startopen').addClass('open').find('slidetoggle').fadeIn();
|
||||
}
|
||||
|
||||
// generic error message
|
||||
function wpQueueError(message) {
|
||||
jQuery('#media-upload-error').show().html( '<div class="error"><p>' + message + '</p></div>' );
|
||||
}
|
||||
|
||||
// file-specific error messages
|
||||
function wpFileError(fileObj, message) {
|
||||
itemAjaxError(fileObj.id, message);
|
||||
}
|
||||
|
||||
function itemAjaxError(id, message) {
|
||||
var item = jQuery('#media-item-' + id), filename = item.find('.filename').text(), last_err = item.data('last-err');
|
||||
|
||||
if ( last_err == id ) // prevent firing an error for the same file twice
|
||||
return;
|
||||
|
||||
item.html('<div class="error-div">' +
|
||||
'<a class="dismiss" href="#">' + pluploadL10n.dismiss + '</a>' +
|
||||
'<strong>' + pluploadL10n.error_uploading.replace('%s', jQuery.trim(filename)) + '</strong> ' +
|
||||
message +
|
||||
'</div>').data('last-err', id);
|
||||
}
|
||||
|
||||
function deleteSuccess(data) {
|
||||
var type, id, item;
|
||||
if ( data == '-1' )
|
||||
return itemAjaxError(this.id, 'You do not have permission. Has your session expired?');
|
||||
|
||||
if ( data == '0' )
|
||||
return itemAjaxError(this.id, 'Could not be deleted. Has it been deleted already?');
|
||||
|
||||
id = this.id;
|
||||
item = jQuery('#media-item-' + id);
|
||||
|
||||
// Decrement the counters.
|
||||
if ( type = jQuery('#type-of-' + id).val() )
|
||||
jQuery('#' + type + '-counter').text( jQuery('#' + type + '-counter').text() - 1 );
|
||||
|
||||
if ( post_id && item.hasClass('child-of-'+post_id) )
|
||||
jQuery('#attachments-count').text( jQuery('#attachments-count').text() - 1 );
|
||||
|
||||
if ( jQuery('form.type-form #media-items').children().length == 1 && jQuery('.hidden', '#media-items').length > 0 ) {
|
||||
jQuery('.toggle').toggle();
|
||||
jQuery('.slidetoggle').slideUp(200).siblings().removeClass('hidden');
|
||||
}
|
||||
|
||||
// Vanish it.
|
||||
jQuery('.toggle', item).toggle();
|
||||
jQuery('.slidetoggle', item).slideUp(200).siblings().removeClass('hidden');
|
||||
item.css( {backgroundColor:'#faa'} ).animate( {backgroundColor:'#f4f4f4'}, {queue:false, duration:500} ).addClass('undo');
|
||||
|
||||
jQuery('.filename:empty', item).remove();
|
||||
jQuery('.filename .title', item).css('font-weight','bold');
|
||||
jQuery('.filename', item).append('<span class="trashnotice"> ' + pluploadL10n.deleted + ' </span>').siblings('a.toggle').hide();
|
||||
jQuery('.filename', item).append( jQuery('a.undo', item).removeClass('hidden') );
|
||||
jQuery('.menu_order_input', item).hide();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
function deleteError() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
function uploadComplete() {
|
||||
jQuery('#insert-gallery').prop('disabled', false);
|
||||
}
|
||||
|
||||
function switchUploader(s) {
|
||||
if ( s ) {
|
||||
deleteUserSetting('uploader');
|
||||
jQuery('.media-upload-form').removeClass('html-uploader');
|
||||
|
||||
if ( typeof(uploader) == 'object' )
|
||||
uploader.refresh();
|
||||
} else {
|
||||
setUserSetting('uploader', '1'); // 1 == html uploader
|
||||
jQuery('.media-upload-form').addClass('html-uploader');
|
||||
}
|
||||
}
|
||||
|
||||
function uploadError(fileObj, errorCode, message, uploader) {
|
||||
var hundredmb = 100 * 1024 * 1024, max;
|
||||
|
||||
switch (errorCode) {
|
||||
case plupload.FAILED:
|
||||
wpFileError(fileObj, pluploadL10n.upload_failed);
|
||||
break;
|
||||
case plupload.FILE_EXTENSION_ERROR:
|
||||
wpFileExtensionError( uploader, fileObj, pluploadL10n.invalid_filetype );
|
||||
break;
|
||||
case plupload.FILE_SIZE_ERROR:
|
||||
uploadSizeError(uploader, fileObj);
|
||||
break;
|
||||
case plupload.IMAGE_FORMAT_ERROR:
|
||||
wpFileError(fileObj, pluploadL10n.not_an_image);
|
||||
break;
|
||||
case plupload.IMAGE_MEMORY_ERROR:
|
||||
wpFileError(fileObj, pluploadL10n.image_memory_exceeded);
|
||||
break;
|
||||
case plupload.IMAGE_DIMENSIONS_ERROR:
|
||||
wpFileError(fileObj, pluploadL10n.image_dimensions_exceeded);
|
||||
break;
|
||||
case plupload.GENERIC_ERROR:
|
||||
wpQueueError(pluploadL10n.upload_failed);
|
||||
break;
|
||||
case plupload.IO_ERROR:
|
||||
max = parseInt( uploader.settings.filters.max_file_size, 10 );
|
||||
|
||||
if ( max > hundredmb && fileObj.size > hundredmb )
|
||||
wpFileError( fileObj, pluploadL10n.big_upload_failed.replace('%1$s', '<a class="uploader-html" href="#">').replace('%2$s', '</a>') );
|
||||
else
|
||||
wpQueueError(pluploadL10n.io_error);
|
||||
break;
|
||||
case plupload.HTTP_ERROR:
|
||||
wpQueueError(pluploadL10n.http_error);
|
||||
break;
|
||||
case plupload.INIT_ERROR:
|
||||
jQuery('.media-upload-form').addClass('html-uploader');
|
||||
break;
|
||||
case plupload.SECURITY_ERROR:
|
||||
wpQueueError(pluploadL10n.security_error);
|
||||
break;
|
||||
/* case plupload.UPLOAD_ERROR.UPLOAD_STOPPED:
|
||||
case plupload.UPLOAD_ERROR.FILE_CANCELLED:
|
||||
jQuery('#media-item-' + fileObj.id).remove();
|
||||
break;*/
|
||||
default:
|
||||
wpFileError(fileObj, pluploadL10n.default_error);
|
||||
}
|
||||
}
|
||||
|
||||
function uploadSizeError( up, file ) {
|
||||
var message, errorDiv;
|
||||
|
||||
message = pluploadL10n.file_exceeds_size_limit.replace('%s', file.name);
|
||||
|
||||
// Construct the error div.
|
||||
errorDiv = jQuery( '<div />' )
|
||||
.attr( {
|
||||
'id': 'media-item-' + file.id,
|
||||
'class': 'media-item error'
|
||||
} )
|
||||
.append(
|
||||
jQuery( '<p />' )
|
||||
.text( message )
|
||||
);
|
||||
|
||||
// Append the error.
|
||||
jQuery('#media-items').append( errorDiv );
|
||||
up.removeFile(file);
|
||||
}
|
||||
|
||||
function wpFileExtensionError( up, file, message ) {
|
||||
jQuery('#media-items').append('<div id="media-item-' + file.id + '" class="media-item error"><p>' + message + '</p></div>');
|
||||
up.removeFile(file);
|
||||
}
|
||||
|
||||
jQuery(document).ready(function($){
|
||||
$('.media-upload-form').bind('click.uploader', function(e) {
|
||||
var target = $(e.target), tr, c;
|
||||
|
||||
if ( target.is('input[type="radio"]') ) { // remember the last used image size and alignment
|
||||
tr = target.closest('tr');
|
||||
|
||||
if ( tr.hasClass('align') )
|
||||
setUserSetting('align', target.val());
|
||||
else if ( tr.hasClass('image-size') )
|
||||
setUserSetting('imgsize', target.val());
|
||||
|
||||
} else if ( target.is('button.button') ) { // remember the last used image link url
|
||||
c = e.target.className || '';
|
||||
c = c.match(/url([^ '"]+)/);
|
||||
|
||||
if ( c && c[1] ) {
|
||||
setUserSetting('urlbutton', c[1]);
|
||||
target.siblings('.urlfield').val( target.data('link-url') );
|
||||
}
|
||||
} else if ( target.is('a.dismiss') ) {
|
||||
target.parents('.media-item').fadeOut(200, function(){
|
||||
$(this).remove();
|
||||
});
|
||||
} else if ( target.is('.upload-flash-bypass a') || target.is('a.uploader-html') ) { // switch uploader to html4
|
||||
$('#media-items, p.submit, span.big-file-warning').css('display', 'none');
|
||||
switchUploader(0);
|
||||
e.preventDefault();
|
||||
} else if ( target.is('.upload-html-bypass a') ) { // switch uploader to multi-file
|
||||
$('#media-items, p.submit, span.big-file-warning').css('display', '');
|
||||
switchUploader(1);
|
||||
e.preventDefault();
|
||||
} else if ( target.is('a.describe-toggle-on') ) { // Show
|
||||
target.parent().addClass('open');
|
||||
target.siblings('.slidetoggle').fadeIn(250, function(){
|
||||
var S = $(window).scrollTop(), H = $(window).height(), top = $(this).offset().top, h = $(this).height(), b, B;
|
||||
|
||||
if ( H && top && h ) {
|
||||
b = top + h;
|
||||
B = S + H;
|
||||
|
||||
if ( b > B ) {
|
||||
if ( b - B < top - S )
|
||||
window.scrollBy(0, (b - B) + 10);
|
||||
else
|
||||
window.scrollBy(0, top - S - 40);
|
||||
}
|
||||
}
|
||||
});
|
||||
e.preventDefault();
|
||||
} else if ( target.is('a.describe-toggle-off') ) { // Hide
|
||||
target.siblings('.slidetoggle').fadeOut(250, function(){
|
||||
target.parent().removeClass('open');
|
||||
});
|
||||
e.preventDefault();
|
||||
}
|
||||
});
|
||||
|
||||
// init and set the uploader
|
||||
uploader_init = function() {
|
||||
var isIE = navigator.userAgent.indexOf('Trident/') != -1 || navigator.userAgent.indexOf('MSIE ') != -1;
|
||||
|
||||
// Make sure flash sends cookies (seems in IE it does whitout switching to urlstream mode)
|
||||
if ( ! isIE && 'flash' === plupload.predictRuntime( wpUploaderInit ) &&
|
||||
( ! wpUploaderInit.required_features || ! wpUploaderInit.required_features.hasOwnProperty( 'send_binary_string' ) ) ) {
|
||||
|
||||
wpUploaderInit.required_features = wpUploaderInit.required_features || {};
|
||||
wpUploaderInit.required_features.send_binary_string = true;
|
||||
}
|
||||
|
||||
uploader = new plupload.Uploader(wpUploaderInit);
|
||||
|
||||
$('#image_resize').bind('change', function() {
|
||||
var arg = $(this).prop('checked');
|
||||
|
||||
setResize( arg );
|
||||
|
||||
if ( arg )
|
||||
setUserSetting('upload_resize', '1');
|
||||
else
|
||||
deleteUserSetting('upload_resize');
|
||||
});
|
||||
|
||||
uploader.bind('Init', function(up) {
|
||||
var uploaddiv = $('#plupload-upload-ui');
|
||||
|
||||
setResize( getUserSetting('upload_resize', false) );
|
||||
|
||||
if ( up.features.dragdrop && ! $(document.body).hasClass('mobile') ) {
|
||||
uploaddiv.addClass('drag-drop');
|
||||
$('#drag-drop-area').on('dragover.wp-uploader', function(){ // dragenter doesn't fire right :(
|
||||
uploaddiv.addClass('drag-over');
|
||||
}).on('dragleave.wp-uploader, drop.wp-uploader', function(){
|
||||
uploaddiv.removeClass('drag-over');
|
||||
});
|
||||
} else {
|
||||
uploaddiv.removeClass('drag-drop');
|
||||
$('#drag-drop-area').off('.wp-uploader');
|
||||
}
|
||||
|
||||
if ( up.runtime === 'html4' ) {
|
||||
$('.upload-flash-bypass').hide();
|
||||
}
|
||||
});
|
||||
|
||||
uploader.bind( 'postinit', function( up ) {
|
||||
up.refresh();
|
||||
});
|
||||
|
||||
uploader.init();
|
||||
|
||||
uploader.bind('FilesAdded', function( up, files ) {
|
||||
$('#media-upload-error').empty();
|
||||
uploadStart();
|
||||
|
||||
plupload.each( files, function( file ) {
|
||||
fileQueued( file );
|
||||
});
|
||||
|
||||
up.refresh();
|
||||
up.start();
|
||||
});
|
||||
|
||||
uploader.bind('UploadFile', function(up, file) {
|
||||
fileUploading(up, file);
|
||||
});
|
||||
|
||||
uploader.bind('UploadProgress', function(up, file) {
|
||||
uploadProgress(up, file);
|
||||
});
|
||||
|
||||
uploader.bind('Error', function(up, err) {
|
||||
uploadError(err.file, err.code, err.message, up);
|
||||
up.refresh();
|
||||
});
|
||||
|
||||
uploader.bind('FileUploaded', function(up, file, response) {
|
||||
uploadSuccess(file, response.response);
|
||||
});
|
||||
|
||||
uploader.bind('UploadComplete', function() {
|
||||
uploadComplete();
|
||||
});
|
||||
};
|
||||
|
||||
if ( typeof(wpUploaderInit) == 'object' ) {
|
||||
uploader_init();
|
||||
}
|
||||
|
||||
});
|
||||
@@ -0,0 +1,339 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
||||