Added login request

This commit is contained in:
Nedim Uka
2018-06-20 18:03:43 +02:00
parent 4e52521fae
commit 593b445a21
4716 changed files with 1218265 additions and 57 deletions

View File

@@ -0,0 +1,364 @@
<?php
/**
* Module Name: Spelling and Grammar
* Module Description: Check your spelling, style, and grammar
* Sort Order: 6
* First Introduced: 1.1
* Requires Connection: Yes
* Auto Activate: Yes
* Module Tags: Writing
* Feature: Writing
* Additional Search Queries: after the deadline, afterthedeadline, spell, spellchecker, spelling, grammar, proofreading, style, language, cliche
*/
if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
// This wpcom-specific code should eventually be moved elsewhere.
function AtD_http_post_timeout_action() {
return 5;
}
add_filter( 'atd_http_post_timeout', 'AtD_http_post_timeout_action' );
function AtD_http_post_error_action( $code ) {
/** This action is documented in modules/widgets/social-media-icons.php */
do_action( 'jetpack_bump_stats_extras', 'atd-remote-error', $code );
}
add_action( 'atd_http_post_error', 'AtD_http_post_error_action' );
function AtD_service_domain_action() {
return 'en.service.afterthedeadline.com';
}
add_filter( 'atd_service_domain', 'AtD_service_domain_action' );
function AtD_update_setting( $user_id, $name, $value ) {
update_user_attribute( $user_id, $name, $value );
}
function AtD_get_setting( $user_id, $name, $single = true ) {
return get_user_attribute( $user_id, $name );
}
function AtD_get_rpc_id() {
return get_bloginfo( 'wpurl' );
}
} else {
// This code is used only in Jetpack.
add_action( 'jetpack_modules_loaded', 'AtD_load' );
function AtD_load() {
Jetpack::enable_module_configurable( __FILE__ );
Jetpack::module_configuration_load( __FILE__, 'AtD_configuration_load' );
}
function AtD_configuration_load() {
wp_safe_redirect( get_edit_profile_url( get_current_user_id() ) . '#atd' );
exit;
}
function AtD_update_setting( $user_id, $name, $value ) {
return update_user_meta( $user_id, $name, $value );
}
function AtD_get_setting( $user_id, $name, $single = true ) {
return get_user_meta( $user_id, $name, $single );
}
function AtD_get_rpc_id() {
return 'WPORG-' . md5( get_bloginfo( 'wpurl ') );
}
}
/*
* Load necessary include files
*/
include( dirname( __FILE__ ) . '/after-the-deadline/config-options.php' );
include( dirname( __FILE__ ) . '/after-the-deadline/config-unignore.php' );
include( dirname( __FILE__ ) . '/after-the-deadline/proxy.php' );
define( 'ATD_VERSION', '20150715' );
/*
* Display the AtD configuration options
*/
function AtD_config() {
AtD_display_options_form();
AtD_display_unignore_form();
}
/*
* Code to update the toolbar with the AtD Button and Install the AtD TinyMCE Plugin
*/
function AtD_addbuttons() {
/* Don't bother doing this stuff if the current user lacks permissions */
if ( ! AtD_is_allowed() )
return;
if ( ! defined( 'ATD_TINYMCE_4' ) ) {
define( 'ATD_TINYMCE_4', ( ! empty( $GLOBALS['tinymce_version'] ) && substr( $GLOBALS['tinymce_version'], 0, 1 ) >= 4 ) );
}
/* Add only in Rich Editor mode */
if ( get_user_option( 'rich_editing' ) == 'true' ) {
add_filter( 'mce_external_plugins', 'add_AtD_tinymce_plugin' );
add_filter( 'mce_buttons', 'register_AtD_button' );
}
add_action( 'personal_options_update', 'AtD_process_options_update' );
add_action( 'personal_options_update', 'AtD_process_unignore_update' );
add_action( 'profile_personal_options', 'AtD_config' );
}
/*
* Hook into the TinyMCE buttons and replace the current spellchecker
*/
function register_AtD_button( $buttons ) {
if ( ATD_TINYMCE_4 ) {
// Use the default icon in TinyMCE 4.0 (replaced by dashicons in editor.css)
if ( ! in_array( 'spellchecker', $buttons, true ) ) {
$buttons[] = 'spellchecker';
}
return $buttons;
}
/* kill the spellchecker.. don't need no steenkin PHP spell checker */
foreach ( $buttons as $key => $button ) {
if ( $button == 'spellchecker' ) {
$buttons[$key] = 'AtD';
return $buttons;
}
}
/* hrm... ok add us last plz */
array_push( $buttons, '|', 'AtD' );
return $buttons;
}
/*
* Load the TinyMCE plugin : editor_plugin.js (TinyMCE 3.x) | plugin.js (TinyMCE 4.0)
*/
function add_AtD_tinymce_plugin( $plugin_array ) {
$plugin = ATD_TINYMCE_4 ? 'plugin' : 'editor_plugin';
$plugin_array['AtD'] = add_query_arg( 'v', ATD_VERSION, plugins_url( 'after-the-deadline/tinymce/' . $plugin . '.js', __FILE__ ) );
return $plugin_array;
}
/*
* Update the TinyMCE init block with AtD specific settings
*/
function AtD_change_mce_settings( $init_array ) {
if ( ! AtD_is_allowed() )
return $init_array;
if ( ! is_array( $init_array ) )
$init_array = array();
$user = wp_get_current_user();
$init_array['atd_rpc_url'] = admin_url( 'admin-ajax.php?action=proxy_atd&_wpnonce=' . wp_create_nonce( 'proxy_atd' ) . '&url=' );
$init_array['atd_ignore_rpc_url'] = admin_url( 'admin-ajax.php?action=atd_ignore&_wpnonce=' . wp_create_nonce( 'atd_ignore' ) . '&phrase=' );
$init_array['atd_rpc_id'] = AtD_get_rpc_id();
$init_array['atd_theme'] = 'wordpress';
$init_array['atd_ignore_enable'] = 'true';
$init_array['atd_strip_on_get'] = 'true';
$init_array['atd_ignore_strings'] = json_encode( explode( ',', AtD_get_setting( $user->ID, 'AtD_ignored_phrases' ) ) );
$init_array['atd_show_types'] = AtD_get_setting( $user->ID, 'AtD_options' );
$init_array['gecko_spellcheck'] = 'false';
return $init_array;
}
/*
* Sanitizes AtD AJAX data to acceptable chars, caller needs to make sure ' is escaped
*/
function AtD_sanitize( $untrusted ) {
return preg_replace( '/[^a-zA-Z0-9\-\',_ ]/i', "", $untrusted );
}
/*
* AtD HTML Editor Stuff
*/
function AtD_settings() {
$user = wp_get_current_user();
header( 'Content-Type: text/javascript' );
/* set the RPC URL for AtD */
echo "AtD.rpc = " . json_encode( esc_url_raw( admin_url( 'admin-ajax.php?action=proxy_atd&_wpnonce=' . wp_create_nonce( 'proxy_atd' ) . '&url=' ) ) ) . ";\n";
/* set the API key for AtD */
echo "AtD.api_key = " . json_encode( AtD_get_rpc_id() ) . ";\n";
/* set the ignored phrases for AtD */
echo "AtD.setIgnoreStrings(" . json_encode( AtD_get_setting( $user->ID, 'AtD_ignored_phrases' ) ) . ");\n";
/* honor the types we want to show */
echo "AtD.showTypes(" . json_encode( AtD_get_setting( $user->ID, 'AtD_options' ) ) .");\n";
/* this is not an AtD/jQuery setting but I'm putting it in AtD to make it easy for the non-viz plugin to find it */
$admin_ajax_url = admin_url( 'admin-ajax.php?action=atd_ignore&_wpnonce=' . wp_create_nonce( 'atd_ignore' ) . '&phrase=' );
echo "AtD.rpc_ignore = " . json_encode( esc_url_raw( $admin_ajax_url ) ) . ";\n";
die;
}
function AtD_load_javascripts() {
if ( AtD_should_load_on_page() ) {
wp_enqueue_script(
'AtD_core',
Jetpack::get_file_url_for_environment(
'_inc/build/after-the-deadline/atd.core.min.js',
'modules/after-the-deadline/atd.core.js'
),
array(),
ATD_VERSION
);
wp_enqueue_script(
'AtD_quicktags',
Jetpack::get_file_url_for_environment(
'_inc/build/after-the-deadline/atd-nonvis-editor-plugin.min.js',
'modules/after-the-deadline/atd-nonvis-editor-plugin.js'
),
array('quicktags'),
ATD_VERSION
);
wp_enqueue_script(
'AtD_jquery',
Jetpack::get_file_url_for_environment(
'_inc/build/after-the-deadline/jquery.atd.min.js',
'modules/after-the-deadline/jquery.atd.js'
),
array('jquery'),
ATD_VERSION
);
wp_enqueue_script( 'AtD_settings', admin_url() . 'admin-ajax.php?action=atd_settings', array('AtD_jquery'), ATD_VERSION );
wp_enqueue_script(
'AtD_autoproofread',
Jetpack::get_file_url_for_environment(
'_inc/build/after-the-deadline/atd-autoproofread.min.js',
'modules/after-the-deadline/atd-autoproofread.js'
),
array('AtD_jquery'),
ATD_VERSION
);
/* load localized strings for AtD */
wp_localize_script( 'AtD_core', 'AtD_l10n_r0ar', array (
'menu_title_spelling' => __( 'Spelling', 'jetpack' ),
'menu_title_repeated_word' => __( 'Repeated Word', 'jetpack' ),
'menu_title_no_suggestions' => __( 'No suggestions', 'jetpack' ),
'menu_option_explain' => __( 'Explain...', 'jetpack' ),
'menu_option_ignore_once' => __( 'Ignore suggestion', 'jetpack' ),
'menu_option_ignore_always' => __( 'Ignore always', 'jetpack' ),
'menu_option_ignore_all' => __( 'Ignore all', 'jetpack' ),
'menu_option_edit_selection' => __( 'Edit Selection...', 'jetpack' ),
'button_proofread' => __( 'proofread', 'jetpack' ),
'button_edit_text' => __( 'edit text', 'jetpack' ),
'button_proofread_tooltip' => __( 'Proofread Writing', 'jetpack' ),
'message_no_errors_found' => __( 'No writing errors were found.', 'jetpack' ),
'message_server_error' => __( 'There was a problem communicating with the Proofreading service. Try again in one minute.', 'jetpack' ),
'message_server_error_short' => __( 'There was an error communicating with the proofreading service.', 'jetpack' ),
'dialog_replace_selection' => __( 'Replace selection with:', 'jetpack' ),
'dialog_confirm_post_publish' => __( "The proofreader has suggestions for this post. Are you sure you want to publish it?\n\nPress OK to publish your post, or Cancel to view the suggestions and edit your post.", 'jetpack' ),
'dialog_confirm_post_update' => __( "The proofreader has suggestions for this post. Are you sure you want to update it?\n\nPress OK to update your post, or Cancel to view the suggestions and edit your post.", 'jetpack' ),
) );
}
}
/* Spits out user options for auto-proofreading on publish/update */
function AtD_load_submit_check_javascripts() {
global $pagenow;
$user = wp_get_current_user();
if ( ! $user || $user->ID == 0 )
return;
if ( AtD_should_load_on_page() ) {
$atd_check_when = AtD_get_setting( $user->ID, 'AtD_check_when' );
if ( !empty( $atd_check_when ) ) {
$check_when = array();
/* Set up the options in json */
foreach( explode( ',', $atd_check_when ) as $option ) {
$check_when[$option] = true;
}
echo '<script type="text/javascript">' . "\n";
echo 'AtD_check_when = ' . json_encode( (object) $check_when ) . ";\n";
echo '</script>' . "\n";
}
}
}
/*
* Check if a user is allowed to use AtD
*/
function AtD_is_allowed() {
if ( ( defined( 'AtD_FORCED_ON' ) && AtD_FORCED_ON ) ) {
return true;
}
$user = wp_get_current_user();
if ( ! $user || $user->ID == 0 )
return;
if ( ! current_user_can( 'edit_posts' ) && ! current_user_can( 'edit_pages' ) )
return;
return 1;
}
function AtD_load_css() {
if ( AtD_should_load_on_page() ) {
wp_enqueue_style( 'AtD_style', plugins_url( '/after-the-deadline/atd.css', __FILE__ ), null, ATD_VERSION, 'screen' );
wp_style_add_data( 'AtD_style', 'rtl', 'replace' );
}
}
/* Helper used to check if javascript should be added to page. Helps avoid bloat in admin */
function AtD_should_load_on_page() {
global $pagenow, $current_screen;
$pages = array( 'post.php', 'post-new.php', 'page.php', 'page-new.php', 'admin.php', 'profile.php' );
if ( in_array( $pagenow, $pages ) ) {
if ( isset( $current_screen->post_type ) && $current_screen->post_type ) {
return post_type_supports( $current_screen->post_type, 'editor' );
}
return true;
}
/**
* Allows scripts to be loaded via AtD in admin.
*
* By default, AtD only enqueues JS on certain admin pages to reduce bloat. The filter allows additional pages to have AtD JS.
*
* @module after-the-deadline
*
* @since 1.2.3
*
* @param bool false Boolean to load or not load AtD scripts in admin.
*/
return apply_filters( 'atd_load_scripts', false );
}
// add button to DFW
if ( ! ( defined( 'IS_WPCOM' ) && IS_WPCOM ) ) {
add_filter( 'wp_fullscreen_buttons', 'AtD_fullscreen' );
}
function AtD_fullscreen($buttons) {
$buttons['spellchecker'] = array( 'title' => __( 'Proofread Writing', 'jetpack' ), 'onclick' => "tinyMCE.execCommand('mceWritingImprovementTool');", 'both' => false );
return $buttons;
}
/* add some vars into the AtD plugin */
add_filter( 'tiny_mce_before_init', 'AtD_change_mce_settings' );
/* load some stuff for non-visual editor */
add_action( 'admin_enqueue_scripts', 'AtD_load_javascripts' );
add_action( 'admin_enqueue_scripts', 'AtD_load_submit_check_javascripts' );
add_action( 'admin_enqueue_scripts', 'AtD_load_css' );
/* init process for button control */
add_action( 'init', 'AtD_addbuttons' );
/* setup hooks for our PHP functions we want to make available via an AJAX call */
add_action( 'wp_ajax_proxy_atd', 'AtD_redirect_call' );
add_action( 'wp_ajax_atd_ignore', 'AtD_ignore_call' );
add_action( 'wp_ajax_atd_settings', 'AtD_settings' );

View File

@@ -0,0 +1,93 @@
/* jshint devel: true, onevar: false */
/* global tinyMCE, AtD_restore_if_proofreading, AtD_check, AtD_unbind_proofreader_listeners,
AtD, AtD_bind_proofreader_listeners, AtD_check_when
*/
/* the AtD/jQuery and AtD/TinyMCE plugins check if this variable exists and increment it when a proofread check happens */
var AtD_proofread_click_count = 0;
/* This is function called when the publish/update button is pressed */
function AtD_submit_check( e ) {
/* User has already checked their document... no need to hold up their submit */
if (AtD_proofread_click_count > 0) {
return;
}
/* Let's not submit the form, shall we? */
e.stopImmediatePropagation();
e.preventDefault();
/* We'll call the AtD function based on which editor is currently active */
if ( typeof(tinyMCE) !== 'undefined' && tinyMCE.activeEditor && !tinyMCE.activeEditor.isHidden() ) {
/* Woo! We're running tinyMCE! */
tinyMCE.activeEditor.execCommand('mceWritingImprovementTool', AtD_submit_check_callback);
} else {
/* Go Go HTML editor! */
AtD_restore_if_proofreading();
AtD_check( AtD_submit_check_callback );
}
}
/* This is the callback function that runs after the publish/update button is pressed */
function AtD_submit_check_callback(count) {
count = Number( count || 0 );
AtD_unbind_proofreader_listeners();
if ( 0 === count || 1 < AtD_proofread_click_count ) {
/* if no errors were found, submit form */
AtD_update_post();
} else if ( -1 === count ) {
/* If there was an error, alert the user and submit form */
alert( AtD.getLang('message_server_error', 'There was a problem communicating with the Proofreading service. Try again in one minute.') );
AtD_update_post();
} else {
var original_post_status = jQuery('#original_post_status').val();
/* Okay, the user has tried to publish/update already but there are still errors. Ask them what to do */
var message;
if ( original_post_status === 'publish' ) {
message = AtD.getLang('dialog_confirm_post_publish', 'The proofreader has suggestions for this post. Are you sure you want to publish it?\n\nPress OK to publish your post, or Cancel to view the suggestions and edit your post.');
} else {
message = AtD.getLang('dialog_confirm_post_update', 'The proofreader has suggestions for this post. Are you sure you want to update it?\n\nPress OK to update your post, or Cancel to view the suggestions and edit your post.');
}
if ( confirm( message ) ) {
AtD_update_post();
} else {
AtD_bind_proofreader_listeners();
AtD_kill_autoproofread();
}
/* Let's do some interface clean-up */
jQuery('#publish').removeClass('button-primary-disabled');
jQuery('#ajax-loading').hide();
}
}
/* Stop the proofreader from doing its auto proofread thing (activated when the proofread button is clicked) */
function AtD_kill_autoproofread() {
jQuery('#publish').unbind('click.AtD_submit_check');
}
/* a function to force the post to be submitted */
function AtD_update_post() {
if ( typeof(tinyMCE) === 'undefined' || !tinyMCE.activeEditor || tinyMCE.activeEditor.isHidden() ) {
AtD_restore_if_proofreading();
}
jQuery('#publish').unbind('click.AtD_submit_check').click();
}
/* init the autoproofread options */
jQuery( document ).ready( function($){
var orig_status = $('#original_post_status').val();
/* check if auto-check is enabled && if #content exists */
if ( typeof AtD_check_when !== 'undefined' && $('#content').length &&
( ( orig_status !== 'publish' && AtD_check_when.onpublish ) ||
( ( orig_status === 'publish' || orig_status === 'schedule' ) && AtD_check_when.onupdate ) ) ) {
$('#publish').bind( 'click.AtD_submit_check', AtD_submit_check );
}
});

View File

@@ -0,0 +1,268 @@
/* jshint devel: true, onevar: false, smarttabs: true */
/* global AtD, QTags, AtD_l10n_r0ar, edButtons, edButton, switchEditors, AtD_unbind_proofreader_listeners */
/* exported AtD_unbind_proofreader_listeners */
var AtD_qtbutton, autosave;
/* convienence method to restore the text area from the preview div */
function AtD_restore_text_area() {
var content;
/* swap the preview div for the textarea, notice how I have to restore the appropriate class/id/style attributes */
if( jQuery('#atd-content').get(0) ) {
AtD.remove('atd-content');
content = jQuery('#atd-content').html();
} else {
AtD.remove('content');
content = jQuery('#content').html();
}
if ( navigator.appName === 'Microsoft Internet Explorer' ) {
content = content.replace(/<BR.*?class.*?atd_remove_me.*?>/gi, '\n');
}
// Remove emoji replacement images
if ( typeof window.twemoji !== 'undefined' ) {
content = content.replace( /<img [^>]+>/g, function( img ) {
// The images should have class containing 'emoji'
if ( img.indexOf( 'emoji' ) !== -1 ) {
var alt = img.match( /alt="([^"]+)"/ );
if ( alt && alt[1] && window.twemoji.test( alt[1] ) ) {
return alt[1];
}
}
return img;
});
}
// jQuery('#content').replaceWith( AtD.content_canvas );
jQuery('#content').val( content.replace(/\&lt\;/g, '<').replace(/\&gt\;/g, '>').replace(/\&amp;/g, '&') )
.height(AtD.height)
.show();
jQuery('#atd-content').remove();
if ( AtD_qtbutton ) {
/* change the link text back to its original label */
jQuery(AtD_qtbutton).val( AtD.getLang('button_proofread', 'proofread') );
jQuery(AtD_qtbutton).css({ 'color' : '#464646' });
/* enable the toolbar buttons */
jQuery( AtD_qtbutton ).siblings('input').andSelf().attr( 'disabled', false );
}
/* restore autosave */
if ( AtD.autosave !== undefined ) {
if ( window.wp && window.wp.autosave && window.wp.autosave.server ) {
window.wp.autosave.local.resume && window.wp.autosave.local.resume();
window.wp.autosave.server.resume && window.wp.autosave.server.resume();
} else {
autosave = AtD.autosave;
}
}
}
// add the AtD button properly to quicktags
if ( typeof(QTags) !== 'undefined' && QTags.addButton ) {
jQuery(document).ready(function(){
QTags.addButton( 'AtD', AtD_l10n_r0ar.button_proofread, AtD_check );
});
} else {
edButtons[edButtons.length] = new edButton('ed_AtD', 'AtD', '', '', '');
jQuery(document).ready(function($){
$('#ed_AtD').replaceWith('<input type="button" id="ed_AtD" accesskey="" class="ed_button" onclick="AtD_check(this);" value="' + AtD_l10n_r0ar.button_proofread + '" />');
});
}
function AtD_restore_if_proofreading() {
if ( AtD_qtbutton && jQuery(AtD_qtbutton).val() === AtD.getLang('button_edit_text', 'edit text') ) {
AtD_restore_text_area();
}
}
/* exported AtD_unbind_proofreader_listeners */
function AtD_unbind_proofreader_listeners() {
jQuery('#save-post, #post-preview, #publish, #edButtonPreview').unbind('focus', AtD_restore_if_proofreading );
jQuery('#add_poll, #add_image, #add_video, #add_audio, #add_media').unbind('click', AtD_restore_if_proofreading );
jQuery('#post').unbind('submit', AtD_restore_if_proofreading );
}
function AtD_bind_proofreader_listeners() {
jQuery('#save-post, #post-preview, #publish, #edButtonPreview').focus( AtD_restore_if_proofreading );
jQuery('#add_poll, #add_image, #add_video, #add_audio, #add_media').click( AtD_restore_if_proofreading );
jQuery('#post').submit( AtD_restore_if_proofreading );
}
/* where the magic happens, checks the spelling or restores the form */
function AtD_check(button) {
var callback, divHeight;
if ( jQuery.isFunction( button ) ) {
callback = button;
if ( !AtD_qtbutton ) {
AtD_qtbutton = jQuery( '#qt_content_AtD, #ed_AtD' ).get( 0 );
}
} else {
if ( !button.id ) {
button = button[0];
}
AtD_qtbutton = button;
}
if ( !jQuery('#content').length ) {
if ( 'undefined' !== typeof callback ) {
callback( 0 );
}
AtD_restore_if_proofreading();
return;
}
/* If the text of the link says edit comment, then restore the textarea so the user can edit the text */
if ( jQuery(AtD_qtbutton).val() === AtD.getLang('button_edit_text', 'edit text') ) {
AtD_restore_text_area();
} else {
// Disable editor expand/scroll
if ( window.editorExpand && jQuery( '#postdivrich' ).hasClass( 'wp-editor-expand' ) ) {
AtD.wpEditorExpand = true;
// window.editorExpand.off && window.editorExpand.off();
} else {
AtD.wpEditorExpand = false;
}
/* initialize some of the stuff related to this plugin */
if ( ! AtD.height ) {
AtD.height = jQuery('#content').height();
AtD_bind_proofreader_listeners();
/* make it so clicking the Visual button works when AtD is active */
jQuery('#edButtonPreview').attr( 'onclick', null ).click( function() {
AtD_restore_if_proofreading();
switchEditors.go( 'content', 'tinymce' );
});
/* saved the textarea as we need to restore the original one for the toolbar to continue to function properly */
AtD.content_canvas = jQuery('#content');
/* store the autosave, we're going to make it empty during spellcheck to prevent auto saved text from being
over written with empty text */
AtD.autosave = autosave;
} else {
// Update the height
AtD.height = jQuery('#content').height();
}
/* set the spell check link to a link that lets the user edit the text */
/* disable the button to prevent a race condition where content is deleted if proofread is clicked with a check
in progress. */
jQuery(AtD_qtbutton).css({ 'color' : 'red' }).val( AtD.getLang('button_edit_text', 'edit text') ).attr('disabled', true);
/* replace the div */
var $replacement,
$textarea = jQuery('#content'),
text = $textarea.val().replace( /\&/g, '&amp;' ).replace( /</g, '&lt;' ).replace( /\>/g, '&gt;' ),
fontFamily = $textarea.css('font-family'),
fontSize = $textarea.css('font-size'),
lineHeight = $textarea.css('line-height');
if ( navigator.appName === 'Microsoft Internet Explorer' ) {
text = text.replace( /[\n\r\f]/gm, '<BR class="atd_remove_me">' );
}
$replacement = jQuery( '<div class="input" id="atd-content">' + text + '</div>' );
$textarea.after( $replacement ).hide();
divHeight = AtD.height;
// AtD disables resizing of the Text editor, normalize the size of the replacement div.
if ( divHeight < 200 ) {
divHeight = 200;
} else if ( divHeight > 1000 ) {
divHeight = 1000;
}
var toolBarHeight = jQuery('#ed_toolbar').height();
$replacement.css( {
overflow: 'auto',
'background-color': 'white',
color: 'black',
'white-space': 'pre-wrap',
padding: '10px',
'font-family': fontFamily || 'Consolas, Monaco, monospace',
'font-size': fontSize || '13px',
'line-height': lineHeight || '1.5',
height: divHeight,
'margin-top': toolBarHeight+7+'px'
} );
/* kill autosave... :) */
if ( window.wp && window.wp.autosave && window.wp.autosave.server ) {
window.wp.autosave.local.suspend && window.wp.autosave.local.suspend();
window.wp.autosave.server.suspend && window.wp.autosave.server.suspend();
} else {
autosave = function() { };
}
/* disable the toolbar buttons */
jQuery( AtD_qtbutton ).siblings('input').andSelf().attr( 'disabled', true ); // using .arrt instead of .prop so it's compat with older WP and jQuery
/* check the writing in the textarea */
AtD.check('atd-content', {
success: function(errorCount) {
if ( Number( errorCount ) === 0 && typeof callback !== 'function' ) {
alert( AtD.getLang('message_no_errors_found', 'No writing errors were found') );
}
AtD_restore_if_proofreading();
},
ready: function(errorCount) {
jQuery(AtD_qtbutton).attr('disabled', false);
if ( typeof callback === 'function' ) {
callback( errorCount );
}
},
error: function() {
jQuery(AtD_qtbutton).attr('disabled', false);
if ( typeof callback === 'function' ) {
callback( -1 );
} else {
alert( AtD.getLang('message_server_error', 'There was a problem communicating with the Proofreading service. Try again in one minute.') );
}
AtD_restore_if_proofreading();
},
editSelection: function(element) {
var text = prompt( AtD.getLang('dialog_replace_selection', 'Replace selection with:'), element.text() );
if ( text != null ) {
element.replaceWith( text );
}
},
explain: function(url) {
var left = (screen.width / 2) - (480 / 2);
var top = (screen.height / 2) - (380 / 2);
window.open( url, '', 'width=480,height=380,toolbar=0,status=0,resizable=0,location=0,menuBar=0,left=' + left + ',top=' + top).focus();
},
ignore: function(word) {
jQuery.ajax({
type : 'GET',
url : AtD.rpc_ignore + encodeURI( word ).replace( /&/g, '%26'),
format : 'raw',
error : function(XHR, status, error) {
if ( AtD.callback_f !== undefined && AtD.callback_f.error !== undefined ) {
AtD.callback_f.error(status + ': ' + error);
}
}
});
}
});
}
}

View File

@@ -0,0 +1,122 @@
/* Do not modify this file directly. It is concatenated from individual module CSS files. */
/* AtD error styles */
.hiddenSpellError
{
border-bottom: 2px solid red;
cursor: default;
}
.hiddenGrammarError
{
border-bottom: 2px solid green;
cursor: default;
}
.hiddenSuggestion
{
border-bottom: 2px solid blue;
cursor: default;
}
/* Menu styles derived from:
* jquery.spellchecker.js - a simple jQuery Spell Checker
* Copyright (c) 2008 Richard Willis
* MIT license : http://www.opensource.org/licenses/mit-license.php
* Project : http://jquery-spellchecker.googlecode.com
*/
#suggestmenu
{
min-width: 122px;
background: #ebeaeb;
position: absolute;
display: none;
z-index: 9999;
overflow: none;
margin-top: 1px;
text-align: right;
font-size: 11px;
}
#suggestmenu strong
{
background: #cccccc;
font-weight: bold;
padding:3px 6px 3px 6px;
display:block;
border:1px solid #dddddd;
border-bottom: 1px solid #aaaaaa;
color: black;
}
#suggestmenu em
{
text-align:center;
padding:3px 6px 3px 6px;
display:block;
border-top:1px solid #ccc;
border-right:1px solid #ccc;
}
#suggestmenu a, #suggestmenu a:visited
{
background: #ebeaeb;
border-right:1px solid #dddddd;
border-left:1px solid #dddddd;
padding:3px 6px 3px 6px;
display:block;
margin:0px;
text-decoration:none;
color: black;
outline:none
}
#suggestmenu a.first, #suggestmenu a.first:visited
{
border-top:1px solid #dddddd;
}
.spell_sep_bottom
{
border-bottom: 1px solid #dddddd;
}
.spell_sep_top
{
border-top: 1px solid #aaaaaa;
}
#suggestmenu a:hover
{
color:#000;
background: #f5f5f5;
}
#suggestmenu .foot
{
border-top:1px solid #aaaaaa;
background:#fff
}
#suggestmenu .foot a, #suggestmenu .foot a:visited
{
outline:none
}
/* TinyMCE 4.0 */
div.mce-atd-menu-title.mce-disabled {
padding: 3px 12px 0;
}
div.mce-atd-menu-title.mce-disabled:hover,
div.mce-atd-menu-title.mce-disabled:hover span.mce-text {
background: none;
color: #888;
cursor: default;
}
div.mce-atd-menu-title.mce-disabled span.mce-text {
font-weight: bold;
color: #888;
}

View File

@@ -0,0 +1 @@
.hiddenSpellError{border-bottom:2px solid red;cursor:default}.hiddenGrammarError{border-bottom:2px solid green;cursor:default}.hiddenSuggestion{border-bottom:2px solid #00f;cursor:default}#suggestmenu{min-width:122px;background:#ebeaeb;position:absolute;display:none;z-index:9999;overflow:none;margin-top:1px;text-align:right;font-size:11px}#suggestmenu strong{background:#ccc;font-weight:700;padding:3px 6px 3px 6px;display:block;border:1px solid #ddd;border-bottom:1px solid #aaa;color:#000}#suggestmenu em{text-align:center;padding:3px 6px 3px 6px;display:block;border-top:1px solid #ccc;border-right:1px solid #ccc}#suggestmenu a,#suggestmenu a:visited{background:#ebeaeb;border-right:1px solid #ddd;border-left:1px solid #ddd;padding:3px 6px 3px 6px;display:block;margin:0;text-decoration:none;color:#000;outline:0}#suggestmenu a.first,#suggestmenu a.first:visited{border-top:1px solid #ddd}.spell_sep_bottom{border-bottom:1px solid #ddd}.spell_sep_top{border-top:1px solid #aaa}#suggestmenu a:hover{color:#000;background:#f5f5f5}#suggestmenu .foot{border-top:1px solid #aaa;background:#fff}#suggestmenu .foot a,#suggestmenu .foot a:visited{outline:0}div.mce-atd-menu-title.mce-disabled{padding:3px 12px 0}div.mce-atd-menu-title.mce-disabled:hover,div.mce-atd-menu-title.mce-disabled:hover span.mce-text{background:0 0;color:#888;cursor:default}div.mce-atd-menu-title.mce-disabled span.mce-text{font-weight:700;color:#888}

View File

@@ -0,0 +1,640 @@
/*
* atd.core.js - A building block to create a front-end for AtD
* Author : Raphael Mudge, Automattic
* License : LGPL
* Project : http://www.afterthedeadline.com/developers.slp
* Contact : raffi@automattic.com
*/
/* jshint sub: true, devel: true, onevar: false, smarttabs: true, loopfunc: true */
/* exported EXPORTED_SYMBOLS, atd_sprintf */
/* EXPORTED_SYMBOLS is set so this file can be a JavaScript Module */
var EXPORTED_SYMBOLS = ['AtDCore'];
function AtDCore() {
/* these are the categories of errors AtD should ignore */
this.ignore_types = ['Bias Language', 'Cliches', 'Complex Expression', 'Diacritical Marks', 'Double Negatives', 'Hidden Verbs', 'Jargon Language', 'Passive voice', 'Phrases to Avoid', 'Redundant Expression'];
/* these are the phrases AtD should ignore */
this.ignore_strings = {};
/* Localized strings */
// Back-compat, not used
this.i18n = {};
}
/*
* Internationalization Functions
*/
AtDCore.prototype.getLang = function( key, defaultk ) {
return ( window.AtD_l10n_r0ar && window.AtD_l10n_r0ar[key] ) || defaultk;
};
AtDCore.prototype.addI18n = function( obj ) {
// Back-compat
window.AtD_l10n_r0ar = obj;
};
/*
* Setters
*/
AtDCore.prototype.setIgnoreStrings = function(string) {
var parent = this;
this.map(string.split(/,\s*/g), function(string) {
parent.ignore_strings[string] = 1;
});
};
AtDCore.prototype.showTypes = function(string) {
var show_types = string.split(/,\s*/g);
var types = {};
/* set some default types that we want to make optional */
/* grammar checker options */
types['Double Negatives'] = 1;
types['Hidden Verbs'] = 1;
types['Passive voice'] = 1;
types['Bias Language'] = 1;
/* style checker options */
types['Cliches'] = 1;
types['Complex Expression'] = 1;
types['Diacritical Marks'] = 1;
types['Jargon Language'] = 1;
types['Phrases to Avoid'] = 1;
types['Redundant Expression'] = 1;
var ignore_types = [];
this.map(show_types, function(string) {
types[string] = undefined;
});
this.map(this.ignore_types, function(string) {
if (types[string] !== undefined) {
ignore_types.push(string);
}
});
this.ignore_types = ignore_types;
};
/*
* Error Parsing Code
*/
AtDCore.prototype.makeError = function(error_s, tokens, type, seps/*, pre*/) {
var struct = {};
struct.type = type;
struct.string = error_s;
struct.tokens = tokens;
if (new RegExp('\\b' + error_s + '\\b').test(error_s)) {
struct.regexp = new RegExp('(?!'+error_s+'<)\\b' + error_s.replace(/\s+/g, seps) + '\\b');
}
else if (new RegExp(error_s + '\\b').test(error_s)) {
struct.regexp = new RegExp('(?!'+error_s+'<)' + error_s.replace(/\s+/g, seps) + '\\b');
}
else if (new RegExp('\\b' + error_s).test(error_s)) {
struct.regexp = new RegExp('(?!'+error_s+'<)\\b' + error_s.replace(/\s+/g, seps));
}
else {
struct.regexp = new RegExp('(?!'+error_s+'<)' + error_s.replace(/\s+/g, seps));
}
struct.used = false; /* flag whether we've used this rule or not */
return struct;
};
AtDCore.prototype.addToErrorStructure = function(errors, list, type, seps) {
var parent = this;
this.map(list, function(error) {
var tokens = error['word'].split(/\s+/);
var pre = error['pre'];
var first = tokens[0];
if (errors['__' + first] === undefined) {
errors['__' + first] = {};
errors['__' + first].pretoks = {};
errors['__' + first].defaults = [];
}
if (pre === '') {
errors['__' + first].defaults.push(parent.makeError(error['word'], tokens, type, seps, pre));
} else {
if (errors['__' + first].pretoks['__' + pre] === undefined) {
errors['__' + first].pretoks['__' + pre] = [];
}
errors['__' + first].pretoks['__' + pre].push(parent.makeError(error['word'], tokens, type, seps, pre));
}
});
};
AtDCore.prototype.buildErrorStructure = function(spellingList, enrichmentList, grammarList) {
var seps = this._getSeparators();
var errors = {};
this.addToErrorStructure(errors, spellingList, 'hiddenSpellError', seps);
this.addToErrorStructure(errors, grammarList, 'hiddenGrammarError', seps);
this.addToErrorStructure(errors, enrichmentList, 'hiddenSuggestion', seps);
return errors;
};
AtDCore.prototype._getSeparators = function() {
var re = '', i;
var str = '"s!#$%&()*+,./:;<=>?@[\\]^_{|}';
// Build word separator regexp
for (i=0; i<str.length; i++) {
re += '\\' + str.charAt(i);
}
return '(?:(?:[\xa0' + re + '])|(?:\\-\\-))+';
};
AtDCore.prototype.processXML = function(responseXML) {
/* types of errors to ignore */
var types = {};
this.map(this.ignore_types, function(type) {
types[type] = 1;
});
/* save suggestions in the editor object */
this.suggestions = [];
/* process through the errors */
var errors = responseXML.getElementsByTagName('error');
/* words to mark */
var grammarErrors = [];
var spellingErrors = [];
var enrichment = [];
for (var i = 0; i < errors.length; i++) {
if (errors[i].getElementsByTagName('string').item(0).firstChild !== null) {
var errorString = errors[i].getElementsByTagName('string').item(0).firstChild.data;
var errorType = errors[i].getElementsByTagName('type').item(0).firstChild.data;
var errorDescription = errors[i].getElementsByTagName('description').item(0).firstChild.data;
var errorContext;
if (errors[i].getElementsByTagName('precontext').item(0).firstChild !== null) {
errorContext = errors[i].getElementsByTagName('precontext').item(0).firstChild.data;
} else {
errorContext = '';
}
/* create a hashtable with information about the error in the editor object, we will use this later
to populate a popup menu with information and suggestions about the error */
if (this.ignore_strings[errorString] === undefined) {
var suggestion = {};
suggestion['description'] = errorDescription;
suggestion['suggestions'] = [];
/* used to find suggestions when a highlighted error is clicked on */
suggestion['matcher'] = new RegExp('^' + errorString.replace(/\s+/, this._getSeparators()) + '$');
suggestion['context'] = errorContext;
suggestion['string'] = errorString;
suggestion['type'] = errorType;
this.suggestions.push(suggestion);
if (errors[i].getElementsByTagName('suggestions').item(0) !== null) {
var suggestions = errors[i].getElementsByTagName('suggestions').item(0).getElementsByTagName('option');
for (var j = 0; j < suggestions.length; j++) {
suggestion['suggestions'].push(suggestions[j].firstChild.data);
}
}
/* setup the more info url */
if (errors[i].getElementsByTagName('url').item(0) !== null) {
var errorUrl = errors[i].getElementsByTagName('url').item(0).firstChild.data;
suggestion['moreinfo'] = errorUrl + '&theme=tinymce';
}
if (types[errorDescription] === undefined) {
if (errorType === 'suggestion') {
enrichment.push({ word: errorString, pre: errorContext });
}
if (errorType === 'grammar') {
grammarErrors.push({ word: errorString, pre: errorContext });
}
}
if (errorType === 'spelling' || errorDescription === 'Homophone') {
spellingErrors.push({ word: errorString, pre: errorContext });
}
if (errorDescription === 'Cliches') {
suggestion['description'] = 'Clichés'; /* done here for backwards compatability with current user settings */
}
if (errorDescription === 'Spelling') {
suggestion['description'] = this.getLang('menu_title_spelling', 'Spelling');
}
if (errorDescription === 'Repeated Word') {
suggestion['description'] = this.getLang('menu_title_repeated_word', 'Repeated Word');
}
if (errorDescription === 'Did you mean...') {
suggestion['description'] = this.getLang('menu_title_confused_word', 'Did you mean...');
}
} // end if ignore[errorString] == undefined
} // end if
} // end for loop
var errorStruct;
var ecount = spellingErrors.length + grammarErrors.length + enrichment.length;
if (ecount > 0) {
errorStruct = this.buildErrorStructure(spellingErrors, enrichment, grammarErrors);
} else {
errorStruct = undefined;
}
/* save some state in this object, for retrieving suggestions later */
return { errors: errorStruct, count: ecount, suggestions: this.suggestions };
};
AtDCore.prototype.findSuggestion = function(element) {
var text = element.innerHTML;
var context = ( this.getAttrib(element, 'pre') + '' ).replace(/[\\,!\\?\\."\s]/g, '');
if (this.getAttrib(element, 'pre') === undefined) {
alert(element.innerHTML);
}
var errorDescription;
var len = this.suggestions.length;
for (var i = 0; i < len; i++) {
if ((context === '' || context === this.suggestions[i]['context']) && this.suggestions[i]['matcher'].test(text)) {
errorDescription = this.suggestions[i];
break;
}
}
return errorDescription;
};
/*
* TokenIterator class
*/
function TokenIterator(tokens) {
this.tokens = tokens;
this.index = 0;
this.count = 0;
this.last = 0;
}
TokenIterator.prototype.next = function() {
var current = this.tokens[this.index];
this.count = this.last;
this.last += current.length + 1;
this.index++;
/* strip single quotes from token, AtD does this when presenting errors */
if (current !== '') {
if (current[0] === '\'') {
current = current.substring(1, current.length);
}
if (current[current.length - 1] === '\'') {
current = current.substring(0, current.length - 1);
}
}
return current;
};
TokenIterator.prototype.hasNext = function() {
return this.index < this.tokens.length;
};
TokenIterator.prototype.hasNextN = function(n) {
return (this.index + n) < this.tokens.length;
};
TokenIterator.prototype.skip = function(m, n) {
this.index += m;
this.last += n;
if (this.index < this.tokens.length) {
this.count = this.last - this.tokens[this.index].length;
}
};
TokenIterator.prototype.getCount = function() {
return this.count;
};
TokenIterator.prototype.peek = function(n) {
var peepers = [];
var end = this.index + n;
for (var x = this.index; x < end; x++) {
peepers.push(this.tokens[x]);
}
return peepers;
};
/*
* code to manage highlighting of errors
*/
AtDCore.prototype.markMyWords = function(container_nodes, errors) {
var seps = new RegExp(this._getSeparators()),
nl = [],
ecount = 0, /* track number of highlighted errors */
parent = this,
bogus = this._isTinyMCE ? ' data-mce-bogus="1"' : '',
emptySpan = '<span class="mceItemHidden"' + bogus + '>&nbsp;</span>',
textOnlyMode;
/**
* Split a text node into an ordered list of siblings:
* - text node to the left of the match
* - the element replacing the match
* - text node to the right of the match
*
* We have to leave the text to the left and right of the match alone
* in order to prevent XSS
*
* @return array
*/
function splitTextNode( textnode, regexp, replacement ) {
var text = textnode.nodeValue,
index = text.search( regexp ),
match = text.match( regexp ),
captured = [],
cursor;
if ( index < 0 || ! match.length ) {
return [ textnode ];
}
if ( index > 0 ) {
// capture left text node
captured.push( document.createTextNode( text.substr( 0, index ) ) );
}
// capture the replacement of the matched string
captured.push( parent.create( match[0].replace( regexp, replacement ) ) );
cursor = index + match[0].length;
if ( cursor < text.length ) {
// capture right text node
captured.push( document.createTextNode( text.substr( cursor ) ) );
}
return captured;
}
function _isInPre( node ) {
if ( node ) {
while ( node.parentNode ) {
if ( node.nodeName === 'PRE' ) {
return true;
}
node = node.parentNode;
}
}
return false;
}
/* Collect all text nodes */
/* Our goal--ignore nodes that are already wrapped */
this._walk( container_nodes, function( n ) {
if ( n.nodeType === 3 && ! parent.isMarkedNode( n ) && ! _isInPre( n ) ) {
nl.push( n );
}
});
/* walk through the relevant nodes */
var iterator;
this.map( nl, function( n ) {
var v;
if ( n.nodeType === 3 ) {
v = n.nodeValue; /* we don't want to mangle the HTML so use the actual encoded string */
var tokens = n.nodeValue.split( seps ); /* split on the unencoded string so we get access to quotes as " */
var previous = '';
var doReplaces = [];
iterator = new TokenIterator(tokens);
while ( iterator.hasNext() ) {
var token = iterator.next();
var current = errors['__' + token];
var defaults;
if ( current !== undefined && current.pretoks !== undefined ) {
defaults = current.defaults;
current = current.pretoks['__' + previous];
var done = false;
var prev, curr;
prev = v.substr(0, iterator.getCount());
curr = v.substr(prev.length, v.length);
var checkErrors = function( error ) {
if ( error !== undefined && ! error.used && foundStrings[ '__' + error.string ] === undefined && error.regexp.test( curr ) ) {
foundStrings[ '__' + error.string ] = 1;
doReplaces.push([ error.regexp, '<span class="'+error.type+'" pre="'+previous+'"' + bogus + '>$&</span>' ]);
error.used = true;
done = true;
}
}; // jshint ignore:line
var foundStrings = {};
if (current !== undefined) {
previous = previous + ' ';
parent.map(current, checkErrors);
}
if (!done) {
previous = '';
parent.map(defaults, checkErrors);
}
}
previous = token;
} // end while
/* do the actual replacements on this span */
if ( doReplaces.length > 0 ) {
var newNode = n;
for ( var x = 0; x < doReplaces.length; x++ ) {
var regexp = doReplaces[x][0], result = doReplaces[x][1];
/* it's assumed that this function is only being called on text nodes (nodeType == 3), the iterating is necessary
because eventually the whole thing gets wrapped in an mceItemHidden span and from there it's necessary to
handle each node individually. */
var bringTheHurt = function( node ) {
var span, splitNodes;
if ( node.nodeType === 3 ) {
ecount++;
/* sometimes IE likes to ignore the space between two spans, solution is to insert a placeholder span with
a non-breaking space. The markup removal code substitutes this span for a space later */
if ( parent.isIE() && node.nodeValue.length > 0 && node.nodeValue.substr(0, 1) === ' ' ) {
return parent.create( emptySpan + node.nodeValue.substr( 1, node.nodeValue.length - 1 ).replace( regexp, result ), false );
} else {
if ( textOnlyMode ) {
return parent.create( node.nodeValue.replace( regexp, result ), false );
}
span = parent.create( '<span />' );
if ( typeof textOnlyMode === 'undefined' ) {
// cache this to avoid adding / removing nodes unnecessarily
textOnlyMode = typeof span.appendChild !== 'function';
if ( textOnlyMode ) {
parent.remove( span );
return parent.create( node.nodeValue.replace( regexp, result ), false );
}
}
// "Visual" mode
splitNodes = splitTextNode( node, regexp, result );
for ( var i = 0; i < splitNodes.length; i++ ) {
span.appendChild( splitNodes[i] );
}
node = span;
return node;
}
}
else {
var contents = parent.contents(node);
for ( var y = 0; y < contents.length; y++ ) {
if ( contents[y].nodeType === 3 && regexp.test( contents[y].nodeValue ) ) {
var nnode;
if ( parent.isIE() && contents[y].nodeValue.length > 0 && contents[y].nodeValue.substr(0, 1) === ' ') {
nnode = parent.create( emptySpan + contents[y].nodeValue.substr( 1, contents[y].nodeValue.length - 1 ).replace( regexp, result ), true );
} else {
nnode = parent.create( contents[y].nodeValue.replace( regexp, result ), true );
}
parent.replaceWith( contents[y], nnode );
parent.removeParent( nnode );
ecount++;
return node; /* we did a replacement so we can call it quits, errors only get used once */
}
}
return node;
}
}; // jshint ignore:line
newNode = bringTheHurt(newNode);
}
parent.replaceWith(n, newNode);
}
}
});
return ecount;
};
AtDCore.prototype._walk = function(elements, f) {
var i;
for (i = 0; i < elements.length; i++) {
f.call(f, elements[i]);
this._walk(this.contents(elements[i]), f);
}
};
AtDCore.prototype.removeWords = function(node, w) {
var count = 0;
var parent = this;
this.map(this.findSpans(node).reverse(), function(n) {
if (n && (parent.isMarkedNode(n) || parent.hasClass(n, 'mceItemHidden') || parent.isEmptySpan(n)) ) {
if (n.innerHTML === '&nbsp;') {
var nnode = document.createTextNode(' '); /* hax0r */
parent.replaceWith(n, nnode);
} else if (!w || n.innerHTML === w) {
parent.removeParent(n);
count++;
}
}
});
return count;
};
AtDCore.prototype.isEmptySpan = function(node) {
return (this.getAttrib(node, 'class') === '' && this.getAttrib(node, 'style') === '' && this.getAttrib(node, 'id') === '' && !this.hasClass(node, 'Apple-style-span') && this.getAttrib(node, 'mce_name') === '');
};
AtDCore.prototype.isMarkedNode = function(node) {
return (this.hasClass(node, 'hiddenGrammarError') || this.hasClass(node, 'hiddenSpellError') || this.hasClass(node, 'hiddenSuggestion'));
};
/*
* Context Menu Helpers
*/
AtDCore.prototype.applySuggestion = function(element, suggestion) {
if (suggestion === '(omit)') {
this.remove(element);
}
else {
var node = this.create(suggestion);
this.replaceWith(element, node);
this.removeParent(node);
}
};
/*
* Check for an error
*/
AtDCore.prototype.hasErrorMessage = function(xmlr) {
return (xmlr !== undefined && xmlr.getElementsByTagName('message').item(0) !== null);
};
AtDCore.prototype.getErrorMessage = function(xmlr) {
return xmlr.getElementsByTagName('message').item(0);
};
/* this should always be an error, alas... not practical */
AtDCore.prototype.isIE = function() {
return navigator.appName === 'Microsoft Internet Explorer';
};
// TODO: this doesn't seem used anywhere in AtD, moved here from install_atd_l10n.js for eventual back-compat
/* a quick poor man's sprintf */
function atd_sprintf(format, values) {
var result = format;
for (var x = 0; x < values.length; x++) {
result = result.replace(new RegExp('%' + (x + 1) + '\\$', 'g'), values[x]);
}
return result;
}

View File

@@ -0,0 +1,121 @@
/* AtD error styles */
.hiddenSpellError
{
border-bottom: 2px solid red;
cursor: default;
}
.hiddenGrammarError
{
border-bottom: 2px solid green;
cursor: default;
}
.hiddenSuggestion
{
border-bottom: 2px solid blue;
cursor: default;
}
/* Menu styles derived from:
* jquery.spellchecker.js - a simple jQuery Spell Checker
* Copyright (c) 2008 Richard Willis
* MIT license : http://www.opensource.org/licenses/mit-license.php
* Project : http://jquery-spellchecker.googlecode.com
*/
#suggestmenu
{
min-width: 122px;
background: #ebeaeb;
position: absolute;
display: none;
z-index: 9999;
overflow: none;
margin-top: 1px;
text-align: left;
font-size: 11px;
}
#suggestmenu strong
{
background: #cccccc;
font-weight: bold;
padding:3px 6px 3px 6px;
display:block;
border:1px solid #dddddd;
border-bottom: 1px solid #aaaaaa;
color: black;
}
#suggestmenu em
{
text-align:center;
padding:3px 6px 3px 6px;
display:block;
border-top:1px solid #ccc;
border-left:1px solid #ccc;
}
#suggestmenu a, #suggestmenu a:visited
{
background: #ebeaeb;
border-left:1px solid #dddddd;
border-right:1px solid #dddddd;
padding:3px 6px 3px 6px;
display:block;
margin:0px;
text-decoration:none;
color: black;
outline:none
}
#suggestmenu a.first, #suggestmenu a.first:visited
{
border-top:1px solid #dddddd;
}
.spell_sep_bottom
{
border-bottom: 1px solid #dddddd;
}
.spell_sep_top
{
border-top: 1px solid #aaaaaa;
}
#suggestmenu a:hover
{
color:#000;
background: #f5f5f5;
}
#suggestmenu .foot
{
border-top:1px solid #aaaaaa;
background:#fff
}
#suggestmenu .foot a, #suggestmenu .foot a:visited
{
outline:none
}
/* TinyMCE 4.0 */
div.mce-atd-menu-title.mce-disabled {
padding: 3px 12px 0;
}
div.mce-atd-menu-title.mce-disabled:hover,
div.mce-atd-menu-title.mce-disabled:hover span.mce-text {
background: none;
color: #888;
cursor: default;
}
div.mce-atd-menu-title.mce-disabled span.mce-text {
font-weight: bold;
color: #888;
}

View File

@@ -0,0 +1,2 @@
/* Do not modify this file directly. It is concatenated from individual module CSS files. */
.hiddenSpellError{border-bottom:2px solid red;cursor:default}.hiddenGrammarError{border-bottom:2px solid green;cursor:default}.hiddenSuggestion{border-bottom:2px solid #00f;cursor:default}#suggestmenu{min-width:122px;background:#ebeaeb;position:absolute;display:none;z-index:9999;overflow:none;margin-top:1px;text-align:left;font-size:11px}#suggestmenu strong{background:#ccc;font-weight:700;padding:3px 6px 3px 6px;display:block;border:1px solid #ddd;border-bottom:1px solid #aaa;color:#000}#suggestmenu em{text-align:center;padding:3px 6px 3px 6px;display:block;border-top:1px solid #ccc;border-left:1px solid #ccc}#suggestmenu a,#suggestmenu a:visited{background:#ebeaeb;border-left:1px solid #ddd;border-right:1px solid #ddd;padding:3px 6px 3px 6px;display:block;margin:0;text-decoration:none;color:#000;outline:0}#suggestmenu a.first,#suggestmenu a.first:visited{border-top:1px solid #ddd}.spell_sep_bottom{border-bottom:1px solid #ddd}.spell_sep_top{border-top:1px solid #aaa}#suggestmenu a:hover{color:#000;background:#f5f5f5}#suggestmenu .foot{border-top:1px solid #aaa;background:#fff}#suggestmenu .foot a,#suggestmenu .foot a:visited{outline:0}div.mce-atd-menu-title.mce-disabled{padding:3px 12px 0}div.mce-atd-menu-title.mce-disabled:hover,div.mce-atd-menu-title.mce-disabled:hover span.mce-text{background:0 0;color:#888;cursor:default}div.mce-atd-menu-title.mce-disabled span.mce-text{font-weight:700;color:#888}

Binary file not shown.

After

Width:  |  Height:  |  Size: 515 B

View File

@@ -0,0 +1,128 @@
<?php
/*
* Display the configuration options for AtD
*/
/*
* A convienence function to display the HTML for an AtD option
*/
function AtD_print_option( $name, $value, $options ) {
// Attribute-safe version of $name
$attr_name = sanitize_title($name); // Using sanitize_title since there's no comparable function for attributes
?>
<input type="checkbox" id="atd_<?php echo esc_attr( $attr_name ) ?>" name="<?php echo esc_attr( $options['name'] ); ?>[<?php echo esc_attr( $name ); ?>]" value="1" <?php checked( '1', isset( $options[$name] ) ? $options[$name] : false ); ?>> <label for="atd_<?php echo esc_attr( $attr_name ); ?>"><?php echo esc_html( $value ); ?></label>
<?php
}
/*
* Save AtD options
*/
function AtD_process_options_update() {
$user = wp_get_current_user();
if ( ! $user || $user->ID == 0 )
return;
AtD_update_options( $user->ID, 'AtD_options' );
AtD_update_options( $user->ID, 'AtD_check_when' );
AtD_update_options( $user->ID, 'AtD_guess_lang' );
}
/*
* Display the various AtD options
*/
function AtD_display_options_form() {
/* grab our user and validate their existence */
$user = wp_get_current_user();
if ( ! $user || $user->ID == 0 )
return;
$options_show_types = AtD_get_options( $user->ID, 'AtD_options' );
$options_check_when = AtD_get_options( $user->ID, 'AtD_check_when' );
$options_guess_lang = AtD_get_options( $user->ID, 'AtD_guess_lang' );
?>
<table class="form-table">
<tr valign="top">
<th scope="row"> <a id="atd"></a> <?php _e( 'Proofreading', 'jetpack' ); ?></th>
<td>
<p><?php _e( 'Automatically proofread content when:', 'jetpack' ); ?>
<p><?php
AtD_print_option( 'onpublish', __('a post or page is first published', 'jetpack'), $options_check_when );
echo '<br />';
AtD_print_option( 'onupdate', __('a post or page is updated', 'jetpack'), $options_check_when );
?></p>
<p style="font-weight: bold"><?php _e('English Options', 'jetpack'); ?></p>
<p><?php _e('Enable proofreading for the following grammar and style rules when writing posts and pages:', 'jetpack'); ?></p>
<p><?php
AtD_print_option( 'Bias Language', __('Bias Language', 'jetpack'), $options_show_types );
echo '<br />';
AtD_print_option( 'Cliches', __('Clich&eacute;s', 'jetpack'), $options_show_types );
echo '<br />';
AtD_print_option( 'Complex Expression', __('Complex Phrases', 'jetpack'), $options_show_types );
echo '<br />';
AtD_print_option( 'Diacritical Marks', __('Diacritical Marks', 'jetpack'), $options_show_types );
echo '<br />';
AtD_print_option( 'Double Negative', __('Double Negatives', 'jetpack'), $options_show_types );
echo '<br />';
AtD_print_option( 'Hidden Verbs', __('Hidden Verbs', 'jetpack'), $options_show_types );
echo '<br />';
AtD_print_option( 'Jargon Language', __('Jargon', 'jetpack'), $options_show_types );
echo '<br />';
AtD_print_option( 'Passive voice', __('Passive Voice', 'jetpack'), $options_show_types );
echo '<br />';
AtD_print_option( 'Phrases to Avoid', __('Phrases to Avoid', 'jetpack'), $options_show_types );
echo '<br />';
AtD_print_option( 'Redundant Expression', __('Redundant Phrases', 'jetpack'), $options_show_types );
?></p>
<p><?php printf( __( '<a href="%s" target="_blank">Learn more</a> about these options.', 'jetpack' ), 'http://support.wordpress.com/proofreading/' );
?></p>
<p style="font-weight: bold"><?php _e( 'Language', 'jetpack' ); ?></p>
<p><?php
_e( 'The proofreader supports English, French, German, Portuguese, and Spanish. Your user interface language (see above) is the default proofreading language.', 'jetpack' );
?></p>
<p><?php
AtD_print_option( 'true', __('Use automatically detected language to proofread posts and pages', 'jetpack' ), $options_guess_lang );
?></p>
<?php
}
/*
* Returns an array of AtD user options specified by $name
*/
function AtD_get_options( $user_id, $name ) {
$options_raw = AtD_get_setting( $user_id, $name, 'single' );
$options = array();
$options['name'] = $name;
if ( $options_raw )
foreach ( explode( ',', $options_raw ) as $option )
$options[ $option ] = 1;
return $options;
}
/*
* Saves set of user options specified by $name from POST data
*/
function AtD_update_options( $user_id, $name ) {
/* We should probably run $_POST[name] through an esc_*() function... */
if ( isset( $_POST[$name] ) && is_array( $_POST[$name] ) ) {
$copy = array_map( 'strip_tags', array_keys( $_POST[$name] ) );
AtD_update_setting( $user_id, AtD_sanitize( $name ), implode( ',', $copy ) );
} else {
AtD_update_setting( $user_id, AtD_sanitize( $name ), '');
}
return;
}

View File

@@ -0,0 +1,148 @@
<?php
/*
* Called by the TinyMCE plugin when Ignore Always is clicked (setup as an action through admin-ajax.php)
*/
function AtD_ignore_call() {
if ( ! AtD_is_allowed() )
return;
$user = wp_get_current_user();
if ( ! $user || $user->ID == 0 )
return;
check_admin_referer( 'atd_ignore' );
$ignores = explode( ',', AtD_get_setting( $user->ID, 'AtD_ignored_phrases') );
array_push( $ignores, $_GET['phrase'] );
$ignores = array_filter( array_map( 'strip_tags', $ignores ) );
AtD_update_setting( $user->ID, 'AtD_ignored_phrases', implode( ',', $ignores ) );
header( 'Content-Type: text/xml' );
echo '<success></success>';
die();
}
/*
* Called when a POST occurs, used to save AtD ignored phrases
*/
function AtD_process_unignore_update() {
if ( ! AtD_is_allowed() )
return;
if ( ! isset( $_POST['AtD_ignored_phrases'] ) )
return;
$user = wp_get_current_user();
if ( ! $user || $user->ID == 0 )
return;
$ignores = array_filter( array_map( 'strip_tags', explode( ',', $_POST['AtD_ignored_phrases'] ) ) );
AtD_update_setting( $user->ID, 'AtD_ignored_phrases', join( ',', $ignores ) );
}
/*
* Display the AtD unignore form on a page
*/
function AtD_display_unignore_form() {
if ( ! AtD_is_allowed() )
return;
$user = wp_get_current_user();
if ( ! $user || $user->ID == 0 )
return;
$ignores = AtD_get_setting( $user->ID, 'AtD_ignored_phrases' );
?>
<script>
function atd_show_phrases( ignored )
{
var element = jQuery( '#atd_ignores' ),
items = [],
delLink;
ignored.sort();
element.empty();
for ( var i = 0; i < ignored.length; i++ ) {
if ( ignored[i].length > 0 ) {
delLink = jQuery( '<span id="atd_' + i + '">&nbsp;</span>' );
delLink
.text( delLink.text() + ignored[i] )
.prepend( jQuery( '<a class="ntdelbutton">X</a>' ).data( 'ignored', ignored[i] ) );
element.append( delLink ).append( '<br />' );
}
}
}
function atd_unignore( phrase ) {
/* get the ignored values and remove the unwanted phrase */
var ignored = jQuery( '#AtD_ignored_phrases' ).val().split( /,/g );
ignored = jQuery.map(ignored, function(value, index) { return value == phrase ? null : value; });
jQuery( '#AtD_ignored_phrases' ).val( ignored.join(',') );
/* update the UI */
atd_show_phrases( ignored );
/* show a nifty message to the user */
jQuery( '#AtD_message' ).show();
}
function atd_ignore () {
/* get the ignored values and update the hidden field */
var ignored = jQuery( '#AtD_ignored_phrases' ).val().split( /,/g );
jQuery.map(jQuery( '#AtD_add_ignore' ).val().split(/,\s*/g), function(value, index) { ignored.push(value); });
jQuery( '#AtD_ignored_phrases' ).val( ignored.join(',') );
/* update the UI */
atd_show_phrases( ignored );
jQuery( '#AtD_add_ignore' ).val('');
/* show that nifteroo messaroo to the useroo */
jQuery( '#AtD_message' ).show();
}
function atd_ignore_init() {
jQuery( '#AtD_message' ).hide();
jQuery( '#atd_ignores' ).on( 'click', 'a', function() {
atd_unignore( jQuery(this).data( 'ignored' ) );
return false;
} );
atd_show_phrases( jQuery( '#AtD_ignored_phrases' ).val().split( /,/g ) );
}
/* document.ready() does not execute in IE6 unless it's at the bottom of the page. oi! */
if (navigator.appName == 'Microsoft Internet Explorer')
setTimeout( atd_ignore_init, 2500 );
else
jQuery( document ).ready( atd_ignore_init );
</script>
<input type="hidden" name="AtD_ignored_phrases" id="AtD_ignored_phrases" value="<?php echo esc_attr( $ignores ); ?>">
<p style="font-weight: bold"><?php _e( 'Ignored Phrases', 'jetpack' ); ?></p>
<p><?php _e( 'Identify words and phrases to ignore while proofreading your posts and pages:', 'jetpack' ); ?></p>
<p><input type="text" id="AtD_add_ignore" name="AtD_add_ignore"> <input type="button" value="<?php esc_attr_e( 'Add', 'jetpack' ); ?>" onclick="javascript:atd_ignore()"></p>
<div class="tagchecklist" id="atd_ignores"></div>
<div class="plugin-update-tr" id="AtD_message" style="display: none">
<div class="update-message"><strong><?php _e( 'Be sure to click "Update Profile" at the bottom of the screen to save your changes.', 'jetpack' ); ?></strong></div>
</div>
</td>
</tr>
</table>
<?php
}

View File

@@ -0,0 +1,436 @@
/*
* jquery.atd.js - jQuery powered writing check with After the Deadline
* Author : Raphael Mudge, Automattic Inc.
* License : LGPL or MIT License (take your pick)
* Project : http://www.afterthedeadline.com/development.slp
* Contact : raffi@automattic.com
*
* Derived from:
*
* jquery.spellchecker.js - a simple jQuery Spell Checker
* Copyright (c) 2008 Richard Willis
* MIT license : http://www.opensource.org/licenses/mit-license.php
* Project : http://jquery-spellchecker.googlecode.com
* Contact : willis.rh@gmail.com
*/
/* jshint onevar: false, sub: true, smarttabs: true, loopfunc: true */
/* global AtDCore, AtD_proofread_click_count, CSSHttpRequest, ActiveXObject */
var AtD =
{
rpc : '', /* see the proxy.php that came with the AtD/TinyMCE plugin */
rpc_css : 'http://www.polishmywriting.com/atd-jquery/server/proxycss.php?data=', /* you may use this, but be nice! */
rpc_css_lang : 'en',
api_key : '',
i18n : {}, // Back-compat
listener : {}
};
AtD.getLang = function( key, defaultk ) {
return ( window.AtD_l10n_r0ar && window.AtD_l10n_r0ar[key] ) || defaultk;
};
AtD.addI18n = function( obj ) {
// Back-compat
window.AtD_l10n_r0ar = obj;
};
AtD.setIgnoreStrings = function(string) {
AtD.core.setIgnoreStrings(string);
};
AtD.showTypes = function(string) {
AtD.core.showTypes(string);
};
AtD.checkCrossAJAX = function(container_id, callback_f) {
/* checks if a global var for click stats exists and increments it if it does... */
if (typeof AtD_proofread_click_count !== 'undefined') {
AtD_proofread_click_count++;
}
AtD.callback_f = callback_f; /* remember the callback for later */
AtD.remove(container_id);
var container = jQuery('#' + container_id);
var text = jQuery.trim(container.html());
text = text.replace(/\&lt;/g, '<').replace(/\&gt;/g, '>').replace(/\&amp;/g, '&');
text = encodeURIComponent( text.replace( /\%/g, '%25' ) ); /* % not being escaped here creates problems, I don't know why. */
/* do some sanity checks based on the browser */
if ((text.length > 2000 && navigator.appName === 'Microsoft Internet Explorer') || text.length > 7800) {
if (callback_f !== undefined && callback_f.error !== undefined) {
callback_f.error('Maximum text length for this browser exceeded');
}
return;
}
/* do some cross-domain AJAX action with CSSHttpRequest */
CSSHttpRequest.get(AtD.rpc_css + text + '&lang=' + AtD.rpc_css_lang + '&nocache=' + (new Date().getTime()), function(response) {
/* do some magic to convert the response into an XML document */
var xml;
if (navigator.appName === 'Microsoft Internet Explorer') {
xml = new ActiveXObject('Microsoft.XMLDOM');
xml.async = false;
xml.loadXML(response);
} else {
xml = (new DOMParser()).parseFromString(response, 'text/xml');
}
/* check for and display error messages from the server */
if (AtD.core.hasErrorMessage(xml)) {
if (AtD.callback_f !== undefined && AtD.callback_f.error !== undefined) {
AtD.callback_f.error(AtD.core.getErrorMessage(xml));
}
return;
}
/* highlight the errors */
AtD.container = container_id;
var count = Number( AtD.processXML(container_id, xml) );
if (AtD.callback_f !== undefined && AtD.callback_f.ready !== undefined) {
AtD.callback_f.ready(count);
}
if (count === 0 && AtD.callback_f !== undefined && AtD.callback_f.success !== undefined) {
AtD.callback_f.success(count);
}
AtD.counter = count;
AtD.count = count;
});
};
/* check a div for any incorrectly spelled words */
AtD.check = function(container_id, callback_f) {
/* checks if a global var for click stats exists and increments it if it does... */
if (typeof AtD_proofread_click_count !== 'undefined') {
AtD_proofread_click_count++;
}
AtD.callback_f = callback_f; /* remember the callback for later */
AtD.remove(container_id);
var container = jQuery('#' + container_id);
var text = jQuery.trim(container.html());
text = text.replace(/\&lt;/g, '<').replace(/\&gt;/g, '>').replace(/\&amp;/g, '&');
text = encodeURIComponent( text ); /* re-escaping % is not necessary here. don't do it */
jQuery.ajax({
type : 'POST',
url : AtD.rpc + '/checkDocument',
data : 'key=' + AtD.api_key + '&data=' + text,
format : 'raw',
dataType : (jQuery.browser.msie) ? 'text' : 'xml',
error : function(XHR, status, error) {
if (AtD.callback_f !== undefined && AtD.callback_f.error !== undefined) {
AtD.callback_f.error(status + ': ' + error);
}
},
success : function(data) {
/* apparently IE likes to return XML as plain text-- work around from:
http://docs.jquery.com/Specifying_the_Data_Type_for_AJAX_Requests */
var xml;
if (typeof data === 'string') {
xml = new ActiveXObject('Microsoft.XMLDOM');
xml.async = false;
xml.loadXML(data);
}
else {
xml = data;
}
if (AtD.core.hasErrorMessage(xml)) {
if (AtD.callback_f !== undefined && AtD.callback_f.error !== undefined) {
AtD.callback_f.error(AtD.core.getErrorMessage(xml));
}
return;
}
/* on with the task of processing and highlighting errors */
AtD.container = container_id;
var count = Number( AtD.processXML(container_id, xml) );
if (AtD.callback_f !== undefined && AtD.callback_f.ready !== undefined) {
AtD.callback_f.ready(count);
}
if (count === 0 && AtD.callback_f !== undefined && AtD.callback_f.success !== undefined) {
AtD.callback_f.success(count);
}
AtD.counter = count;
AtD.count = count;
}
});
};
AtD.remove = function(container_id) {
AtD._removeWords(container_id, null);
};
AtD.clickListener = function(event) {
if (AtD.core.isMarkedNode(event.target)) {
AtD.suggest(event.target);
}
};
AtD.processXML = function(container_id, responseXML) {
var results = AtD.core.processXML(responseXML);
if (results.count > 0) {
results.count = AtD.core.markMyWords(jQuery('#' + container_id).contents(), results.errors);
}
jQuery('#' + container_id).unbind('click', AtD.clickListener);
jQuery('#' + container_id).click(AtD.clickListener);
return results.count;
};
AtD.useSuggestion = function(word) {
this.core.applySuggestion(AtD.errorElement, word);
AtD.counter --;
if (AtD.counter === 0 && AtD.callback_f !== undefined && AtD.callback_f.success !== undefined) {
AtD.callback_f.success(AtD.count);
}
};
AtD.editSelection = function() {
var parent = AtD.errorElement.parent();
if (AtD.callback_f !== undefined && AtD.callback_f.editSelection !== undefined) {
AtD.callback_f.editSelection(AtD.errorElement);
}
if (AtD.errorElement.parent() !== parent) {
AtD.counter --;
if (AtD.counter === 0 && AtD.callback_f !== undefined && AtD.callback_f.success !== undefined) {
AtD.callback_f.success(AtD.count);
}
}
};
AtD.ignoreSuggestion = function() {
AtD.core.removeParent(AtD.errorElement);
AtD.counter --;
if (AtD.counter === 0 && AtD.callback_f !== undefined && AtD.callback_f.success !== undefined) {
AtD.callback_f.success(AtD.count);
}
};
AtD.ignoreAll = function(container_id) {
var target = AtD.errorElement.text();
var removed = AtD._removeWords(container_id, target);
AtD.counter -= removed;
if (AtD.counter === 0 && AtD.callback_f !== undefined && AtD.callback_f.success !== undefined) {
AtD.callback_f.success(AtD.count);
}
if (AtD.callback_f !== undefined && AtD.callback_f.ignore !== undefined) {
AtD.callback_f.ignore(target);
AtD.core.setIgnoreStrings(target);
}
};
AtD.explainError = function() {
if (AtD.callback_f !== undefined && AtD.callback_f.explain !== undefined) {
AtD.callback_f.explain(AtD.explainURL);
}
};
AtD.suggest = function(element) {
/* construct the menu if it doesn't already exist */
var suggest;
if (jQuery('#suggestmenu').length === 0) {
suggest = jQuery('<div id="suggestmenu"></div>');
suggest.prependTo('body');
} else {
suggest = jQuery('#suggestmenu');
suggest.hide();
}
/* find the correct suggestions object */
var errorDescription = AtD.core.findSuggestion(element);
/* build up the menu y0 */
AtD.errorElement = jQuery(element);
suggest.empty();
if (errorDescription === undefined) {
suggest.append('<strong>' + AtD.getLang('menu_title_no_suggestions', 'No suggestions') + '</strong>');
} else if (errorDescription['suggestions'].length === 0) {
suggest.append('<strong>' + errorDescription['description'] + '</strong>');
} else {
suggest.append('<strong>' + errorDescription['description'] + '</strong>');
for (var i = 0; i < errorDescription['suggestions'].length; i++) {
(function(sugg) {
suggest.append('<a href="javascript:AtD.useSuggestion(\'' + sugg.replace(/'/, '\\\'') + '\')">' + sugg + '</a>');
})(errorDescription['suggestions'][i]); // jshint ignore:line
}
}
/* do the explain menu if configured */
if (AtD.callback_f !== undefined && AtD.callback_f.explain !== undefined && errorDescription['moreinfo'] !== undefined) {
suggest.append('<a href="javascript:AtD.explainError()" class="spell_sep_top">' + AtD.getLang('menu_option_explain', 'Explain...') + '</a>');
AtD.explainURL = errorDescription['moreinfo'];
}
/* do the ignore option */
suggest.append('<a href="javascript:AtD.ignoreSuggestion()" class="spell_sep_top">' + AtD.getLang('menu_option_ignore_once', 'Ignore suggestion') + '</a>');
/* add the edit in place and ignore always option */
if (AtD.callback_f !== undefined && AtD.callback_f.editSelection !== undefined) {
if (AtD.callback_f !== undefined && AtD.callback_f.ignore !== undefined) {
suggest.append('<a href="javascript:AtD.ignoreAll(\'' + AtD.container + '\')">' + AtD.getLang('menu_option_ignore_always', 'Ignore always') + '</a>');
} else {
suggest.append('<a href="javascript:AtD.ignoreAll(\'' + AtD.container + '\')">' + AtD.getLang('menu_option_ignore_all', 'Ignore all') + '</a>');
}
suggest.append('<a href="javascript:AtD.editSelection(\'' + AtD.container + '\')" class="spell_sep_bottom spell_sep_top">' + AtD.getLang('menu_option_edit_selection', 'Edit Selection...') + '</a>');
}
else {
if (AtD.callback_f !== undefined && AtD.callback_f.ignore !== undefined) {
suggest.append('<a href="javascript:AtD.ignoreAll(\'' + AtD.container + '\')" class="spell_sep_bottom">' + AtD.getLang('menu_option_ignore_always', 'Ignore always') + '</a>');
} else {
suggest.append('<a href="javascript:AtD.ignoreAll(\'' + AtD.container + '\')" class="spell_sep_bottom">' + AtD.getLang('menu_option_ignore_all', 'Ignore all') + '</a>');
}
}
/* show the menu */
var pos = jQuery(element).offset();
var width = jQuery(element).width();
/* a sanity check for Internet Explorer--my favorite browser in every possible way */
if (width > 100) {
width = 50;
}
jQuery(suggest).css({ left: (pos.left + width) + 'px', top: pos.top + 'px' });
jQuery(suggest).fadeIn(200);
/* bind events to make the menu disappear when the user clicks outside of it */
AtD.suggestShow = true;
setTimeout(function() {
jQuery('body').bind('click', function() {
if (!AtD.suggestShow) {
jQuery('#suggestmenu').fadeOut(200);
}
});
}, 1);
setTimeout(function() {
AtD.suggestShow = false;
}, 2);
};
AtD._removeWords = function(container_id, w) {
return this.core.removeWords(jQuery('#' + container_id), w);
};
/*
* Set prototypes used by AtD Core UI
*/
AtD.initCoreModule = function() {
var core = new AtDCore();
core.hasClass = function(node, className) {
return jQuery(node).hasClass(className);
};
core.map = jQuery.map;
core.contents = function(node) {
return jQuery(node).contents();
};
core.replaceWith = function(old_node, new_node) {
return jQuery(old_node).replaceWith(new_node);
};
core.findSpans = function(parent) {
return jQuery.makeArray(parent.find('span'));
};
core.create = function(string/*, isTextNode*/) {
// replace out all tags with &-equivalents so that we preserve tag text.
string = string.replace(/\&/g, '&amp;');
string = string.replace(/</g, '&lt;').replace(/\>/g, '&gt;');
// find all instances of AtD-created spans
var matches = string.match(/\&lt;span class="hidden\w+?" pre="[^"]*"\&gt;.*?\&lt;\/span\&gt;/g);
var x;
// ... and fix the tags in those substrings.
if (matches) {
for (x = 0; x < matches.length; x++) {
string = string.replace(matches[x], matches[x].replace(/\&lt;/gi, '<').replace(/\&gt;/gi, '>'));
}
}
if (core.isIE()) {
// and... one more round of corrections for our friends over at the Internet Explorer
matches = string.match(/\&lt;span class="mceItemHidden"\&gt;\&amp;nbsp;\&lt;\/span&gt;/g, string);
//|&lt;BR.*?class.*?atd_remove_me.*?\&gt;/gi, string);
if (matches) {
for (x = 0; x < matches.length; x++) {
string = string.replace(matches[x], matches[x].replace(/\&lt;/gi, '<').replace(/\&gt;/gi, '>').replace(/\&amp;/gi, '&'));
}
}
}
var node = jQuery('<span class="mceItemHidden"></span>');
node.html(string);
return node;
};
core.remove = function(node) {
return jQuery(node).remove();
};
core.removeParent = function(node) {
/* unwrap exists in jQuery 1.4+ only. Thankfully because replaceWith as-used here won't work in 1.4 */
if (jQuery(node).unwrap) {
return jQuery(node).contents().unwrap();
} else {
return jQuery(node).replaceWith(jQuery(node).html());
}
};
core.getAttrib = function(node, name) {
return jQuery(node).attr(name);
};
return core;
};
AtD.core = AtD.initCoreModule();

View File

@@ -0,0 +1,115 @@
<?php
/*
* This script redirects AtD AJAX requests to the AtD service
*/
/**
* Returns array with headers in $response[0] and body in $response[1]
* Based on a function from Akismet
*/
function AtD_http_post( $request, $host, $path, $port = 80 ) {
$http_args = array(
'body' => $request,
'headers' => array(
'Content-Type' => 'application/x-www-form-urlencoded; charset=' . get_option( 'blog_charset' ),
'Host' => $host,
'User-Agent' => 'AtD/0.1'
),
'httpversion' => '1.0',
/**
* Change the timeout time for AtD post.
*
* @module after-the-deadline
*
* @since 1.2.3
*
* @param int $var Timeout time in seconds, default 15.
*/
'timeout' => apply_filters( 'atd_http_post_timeout', 15 ),
);
// Handle non-standard ports being passed in.
if ( ( 80 !== $port ) && is_numeric( $port ) && ( intval( $port ) > 0 ) ) {
$host .= ':' . intval( $port );
}
// Strip any / off the begining so we can add it back and protect against SSRF
$path = ltrim( $path, '/' );
$AtD_url = set_url_scheme( "http://{$host}/{$path}" );
$response = wp_remote_post( $AtD_url, $http_args );
$code = (int) wp_remote_retrieve_response_code( $response );
if ( is_wp_error( $response ) ) {
/**
* Fires when there is a post error to AtD.
*
* @module after-the-deadline
*
* @since 1.2.3
*
* @param int|string http-error The error that AtD runs into.
*/
do_action( 'atd_http_post_error', 'http-error' );
return array();
} elseif ( 200 != $code ) {
/** This action is documented in modules/after-the-deadline/proxy.php */
do_action( 'atd_http_post_error', $code );
}
return array(
wp_remote_retrieve_headers( $response ),
wp_remote_retrieve_body( $response ),
);
}
/*
* This function is called as an action handler to admin-ajax.php
*/
function AtD_redirect_call() {
if ( $_SERVER['REQUEST_METHOD'] === 'POST' )
$postText = trim( file_get_contents( 'php://input' ) );
check_admin_referer( 'proxy_atd' );
$url = $_GET['url'];
/**
* Change the AtD service domain.
*
* @module after-the-deadline
*
* @since 1.2.3
*
* @param string $var The URL for AtD service domain, default is service.afterthedeadline.com.
*/
$service = apply_filters( 'atd_service_domain', 'service.afterthedeadline.com' );
$user = wp_get_current_user();
$atd_lang = get_locale();
// If we're on WPCOM, this function should be available.
if ( function_exists( 'get_user_locale' ) ) {
$atd_lang = get_user_locale( $user->ID );
}
if ( ! empty( $atd_lang ) ) {
if ( strpos($atd_lang, 'pt') !== false )
$service = 'pt.service.afterthedeadline.com';
else if ( strpos($atd_lang, 'de') !== false )
$service = 'de.service.afterthedeadline.com';
else if ( strpos($atd_lang, 'es') !== false )
$service = 'es.service.afterthedeadline.com';
else if ( strpos($atd_lang, 'fr') !== false )
$service = 'fr.service.afterthedeadline.com';
}
$guess = strcmp( AtD_get_setting( $user->ID, 'AtD_guess_lang' ), "true" ) == 0 ? "true" : "false";
$data = AtD_http_post( $postText . "&guess=$guess", defined('ATD_HOST') ? ATD_HOST : $service, $url, defined('ATD_PORT') ? ATD_PORT : 80 );
header( 'Content-Type: text/xml' );
if ( ! empty( $data[1] ) )
echo $data[1];
die();
}

View File

@@ -0,0 +1,124 @@
/* This file was automatically generated on Mar 20 2014 23:59:38 */
/* AtD error styles */
.hiddenSpellError
{
border-bottom: 2px solid red;
cursor: default;
}
.hiddenGrammarError
{
border-bottom: 2px solid green;
cursor: default;
}
.hiddenSuggestion
{
border-bottom: 2px solid blue;
cursor: default;
}
/* Menu styles derived from:
* jquery.spellchecker.js - a simple jQuery Spell Checker
* Copyright (c) 2008 Richard Willis
* MIT license : http://www.opensource.org/licenses/mit-license.php
* Project : http://jquery-spellchecker.googlecode.com
*/
#suggestmenu
{
min-width: 122px;
background: #ebeaeb;
position: absolute;
display: none;
z-index: 9999;
overflow: none;
margin-top: 1px;
text-align: right;
font-size: 11px;
font-family: Tahoma, Verdana, Arial, Helvetica;
}
#suggestmenu strong
{
background: #cccccc;
font-weight: bold;
padding:3px 6px 3px 6px;
display:block;
border:1px solid #dddddd;
border-bottom: 1px solid #aaaaaa;
color: black;
}
#suggestmenu em
{
text-align:center;
padding:3px 6px 3px 6px;
display:block;
border-top:1px solid #ccc;
border-right:1px solid #ccc;
}
#suggestmenu a, #suggestmenu a:visited
{
background: #ebeaeb;
border-right:1px solid #dddddd;
border-left:1px solid #dddddd;
padding:3px 6px 3px 6px;
display:block;
margin:0px;
text-decoration:none;
color: black;
outline:none
}
#suggestmenu a.first, #suggestmenu a.first:visited
{
border-top:1px solid #dddddd;
}
.spell_sep_bottom
{
border-bottom: 1px solid #dddddd;
}
.spell_sep_top
{
border-top: 1px solid #aaaaaa;
}
#suggestmenu a:hover
{
color:#000;
background: #f5f5f5;
}
#suggestmenu .foot
{
border-top:1px solid #aaaaaa;
background:#fff
}
#suggestmenu .foot a, #suggestmenu .foot a:visited
{
outline:none
}
/* TinyMCE 4.0 */
div.mce-atd-menu-title.mce-disabled {
padding: 3px 12px 0;
}
div.mce-atd-menu-title.mce-disabled:hover,
div.mce-atd-menu-title.mce-disabled:hover span.mce-text {
background: none;
color: #888;
cursor: default;
}
div.mce-atd-menu-title.mce-disabled span.mce-text {
font-weight: bold;
color: #888;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 B

View File

@@ -0,0 +1,19 @@
/* Do not modify this file directly. It is concatenated from individual module CSS files. */
.hiddenSpellError
{
border-bottom: 2px solid red;
cursor: default;
}
.hiddenGrammarError
{
border-bottom: 2px solid green;
cursor: default;
}
.hiddenSuggestion
{
border-bottom: 2px solid blue;
cursor: default;
}

View File

@@ -0,0 +1 @@
.hiddenSpellError{border-bottom:2px solid red;cursor:default}.hiddenGrammarError{border-bottom:2px solid green;cursor:default}.hiddenSuggestion{border-bottom:2px solid #00f;cursor:default}

View File

@@ -0,0 +1,18 @@
.hiddenSpellError
{
border-bottom: 2px solid red;
cursor: default;
}
.hiddenGrammarError
{
border-bottom: 2px solid green;
cursor: default;
}
.hiddenSuggestion
{
border-bottom: 2px solid blue;
cursor: default;
}

View File

@@ -0,0 +1,2 @@
/* Do not modify this file directly. It is concatenated from individual module CSS files. */
.hiddenSpellError{border-bottom:2px solid red;cursor:default}.hiddenGrammarError{border-bottom:2px solid green;cursor:default}.hiddenSuggestion{border-bottom:2px solid #00f;cursor:default}

View File

@@ -0,0 +1,479 @@
/*
* TinyMCE Writing Improvement Tool Plugin
* Author: Raphael Mudge (raffi@automattic.com)
*
* http://www.afterthedeadline.com
*
* Distributed under the LGPL
*
* Derived from:
* $Id: editor_plugin_src.js 425 2007-11-21 15:17:39Z spocke $
*
* @author Moxiecode
* @copyright Copyright (C) 2004-2008, Moxiecode Systems AB, All rights reserved.
*
* Moxiecode Spell Checker plugin released under the LGPL with TinyMCE
*/
/* jshint onevar: false, sub: true, devel: true, loopfunc: true */
/* global tinymce, AtDCore, AtD_proofread_click_count */
(function()
{
var each = tinymce.each, DOM = tinymce.DOM, core;
function getLang( key, defaultStr ) {
return ( window.AtD_l10n_r0ar && window.AtD_l10n_r0ar[key] ) || defaultStr;
}
tinymce.create('tinymce.plugins.AfterTheDeadlinePlugin',
{
getInfo : function()
{
return {
longname : 'After The Deadline',
author : 'Raphael Mudge',
authorurl : 'http://blog.afterthedeadline.com',
infourl : 'http://www.afterthedeadline.com',
version : tinymce.majorVersion + '.' + tinymce.minorVersion
};
},
/* initializes the functions used by the AtD Core UI Module */
initAtDCore : function(editor/*, plugin*/)
{
var core = new AtDCore();
core.map = each;
core.getAttrib = function(node, key)
{
return editor.dom.getAttrib(node, key);
};
core.findSpans = function(parent)
{
if (!parent) {
return editor.dom.select('span');
} else {
return editor.dom.select('span', parent);
}
};
core.hasClass = function(node, className)
{
return editor.dom.hasClass(node, className);
};
core.contents = function(node)
{
return node.childNodes;
};
core.replaceWith = function(old_node, new_node)
{
return editor.dom.replace(new_node, old_node);
};
core.create = function(node_html)
{
return editor.dom.create('span', { 'class': 'mceItemHidden' }, node_html);
};
core.removeParent = function(node)
{
editor.dom.remove(node, 1);
return node;
};
core.remove = function(node)
{
editor.dom.remove(node);
};
core.setIgnoreStrings(editor.getParam('atd_ignore_strings', [] ).join(','));
core.showTypes(editor.getParam('atd_show_types', ''));
return core;
},
/* called when the plugin is initialized */
init : function(ed, url)
{
if ( typeof(AtDCore) === 'undefined' ) {
return;
}
var plugin = this;
var editor = ed;
this.url = url;
this.editor = ed;
core = ed.core = this.initAtDCore(editor, plugin);
/* look at the atd_ignore variable and put that stuff into a hash */
var ignore = tinymce.util.Cookie.getHash('atd_ignore');
if (!ignore) {
ignore = {};
}
/* add a command to request a document check and process the results. */
editor.addCommand('mceWritingImprovementTool', function(callback)
{
/* checks if a global var for click stats exists and increments it if it does... */
if (typeof AtD_proofread_click_count !== 'undefined') {
AtD_proofread_click_count++;
}
/* create the nifty spinny thing that says "hizzo, I'm doing something fo realz" */
plugin.editor.setProgressState(1);
/* remove the previous errors */
plugin._removeWords();
/* send request to our service */
plugin.sendRequest('checkDocument', ed.getContent({ format: 'raw' }), function(data, request/*, someObject*/)
{
/* turn off the spinning thingie */
plugin.editor.setProgressState(0);
/* if the server is not accepting requests, let the user know */
if ( request.status !== 200 || request.responseText.substr(1, 4) === 'html' || !request.responseXML )
{
ed.windowManager.alert(
getLang( 'message_server_error', 'There was a problem communicating with the Proofreading service. Try again in one minute.' ),
callback ? function() { callback( 0 ); } : function() {}
);
return;
}
/* check to see if things are broken first and foremost */
if (request.responseXML.getElementsByTagName('message').item(0) != null)
{
ed.windowManager.alert(
request.responseXML.getElementsByTagName('message').item(0).firstChild.data,
callback ? function() { callback( 0 ); } : function() {}
);
return;
}
var results = core.processXML(request.responseXML);
var ecount = 0;
if (results.count > 0)
{
ecount = plugin.markMyWords(results.errors);
ed.suggestions = results.suggestions;
}
if (ecount === 0 && (!callback || callback === undefined)) {
ed.windowManager.alert( getLang('message_no_errors_found', 'No writing errors were found.') );
} else if (callback) {
callback(ecount);
}
});
});
/* load cascading style sheet for this plugin */
editor.onInit.add(function()
{
/* loading the content.css file, why? I have no clue */
if (editor.settings.content_css !== false)
{
editor.dom.loadCSS(editor.getParam('atd_css_url', url + '/css/content.css'));
}
});
/* again showing a menu, I have no clue what */
editor.onClick.add(plugin._showMenu, plugin);
/* we're showing some sort of menu, no idea what */
editor.onContextMenu.add(plugin._showMenu, plugin);
/* strip out the markup before the contents is serialized (and do it on a copy of the markup so we don't affect the user experience) */
editor.onPreProcess.add(function(sender, object)
{
var dom = sender.dom;
each(dom.select('span', object.node).reverse(), function(n)
{
if (n && (dom.hasClass(n, 'hiddenGrammarError') || dom.hasClass(n, 'hiddenSpellError') || dom.hasClass(n, 'hiddenSuggestion') || dom.hasClass(n, 'mceItemHidden') || (!dom.getAttrib(n, 'class') && !dom.getAttrib(n, 'style') && !dom.getAttrib(n, 'id') && !dom.hasClass(n, 'Apple-style-span') && !dom.getAttrib(n, 'mce_name'))))
{
dom.remove(n, 1);
}
});
});
/* cleanup the HTML before executing certain commands */
editor.onBeforeExecCommand.add(function(editor, command)
{
if (command === 'mceCodeEditor')
{
plugin._removeWords();
}
else if (command === 'mceFullScreen')
{
plugin._done();
}
});
ed.addButton('AtD', {
title: getLang( 'button_proofread_tooltip', 'Proofread Writing' ),
image: ed.getParam('atd_button_url', url + '/atdbuttontr.gif'),
cmd: 'mceWritingImprovementTool'
});
},
_removeWords : function(w)
{
var ed = this.editor, dom = ed.dom, se = ed.selection, b = se.getBookmark();
ed.core.removeWords(undefined, w);
/* force a rebuild of the DOM... even though the right elements are stripped, the DOM is still organized
as if the span were there and this breaks my code */
dom.setHTML(dom.getRoot(), dom.getRoot().innerHTML);
se.moveToBookmark(b);
},
markMyWords : function(errors)
{
var ed = this.editor;
var se = ed.selection, b = se.getBookmark();
var ecount = ed.core.markMyWords(ed.core.contents(this.editor.getBody()), errors);
se.moveToBookmark(b);
return ecount;
},
_showMenu : function(ed, e)
{
var t = this;
ed = t.editor; // not clear why this overwrites the function parameter
var m = t._menu, p1, dom = ed.dom, vp = dom.getViewPort(ed.getWin());
if (!m)
{
p1 = DOM.getPos(ed.getContentAreaContainer());
//p2 = DOM.getPos(ed.getContainer());
m = ed.controlManager.createDropMenu('spellcheckermenu',
{
offset_x : p1.x,
offset_y : p1.y,
'class' : 'mceNoIcons'
});
t._menu = m;
}
if (ed.core.isMarkedNode(e.target))
{
/* remove these other lame-o elements */
m.removeAll();
/* find the correct suggestions object */
var errorDescription = ed.core.findSuggestion(e.target);
if (!errorDescription)
{
m.add({ title: getLang( 'menu_title_no_suggestions', 'No suggestions' ), 'class': 'mceMenuItemTitle' }).setDisabled(1);
}
else if (errorDescription['suggestions'].length === 0)
{
m.add({ title: errorDescription['description'], 'class' : 'mceMenuItemTitle' }).setDisabled(1);
}
else
{
m.add({ title : errorDescription['description'], 'class' : 'mceMenuItemTitle' }).setDisabled(1);
for (var i = 0; i < errorDescription['suggestions'].length; i++)
{
(function(sugg)
{
m.add({
title : sugg,
onclick : function()
{
ed.core.applySuggestion(e.target, sugg);
t._checkDone();
}
});
})(errorDescription['suggestions'][i]); // jshint ignore:line
}
m.addSeparator();
}
if (errorDescription && errorDescription['moreinfo'])
{
(function(url)
{
m.add({
title : getLang( 'menu_option_explain', 'Explain...' ),
onclick : function()
{
ed.windowManager.open({
url : url,
width : 480,
height : 380,
inline : true
}, { theme_url : this.url });
}
});
})(errorDescription['moreinfo']);
m.addSeparator();
}
m.add({
title : getLang( 'menu_option_ignore_once', 'Ignore suggestion' ),
onclick : function()
{
dom.remove(e.target, 1);
t._checkDone();
}
});
if (String(this.editor.getParam('atd_ignore_enable', 'false')) === 'true')
{
m.add({
title : getLang( 'menu_option_ignore_always', 'Ignore always' ),
onclick : function()
{
var url = t.editor.getParam('atd_ignore_rpc_url', '{backend}');
if (url === '{backend}')
{
/* Default scheme is to save ignore preferences in a cookie */
var ignore = tinymce.util.Cookie.getHash('atd_ignore');
if (!ignore) { ignore = {}; }
ignore[e.target.innerHTML] = 1;
tinymce.util.Cookie.setHash('atd_ignore', ignore, new Date( (new Date().getTime()) + 157680000000) );
}
else
{
/* Plugin is configured to send ignore preferences to server, do that */
var id = t.editor.getParam('atd_rpc_id', '12345678');
tinymce.util.XHR.send({
url : url + encodeURI(e.target.innerHTML).replace(/&/g, '%26') + '&key=' + id,
content_type : 'text/xml',
async : true,
type : 'GET',
success : function(/* type, req, o */)
{
/* do nothing */
},
error : function( type, req, o )
{
alert( 'Ignore preference save failed\n' + type + '\n' + req.status + '\nAt: ' + o.url );
}
});
/* update atd_ignore_strings with the new value */
t.editor.core.setIgnoreStrings(e.target.innerHTML); /* this does an update */
}
t._removeWords(e.target.innerHTML);
t._checkDone();
}
});
}
else
{
m.add({
title : getLang( 'menu_option_ignore_all', 'Ignore all' ),
onclick : function()
{
t._removeWords(e.target.innerHTML);
t._checkDone();
}
});
}
/* show the menu please */
ed.selection.select(e.target);
p1 = dom.getPos(e.target);
m.showMenu(p1.x, p1.y + e.target.offsetHeight - vp.y);
return tinymce.dom.Event.cancel(e);
}
else
{
m.hideMenu();
}
},
/* loop through editor DOM, call _done if no mce tags exist. */
_checkDone : function()
{
var t = this, ed = t.editor, dom = ed.dom, o;
each(dom.select('span'), function(n)
{
if (n && dom.hasClass(n, 'mceItemHidden'))
{
o = true;
return false;
}
});
if (!o)
{
t._done();
}
},
/* remove all tags, hide the menu, and fire a dom change event */
_done : function()
{
var plugin = this;
plugin._removeWords();
if (plugin._menu)
{
plugin._menu.hideMenu();
}
plugin.editor.nodeChanged();
},
sendRequest : function(file, data, success)
{
var id = this.editor.getParam('atd_rpc_id', '12345678');
var url = this.editor.getParam('atd_rpc_url', '{backend}');
var plugin = this;
if (url === '{backend}' || id === '12345678')
{
this.editor.setProgressState(0);
alert('Please specify: atd_rpc_url and atd_rpc_id');
return;
}
tinymce.util.XHR.send({
url : url + '/' + file,
content_type : 'text/xml',
type : 'POST',
data : 'data=' + encodeURI(data).replace(/&/g, '%26') + '&key=' + id,
async : true,
success : success,
error : function( type, req, o )
{
plugin.editor.setProgressState(0);
alert( type + '\n' + req.status + '\nAt: ' + o.url );
}
});
}
});
// Register plugin
tinymce.PluginManager.add('AtD', tinymce.plugins.AfterTheDeadlinePlugin);
})();

View File

@@ -0,0 +1,427 @@
/* global tinymce */
/*
* TinyMCE Writing Improvement Tool Plugin
* Author: Raphael Mudge (raffi@automattic.com)
*
* Updated for TinyMCE 4.0
*
* http://www.afterthedeadline.com
*
* Distributed under the LGPL
*
* Derived from:
* $Id: editor_plugin_src.js 425 2007-11-21 15:17:39Z spocke $
*
* @author Moxiecode
* @copyright Copyright (C) 2004-2008, Moxiecode Systems AB, All rights reserved.
*
* Moxiecode Spell Checker plugin released under the LGPL with TinyMCE
*/
tinymce.PluginManager.add( 'AtD', function( editor ) {
var suggestionsMenu, started, atdCore, dom,
each = tinymce.each;
/* initializes the functions used by the AtD Core UI Module */
function initAtDCore() {
atdCore = new window.AtDCore();
atdCore.map = each;
atdCore._isTinyMCE = true;
atdCore.getAttrib = function( node, key ) {
return dom.getAttrib( node, key );
};
atdCore.findSpans = function( parent ) {
if ( parent === undefined ) {
return dom.select('span');
} else {
return dom.select( 'span', parent );
}
};
atdCore.hasClass = function( node, className ) {
return dom.hasClass( node, className );
};
atdCore.contents = function( node ) {
return node.childNodes;
};
atdCore.replaceWith = function( old_node, new_node ) {
return dom.replace( new_node, old_node );
};
atdCore.create = function( node_html ) {
return dom.create( 'span', { 'class': 'mceItemHidden', 'data-mce-bogus': 1 }, node_html );
};
atdCore.removeParent = function( node ) {
dom.remove( node, true );
return node;
};
atdCore.remove = function( node ) {
dom.remove( node );
};
atdCore.setIgnoreStrings( editor.getParam( 'atd_ignore_strings', [] ).join(',') );
atdCore.showTypes( editor.getParam( 'atd_show_types', '' ) );
}
function getLang( key, defaultStr ) {
return ( window.AtD_l10n_r0ar && window.AtD_l10n_r0ar[key] ) || defaultStr;
}
function isMarkedNode( node ) {
return ( node.className && /\bhidden(GrammarError|SpellError|Suggestion)\b/.test( node.className ) );
}
function markMyWords( errors ) {
return atdCore.markMyWords( atdCore.contents( editor.getBody() ), errors );
}
// If no more suggestions, finish.
function checkIfFinished() {
if ( ! editor.dom.select('span.hiddenSpellError, span.hiddenGrammarError, span.hiddenSuggestion').length ) {
if ( suggestionsMenu ) {
suggestionsMenu.hideMenu();
}
finish();
}
}
function ignoreWord( target, word, all ) {
var dom = editor.dom;
if ( all ) {
each( editor.dom.select( 'span.hiddenSpellError, span.hiddenGrammarError, span.hiddenSuggestion' ), function( node ) {
var text = node.innerText || node.textContent;
if ( text === word ) {
dom.remove( node, true );
}
});
} else {
dom.remove( target, true );
}
checkIfFinished();
}
// Called when the user clicks "Finish" or when no more suggestions left.
// Removes all remaining spans and fires custom event.
function finish() {
var node,
dom = editor.dom,
regex = new RegExp( 'mceItemHidden|hidden(((Grammar|Spell)Error)|Suggestion)' ),
nodes = dom.select('span'),
i = nodes.length;
while ( i-- ) { // reversed
node = nodes[i];
if ( node.className && regex.test( node.className ) ) {
dom.remove( node, true );
}
}
// Rebuild the DOM so AtD core can find the text nodes
editor.setContent( editor.getContent({ format: 'raw' }), { format: 'raw' } );
started = false;
editor.nodeChanged();
editor.fire('SpellcheckEnd');
}
function sendRequest( file, data, success ) {
var id = editor.getParam( 'atd_rpc_id', '12345678' ),
url = editor.getParam( 'atd_rpc_url', '{backend}' );
if ( url === '{backend}' || id === '12345678' ) {
window.alert( 'Please specify: atd_rpc_url and atd_rpc_id' );
return;
}
// create the nifty spinny thing that says "hizzo, I'm doing something fo realz"
editor.setProgressState( true );
tinymce.util.XHR.send({
url: url + '/' + file,
content_type: 'text/xml',
type: 'POST',
data: 'data=' + encodeURI( data ).replace( /&/g, '%26' ) + '&key=' + id,
success: success,
error: function( type, req, o ) {
editor.setProgressState();
window.alert( type + '\n' + req.status + '\nAt: ' + o.url );
}
});
}
function storeIgnoredStrings( /*text*/ ) {
// Store in sessionStorage?
}
function setAlwaysIgnore( text ) {
var url = editor.getParam( 'atd_ignore_rpc_url' );
if ( ! url || url === '{backend}' ) {
// Store ignored words for this session only
storeIgnoredStrings( text );
} else {
// Plugin is configured to send ignore preferences to server, do that
tinymce.util.XHR.send({
url: url + encodeURIComponent( text ) + '&key=' + editor.getParam( 'atd_rpc_id', '12345678' ),
content_type: 'text/xml',
type: 'GET',
error: function() {
storeIgnoredStrings( text );
}
});
}
// Update atd_ignore_strings with the new value
atdCore.setIgnoreStrings( text );
}
// Create the suggestions menu
function showSuggestions( target ) {
var pos, root, targetPos,
items = [],
text = target.innerText || target.textContent,
errorDescription = atdCore.findSuggestion( target );
if ( ! errorDescription ) {
items.push({
text: getLang( 'menu_title_no_suggestions', 'No suggestions' ),
classes: 'atd-menu-title',
disabled: true
});
} else {
items.push({
text: errorDescription.description,
classes: 'atd-menu-title',
disabled: true
});
if ( errorDescription.suggestions.length ) {
items.push({ text: '-' }); // separator
each( errorDescription.suggestions, function( suggestion ) {
items.push({
text: suggestion,
onclick: function() {
atdCore.applySuggestion( target, suggestion );
checkIfFinished();
}
});
});
}
}
if ( errorDescription && errorDescription.moreinfo ) {
items.push({ text: '-' }); // separator
items.push({
text: getLang( 'menu_option_explain', 'Explain...' ),
onclick : function() {
editor.windowManager.open({
title: getLang( 'menu_option_explain', 'Explain...' ),
url: errorDescription.moreinfo,
width: 480,
height: 380,
inline: true
});
}
});
}
items.push.apply( items, [
{ text: '-' }, // separator
{ text: getLang( 'menu_option_ignore_once', 'Ignore suggestion' ), onclick: function() {
ignoreWord( target, text );
}}
]);
if ( editor.getParam( 'atd_ignore_enable' ) ) {
items.push({
text: getLang( 'menu_option_ignore_always', 'Ignore always' ),
onclick: function() {
setAlwaysIgnore( text );
ignoreWord( target, text, true );
}
});
} else {
items.push({
text: getLang( 'menu_option_ignore_all', 'Ignore all' ),
onclick: function() {
ignoreWord( target, text, true );
}
});
}
// Render menu
suggestionsMenu = new tinymce.ui.Menu({
items: items,
context: 'contextmenu',
onautohide: function( event ) {
if ( isMarkedNode( event.target ) ) {
event.preventDefault();
}
},
onhide: function() {
suggestionsMenu.remove();
suggestionsMenu = null;
}
});
suggestionsMenu.renderTo( document.body );
// Position menu
pos = tinymce.DOM.getPos( editor.getContentAreaContainer() );
targetPos = editor.dom.getPos( target );
root = editor.dom.getRoot();
// Adjust targetPos for scrolling in the editor
if ( root.nodeName === 'BODY' ) {
targetPos.x -= root.ownerDocument.documentElement.scrollLeft || root.scrollLeft;
targetPos.y -= root.ownerDocument.documentElement.scrollTop || root.scrollTop;
} else {
targetPos.x -= root.scrollLeft;
targetPos.y -= root.scrollTop;
}
pos.x += targetPos.x;
pos.y += targetPos.y;
suggestionsMenu.moveTo( pos.x, pos.y + target.offsetHeight );
}
// Init everything
editor.on( 'init', function() {
if ( typeof window.AtDCore === 'undefined' ) {
return;
}
// Set dom and atdCore
dom = editor.dom;
initAtDCore();
// add a command to request a document check and process the results.
editor.addCommand( 'mceWritingImprovementTool', function( callback ) {
var results,
errorCount = 0;
if ( typeof callback !== 'function' ) {
callback = function(){};
}
// checks if a global var for click stats exists and increments it if it does...
if ( typeof window.AtD_proofread_click_count !== 'undefined' ) {
window.AtD_proofread_click_count++;
}
// remove the previous errors
if ( started ) {
finish();
return;
}
// send request to our service
sendRequest( 'checkDocument', editor.getContent({ format: 'raw' }), function( data, request ) {
// turn off the spinning thingie
editor.setProgressState();
// if the server is not accepting requests, let the user know
if ( request.status !== 200 || request.responseText.substr( 1, 4 ) === 'html' || ! request.responseXML ) {
editor.windowManager.alert(
getLang( 'message_server_error', 'There was a problem communicating with the Proofreading service. Try again in one minute.' ),
callback(0)
);
return;
}
// check to see if things are broken first and foremost
if ( request.responseXML.getElementsByTagName('message').item(0) !== null ) {
editor.windowManager.alert(
request.responseXML.getElementsByTagName('message').item(0).firstChild.data,
callback(0)
);
return;
}
results = atdCore.processXML( request.responseXML );
if ( results.count > 0 ) {
errorCount = markMyWords( results.errors );
}
if ( ! errorCount ) {
editor.windowManager.alert( getLang( 'message_no_errors_found', 'No writing errors were found.' ) );
} else {
started = true;
editor.fire('SpellcheckStart');
}
callback( errorCount );
});
});
if ( editor.settings.content_css !== false ) {
// CSS for underlining suggestions
dom.addStyle( '.hiddenSpellError{border-bottom:2px solid red;cursor:default;}' +
'.hiddenGrammarError{border-bottom:2px solid green;cursor:default;}' +
'.hiddenSuggestion{border-bottom:2px solid blue;cursor:default;}' );
}
// Menu z-index > DFW
tinymce.DOM.addStyle( 'div.mce-floatpanel{z-index:150100 !important;}' );
// Click on misspelled word
editor.on( 'click', function( event ) {
if ( isMarkedNode( event.target ) ) {
event.preventDefault();
editor.selection.select( event.target );
// Create the suggestions menu
showSuggestions( event.target );
}
});
});
editor.addMenuItem( 'spellchecker', {
text: getLang( 'button_proofread_tooltip', 'Proofread Writing' ),
context: 'tools',
cmd: 'mceWritingImprovementTool',
onPostRender: function() {
var self = this;
editor.on('SpellcheckStart SpellcheckEnd', function() {
self.active( started );
});
}
});
editor.addButton( 'spellchecker', {
tooltip: getLang( 'button_proofread_tooltip', 'Proofread Writing' ),
cmd: 'mceWritingImprovementTool',
onPostRender: function() {
var self = this;
editor.on( 'SpellcheckStart SpellcheckEnd', function() {
self.active( started );
});
}
});
editor.on( 'remove', function() {
if ( suggestionsMenu ) {
suggestionsMenu.remove();
suggestionsMenu = null;
}
});
});

View File

@@ -0,0 +1,17 @@
<?php
/**
* Module Name: Carousel
* Module Description: Display images and galleries in a gorgeous, full-screen browsing experience
* Jumpstart Description: Brings your photos and images to life as full-size, easily navigable galleries.
* Sort Order: 22
* Recommendation Order: 12
* First Introduced: 1.5
* Requires Connection: No
* Auto Activate: No
* Module Tags: Photos and Videos
* Feature: Appearance, Jumpstart
* Additional Search Queries: gallery, carousel, diaporama, slideshow, images, lightbox, exif, metadata, image
*/
include dirname( __FILE__ ) . '/carousel/jetpack-carousel.php';

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 547 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 867 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 431 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1,13 @@
.jp-carousel .jp-carousel-slide {
display: none !important;
}
.jp-carousel {
text-align: center!important;
width:100%!important;
}
.jp-carousel .selected {
margin: 0 auto;
display: block !important;
width: auto;
position: relative!important;
}

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,742 @@
<?php
/*
Plugin Name: Jetpack Carousel
Plugin URL: https://wordpress.com/
Description: Transform your standard image galleries into an immersive full-screen experience.
Version: 0.1
Author: Automattic
Released under the GPL v.2 license.
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.
*/
class Jetpack_Carousel {
public $prebuilt_widths = array( 370, 700, 1000, 1200, 1400, 2000 );
public $first_run = true;
public $in_gallery = false;
public $in_jetpack = true;
public $single_image_gallery_enabled = false;
public $single_image_gallery_enabled_media_file = false;
function __construct() {
add_action( 'init', array( $this, 'init' ) );
}
function init() {
if ( $this->maybe_disable_jp_carousel() )
return;
$this->in_jetpack = ( class_exists( 'Jetpack' ) && method_exists( 'Jetpack', 'enable_module_configurable' ) ) ? true : false;
$this->single_image_gallery_enabled = !$this->maybe_disable_jp_carousel_single_images();
$this->single_image_gallery_enabled_media_file = $this->maybe_enable_jp_carousel_single_images_media_file();
if ( is_admin() ) {
// Register the Carousel-related related settings
add_action( 'admin_init', array( $this, 'register_settings' ), 5 );
if ( ! $this->in_jetpack ) {
if ( 0 == $this->test_1or0_option( get_option( 'carousel_enable_it' ), true ) )
return; // Carousel disabled, abort early, but still register setting so user can switch it back on
}
// If in admin, register the ajax endpoints.
add_action( 'wp_ajax_get_attachment_comments', array( $this, 'get_attachment_comments' ) );
add_action( 'wp_ajax_nopriv_get_attachment_comments', array( $this, 'get_attachment_comments' ) );
add_action( 'wp_ajax_post_attachment_comment', array( $this, 'post_attachment_comment' ) );
add_action( 'wp_ajax_nopriv_post_attachment_comment', array( $this, 'post_attachment_comment' ) );
} else {
if ( ! $this->in_jetpack ) {
if ( 0 == $this->test_1or0_option( get_option( 'carousel_enable_it' ), true ) )
return; // Carousel disabled, abort early
}
// If on front-end, do the Carousel thang.
/**
* Filter the array of default prebuilt widths used in Carousel.
*
* @module carousel
*
* @since 1.6.0
*
* @param array $this->prebuilt_widths Array of default widths.
*/
$this->prebuilt_widths = apply_filters( 'jp_carousel_widths', $this->prebuilt_widths );
// below: load later than other callbacks hooked it (e.g. 3rd party plugins handling gallery shortcode)
add_filter( 'post_gallery', array( $this, 'check_if_shortcode_processed_and_enqueue_assets' ), 1000, 2 );
add_filter( 'post_gallery', array( $this, 'set_in_gallery' ), -1000 );
add_filter( 'gallery_style', array( $this, 'add_data_to_container' ) );
add_filter( 'wp_get_attachment_image_attributes', array( $this, 'add_data_to_images' ), 10, 2 );
if ( $this->single_image_gallery_enabled ) {
add_filter( 'the_content', array( $this, 'add_data_img_tags_and_enqueue_assets' ) );
}
}
if ( $this->in_jetpack && method_exists( 'Jetpack', 'module_configuration_load' ) ) {
Jetpack::enable_module_configurable( dirname( dirname( __FILE__ ) ) . '/carousel.php' );
Jetpack::module_configuration_load( dirname( dirname( __FILE__ ) ) . '/carousel.php', array( $this, 'jetpack_configuration_load' ) );
}
}
function maybe_disable_jp_carousel() {
/**
* Allow third-party plugins or themes to disable Carousel.
*
* @module carousel
*
* @since 1.6.0
*
* @param bool false Should Carousel be disabled? Default to false.
*/
return apply_filters( 'jp_carousel_maybe_disable', false );
}
function maybe_disable_jp_carousel_single_images() {
/**
* Allow third-party plugins or themes to disable Carousel for single images.
*
* @module carousel
*
* @since 4.5.0
*
* @param bool false Should Carousel be disabled for single images? Default to false.
*/
return apply_filters( 'jp_carousel_maybe_disable_single_images', false );
}
function maybe_enable_jp_carousel_single_images_media_file() {
/**
* Allow third-party plugins or themes to enable Carousel
* for single images linking to 'Media File' (full size image).
*
* @module carousel
*
* @since 4.5.0
*
* @param bool false Should Carousel be enabled for single images linking to 'Media File'? Default to false.
*/
return apply_filters( 'jp_carousel_load_for_images_linked_to_file', false );
}
function jetpack_configuration_load() {
wp_safe_redirect( admin_url( 'options-media.php#carousel_background_color' ) );
exit;
}
function asset_version( $version ) {
/**
* Filter the version string used when enqueuing Carousel assets.
*
* @module carousel
*
* @since 1.6.0
*
* @param string $version Asset version.
*/
return apply_filters( 'jp_carousel_asset_version', $version );
}
function display_bail_message( $output= '' ) {
// Displays a message on top of gallery if carousel has bailed
$message = '<div class="jp-carousel-msg"><p>';
$message .= __( 'Jetpack\'s Carousel has been disabled, because another plugin or your theme is overriding the [gallery] shortcode.', 'jetpack' );
$message .= '</p></div>';
// put before gallery output
$output = $message . $output;
return $output;
}
function check_if_shortcode_processed_and_enqueue_assets( $output ) {
if (
! empty( $output ) &&
/**
* Allow third-party plugins or themes to force-enable Carousel.
*
* @module carousel
*
* @since 1.9.0
*
* @param bool false Should we force enable Carousel? Default to false.
*/
! apply_filters( 'jp_carousel_force_enable', false )
) {
// Bail because someone is overriding the [gallery] shortcode.
remove_filter( 'gallery_style', array( $this, 'add_data_to_container' ) );
remove_filter( 'wp_get_attachment_image_attributes', array( $this, 'add_data_to_images' ) );
remove_filter( 'the_content', array( $this, 'add_data_img_tags_and_enqueue_assets' ) );
// Display message that carousel has bailed, if user is super_admin, and if we're not on WordPress.com.
if (
is_super_admin() &&
! ( defined( 'IS_WPCOM' ) && IS_WPCOM )
) {
add_filter( 'post_gallery', array( $this, 'display_bail_message' ) );
}
return $output;
}
/**
* Fires when thumbnails are shown in Carousel.
*
* @module carousel
*
* @since 1.6.0
**/
do_action( 'jp_carousel_thumbnails_shown' );
$this->enqueue_assets();
return $output;
}
function enqueue_assets() {
if ( $this->first_run ) {
wp_enqueue_script(
'jetpack-carousel',
Jetpack::get_file_url_for_environment(
'_inc/build/carousel/jetpack-carousel.min.js',
'modules/carousel/jetpack-carousel.js'
),
array( 'jquery.spin' ),
$this->asset_version( '20170209' ),
true
);
// Note: using home_url() instead of admin_url() for ajaxurl to be sure to get same domain on wpcom when using mapped domains (also works on self-hosted)
// Also: not hardcoding path since there is no guarantee site is running on site root in self-hosted context.
$is_logged_in = is_user_logged_in();
$current_user = wp_get_current_user();
$comment_registration = intval( get_option( 'comment_registration' ) );
$require_name_email = intval( get_option( 'require_name_email' ) );
$localize_strings = array(
'widths' => $this->prebuilt_widths,
'is_logged_in' => $is_logged_in,
'lang' => strtolower( substr( get_locale(), 0, 2 ) ),
'ajaxurl' => set_url_scheme( admin_url( 'admin-ajax.php' ) ),
'nonce' => wp_create_nonce( 'carousel_nonce' ),
'display_exif' => $this->test_1or0_option( Jetpack_Options::get_option_and_ensure_autoload( 'carousel_display_exif', true ) ),
'display_geo' => $this->test_1or0_option( Jetpack_Options::get_option_and_ensure_autoload( 'carousel_display_geo', true ) ),
'single_image_gallery' => $this->single_image_gallery_enabled,
'single_image_gallery_media_file' => $this->single_image_gallery_enabled_media_file,
'background_color' => $this->carousel_background_color_sanitize( Jetpack_Options::get_option_and_ensure_autoload( 'carousel_background_color', '' ) ),
'comment' => __( 'Comment', 'jetpack' ),
'post_comment' => __( 'Post Comment', 'jetpack' ),
'write_comment' => __( 'Write a Comment...', 'jetpack' ),
'loading_comments' => __( 'Loading Comments...', 'jetpack' ),
'download_original' => sprintf( __( 'View full size <span class="photo-size">%1$s<span class="photo-size-times">&times;</span>%2$s</span>', 'jetpack' ), '{0}', '{1}' ),
'no_comment_text' => __( 'Please be sure to submit some text with your comment.', 'jetpack' ),
'no_comment_email' => __( 'Please provide an email address to comment.', 'jetpack' ),
'no_comment_author' => __( 'Please provide your name to comment.', 'jetpack' ),
'comment_post_error' => __( 'Sorry, but there was an error posting your comment. Please try again later.', 'jetpack' ),
'comment_approved' => __( 'Your comment was approved.', 'jetpack' ),
'comment_unapproved' => __( 'Your comment is in moderation.', 'jetpack' ),
'camera' => __( 'Camera', 'jetpack' ),
'aperture' => __( 'Aperture', 'jetpack' ),
'shutter_speed' => __( 'Shutter Speed', 'jetpack' ),
'focal_length' => __( 'Focal Length', 'jetpack' ),
'copyright' => __( 'Copyright', 'jetpack' ),
'comment_registration' => $comment_registration,
'require_name_email' => $require_name_email,
/** This action is documented in core/src/wp-includes/link-template.php */
'login_url' => wp_login_url( apply_filters( 'the_permalink', get_permalink() ) ),
'blog_id' => (int) get_current_blog_id(),
'meta_data' => array( 'camera', 'aperture', 'shutter_speed', 'focal_length', 'copyright' )
);
if ( ! isset( $localize_strings['jetpack_comments_iframe_src'] ) || empty( $localize_strings['jetpack_comments_iframe_src'] ) ) {
// We're not using Comments after all, so fallback to standard local comments.
if ( $is_logged_in ) {
$localize_strings['local_comments_commenting_as'] = '<p id="jp-carousel-commenting-as">' . sprintf( __( 'Commenting as %s', 'jetpack' ), $current_user->data->display_name ) . '</p>';
} else {
if ( $comment_registration ) {
$localize_strings['local_comments_commenting_as'] = '<p id="jp-carousel-commenting-as">' . __( 'You must be <a href="#" class="jp-carousel-comment-login">logged in</a> to post a comment.', 'jetpack' ) . '</p>';
} else {
$required = ( $require_name_email ) ? __( '%s (Required)', 'jetpack' ) : '%s';
$localize_strings['local_comments_commenting_as'] = ''
. '<fieldset><label for="email">' . sprintf( $required, __( 'Email', 'jetpack' ) ) . '</label> '
. '<input type="text" name="email" class="jp-carousel-comment-form-field jp-carousel-comment-form-text-field" id="jp-carousel-comment-form-email-field" /></fieldset>'
. '<fieldset><label for="author">' . sprintf( $required, __( 'Name', 'jetpack' ) ) . '</label> '
. '<input type="text" name="author" class="jp-carousel-comment-form-field jp-carousel-comment-form-text-field" id="jp-carousel-comment-form-author-field" /></fieldset>'
. '<fieldset><label for="url">' . __( 'Website', 'jetpack' ) . '</label> '
. '<input type="text" name="url" class="jp-carousel-comment-form-field jp-carousel-comment-form-text-field" id="jp-carousel-comment-form-url-field" /></fieldset>';
}
}
}
/**
* Handle WP stats for images in full-screen.
* Build string with tracking info.
*/
/**
* Filter if Jetpack should enable stats collection on carousel views
*
* @module carousel
*
* @since 4.3.2
*
* @param bool Enable Jetpack Carousel stat collection. Default false.
*/
if ( apply_filters( 'jetpack_enable_carousel_stats', false ) && in_array( 'stats', Jetpack::get_active_modules() ) && ! Jetpack::is_development_mode() ) {
$localize_strings['stats'] = 'blog=' . Jetpack_Options::get_option( 'id' ) . '&host=' . parse_url( get_option( 'home' ), PHP_URL_HOST ) . '&v=ext&j=' . JETPACK__API_VERSION . ':' . JETPACK__VERSION;
// Set the stats as empty if user is logged in but logged-in users shouldn't be tracked.
if ( is_user_logged_in() && function_exists( 'stats_get_options' ) ) {
$stats_options = stats_get_options();
$track_loggedin_users = isset( $stats_options['reg_users'] ) ? (bool) $stats_options['reg_users'] : false;
if ( ! $track_loggedin_users ) {
$localize_strings['stats'] = '';
}
}
}
/**
* Filter the strings passed to the Carousel's js file.
*
* @module carousel
*
* @since 1.6.0
*
* @param array $localize_strings Array of strings passed to the Jetpack js file.
*/
$localize_strings = apply_filters( 'jp_carousel_localize_strings', $localize_strings );
wp_localize_script( 'jetpack-carousel', 'jetpackCarouselStrings', $localize_strings );
wp_enqueue_style( 'jetpack-carousel', plugins_url( 'jetpack-carousel.css', __FILE__ ), array(), $this->asset_version( '20120629' ) );
wp_style_add_data( 'jetpack-carousel', 'rtl', 'replace' );
wp_register_style( 'jetpack-carousel-ie8fix', plugins_url( 'jetpack-carousel-ie8fix.css', __FILE__ ), array(), $this->asset_version( '20121024' ) );
$GLOBALS['wp_styles']->add_data( 'jetpack-carousel-ie8fix', 'conditional', 'lte IE 8' );
wp_enqueue_style( 'jetpack-carousel-ie8fix' );
/**
* Fires after carousel assets are enqueued for the first time.
* Allows for adding additional assets to the carousel page.
*
* @module carousel
*
* @since 1.6.0
*
* @param bool $first_run First load if Carousel on the page.
* @param array $localized_strings Array of strings passed to the Jetpack js file.
*/
do_action( 'jp_carousel_enqueue_assets', $this->first_run, $localize_strings );
$this->first_run = false;
}
}
function set_in_gallery( $output ) {
$this->in_gallery = true;
return $output;
}
/**
* Adds data-* attributes required by carousel to img tags in post HTML
* content. To be used by 'the_content' filter.
*
* @see add_data_to_images()
* @see wp_make_content_images_responsive() in wp-includes/media.php
*
* @param string $content HTML content of the post
* @return string Modified HTML content of the post
*/
function add_data_img_tags_and_enqueue_assets( $content ) {
if ( ! preg_match_all( '/<img [^>]+>/', $content, $matches ) ) {
return $content;
}
$selected_images = array();
foreach( $matches[0] as $image_html ) {
if ( preg_match( '/wp-image-([0-9]+)/i', $image_html, $class_id ) &&
( $attachment_id = absint( $class_id[1] ) ) ) {
/*
* If exactly the same image tag is used more than once, overwrite it.
* All identical tags will be replaced later with 'str_replace()'.
*/
$selected_images[ $attachment_id ] = $image_html;
}
}
$find = array();
$replace = array();
if ( empty( $selected_images ) ) {
return $content;
}
$attachments = get_posts( array(
'include' => array_keys( $selected_images ),
'post_type' => 'any',
'post_status' => 'any',
'suppress_filters' => false,
) );
foreach ( $attachments as $attachment ) {
$image_html = $selected_images[ $attachment->ID ];
$attributes = $this->add_data_to_images( array(), $attachment );
$attributes_html = '';
foreach( $attributes as $k => $v ) {
$attributes_html .= esc_attr( $k ) . '="' . esc_attr( $v ) . '" ';
}
$find[] = $image_html;
$replace[] = str_replace( '<img ', "<img $attributes_html", $image_html );
}
$content = str_replace( $find, $replace, $content );
$this->enqueue_assets();
return $content;
}
function add_data_to_images( $attr, $attachment = null ) {
$attachment_id = intval( $attachment->ID );
if ( ! wp_attachment_is_image( $attachment_id ) ) {
return $attr;
}
$orig_file = wp_get_attachment_image_src( $attachment_id, 'full' );
$orig_file = isset( $orig_file[0] ) ? $orig_file[0] : wp_get_attachment_url( $attachment_id );
$meta = wp_get_attachment_metadata( $attachment_id );
$size = isset( $meta['width'] ) ? intval( $meta['width'] ) . ',' . intval( $meta['height'] ) : '';
$img_meta = ( ! empty( $meta['image_meta'] ) ) ? (array) $meta['image_meta'] : array();
$comments_opened = intval( comments_open( $attachment_id ) );
/*
* Note: Cannot generate a filename from the width and height wp_get_attachment_image_src() returns because
* it takes the $content_width global variable themes can set in consideration, therefore returning sizes
* which when used to generate a filename will likely result in a 404 on the image.
* $content_width has no filter we could temporarily de-register, run wp_get_attachment_image_src(), then
* re-register. So using returned file URL instead, which we can define the sizes from through filename
* parsing in the JS, as this is a failsafe file reference.
*
* EG with Twenty Eleven activated:
* array(4) { [0]=> string(82) "http://vanillawpinstall.blah/wp-content/uploads/2012/06/IMG_3534-1024x764.jpg" [1]=> int(584) [2]=> int(435) [3]=> bool(true) }
*
* EG with Twenty Ten activated:
* array(4) { [0]=> string(82) "http://vanillawpinstall.blah/wp-content/uploads/2012/06/IMG_3534-1024x764.jpg" [1]=> int(640) [2]=> int(477) [3]=> bool(true) }
*/
$medium_file_info = wp_get_attachment_image_src( $attachment_id, 'medium' );
$medium_file = isset( $medium_file_info[0] ) ? $medium_file_info[0] : '';
$large_file_info = wp_get_attachment_image_src( $attachment_id, 'large' );
$large_file = isset( $large_file_info[0] ) ? $large_file_info[0] : '';
$attachment = get_post( $attachment_id );
$attachment_title = wptexturize( $attachment->post_title );
$attachment_desc = wpautop( wptexturize( $attachment->post_content ) );
// Not yet providing geo-data, need to "fuzzify" for privacy
if ( ! empty( $img_meta ) ) {
foreach ( $img_meta as $k => $v ) {
if ( 'latitude' == $k || 'longitude' == $k )
unset( $img_meta[$k] );
}
}
// See https://github.com/Automattic/jetpack/issues/2765
if ( isset( $img_meta['keywords'] ) ) {
unset( $img_meta['keywords'] );
}
$img_meta = json_encode( array_map( 'strval', array_filter( $img_meta, 'is_scalar' ) ) );
$attr['data-attachment-id'] = $attachment_id;
$attr['data-permalink'] = esc_attr( get_permalink( $attachment->ID ) );
$attr['data-orig-file'] = esc_attr( $orig_file );
$attr['data-orig-size'] = $size;
$attr['data-comments-opened'] = $comments_opened;
$attr['data-image-meta'] = esc_attr( $img_meta );
$attr['data-image-title'] = esc_attr( htmlspecialchars( $attachment_title ) );
$attr['data-image-description'] = esc_attr( htmlspecialchars( $attachment_desc ) );
$attr['data-medium-file'] = esc_attr( $medium_file );
$attr['data-large-file'] = esc_attr( $large_file );
return $attr;
}
function add_data_to_container( $html ) {
global $post;
if ( isset( $post ) ) {
$blog_id = (int) get_current_blog_id();
$extra_data = array(
'data-carousel-extra' => array(
'blog_id' => $blog_id,
'permalink' => get_permalink( $post->ID ),
)
);
/**
* Filter the data added to the Gallery container.
*
* @module carousel
*
* @since 1.6.0
*
* @param array $extra_data Array of data about the site and the post.
*/
$extra_data = apply_filters( 'jp_carousel_add_data_to_container', $extra_data );
foreach ( (array) $extra_data as $data_key => $data_values ) {
$html = str_replace( '<div ', '<div ' . esc_attr( $data_key ) . "='" . json_encode( $data_values ) . "' ", $html );
}
}
return $html;
}
function get_attachment_comments() {
if ( ! headers_sent() )
header('Content-type: text/javascript');
/**
* Allows for the checking of privileges of the blog user before comments
* are packaged as JSON and sent back from the get_attachment_comments
* AJAX endpoint
*
* @module carousel
*
* @since 1.6.0
*/
do_action('jp_carousel_check_blog_user_privileges');
$attachment_id = ( isset( $_REQUEST['id'] ) ) ? (int) $_REQUEST['id'] : 0;
$offset = ( isset( $_REQUEST['offset'] ) ) ? (int) $_REQUEST['offset'] : 0;
if ( ! $attachment_id ) {
echo json_encode( __( 'Missing attachment ID.', 'jetpack' ) );
die();
}
if ( $offset < 1 )
$offset = 0;
$comments = get_comments( array(
'status' => 'approve',
'order' => ( 'asc' == get_option('comment_order') ) ? 'ASC' : 'DESC',
'number' => 10,
'offset' => $offset,
'post_id' => $attachment_id,
) );
$out = array();
// Can't just send the results, they contain the commenter's email address.
foreach ( $comments as $comment ) {
$avatar = get_avatar( $comment->comment_author_email, 64 );
if( ! $avatar )
$avatar = '';
$out[] = array(
'id' => $comment->comment_ID,
'parent_id' => $comment->comment_parent,
'author_markup' => get_comment_author_link( $comment->comment_ID ),
'gravatar_markup' => $avatar,
'date_gmt' => $comment->comment_date_gmt,
'content' => wpautop($comment->comment_content),
);
}
die( json_encode( $out ) );
}
function post_attachment_comment() {
if ( ! headers_sent() )
header('Content-type: text/javascript');
if ( empty( $_POST['nonce'] ) || ! wp_verify_nonce($_POST['nonce'], 'carousel_nonce') )
die( json_encode( array( 'error' => __( 'Nonce verification failed.', 'jetpack' ) ) ) );
$_blog_id = (int) $_POST['blog_id'];
$_post_id = (int) $_POST['id'];
$comment = $_POST['comment'];
if ( empty( $_blog_id ) )
die( json_encode( array( 'error' => __( 'Missing target blog ID.', 'jetpack' ) ) ) );
if ( empty( $_post_id ) )
die( json_encode( array( 'error' => __( 'Missing target post ID.', 'jetpack' ) ) ) );
if ( empty( $comment ) )
die( json_encode( array( 'error' => __( 'No comment text was submitted.', 'jetpack' ) ) ) );
// Used in context like NewDash
$switched = false;
if ( is_multisite() && $_blog_id != get_current_blog_id() ) {
switch_to_blog( $_blog_id );
$switched = true;
}
/** This action is documented in modules/carousel/jetpack-carousel.php */
do_action('jp_carousel_check_blog_user_privileges');
if ( ! comments_open( $_post_id ) )
die( json_encode( array( 'error' => __( 'Comments on this post are closed.', 'jetpack' ) ) ) );
if ( is_user_logged_in() ) {
$user = wp_get_current_user();
$user_id = $user->ID;
$display_name = $user->display_name;
$email = $user->user_email;
$url = $user->user_url;
if ( empty( $user_id ) )
die( json_encode( array( 'error' => __( 'Sorry, but we could not authenticate your request.', 'jetpack' ) ) ) );
} else {
$user_id = 0;
$display_name = $_POST['author'];
$email = $_POST['email'];
$url = $_POST['url'];
if ( get_option( 'require_name_email' ) ) {
if ( empty( $display_name ) )
die( json_encode( array( 'error' => __( 'Please provide your name.', 'jetpack' ) ) ) );
if ( empty( $email ) )
die( json_encode( array( 'error' => __( 'Please provide an email address.', 'jetpack' ) ) ) );
if ( ! is_email( $email ) )
die( json_encode( array( 'error' => __( 'Please provide a valid email address.', 'jetpack' ) ) ) );
}
}
$comment_data = array(
'comment_content' => $comment,
'comment_post_ID' => $_post_id,
'comment_author' => $display_name,
'comment_author_email' => $email,
'comment_author_url' => $url,
'comment_approved' => 0,
'comment_type' => '',
);
if ( ! empty( $user_id ) )
$comment_data['user_id'] = $user_id;
// Note: wp_new_comment() sanitizes and validates the values (too).
$comment_id = wp_new_comment( $comment_data );
/**
* Fires before adding a new comment to the database via the get_attachment_comments ajax endpoint.
*
* @module carousel
*
* @since 1.6.0
*/
do_action( 'jp_carousel_post_attachment_comment' );
$comment_status = wp_get_comment_status( $comment_id );
if ( true == $switched )
restore_current_blog();
die( json_encode( array( 'comment_id' => $comment_id, 'comment_status' => $comment_status ) ) );
}
function register_settings() {
add_settings_section('carousel_section', __( 'Image Gallery Carousel', 'jetpack' ), array( $this, 'carousel_section_callback' ), 'media');
if ( ! $this->in_jetpack ) {
add_settings_field('carousel_enable_it', __( 'Enable carousel', 'jetpack' ), array( $this, 'carousel_enable_it_callback' ), 'media', 'carousel_section' );
register_setting( 'media', 'carousel_enable_it', array( $this, 'carousel_enable_it_sanitize' ) );
}
add_settings_field('carousel_background_color', __( 'Background color', 'jetpack' ), array( $this, 'carousel_background_color_callback' ), 'media', 'carousel_section' );
register_setting( 'media', 'carousel_background_color', array( $this, 'carousel_background_color_sanitize' ) );
add_settings_field('carousel_display_exif', __( 'Metadata', 'jetpack'), array( $this, 'carousel_display_exif_callback' ), 'media', 'carousel_section' );
register_setting( 'media', 'carousel_display_exif', array( $this, 'carousel_display_exif_sanitize' ) );
// No geo setting yet, need to "fuzzify" data first, for privacy
// add_settings_field('carousel_display_geo', __( 'Geolocation', 'jetpack' ), array( $this, 'carousel_display_geo_callback' ), 'media', 'carousel_section' );
// register_setting( 'media', 'carousel_display_geo', array( $this, 'carousel_display_geo_sanitize' ) );
}
// Fulfill the settings section callback requirement by returning nothing
function carousel_section_callback() {
return;
}
function test_1or0_option( $value, $default_to_1 = true ) {
if ( true == $default_to_1 ) {
// Binary false (===) of $value means it has not yet been set, in which case we do want to default sites to 1
if ( false === $value )
$value = 1;
}
return ( 1 == $value ) ? 1 : 0;
}
function sanitize_1or0_option( $value ) {
return ( 1 == $value ) ? 1 : 0;
}
function settings_checkbox($name, $label_text, $extra_text = '', $default_to_checked = true) {
if ( empty( $name ) )
return;
$option = $this->test_1or0_option( get_option( $name ), $default_to_checked );
echo '<fieldset>';
echo '<input type="checkbox" name="'.esc_attr($name).'" id="'.esc_attr($name).'" value="1" ';
checked( '1', $option );
echo '/> <label for="'.esc_attr($name).'">'.$label_text.'</label>';
if ( ! empty( $extra_text ) )
echo '<p class="description">'.$extra_text.'</p>';
echo '</fieldset>';
}
function settings_select($name, $values, $extra_text = '') {
if ( empty( $name ) || ! is_array( $values ) || empty( $values ) )
return;
$option = get_option( $name );
echo '<fieldset>';
echo '<select name="'.esc_attr($name).'" id="'.esc_attr($name).'">';
foreach( $values as $key => $value ) {
echo '<option value="'.esc_attr($key).'" ';
selected( $key, $option );
echo '>'.esc_html($value).'</option>';
}
echo '</select>';
if ( ! empty( $extra_text ) )
echo '<p class="description">'.$extra_text.'</p>';
echo '</fieldset>';
}
function carousel_display_exif_callback() {
$this->settings_checkbox( 'carousel_display_exif', __( 'Show photo metadata (<a href="http://en.wikipedia.org/wiki/Exchangeable_image_file_format" target="_blank">Exif</a>) in carousel, when available.', 'jetpack' ) );
}
function carousel_display_exif_sanitize( $value ) {
return $this->sanitize_1or0_option( $value );
}
function carousel_display_geo_callback() {
$this->settings_checkbox( 'carousel_display_geo', __( 'Show map of photo location in carousel, when available.', 'jetpack' ) );
}
function carousel_display_geo_sanitize( $value ) {
return $this->sanitize_1or0_option( $value );
}
function carousel_background_color_callback() {
$this->settings_select( 'carousel_background_color', array( 'black' => __( 'Black', 'jetpack' ), 'white' => __( 'White', 'jetpack', 'jetpack' ) ) );
}
function carousel_background_color_sanitize( $value ) {
return ( 'white' == $value ) ? 'white' : 'black';
}
function carousel_enable_it_callback() {
$this->settings_checkbox( 'carousel_enable_it', __( 'Display images in full-size carousel slideshow.', 'jetpack' ) );
}
function carousel_enable_it_sanitize( $value ) {
return $this->sanitize_1or0_option( $value );
}
}
new Jetpack_Carousel;

View File

@@ -0,0 +1,213 @@
<?php
/**
* Module Name: Comment Likes
* Module Description: Increase visitor engagement by adding a Like button to comments.
* Sort Order: 39
* Recommendation Order: 17
* First Introduced: 5.1
* Requires Connection: Yes
* Auto Activate: No
* Module Tags: Social
* Additional Search Queries: like widget, like button, like, likes
*/
Jetpack::dns_prefetch( array(
'//widgets.wp.com',
'//s0.wp.com',
'//s1.wp.com',
'//s2.wp.com',
'//0.gravatar.com',
'//1.gravatar.com',
'//2.gravatar.com',
) );
require_once dirname( __FILE__ ) . '/likes/jetpack-likes-master-iframe.php';
require_once dirname( __FILE__ ) . '/likes/jetpack-likes-settings.php';
class Jetpack_Comment_Likes {
public static function init() {
static $instance = NULL;
if ( ! $instance ) {
$instance = new Jetpack_Comment_Likes;
}
return $instance;
}
private function __construct() {
$this->settings = new Jetpack_Likes_Settings();
$this->blog_id = Jetpack_Options::get_option( 'id' );
$this->url = home_url();
$this->url_parts = parse_url( $this->url );
$this->domain = $this->url_parts['host'];
add_action( 'init', array( $this, 'frontend_init' ) );
add_action( 'admin_init', array( $this, 'admin_init' ) );
if ( ! Jetpack::is_module_active( 'likes' ) ) {
$active = Jetpack::get_active_modules();
if ( ! in_array( 'sharedaddy', $active ) && ! in_array( 'publicize', $active ) ) {
// we don't have a sharing page yet
add_action( 'admin_menu', array( $this->settings, 'sharing_menu' ) );
}
if ( in_array( 'publicize', $active ) && ! in_array( 'sharedaddy', $active ) ) {
// we have a sharing page but not the global options area
add_action( 'pre_admin_screen_sharing', array( $this->settings, 'sharing_block' ), 20 );
add_action( 'pre_admin_screen_sharing', array( $this->settings, 'updated_message' ), -10 );
}
if( ! in_array( 'sharedaddy', $active ) ) {
add_action( 'admin_init', array( $this->settings, 'process_update_requests_if_sharedaddy_not_loaded' ) );
add_action( 'sharing_global_options', array( $this->settings, 'admin_settings_showbuttonon_init' ), 19 );
add_action( 'sharing_admin_update', array( $this->settings, 'admin_settings_showbuttonon_callback' ), 19 );
add_action( 'admin_init', array( $this->settings, 'add_meta_box' ) );
} else {
add_filter( 'sharing_meta_box_title', array( $this->settings, 'add_likes_to_sharing_meta_box_title' ) );
add_action( 'start_sharing_meta_box_content', array( $this->settings, 'meta_box_content' ) );
}
add_action( 'save_post', array( $this->settings, 'meta_box_save' ) );
add_action( 'edit_attachment', array( $this->settings, 'meta_box_save' ) );
add_action( 'sharing_global_options', array( $this->settings, 'admin_settings_init' ), 20 );
add_action( 'sharing_admin_update', array( $this->settings, 'admin_settings_callback' ), 20 );
}
}
public function admin_init() {
add_filter( 'manage_edit-comments_columns', array( $this, 'add_like_count_column' ) );
add_action( 'manage_comments_custom_column', array( $this, 'comment_likes_edit_column' ), 10, 2 );
add_action( 'admin_print_styles-edit-comments.php', array( $this, 'enqueue_admin_styles_scripts' ) );
}
public function comment_likes_edit_column( $column_name, $comment_id ) {
if ( 'comment_likes' !== $column_name ) {
return;
}
$permalink = get_permalink( get_the_ID() );
?>
<a
data-comment-id="<?php echo absint( $comment_id ); ?>"
data-blog-id="<?php echo absint( $this->blog_id ); ?>"
class="comment-like-count"
id="comment-like-count-<?php echo absint( $comment_id ); ?>"
href="<?php echo esc_url( $permalink ); ?>#comment-<?php echo absint( $comment_id ); ?>"
>
<span class="like-count">0</span>
</a>
<?php
}
function enqueue_admin_styles_scripts() {
wp_enqueue_style( 'comment-like-count', plugins_url( 'comment-likes/admin-style.css', __FILE__ ), array(), JETPACK__VERSION );
wp_enqueue_script(
'comment-like-count',
Jetpack::get_file_url_for_environment(
'_inc/build/comment-likes/comment-like-count.min.js',
'modules/comment-likes/comment-like-count.js'
),
array( 'jquery' ),
JETPACK__VERSION
);
}
public function add_like_count_column( $columns ) {
$columns['comment_likes'] = '<span class="vers"></span>';
return $columns;
}
public function frontend_init() {
if ( is_admin() ) {
return;
}
if ( Jetpack_AMP_Support::is_amp_request() ) {
return;
}
add_action( 'wp_enqueue_scripts', array( $this, 'load_styles_register_scripts' ) );
add_filter( 'comment_text', array( $this, 'comment_likes' ), 10, 2 );
}
public function load_styles_register_scripts() {
if ( ! wp_style_is( 'open-sans', 'registered' ) ) {
wp_register_style( 'open-sans', 'https://fonts.googleapis.com/css?family=Open+Sans', array(), JETPACK__VERSION );
}
wp_enqueue_style( 'jetpack_likes', plugins_url( 'likes/style.css', __FILE__ ), array( 'open-sans' ), JETPACK__VERSION );
wp_enqueue_script(
'postmessage',
Jetpack::get_file_url_for_environment( '_inc/build/postmessage.min.js', '_inc/postmessage.js' ),
array( 'jquery' ),
JETPACK__VERSION,
false
);
wp_enqueue_script(
'jetpack_resize',
Jetpack::get_file_url_for_environment(
'_inc/build/jquery.jetpack-resize.min.js',
'_inc/jquery.jetpack-resize.js'
),
array( 'jquery' ),
JETPACK__VERSION,
false
);
wp_enqueue_script( 'jetpack_likes_queuehandler', plugins_url( 'likes/queuehandler.js' , __FILE__ ), array( 'jquery', 'postmessage', 'jetpack_resize' ), JETPACK__VERSION, true );
}
public function comment_likes( $content, $comment = null ) {
if ( empty( $comment ) ) {
return $content;
}
if ( ! $this->settings->is_likes_visible() ) {
return $content;
}
$comment_id = get_comment_ID();
if ( empty( $comment_id ) && ! empty( $comment->comment_ID ) ) {
$comment_id = $comment->comment_ID;
}
if ( empty( $content ) || empty( $comment_id ) ) {
return $content;
}
// In case master iframe hasn't been loaded. This could be the case when Post Likes module is disabled,
// or on pages on which we have comments but post likes are disabled.
if ( false === has_action( 'wp_footer', 'jetpack_likes_master_iframe' ) ) {
add_action( 'wp_footer', 'jetpack_likes_master_iframe', 21 );
}
$uniqid = uniqid();
$src = sprintf( 'https://widgets.wp.com/likes/#blog_id=%1$d&amp;comment_id=%2$d&amp;origin=%3$s&amp;obj_id=%1$d-%2$d-%4$s', $this->blog_id, $comment_id, $this->domain, $uniqid );
$name = sprintf( 'like-comment-frame-%1$d-%2$d-%3$s', $this->blog_id, $comment_id, $uniqid );
$wrapper = sprintf( 'like-comment-wrapper-%1$d-%2$d-%3$s', $this->blog_id, $comment_id, $uniqid );
$html = '';
$html .= "<div class='jetpack-comment-likes-widget-wrapper jetpack-likes-widget-unloaded' id='$wrapper' data-src='$src' data-name='$name'>";
$html .= "<div class='likes-widget-placeholder comment-likes-widget-placeholder comment-likes'><span class='loading'>" . esc_html__( 'Loading...', 'jetpack' ) . "</span></div>";
$html .= "<div class='comment-likes-widget jetpack-likes-widget comment-likes'><span class='comment-like-feedback'></span>";
$html .= "<span class='sd-text-color'></span><a class='sd-link-color'></a>";
$html .= '</div></div>';
/**
* Filters the Comment Likes button content.
*
* @module comment-likes
*
* @since 5.1.0
*
* @param string $html Comment Likes button content.
*/
$like_button = apply_filters( 'comment_like_button', $html );
return $content . $like_button;
}
}
Jetpack_Comment_Likes::init();

View File

@@ -0,0 +1,45 @@
.fixed .column-comment_likes {
width: 5.5em;
padding: 8px 0;
text-align: center;
}
.fixed .column-stats {
width: 5em;
}
.fixed .column-comment_likes .comment-like-count {
box-sizing: border-box;
display: inline-block;
padding: 0 8px;
height: 2em;
margin-top: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
background-color: #72777c;
color: #fff;
font-size: 11px;
line-height: 21px;
}
.fixed .column-comment_likes .comment-like-count:after {
border: none;
}
.fixed .column-comment_likes .comment-like-count:hover {
background-color: #0073aa;
}
.fixed .column-comment_likes .vers:before {
font: normal 20px/1 dashicons;
content: '\f155';
speak: none;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
@media screen and (max-width: 782px) {
.fixed .column-comment_likes {
display: none;
}
}

View File

@@ -0,0 +1,38 @@
jQuery( document ).ready( function( $ ) {
var jsonAPIbase = 'https://public-api.wordpress.com/rest/v1',
APIqueue = [];
function getCommentLikeCounts() {
$( '.comment-like-count' ).each( function() {
var blogId = $( this ).attr( 'data-blog-id' ),
commentId = $( this ).attr( 'data-comment-id' );
APIqueue.push( '/sites/' + blogId + '/comments/' + commentId + '/likes' );
} );
return $.ajax( {
type: 'GET',
url: jsonAPIbase + '/batch',
dataType: 'jsonp',
data: 'urls[]=' + APIqueue.map( encodeURIComponent ).join( '&urls[]=' ),
success: function( response ) {
for ( var path in response ) {
if ( ! response[ path ].error_data ) {
var urlPieces = path.split( '/' ),
commentId = urlPieces[ 4 ],
likeCount = response[ path ].found;
if ( likeCount < 1 ) {
return;
}
$( '#comment-like-count-' + commentId ).find( '.like-count' ).hide().text( likeCount ).fadeIn();
}
}
},
error: function() {}
} );
}
getCommentLikeCounts();
} );

View File

@@ -0,0 +1,42 @@
<?php
/**
* Module Name: Comments
* Module Description: Let readers use WordPress.com, Twitter, Facebook, or Google+ accounts to comment
* First Introduced: 1.4
* Sort Order: 20
* Requires Connection: Yes
* Auto Activate: No
* Module Tags: Social
* Feature: Engagement
* Additional Search Queries: comments, comment, facebook, twitter, google+, social
*/
require dirname( __FILE__ ) . '/comments/comments.php';
if ( is_admin() ) {
require dirname( __FILE__ ) . '/comments/admin.php';
}
function jetpack_comments_load() {
Jetpack::enable_module_configurable( __FILE__ );
Jetpack::module_configuration_load( __FILE__, 'jetpack_comments_configuration_load' );
}
function jetpack_comments_configuration_load() {
wp_safe_redirect( admin_url( 'options-discussion.php#jetpack-comments-settings' ) );
exit;
}
add_action( 'jetpack_modules_loaded', 'jetpack_comments_load' );
Jetpack::dns_prefetch( array(
'//jetpack.wordpress.com',
'//s0.wp.com',
'//s1.wp.com',
'//s2.wp.com',
'//public-api.wordpress.com',
'//0.gravatar.com',
'//1.gravatar.com',
'//2.gravatar.com',
) );

View File

@@ -0,0 +1,208 @@
<?php
class Jetpack_Comments_Settings {
/** Variables *************************************************************/
/**
* The Jetpack Coments singleton
*/
public $jetpack_comments;
/**
* The default comment form greeting
* @var string
*/
public $default_greeting = ''; // Set in constructor
/**
* The default comment form color scheme
* @var string
*/
public $color_schemes = array();
public static function init() {
static $instance = false;
if ( !$instance ) {
$instance = new Jetpack_Comments_Settings( Jetpack_Comments::init() );
}
return $instance;
}
public function __construct( Highlander_Comments_Base $jetpack_comments ) {
$this->jetpack_comments = $jetpack_comments;
// Setup settings
add_action( 'admin_init', array( $this, 'add_settings' ) );
$this->setup_globals();
}
/** Private Methods *******************************************************/
/**
* Set any global variables or class variables
* @since JetpackComments (1.4)
*/
protected function setup_globals() {
// Default option values
$this->default_greeting = __( 'Leave a Reply', 'jetpack' );
// Possible color schemes
$this->color_schemes = array(
'light' => __( 'Light', 'jetpack' ),
'dark' => __( 'Dark', 'jetpack' ),
'transparent' => __( 'Transparent', 'jetpack' ),
);
}
/** Settings **************************************************************/
/**
* Add the Jetpack settings to WordPress's discussions page
*
* @since JetpackComments (1.4)
*/
public function add_settings() {
// Create the section
add_settings_section(
'jetpack_comment_form',
__( 'Comments', 'jetpack' ),
array( $this, 'comment_form_settings_section' ),
'discussion'
);
/** Clever Greeting ***************************************************/
add_settings_field(
'highlander_comment_form_prompt',
__( 'Greeting Text', 'jetpack' ),
array( $this, 'comment_form_greeting_setting' ),
'discussion',
'jetpack_comment_form'
);
register_setting(
'discussion',
'highlander_comment_form_prompt',
array( $this, 'comment_form_greeting_sanitize' )
);
/** Color Scheme ******************************************************/
add_settings_field(
'jetpack_comment_form_color_scheme',
__( 'Color Scheme', 'jetpack' ),
array( $this, 'comment_form_color_scheme_setting' ),
'discussion',
'jetpack_comment_form'
);
register_setting(
'discussion',
'jetpack_comment_form_color_scheme',
array( $this, 'comment_form_color_scheme_sanitize' )
);
}
/**
* Discussions setting section blurb
*
* @since JetpackComments (1.4)
*/
public function comment_form_settings_section() {
?>
<p id="jetpack-comments-settings"><?php _e( 'Adjust your Comments form with a clever greeting and color-scheme.', 'jetpack' ); ?></p>
<?php
}
/**
* Custom Comment Greeting Text
*
* @since JetpackComments (1.4)
*/
public function comment_form_greeting_setting() {
// The greeting
$greeting = get_option( 'highlander_comment_form_prompt', $this->default_greeting ); ?>
<input type="text" name="highlander_comment_form_prompt" id="jetpack-comment-form-greeting" value="<?php echo esc_attr( $greeting ); ?>" class="regular-text">
<p class="description"><?php _e( 'A few catchy words to motivate your readers to comment', 'jetpack' ); ?></p>
<?php
}
/**
* Sanitize the clever comment greeting
*
* @since JetpackComments (1.4)
* @param type $val
* @return string
*/
function comment_form_greeting_sanitize( $val ) {
// Delete if empty or the default
if ( empty( $val ) || ( $this->default_greeting == $val ) ) {
delete_option( 'highlander_comment_form_prompt' );
return false;
}
return wp_kses( $val, array() );
}
/**
* Color Scheme Setting
*
* @since JetpackComments (1.4)
*/
public function comment_form_color_scheme_setting() {
// The color scheme
$scheme = get_option( 'jetpack_comment_form_color_scheme', $this->jetpack_comments->default_color_scheme ); ?>
<fieldset>
<legend class="screen-reader-text"><?php _e( 'Color Scheme', 'jetpack' ); ?></legend>
<?php foreach( $this->color_schemes as $key => $label ) : ?>
<label>
<input type="radio" name="jetpack_comment_form_color_scheme" id="jetpack-comment-form-color-scheme" value="<?php echo $key; ?>" <?php checked( $scheme, $key ); ?>>
<?php echo $label; ?>
</label>
<br />
<?php endforeach; ?>
</fieldset>
<?php
}
/**
* Sanitize the color scheme
*
* @since JetpackComments (1.4)
* @param type $val
* @return string
*/
public function comment_form_color_scheme_sanitize( $val ) {
// Delete the option if it's...
if (
empty( $val ) || !in_array( $val, array_keys( $this->color_schemes ) ) // ... unknown
||
$val == $this->jetpack_comments->default_color_scheme // ... or the default
) {
delete_option( 'jetpack_comment_form_color_scheme' );
return false;
}
return $val;
}
}
Jetpack_Comments_Settings::init();

View File

@@ -0,0 +1,294 @@
<?php
/**
* All the code shared between WP.com Highlander and Jetpack Highlander
*/
class Highlander_Comments_Base {
function __construct() {
$this->setup_globals();
$this->setup_actions();
$this->setup_filters();
}
/**
* Set any global variables or class variables
* @since JetpackComments (1.4)
*/
protected function setup_globals() {}
/**
* Setup actions for methods in this class
* @since JetpackComments (1.4)
*/
protected function setup_actions() {
// Before a comment is posted
add_action( 'pre_comment_on_post', array( $this, 'allow_logged_out_user_to_comment_as_external' ) );
// After a comment is posted
add_action( 'comment_post', array( $this, 'set_comment_cookies' ) );
}
/**
* Setup filters for methods in this class
* @since JetpackComments (1.4)
*/
protected function setup_filters() {
add_filter( 'comments_array', array( $this, 'comments_array' ) );
add_filter( 'preprocess_comment', array( $this, 'allow_logged_in_user_to_comment_as_guest' ), 0 );
}
/**
* Is this a Highlander POST request?
* Optionally restrict to one or more credentials slug (facebook, twitter, ...)
*
* @param string Comment credentials slug
* @param ...
* @return false|string false if it's not a Highlander POST request. The matching credentials slug if it is.
*/
function is_highlander_comment_post() {
if ( empty( $_POST['hc_post_as'] ) ) {
return false;
}
if ( func_num_args() ) {
foreach ( func_get_args() as $id_source ) {
if ( $id_source === $_POST['hc_post_as'] ) {
return $id_source;
}
}
return false;
}
return is_string( $_POST['hc_post_as'] ) && in_array( $_POST['hc_post_as'], $this->id_sources ) ? $_POST['hc_post_as'] : false;
}
/**
* Signs an array of scalars with the self-hosted blog's Jetpack Token
*
* @param array $parameters
* @param string $key
* @return string HMAC
*/
static function sign_remote_comment_parameters( $parameters, $key ) {
unset(
$parameters['sig'], // Don't sign the signature
$parameters['replytocom'] // This parameter is unsigned - it changes dynamically as the comment form moves from parent comment to parent comment
);
ksort( $parameters );
$signing = array();
foreach ( $parameters as $k => $v ) {
if ( !is_scalar( $v ) ) {
return new WP_Error( 'invalid_input', __( 'Invalid request', 'jetpack' ) );
}
$signing[] = "{$k}={$v}";
}
return hash_hmac( 'sha1', implode( ':', $signing ), $key );
}
/*
* After commenting as a guest while logged in, the user needs to see both:
*
* ( user_id = blah AND comment_approved = 0 )
* and
* ( comment_author_email = blah AND comment_approved = 0 )
*
* Core only does the first since the user is logged in.
*
* Add the second to the comments array.
*/
function comments_array( $comments ) {
global $wpdb, $post;
$commenter = $this->get_current_commenter();
if ( !$commenter['user_id'] )
return $comments;
if ( !$commenter['comment_author'] )
return $comments;
$in_moderation_comments = $wpdb->get_results( $wpdb->prepare(
"SELECT * FROM `$wpdb->comments` WHERE `comment_post_ID` = %d AND `user_id` = 0 AND `comment_author` = %s AND `comment_author_email` = %s AND `comment_approved` = '0' ORDER BY `comment_date_gmt` /* Highlander_Comments_Base::comments_array() */",
$post->ID,
wp_specialchars_decode( $commenter['comment_author'], ENT_QUOTES ),
$commenter['comment_author_email']
) );
if ( !$in_moderation_comments )
return $comments;
// @todo ZOMG this is a bad idea
$comments = array_merge( $comments, $in_moderation_comments );
usort( $comments, array( $this, 'sort_comments_by_comment_date_gmt' ) );
return $comments;
}
/**
* Comment sort comparator: comment_date_gmt
*
* @since JetpackComments (1.4)
* @param object $a
* @param object $b
* @return int
*/
public function sort_comments_by_comment_date_gmt( $a, $b ) {
if ( $a->comment_date_gmt == $b->comment_date_gmt ) {
return 0;
}
return $a->comment_date_gmt < $b->comment_date_gmt ? -1 : 1;
}
/**
* Get the current commenter's information from their cookie
*
* @since JetpackComments (1.4)
* @return array Commenters information from cookie
*/
protected function get_current_commenter() {
// Defaults
$user_id = 0;
$comment_author = '';
$comment_author_email = '';
$comment_author_url = '';
if ( isset( $_COOKIE['comment_author_' . COOKIEHASH] ) ) {
$comment_author = $_COOKIE['comment_author_' . COOKIEHASH];
}
if ( isset( $_COOKIE['comment_author_email_' . COOKIEHASH] ) ) {
$comment_author_email = $_COOKIE['comment_author_email_' . COOKIEHASH];
}
if ( isset( $_COOKIE['comment_author_url_' . COOKIEHASH] ) ) {
$comment_author_url = $_COOKIE['comment_author_url_' . COOKIEHASH];
}
if ( is_user_logged_in() ) {
$user = wp_get_current_user();
$user_id = $user->ID;
}
return compact( 'comment_author', 'comment_author_email', 'comment_author_url', 'user_id' );
}
/**
* Allows a logged out user to leave a comment as a facebook or twitter credentialed user.
* Overrides WordPress' core comment_registration option to treat these commenters as "registered" (verified) users.
*
* @since JetpackComments (1.4)
* @return If no
*/
function allow_logged_out_user_to_comment_as_external() {
if ( !$this->is_highlander_comment_post( 'facebook', 'twitter', 'googleplus' ) ) {
return;
}
add_filter( 'pre_option_comment_registration', '__return_zero' );
}
/**
* Allow a logged in user to post as a guest, FB, or twitter credentialed request.
* Bypasses WordPress' core overrides that force a logged in user to comment as that user.
* Respects comment_registration option.
*
* @since JetpackComments (1.4)
* @param array $comment_data
* @return int
*/
function allow_logged_in_user_to_comment_as_guest( $comment_data ) {
// Bail if user registration is allowed
if ( get_option( 'comment_registration' ) ) {
return $comment_data;
}
// Bail if user is not logged in or not a post request
if ( 'POST' != strtoupper( $_SERVER['REQUEST_METHOD'] ) || !is_user_logged_in() ) {
return $comment_data;
}
// Bail if this is not a guest or external service credentialed request
if ( !$this->is_highlander_comment_post( 'guest', 'facebook', 'twitter', 'googleplus' ) ) {
return $comment_data;
}
$user = wp_get_current_user();
foreach ( array( 'comment_author' => 'display_name', 'comment_author_email' => 'user_email', 'comment_author_url' => 'user_url' ) as $comment_field => $user_field ) {
if ( $comment_data[$comment_field] != addslashes( $user->$user_field ) ) {
return $comment_data; // some other plugin already did something funky
}
}
if ( get_option( 'require_name_email' ) ) {
if ( 6 > strlen( $_POST['email'] ) || empty( $_POST['author'] ) ) {
wp_die( __( 'Error: please fill the required fields (name, email).', 'jetpack' ) );
} elseif ( ! is_email( $_POST['email'] ) ) {
wp_die( __( 'Error: please enter a valid email address.', 'jetpack' ) );
}
}
$author_change = false;
foreach ( array( 'comment_author' => 'author', 'comment_author_email' => 'email', 'comment_author_url' => 'url' ) as $comment_field => $post_field ) {
if ( $comment_data[$comment_field] != $_POST[$post_field] && 'url' != $post_field ) {
$author_change = true;
}
$comment_data[$comment_field] = $_POST[$post_field];
}
// Mark as guest comment if name or email were changed
if ( $author_change ) {
$comment_data['user_id'] = $comment_data['user_ID'] = 0;
}
return $comment_data;
}
/**
* Set the comment cookies or bail if comment is invalid
*
* @since JetpackComments (1.4)
* @param type $comment_id
* @return If comment is invalid
*/
public function set_comment_cookies( $comment_id ) {
// Get comment and bail if it's invalid somehow
$comment = get_comment( $comment_id );
if ( empty( $comment ) || is_wp_error( $comment ) ) {
return;
}
$id_source = $this->is_highlander_comment_post();
if ( empty( $id_source ) ) {
return;
}
// Set comment author cookies
if ( ( 'wordpress' != $id_source ) && is_user_logged_in() ) {
/** This filter is already documented in core/wp-includes/comment-functions.php */
$comment_cookie_lifetime = apply_filters( 'comment_cookie_lifetime', 30000000 );
setcookie( 'comment_author_' . COOKIEHASH, $comment->comment_author, time() + $comment_cookie_lifetime, COOKIEPATH, COOKIE_DOMAIN );
setcookie( 'comment_author_email_' . COOKIEHASH, $comment->comment_author_email, time() + $comment_cookie_lifetime, COOKIEPATH, COOKIE_DOMAIN );
setcookie( 'comment_author_url_' . COOKIEHASH, esc_url($comment->comment_author_url), time() + $comment_cookie_lifetime, COOKIEPATH, COOKIE_DOMAIN );
}
}
/**
* Get an avatar from Photon
*
* @since JetpackComments (1.4)
* @param string $url
* @param int $size
* @return string
*/
protected function photon_avatar( $url, $size ) {
$size = (int) $size;
return jetpack_photon_url( $url, array( 'resize' => "$size,$size" ) );
}
}

View File

@@ -0,0 +1,618 @@
<?php
require dirname( __FILE__ ) . '/base.php';
/**
* Main Comments class
*
* @package JetpackComments
* @version 1.4
* @since 1.4
*/
class Jetpack_Comments extends Highlander_Comments_Base {
/** Variables *************************************************************/
/**
* Possible comment form sources
* @var array
*/
public $id_sources = array();
/**
* URL
* @var string
*/
public $signed_url = '';
/**
* The default comment form color scheme
* @var string
* @see ::set_default_color_theme_based_on_theme_settings()
*/
public $default_color_scheme = 'light';
/** Methods ***************************************************************/
public static function init() {
static $instance = false;
if ( ! $instance ) {
$instance = new Jetpack_Comments;
}
return $instance;
}
/**
* Main constructor for Comments
*
* @since JetpackComments (1.4)
*/
public function __construct() {
parent::__construct();
// Comments is loaded
/**
* Fires after the Jetpack_Comments object has been instantiated
*
* @module comments
*
* @since 1.4.0
*
* @param array $jetpack_comments_loaded First element in array of type Jetpack_Comments
**/
do_action_ref_array( 'jetpack_comments_loaded', array( $this ) );
add_action( 'after_setup_theme', array( $this, 'set_default_color_theme_based_on_theme_settings' ), 100 );
}
public function set_default_color_theme_based_on_theme_settings() {
if ( function_exists( 'twentyeleven_get_theme_options' ) ) {
$theme_options = twentyeleven_get_theme_options();
$theme_color_scheme = isset( $theme_options['color_scheme'] ) ? $theme_options['color_scheme'] : 'transparent';
} else {
$theme_color_scheme = get_theme_mod( 'color_scheme', 'transparent' );
}
// Default for $theme_color_scheme is 'transparent' just so it doesn't match 'light' or 'dark'
// The default for Jetpack's color scheme is still defined above as 'light'
if ( false !== stripos( $theme_color_scheme, 'light' ) ) {
$this->default_color_scheme = 'light';
} elseif ( false !== stripos( $theme_color_scheme, 'dark' ) ) {
$this->default_color_scheme = 'dark';
}
}
/** Private Methods *******************************************************/
/**
* Set any global variables or class variables
* @since JetpackComments (1.4)
*/
protected function setup_globals() {
parent::setup_globals();
// Sources
$this->id_sources = array(
'guest',
'jetpack',
'wordpress',
'twitter',
'facebook'
);
}
/**
* Setup actions for methods in this class
* @since JetpackComments (1.4)
*/
protected function setup_actions() {
parent::setup_actions();
// Selfishly remove everything from the existing comment form
remove_all_actions( 'comment_form_before' );
// Selfishly add only our actions back to the comment form
add_action( 'comment_form_before', array( $this, 'comment_form_before' ) );
add_action( 'comment_form_after', array( $this, 'comment_form_after' ), 1 ); // Set very early since we remove everything outputed before our action.
// Before a comment is posted
add_action( 'pre_comment_on_post', array( $this, 'pre_comment_on_post' ), 1 );
// After a comment is posted
add_action( 'comment_post', array( $this, 'add_comment_meta' ) );
}
/**
* Setup filters for methods in this class
* @since 1.6.2
*/
protected function setup_filters() {
parent::setup_filters();
add_filter( 'comment_post_redirect', array( $this, 'capture_comment_post_redirect_to_reload_parent_frame' ), 100 );
add_filter( 'get_avatar', array( $this, 'get_avatar' ), 10, 4 );
}
/**
* Get the comment avatar from Gravatar, Twitter, or Facebook
*
* @since JetpackComments (1.4)
*
* @param string $avatar Current avatar URL
* @param string $comment Comment for the avatar
* @param int $size Size of the avatar
* @param string $default Not used
*
* @return string New avatar
*/
public function get_avatar( $avatar, $comment, $size, $default ) {
if ( ! isset( $comment->comment_post_ID ) || ! isset( $comment->comment_ID ) ) {
// it's not a comment - bail
return $avatar;
}
// Detect whether it's a Facebook or Twitter avatar
$foreign_avatar = get_comment_meta( $comment->comment_ID, 'hc_avatar', true );
$foreign_avatar_hostname = parse_url( $foreign_avatar, PHP_URL_HOST );
if ( ! $foreign_avatar_hostname ||
! preg_match( '/\.?(graph\.facebook\.com|twimg\.com)$/', $foreign_avatar_hostname ) ) {
return $avatar;
}
// Return the FB or Twitter avatar
return preg_replace( '#src=([\'"])[^\'"]+\\1#', 'src=\\1' . esc_url( set_url_scheme( $this->photon_avatar( $foreign_avatar, $size ), 'https' ) ) . '\\1', $avatar );
}
/** Output Methods ********************************************************/
/**
* Start capturing the core comment_form() output
* @since JetpackComments (1.4)
*/
public function comment_form_before() {
/**
* Filters the setting that determines if Jetpagk comments should be enabled for
* the current post type.
*
* @module comments
*
* @since 3.8.1
*
* @param boolean $return Should comments be enabled?
*/
if ( ! apply_filters( 'jetpack_comment_form_enabled_for_' . get_post_type(), true ) ) {
return;
}
// Add some JS to the footer
add_action( 'wp_footer', array( $this, 'watch_comment_parent' ), 100 );
ob_start();
}
/**
* Noop the default comment form output, get some options, and output our
* tricked out totally radical comment form.
*
* @since JetpackComments (1.4)
*/
public function comment_form_after() {
/** This filter is documented in modules/comments/comments.php */
if ( ! apply_filters( 'jetpack_comment_form_enabled_for_' . get_post_type(), true ) ) {
return;
}
// Throw it all out and drop in our replacement
ob_end_clean();
// If users are required to be logged in, and they're not, then we don't need to do anything else
if ( get_option( 'comment_registration' ) && ! is_user_logged_in() ) {
/**
* Changes the log in to comment prompt.
*
* @module comments
*
* @since 1.4.0
*
* @param string $var Default is "You must log in to post a comment."
*/
echo '<p class="must-log-in">' . sprintf( apply_filters( 'jetpack_must_log_in_to_comment', __( 'You must <a href="%s">log in</a> to post a comment.', 'jetpack' ) ), wp_login_url( get_permalink() . '#respond' ) ) . '</p>';
return;
}
if ( in_array( 'subscriptions', Jetpack::get_active_modules() ) ) {
$stb_enabled = get_option( 'stb_enabled', 1 );
$stb_enabled = empty( $stb_enabled ) ? 0 : 1;
$stc_enabled = get_option( 'stc_enabled', 1 );
$stc_enabled = empty( $stc_enabled ) ? 0 : 1;
} else {
$stb_enabled = 0;
$stc_enabled = 0;
}
$params = array(
'blogid' => Jetpack_Options::get_option( 'id' ),
'postid' => get_the_ID(),
'comment_registration' => ( get_option( 'comment_registration' ) ? '1' : '0' ), // Need to explicitly send a '1' or a '0' for these
'require_name_email' => ( get_option( 'require_name_email' ) ? '1' : '0' ),
'stc_enabled' => $stc_enabled,
'stb_enabled' => $stb_enabled,
'show_avatars' => ( get_option( 'show_avatars' ) ? '1' : '0' ),
'avatar_default' => get_option( 'avatar_default' ),
'greeting' => get_option( 'highlander_comment_form_prompt', __( 'Leave a Reply', 'jetpack' ) ),
/**
* Changes the comment form prompt.
*
* @module comments
*
* @since 2.3.0
*
* @param string $var Default is "Leave a Reply to %s."
*/
'greeting_reply' => apply_filters( 'jetpack_comment_form_prompt_reply', __( 'Leave a Reply to %s', 'jetpack' ) ),
'color_scheme' => get_option( 'jetpack_comment_form_color_scheme', $this->default_color_scheme ),
'lang' => get_locale(),
'jetpack_version' => JETPACK__VERSION,
);
// Extra parameters for logged in user
if ( is_user_logged_in() ) {
$current_user = wp_get_current_user();
$params['hc_post_as'] = 'jetpack';
$params['hc_userid'] = $current_user->ID;
$params['hc_username'] = $current_user->display_name;
$params['hc_userurl'] = $current_user->user_url;
$params['hc_useremail'] = md5( strtolower( trim( $current_user->user_email ) ) );
if ( current_user_can( 'unfiltered_html' ) ) {
$params['_wp_unfiltered_html_comment'] = wp_create_nonce( 'unfiltered-html-comment_' . get_the_ID() );
}
}
$signature = Jetpack_Comments::sign_remote_comment_parameters( $params, Jetpack_Options::get_option( 'blog_token' ) );
if ( is_wp_error( $signature ) ) {
$signature = 'error';
}
$params['sig'] = $signature;
$url_origin = set_url_scheme( 'http://jetpack.wordpress.com' );
$url = "{$url_origin}/jetpack-comment/?" . http_build_query( $params );
$url = "{$url}#parent=" . urlencode( set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] ) );
$this->signed_url = $url;
$height = $params['comment_registration'] || is_user_logged_in() ? '315' : '430'; // Iframe can be shorter if we're not allowing guest commenting
$transparent = ( $params['color_scheme'] == 'transparent' ) ? 'true' : 'false';
if ( isset( $_GET['replytocom'] ) ) {
$url .= '&replytocom=' . (int) $_GET['replytocom'];
}
/**
* Filter whether the comment title can be displayed.
*
* @module comments
*
* @since 4.7.0
*
* @param bool $show Can the comment be displayed? Default to true.
*/
$show_greeting = apply_filters( 'jetpack_comment_form_display_greeting', true );
// The actual iframe (loads comment form from Jetpack server)
?>
<div id="respond" class="comment-respond">
<?php if ( true === $show_greeting ) : ?>
<h3 id="reply-title" class="comment-reply-title"><?php comment_form_title( esc_html( $params['greeting'] ), esc_html( $params['greeting_reply'] ) ); ?>
<small><?php cancel_comment_reply_link( esc_html__( 'Cancel reply', 'jetpack' ) ); ?></small>
</h3>
<?php endif; ?>
<form id="commentform" class="comment-form">
<iframe title="<?php esc_attr_e( 'Comment Form' , 'jetpack' ); ?>" src="<?php echo esc_url( $url ); ?>" style="width:100%; height: <?php echo $height; ?>px; border:0;" name="jetpack_remote_comment" class="jetpack_remote_comment" id="jetpack_remote_comment"></iframe>
<!--[if !IE]><!-->
<script>
document.addEventListener('DOMContentLoaded', function () {
var commentForms = document.getElementsByClassName('jetpack_remote_comment');
for (var i = 0; i < commentForms.length; i++) {
commentForms[i].allowTransparency = <?php echo $transparent; ?>;
commentForms[i].scrolling = 'no';
}
});
</script>
<!--<![endif]-->
</form>
</div>
<?php // Below is required for comment reply JS to work ?>
<input type="hidden" name="comment_parent" id="comment_parent" value="" />
<?php
}
/**
* Add some JS to wp_footer to watch for hierarchical reply parent change
*
* @since JetpackComments (1.4)
*/
public function watch_comment_parent() {
$url_origin = set_url_scheme( 'http://jetpack.wordpress.com' );
?>
<!--[if IE]>
<script type="text/javascript">
if ( 0 === window.location.hash.indexOf( '#comment-' ) ) {
// window.location.reload() doesn't respect the Hash in IE
window.location.hash = window.location.hash;
}
</script>
<![endif]-->
<script type="text/javascript">
(function () {
var comm_par_el = document.getElementById( 'comment_parent' ),
comm_par = ( comm_par_el && comm_par_el.value ) ? comm_par_el.value : '',
frame = document.getElementById( 'jetpack_remote_comment' ),
tellFrameNewParent;
tellFrameNewParent = function () {
if ( comm_par ) {
frame.src = "<?php echo esc_url_raw( $this->signed_url ); ?>" + '&replytocom=' + parseInt( comm_par, 10 ).toString();
} else {
frame.src = "<?php echo esc_url_raw( $this->signed_url ); ?>";
}
};
<?php if ( get_option( 'thread_comments' ) && get_option( 'thread_comments_depth' ) ) : ?>
if ( 'undefined' !== typeof addComment ) {
addComment._Jetpack_moveForm = addComment.moveForm;
addComment.moveForm = function ( commId, parentId, respondId, postId ) {
var returnValue = addComment._Jetpack_moveForm( commId, parentId, respondId, postId ),
cancelClick, cancel;
if ( false === returnValue ) {
cancel = document.getElementById( 'cancel-comment-reply-link' );
cancelClick = cancel.onclick;
cancel.onclick = function () {
var cancelReturn = cancelClick.call( this );
if ( false !== cancelReturn ) {
return cancelReturn;
}
if ( ! comm_par ) {
return cancelReturn;
}
comm_par = 0;
tellFrameNewParent();
return cancelReturn;
};
}
if ( comm_par == parentId ) {
return returnValue;
}
comm_par = parentId;
tellFrameNewParent();
return returnValue;
};
}
<?php endif; ?>
// Do the post message bit after the dom has loaded.
document.addEventListener( 'DOMContentLoaded', function () {
var iframe_url = <?php echo json_encode( esc_url_raw( $url_origin ) ); ?>;
if ( window.postMessage ) {
if ( document.addEventListener ) {
window.addEventListener( 'message', function ( event ) {
var origin = event.origin.replace( /^http:\/\//i, 'https://' );
if ( iframe_url.replace( /^http:\/\//i, 'https://' ) !== origin ) {
return;
}
jQuery( frame ).height( event.data );
});
} else if ( document.attachEvent ) {
window.attachEvent( 'message', function ( event ) {
var origin = event.origin.replace( /^http:\/\//i, 'https://' );
if ( iframe_url.replace( /^http:\/\//i, 'https://' ) !== origin ) {
return;
}
jQuery( frame ).height( event.data );
});
}
}
})
})();
</script>
<?php
}
/**
* Verify the hash included in remote comments.
*
* @since JetpackComments (1.4)
*
* @param type $comment Not used
*/
public function pre_comment_on_post( $comment ) {
$post_array = stripslashes_deep( $_POST );
// Bail if missing the Jetpack token
if ( ! isset( $post_array['sig'] ) ) {
unset( $_POST['hc_post_as'] );
return;
}
if ( false !== strpos( $post_array['hc_avatar'], '.gravatar.com' ) ) {
$post_array['hc_avatar'] = htmlentities( $post_array['hc_avatar'] );
}
$check = Jetpack_Comments::sign_remote_comment_parameters( $post_array, Jetpack_Options::get_option( 'blog_token' ) );
if ( is_wp_error( $check ) ) {
wp_die( $check );
}
// Bail if token is expired or not valid
if ( $check !== $post_array['sig'] ) {
wp_die( __( 'Invalid security token.', 'jetpack' ) );
}
/** This filter is documented in modules/comments/comments.php */
if ( ! apply_filters( 'jetpack_comment_form_enabled_for_' . get_post_type( $post_array['comment_post_ID'] ), true ) ) {
// In case the comment POST is legit, but the comments are
// now disabled, we don't allow the comment
wp_die( __( 'Comments are not allowed.', 'jetpack' ) );
}
}
/** Capabilities **********************************************************/
/**
* Add some additional comment meta after comment is saved about what
* service the comment is from, the avatar, user_id, etc...
*
* @since JetpackComments (1.4)
*
* @param type $comment_id
*/
public function add_comment_meta( $comment_id ) {
$comment_meta = array();
switch ( $this->is_highlander_comment_post() ) {
case 'facebook' :
$comment_meta['hc_post_as'] = 'facebook';
$comment_meta['hc_avatar'] = stripslashes( $_POST['hc_avatar'] );
$comment_meta['hc_foreign_user_id'] = stripslashes( $_POST['hc_userid'] );
break;
case 'twitter' :
$comment_meta['hc_post_as'] = 'twitter';
$comment_meta['hc_avatar'] = stripslashes( $_POST['hc_avatar'] );
$comment_meta['hc_foreign_user_id'] = stripslashes( $_POST['hc_userid'] );
break;
case 'wordpress' :
$comment_meta['hc_post_as'] = 'wordpress';
$comment_meta['hc_avatar'] = stripslashes( $_POST['hc_avatar'] );
$comment_meta['hc_foreign_user_id'] = stripslashes( $_POST['hc_userid'] );
$comment_meta['hc_wpcom_id_sig'] = stripslashes( $_POST['hc_wpcom_id_sig'] ); //since 1.9
break;
case 'jetpack' :
$comment_meta['hc_post_as'] = 'jetpack';
$comment_meta['hc_avatar'] = stripslashes( $_POST['hc_avatar'] );
$comment_meta['hc_foreign_user_id'] = stripslashes( $_POST['hc_userid'] );
break;
}
// Bail if no extra comment meta
if ( empty( $comment_meta ) ) {
return;
}
// Loop through extra meta and add values
foreach ( $comment_meta as $key => $value ) {
add_comment_meta( $comment_id, $key, $value, true );
}
}
function capture_comment_post_redirect_to_reload_parent_frame( $url ) {
if ( ! isset( $_GET['for'] ) || 'jetpack' != $_GET['for'] ) {
return $url;
}
?>
<!DOCTYPE html>
<html <?php language_attributes(); ?>>
<!--<![endif]-->
<head>
<meta charset="<?php bloginfo( 'charset' ); ?>" />
<title><?php printf( __( 'Submitting Comment%s', 'jetpack' ), '&hellip;' ); ?></title>
<style type="text/css">
body {
display: table;
width: 100%;
height: 60%;
position: absolute;
top: 0;
left: 0;
overflow: hidden;
color: #333;
}
h1 {
text-align: center;
margin: 0;
padding: 0;
display: table-cell;
vertical-align: middle;
font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", sans-serif;
font-weight: normal;
}
.hidden {
opacity: 0;
}
h1 span {
-moz-transition-property: opacity;
-moz-transition-duration: 1s;
-moz-transition-timing-function: ease-in-out;
-webkit-transition-property: opacity;
-webkit-transition-duration: 1s;
-webbit-transition-timing-function: ease-in-out;
-o-transition-property: opacity;
-o-transition-duration: 1s;
-o-transition-timing-function: ease-in-out;
-ms-transition-property: opacity;
-ms-transition-duration: 1s;
-ms-transition-timing-function: ease-in-out;
transition-property: opacity;
transition-duration: 1s;
transition-timing-function: ease-in-out;
}
</style>
</head>
<body>
<h1><?php printf( __( 'Submitting Comment%s', 'jetpack' ), '<span id="ellipsis" class="hidden">&hellip;</span>' ); ?></h1>
<script type="text/javascript">
try {
window.parent.location = <?php echo json_encode( $url ); ?>;
window.parent.location.reload(true);
} catch (e) {
window.location = <?php echo json_encode( $url ); ?>;
window.location.reload(true);
}
ellipsis = document.getElementById('ellipsis');
function toggleEllipsis() {
ellipsis.className = ellipsis.className ? '' : 'hidden';
}
setInterval(toggleEllipsis, 1200);
</script>
</body>
</html>
<?php
exit;
}
}
Jetpack_Comments::init();

View File

@@ -0,0 +1,30 @@
<?php
/**
* Module Name: Contact Form
* Module Description: Insert a customizable contact form anywhere on your site.
* Jumpstart Description: Adds a button to your post and page editors, allowing you to build simple forms to help visitors stay in touch.
* Sort Order: 15
* Recommendation Order: 14
* First Introduced: 1.3
* Requires Connection: No
* Auto Activate: Yes
* Module Tags: Other
* Feature: Writing, Jumpstart
* Additional Search Queries: contact, form, grunion, feedback, submission
*/
include dirname( __FILE__ ) . '/contact-form/grunion-contact-form.php';
/*
* Filters if the new Contact Form Editor View should be used.
*
* A temporary filter to disable the new Editor View for the older UI.
* Please note this filter and the old UI will be removed in the future.
* Expected to be removed in Jetpack 5.8 or if a security issue merits removing the old code sooner.
*
* @since 5.2.0
*
* @param boolean $view Use new Editor View. Default true.
*/
if ( is_admin() && apply_filters( 'tmp_grunion_allow_editor_view', true ) ) {
require_once dirname( __FILE__ ) . '/contact-form/grunion-editor-view.php';
}

View File

@@ -0,0 +1,885 @@
<?php
/**
* Add a contact form button to the post composition screen
*/
add_action( 'media_buttons', 'grunion_media_button', 999 );
function grunion_media_button( ) {
global $post_ID, $temp_ID, $pagenow;
if ( 'press-this.php' === $pagenow ) {
return;
}
$iframe_post_id = (int) (0 == $post_ID ? $temp_ID : $post_ID);
$title = __( 'Add Contact Form', 'jetpack' );
$plugin_url = esc_url( GRUNION_PLUGIN_URL );
$site_url = esc_url( admin_url( "/admin-ajax.php?post_id={$iframe_post_id}&action=grunion_form_builder&TB_iframe=true&width=768" ) );
?>
<a id="insert-jetpack-contact-form" class="button thickbox" title="<?php echo esc_attr( $title ); ?>" data-editor="content" href="<?php echo $site_url ?>&id=add_form">
<span class="jetpack-contact-form-icon"></span> <?php echo esc_html( $title ); ?>
</a>
<?php
}
add_action( 'wp_ajax_grunion_form_builder', 'grunion_display_form_view' );
function grunion_display_form_view() {
if ( current_user_can( 'edit_posts' ) ) {
require_once GRUNION_PLUGIN_DIR . 'grunion-form-view.php';
}
exit;
}
// feedback specific css items
add_action( 'admin_print_styles', 'grunion_admin_css' );
function grunion_admin_css() {
global $current_screen;
if ( is_null( $current_screen ) ) {
return;
}
if ( 'edit-feedback' !== $current_screen->id ) {
return;
}
wp_enqueue_script( 'wp-lists' );
?>
<style type='text/css'>
.add-new-h2, .view-switch, body.no-js .tablenav select[name^=action], body.no-js #doaction, body.no-js #doaction2 {
display: none
}
.column-feedback_from img {
float:left;
margin-right:10px;
margin-top:3px;
}
.widefat .column-feedback_from {
width: 17%;
}
.widefat .column-feedback_date {
width: 17%;
}
.spam a {
color: #BC0B0B;
}
.untrash a {
color: #D98500;
}
.unspam a {
color: #D98500;
}
</style>
<?php
}
/**
* Hack a 'Bulk Spam' option for bulk edit in other than spam view
* Hack a 'Bulk Delete' option for bulk edit in spam view
*
* There isn't a better way to do this until
* http://core.trac.wordpress.org/changeset/17297 is resolved
*/
add_action( 'admin_head', 'grunion_add_bulk_edit_option' );
function grunion_add_bulk_edit_option() {
$screen = get_current_screen();
if ( is_null( $screen ) ) {
return;
}
if ( 'edit-feedback' != $screen->id ) {
return;
}
// When viewing spam we want to be able to be able to bulk delete
// When viewing anything we want to be able to bulk move to spam
if ( isset( $_GET['post_status'] ) && 'spam' == $_GET['post_status'] ) {
// Create Delete Permanently bulk item
$option_val = 'delete';
$option_txt = __( 'Delete Permanently', 'jetpack' );
$pseudo_selector = 'last-child';
} else {
// Create Mark Spam bulk item
$option_val = 'spam';
$option_txt = __( 'Mark as Spam', 'jetpack' );
$pseudo_selector = 'first-child';
}
?>
<script type="text/javascript">
jQuery(document).ready(function($) {
$('#posts-filter .actions select').filter('[name=action], [name=action2]').find('option:<?php echo $pseudo_selector; ?>').after('<option value="<?php echo $option_val; ?>"><?php echo esc_attr( $option_txt ); ?></option>' );
})
</script>
<?php
}
/**
* Hack an 'Empty Spam' button to spam view
*
* Leverages core's delete_all functionality
*/
add_action( 'admin_head', 'grunion_add_empty_spam_button' );
function grunion_add_empty_spam_button() {
$screen = get_current_screen();
if ( is_null( $screen ) ) {
return;
}
// Only add to feedback, only to spam view
if ( 'edit-feedback' != $screen->id
|| empty( $_GET['post_status'] )
|| 'spam' !== $_GET['post_status'] ) {
return;
}
// Get HTML for the button
$button_html = wp_nonce_field( 'bulk-destroy', '_destroy_nonce', true, false );
$button_html .= get_submit_button( __( 'Empty Spam', 'jetpack' ), 'apply', 'delete_all', false );
// Add the button next to the filter button via js
?>
<script type="text/javascript">
jQuery(document).ready(function($) {
$('#posts-filter #post-query-submit').after('<?php echo $button_html; ?>' );
})
</script>
<?php
}
/**
* Handle a bulk spam report
*/
add_action( 'admin_init', 'grunion_handle_bulk_spam' );
function grunion_handle_bulk_spam() {
global $pagenow;
if ( 'edit.php' != $pagenow
|| ( empty( $_REQUEST['post_type'] ) || 'feedback' != $_REQUEST['post_type'] ) )
return;
// Slip in a success message
if ( ! empty( $_REQUEST['message'] ) && 'marked-spam' == $_REQUEST['message'] )
add_action( 'admin_notices', 'grunion_message_bulk_spam' );
if ( ( empty( $_REQUEST['action'] ) || 'spam' != $_REQUEST['action'] ) && ( empty( $_REQUEST['action2'] ) || 'spam' != $_REQUEST['action2'] ) ) {
return;
}
check_admin_referer('bulk-posts');
if ( empty( $_REQUEST['post'] ) ) {
wp_safe_redirect( wp_get_referer() );
exit;
}
$post_ids = array_map( 'intval', $_REQUEST['post'] );
foreach( $post_ids as $post_id ) {
if ( ! current_user_can( "edit_page", $post_id ) ) {
wp_die( __( 'You are not allowed to manage this item.', 'jetpack' ) );
}
$post = array(
'ID' => $post_id,
'post_status' => 'spam',
);
$akismet_values = get_post_meta( $post_id, '_feedback_akismet_values', true );
wp_update_post( $post );
/**
* Fires after a comment has been marked by Akismet.
*
* Typically this means the comment is spam.
*
* @module contact-form
*
* @since 2.2.0
*
* @param string $comment_status Usually is 'spam', otherwise 'ham'.
* @param array $akismet_values From '_feedback_akismet_values' in comment meta
*/
do_action( 'contact_form_akismet', 'spam', $akismet_values );
}
$redirect_url = add_query_arg( 'message', 'marked-spam', wp_get_referer() );
wp_safe_redirect( $redirect_url );
exit;
}
function grunion_message_bulk_spam() {
echo '<div class="updated"><p>' . __( 'Feedback(s) marked as spam', 'jetpack' ) . '</p></div>';
}
// remove admin UI parts that we don't support in feedback management
add_action( 'admin_menu', 'grunion_admin_menu' );
function grunion_admin_menu() {
global $menu, $submenu;
unset( $submenu['edit.php?post_type=feedback'] );
}
add_filter( 'bulk_actions-edit-feedback', 'grunion_admin_bulk_actions' );
function grunion_admin_bulk_actions( $actions ) {
global $current_screen;
if ( 'edit-feedback' != $current_screen->id )
return $actions;
unset( $actions['edit'] );
return $actions;
}
add_filter( 'views_edit-feedback', 'grunion_admin_view_tabs' );
function grunion_admin_view_tabs( $views ) {
global $current_screen;
if ( 'edit-feedback' != $current_screen->id )
return $views;
unset( $views['publish'] );
preg_match( '|post_type=feedback\'( class="current")?\>(.*)\<span class=|', $views['all'], $match );
if ( !empty( $match[2] ) )
$views['all'] = str_replace( $match[2], __( 'Messages', 'jetpack' ) . ' ', $views['all'] );
return $views;
}
add_filter( 'manage_feedback_posts_columns', 'grunion_post_type_columns_filter' );
function grunion_post_type_columns_filter( $cols ) {
$cols = array(
'cb' => '<input type="checkbox" />',
'feedback_from' => __( 'From', 'jetpack' ),
'feedback_message' => __( 'Message', 'jetpack' ),
'feedback_date' => __( 'Date', 'jetpack' )
);
return $cols;
}
add_action( 'manage_posts_custom_column', 'grunion_manage_post_columns', 10, 2 );
function grunion_manage_post_columns( $col, $post_id ) {
global $post;
/**
* Only call parse_fields_from_content if we're dealing with a Grunion custom column.
*/
if ( ! in_array( $col, array( 'feedback_date', 'feedback_from', 'feedback_message' ) ) ) {
return;
}
$content_fields = Grunion_Contact_Form_Plugin::parse_fields_from_content( $post_id );
switch ( $col ) {
case 'feedback_from':
$author_name = isset( $content_fields['_feedback_author'] ) ? $content_fields['_feedback_author'] : '';
$author_email = isset( $content_fields['_feedback_author_email'] ) ? $content_fields['_feedback_author_email'] : '';
$author_url = isset( $content_fields['_feedback_author_url'] ) ? $content_fields['_feedback_author_url'] : '';
$author_ip = isset( $content_fields['_feedback_ip'] ) ? $content_fields['_feedback_ip'] : '';
$form_url = isset( $post->post_parent ) ? get_permalink( $post->post_parent ) : null;
$author_name_line = '';
if ( !empty( $author_name ) ) {
if ( !empty( $author_email ) )
$author_name_line = get_avatar( $author_email, 32 );
$author_name_line .= sprintf( "<strong>%s</strong><br />", esc_html( $author_name ) );
}
$author_email_line = '';
if ( !empty( $author_email ) ) {
$author_email_line = sprintf( "<a href='%1\$s' target='_blank'>%2\$s</a><br />", esc_url( "mailto:" . $author_email ) , esc_html( $author_email ) );
}
$author_url_line = '';
if ( !empty( $author_url ) ) {
$author_url_line = sprintf( "<a href='%1\$s'>%1\$s</a><br />", esc_url( $author_url ) );
}
echo $author_name_line;
echo $author_email_line;
echo $author_url_line;
echo "<a href='edit.php?post_type=feedback&s=" . urlencode( $author_ip );
echo "&mode=detail'>" . esc_html( $author_ip ) . "</a><br />";
if ( $form_url ) {
echo '<a href="' . esc_url( $form_url ) . '">' . esc_html( $form_url ) . '</a>';
}
break;
case 'feedback_message':
$post_type_object = get_post_type_object( $post->post_type );
if ( isset( $content_fields['_feedback_subject'] ) ) {
echo '<strong>';
echo esc_html( $content_fields['_feedback_subject'] );
echo '</strong>';
echo '<br />';
}
echo sanitize_text_field( get_the_content( '' ) );
echo '<br />';
$extra_fields = get_post_meta( $post_id, '_feedback_extra_fields', TRUE );
if ( !empty( $extra_fields ) ) {
echo '<br /><hr />';
echo '<table cellspacing="0" cellpadding="0" style="">' . "\n";
foreach ( (array) $extra_fields as $k => $v ) {
// Remove prefix from exta fields
echo "<tr><td align='right'><b>". esc_html( preg_replace( '#^\d+_#', '', $k ) ) ."</b></td><td>". sanitize_text_field( $v ) ."</td></tr>\n";
}
echo '</table>';
}
echo '<div class="row-actions">';
if ( $post->post_status == 'trash' ) {
echo '<span class="untrash" id="feedback-restore-' . $post_id;
echo '"><a title="';
echo esc_attr__( 'Restore this item from the Trash', 'jetpack' );
echo '" href="' . wp_nonce_url( admin_url( sprintf( $post_type_object->_edit_link . '&amp;action=untrash', $post->ID ) ), 'untrash-' . $post->post_type . '_' . $post->ID );
echo '">' . __( 'Restore', 'jetpack' ) . '</a></span> | ';
echo "<span class='delete'> <a class='submitdelete' title='";
echo esc_attr( __( 'Delete this item permanently', 'jetpack' ) );
echo "' href='" . get_delete_post_link( $post->ID, '', true );
echo "'>" . __( 'Delete Permanently', 'jetpack' ) . "</a></span>";
?>
<script>
jQuery(document).ready(function($) {
$('#feedback-restore-<?php echo $post_id; ?>').click(function(e) {
e.preventDefault();
$.post(ajaxurl, {
action: 'grunion_ajax_spam',
post_id: '<?php echo $post_id; ?>',
make_it: 'publish',
sub_menu: jQuery('.subsubsub .current').attr('href'),
_ajax_nonce: '<?php echo wp_create_nonce( 'grunion-post-status-' . $post_id ); ?>'
},
function(r) {
$('#post-<?php echo $post_id; ?>')
.css({backgroundColor: '#59C859'})
.fadeOut(350, function() {
$(this).remove();
$('.subsubsub').html(r);
});
}
);
});
});
</script>
<?php
} elseif ( $post->post_status == 'publish' ) {
echo '<span class="spam" id="feedback-spam-' . $post_id;
echo '"><a title="';
echo __( 'Mark this message as spam', 'jetpack' );
echo '" href="' . wp_nonce_url( admin_url( 'admin-ajax.php?post_id=' . $post_id . '&amp;action=spam' ), 'spam-feedback_' . $post_id );
echo '">Spam</a></span>';
echo ' | ';
echo '<span class="delete" id="feedback-trash-' . $post_id;
echo '">';
echo '<a class="submitdelete" title="' . esc_attr__( 'Trash', 'jetpack' );
echo '" href="' . get_delete_post_link( $post_id );
echo '">' . __( 'Trash', 'jetpack' ) . '</a></span>';
?>
<script>
jQuery(document).ready( function($) {
$('#feedback-spam-<?php echo $post_id; ?>').click( function(e) {
e.preventDefault();
$.post( ajaxurl, {
action: 'grunion_ajax_spam',
post_id: '<?php echo $post_id; ?>',
make_it: 'spam',
sub_menu: jQuery('.subsubsub .current').attr('href'),
_ajax_nonce: '<?php echo wp_create_nonce( 'grunion-post-status-' . $post_id ); ?>'
},
function( r ) {
$('#post-<?php echo $post_id; ?>')
.css( {backgroundColor:'#FF7979'} )
.fadeOut(350, function() {
$(this).remove();
$('.subsubsub').html(r);
});
});
});
$('#feedback-trash-<?php echo $post_id; ?>').click(function(e) {
e.preventDefault();
$.post(ajaxurl, {
action: 'grunion_ajax_spam',
post_id: '<?php echo $post_id; ?>',
make_it: 'trash',
sub_menu: jQuery('.subsubsub .current').attr('href'),
_ajax_nonce: '<?php echo wp_create_nonce( 'grunion-post-status-' . $post_id ); ?>'
},
function(r) {
$('#post-<?php echo $post_id; ?>')
.css({backgroundColor: '#FF7979'})
.fadeOut(350, function() {
$(this).remove();
$('.subsubsub').html(r);
});
}
);
});
});
</script>
<?php
} elseif ( $post->post_status == 'spam' ) {
echo '<span class="unspam unapprove" id="feedback-ham-' . $post_id;
echo '"><a title="';
echo __( 'Mark this message as NOT spam', 'jetpack' );
echo '" href="">Not Spam</a></span>';
echo ' | ';
echo "<span class='delete' id='feedback-trash-" . $post_id;
echo "'> <a class='submitdelete' title='";
echo esc_attr( __( 'Delete this item permanently', 'jetpack' ) );
echo "' href='" . get_delete_post_link( $post->ID, '', true );
echo "'>" . __( 'Delete Permanently', 'jetpack' ) . "</a></span>";
?>
<script>
jQuery(document).ready( function($) {
$('#feedback-ham-<?php echo $post_id; ?>').click( function(e) {
e.preventDefault();
$.post( ajaxurl, {
action: 'grunion_ajax_spam',
post_id: '<?php echo $post_id; ?>',
make_it: 'ham',
sub_menu: jQuery('.subsubsub .current').attr('href'),
_ajax_nonce: '<?php echo wp_create_nonce( 'grunion-post-status-' . $post_id ); ?>'
},
function( r ) {
$('#post-<?php echo $post_id; ?>')
.css( {backgroundColor:'#59C859'} )
.fadeOut(350, function() {
$(this).remove();
$('.subsubsub').html(r);
});
});
});
});
</script>
<?php
}
break;
case 'feedback_date':
$date_time_format = _x( '%1$s \a\t %2$s', '{$date_format} \a\t {$time_format}', 'jetpack' );
$date_time_format = sprintf( $date_time_format, get_option( 'date_format' ), get_option( 'time_format' ) );
$time = date_i18n( $date_time_format, get_the_time( 'U' ) );
echo $time;
break;
}
}
function grunion_esc_attr( $attr ) {
$out = esc_attr( $attr );
// we also have to entity-encode square brackets so they don't interfere with the shortcode parser
// FIXME: do this better - just stripping out square brackets for now since they mysteriously keep reappearing
$out = str_replace( '[', '', $out );
$out = str_replace( ']', '', $out );
return $out;
}
function grunion_sort_objects( $a, $b ) {
if ( isset($a['order']) && isset($b['order']) )
return $a['order'] - $b['order'];
return 0;
}
// take an array of field types from the form builder, and construct a shortcode form
// returns both the shortcode form, and HTML markup representing a preview of the form
function grunion_ajax_shortcode() {
check_ajax_referer( 'grunion_shortcode' );
if ( ! current_user_can( 'edit_posts' ) ) {
die( '-1' );
}
$attributes = array();
foreach ( array( 'subject', 'to' ) as $attribute ) {
if ( isset( $_POST[$attribute] ) && strlen( $_POST[$attribute] ) ) {
$attributes[$attribute] = stripslashes( $_POST[$attribute] );
}
}
if ( is_array( $_POST['fields'] ) ) {
$fields = stripslashes_deep( $_POST['fields'] );
usort( $fields, 'grunion_sort_objects' );
$field_shortcodes = array();
foreach ( $fields as $field ) {
$field_attributes = array();
if ( isset( $field['required'] ) && 'true' === $field['required'] ) {
$field_attributes['required'] = 'true';
}
foreach ( array( 'options', 'label', 'type' ) as $attribute ) {
if ( isset( $field[$attribute] ) ) {
$field_attributes[$attribute] = $field[$attribute];
}
}
$field_shortcodes[] = new Grunion_Contact_Form_Field( $field_attributes );
}
}
$grunion = new Grunion_Contact_Form( $attributes, $field_shortcodes );
die( "\n$grunion\n" );
}
// takes a post_id, extracts the contact-form shortcode from that post (if there is one), parses it,
// and constructs a json object representing its contents and attributes
function grunion_ajax_shortcode_to_json() {
global $post, $grunion_form;
check_ajax_referer( 'grunion_shortcode_to_json' );
if ( ! empty( $_POST['post_id'] ) && ! current_user_can( 'edit_post', $_POST['post_id'] ) ) {
die( '-1' );
} elseif ( ! current_user_can( 'edit_posts' ) ) {
die( '-1' );
}
if ( !isset( $_POST['content'] ) || !is_numeric( $_POST['post_id'] ) ) {
die( '-1' );
}
$content = stripslashes( $_POST['content'] );
// doesn't look like a post with a [contact-form] already.
if ( false === has_shortcode( $content, 'contact-form' ) ) {
die( '' );
}
$post = get_post( $_POST['post_id'] );
do_shortcode( $content );
$grunion = Grunion_Contact_Form::$last;
$out = array(
'to' => '',
'subject' => '',
'fields' => array(),
);
foreach ( $grunion->fields as $field ) {
$out['fields'][$field->get_attribute( 'id' )] = $field->attributes;
}
$to = $grunion->get_attribute( 'to' );
$subject = $grunion->get_attribute( 'subject' );
foreach ( array( 'to', 'subject' ) as $attribute ) {
$value = $grunion->get_attribute( $attribute );
if ( isset( $grunion->defaults[$attribute] ) && $value == $grunion->defaults[$attribute] ) {
$value = '';
}
$out[$attribute] = $value;
}
die( json_encode( $out ) );
}
add_action( 'wp_ajax_grunion_shortcode', 'grunion_ajax_shortcode' );
add_action( 'wp_ajax_grunion_shortcode_to_json', 'grunion_ajax_shortcode_to_json' );
// process row-action spam/not spam clicks
add_action( 'wp_ajax_grunion_ajax_spam', 'grunion_ajax_spam' );
function grunion_ajax_spam() {
global $wpdb;
if ( empty( $_POST['make_it'] ) ) {
return;
}
$post_id = (int) $_POST['post_id'];
check_ajax_referer( 'grunion-post-status-' . $post_id );
if ( ! current_user_can( "edit_page", $post_id ) ) {
wp_die( __( 'You are not allowed to manage this item.', 'jetpack' ) );
}
require_once dirname( __FILE__ ) . '/grunion-contact-form.php';
$current_menu = '';
if ( isset( $_POST['sub_menu'] ) && preg_match( '|post_type=feedback|', $_POST['sub_menu'] ) ) {
if ( preg_match( '|post_status=spam|', $_POST['sub_menu'] ) ) {
$current_menu = 'spam';
}
elseif ( preg_match( '|post_status=trash|', $_POST['sub_menu'] ) ) {
$current_menu = 'trash';
}
else {
$current_menu = 'messages';
}
}
$post = get_post( $post_id );
$post_type_object = get_post_type_object( $post->post_type );
$akismet_values = get_post_meta( $post_id, '_feedback_akismet_values', TRUE );
if ( $_POST['make_it'] == 'spam' ) {
$post->post_status = 'spam';
$status = wp_insert_post( $post );
wp_transition_post_status( 'spam', 'publish', $post );
/** This action is already documented in modules/contact-form/admin.php */
do_action( 'contact_form_akismet', 'spam', $akismet_values );
} elseif ( $_POST['make_it'] == 'ham' ) {
$post->post_status = 'publish';
$status = wp_insert_post( $post );
wp_transition_post_status( 'publish', 'spam', $post );
/** This action is already documented in modules/contact-form/admin.php */
do_action( 'contact_form_akismet', 'ham', $akismet_values );
$comment_author_email = $reply_to_addr = $message = $to = $headers = false;
$blog_url = parse_url( site_url() );
// resend the original email
$email = get_post_meta( $post_id, '_feedback_email', TRUE );
$content_fields = Grunion_Contact_Form_Plugin::parse_fields_from_content( $post_id );
if ( ! empty( $email ) && !empty( $content_fields ) ) {
if ( isset( $content_fields['_feedback_author_email'] ) ) {
$comment_author_email = $content_fields['_feedback_author_email'];
}
if ( isset( $email['to'] ) ) {
$to = $email['to'];
}
if ( isset( $email['message'] ) ) {
$message = $email['message'];
}
if ( isset( $email['headers'] ) ) {
$headers = $email['headers'];
}
else {
$headers = 'From: "' . $content_fields['_feedback_author'] .'" <wordpress@' . $blog_url['host'] . ">\r\n";
if ( ! empty( $comment_author_email ) ){
$reply_to_addr = $comment_author_email;
}
elseif ( is_array( $to ) ) {
$reply_to_addr = $to[0];
}
if ( $reply_to_addr ) {
$headers .= 'Reply-To: "' . $content_fields['_feedback_author'] .'" <' . $reply_to_addr . ">\r\n";
}
$headers .= "Content-Type: text/plain; charset=\"" . get_option('blog_charset') . "\"";
}
/**
* Filters the subject of the email sent after a contact form submission.
*
* @module contact-form
*
* @since 3.0.0
*
* @param string $content_fields['_feedback_subject'] Feedback's subject line.
* @param array $content_fields['_feedback_all_fields'] Feedback's data from old fields.
*/
$subject = apply_filters( 'contact_form_subject', $content_fields['_feedback_subject'], $content_fields['_feedback_all_fields'] );
Grunion_Contact_Form::wp_mail( $to, $subject, $message, $headers );
}
} elseif( $_POST['make_it'] == 'publish' ) {
if ( ! current_user_can($post_type_object->cap->delete_post, $post_id) ) {
wp_die( __( 'You are not allowed to move this item out of the Trash.', 'jetpack' ) );
}
if ( ! wp_untrash_post($post_id) ) {
wp_die( __( 'Error in restoring from Trash.', 'jetpack' ) );
}
} elseif( $_POST['make_it'] == 'trash' ) {
if ( ! current_user_can($post_type_object->cap->delete_post, $post_id) ) {
wp_die( __( 'You are not allowed to move this item to the Trash.', 'jetpack' ) );
}
if ( ! wp_trash_post($post_id) ) {
wp_die( __( 'Error in moving to Trash.', 'jetpack' ) );
}
}
$sql = "
SELECT post_status,
COUNT( * ) AS post_count
FROM `{$wpdb->posts}`
WHERE post_type = 'feedback'
GROUP BY post_status
";
$status_count = (array) $wpdb->get_results( $sql, ARRAY_A );
$status = array();
$status_html = '';
foreach ( $status_count as $i => $row ) {
$status[$row['post_status']] = $row['post_count'];
}
if ( isset( $status['publish'] ) ) {
$status_html .= '<li><a href="edit.php?post_type=feedback"';
if ( $current_menu == 'messages' ) {
$status_html .= ' class="current"';
}
$status_html .= '>' . __( 'Messages', 'jetpack' ) . ' <span class="count">';
$status_html .= '(' . number_format( $status['publish'] ) . ')';
$status_html .= '</span></a> |</li>';
}
if ( isset( $status['trash'] ) ) {
$status_html .= '<li><a href="edit.php?post_status=trash&amp;post_type=feedback"';
if ( $current_menu == 'trash' )
$status_html .= ' class="current"';
$status_html .= '>' . __( 'Trash', 'jetpack' ) . ' <span class="count">';
$status_html .= '(' . number_format( $status['trash'] ) . ')';
$status_html .= '</span></a>';
if ( isset( $status['spam'] ) )
$status_html .= ' |';
$status_html .= '</li>';
}
if ( isset( $status['spam'] ) ) {
$status_html .= '<li><a href="edit.php?post_status=spam&amp;post_type=feedback"';
if ( $current_menu == 'spam' )
$status_html .= ' class="current"';
$status_html .= '>' . __( 'Spam', 'jetpack' ) . ' <span class="count">';
$status_html .= '(' . number_format( $status['spam'] ) . ')';
$status_html .= '</span></a></li>';
}
echo $status_html;
exit;
}
/**
* Add the scripts that will add the "Check for Spam" button to the Feedbacks dashboard page.
*/
function grunion_enable_spam_recheck() {
if ( ! defined( 'AKISMET_VERSION' ) ) {
return;
}
$screen = get_current_screen();
// Only add to feedback, only to non-spam view
if ( 'edit-feedback' != $screen->id || ( ! empty( $_GET['post_status'] ) && 'spam' == $_GET['post_status'] ) ) {
return;
}
// Add the scripts that handle the spam check event.
wp_register_script(
'grunion-admin',
Jetpack::get_file_url_for_environment(
'_inc/build/contact-form/js/grunion-admin.min.js',
'modules/contact-form/js/grunion-admin.js'
),
array( 'jquery' )
);
wp_enqueue_script( 'grunion-admin' );
wp_enqueue_style( 'grunion.css' );
// Add the actual "Check for Spam" button.
add_action( 'admin_head', 'grunion_check_for_spam_button' );
}
add_action( 'admin_enqueue_scripts', 'grunion_enable_spam_recheck' );
/**
* Add the "Check for Spam" button to the Feedbacks dashboard page.
*/
function grunion_check_for_spam_button() {
// Get HTML for the button
$button_html = get_submit_button(
__( 'Check for Spam', 'jetpack' ),
'secondary',
'jetpack-check-feedback-spam',
false,
array( 'class' => 'jetpack-check-feedback-spam' )
);
$button_html .= '<span class="jetpack-check-feedback-spam-spinner"></span>';
// Add the button next to the filter button via js
?>
<script type="text/javascript">
jQuery( function( $ ) {
$( '#posts-filter #post-query-submit' ).after( '<?php echo $button_html; ?>' );
} );
</script>
<?php
}
/**
* Recheck all approved feedbacks for spam.
*/
function grunion_recheck_queue() {
global $wpdb;
$query = 'post_type=feedback&post_status=publish';
if ( isset( $_POST['limit'], $_POST['offset'] ) ) {
$query .= '&posts_per_page=' . intval( $_POST['limit'] ) . '&offset=' . intval( $_POST['offset'] );
}
$approved_feedbacks = get_posts( $query );
foreach ( $approved_feedbacks as $feedback ) {
$meta = get_post_meta( $feedback->ID, '_feedback_akismet_values', true );
/**
* Filter whether the submitted feedback is considered as spam.
*
* @module contact-form
*
* @since 3.4.0
*
* @param bool false Is the submitted feedback spam? Default to false.
* @param array $meta Feedack values returned by the Akismet plugin.
*/
$is_spam = apply_filters( 'jetpack_contact_form_is_spam', false, $meta );
if ( $is_spam ) {
wp_update_post( array( 'ID' => $feedback->ID, 'post_status' => 'spam' ) );
/** This action is already documented in modules/contact-form/admin.php */
do_action( 'contact_form_akismet', 'spam', $meta );
}
}
wp_send_json( array(
'processed' => count( $approved_feedbacks ),
) );
}
add_action( 'wp_ajax_grunion_recheck_queue', 'grunion_recheck_queue' );

View File

@@ -0,0 +1,52 @@
<?php
/*
* Plugin Name: Feedback CPT Permissions over-ride
*/
if ( class_exists( 'WP_REST_Posts_Controller' ) ) {
/**
* Class Grunion_Contact_Form_Endpoint
* Used as 'rest_controller_class' parameter when 'feedback' post type is registered in modules/contact-form/grunion-contact-form.php.
*/
class Grunion_Contact_Form_Endpoint extends WP_REST_Posts_Controller {
/**
* Check whether a given request has proper authorization to view feedback items.
*
* @param WP_REST_Request $request Full details about the request.
* @return WP_Error|boolean
*/
public function get_items_permissions_check( $request ) {
if ( ! is_user_member_of_blog( get_current_user_id(), get_current_blog_id() ) ) {
return new WP_Error(
'rest_cannot_view',
esc_html__( 'Sorry, you cannot view this resource.', 'jetpack' ),
array( 'status' => 401 )
);
}
return true;
}
/**
* Check whether a given request has proper authorization to view feedback item.
*
* @param WP_REST_Request $request Full details about the request.
* @return WP_Error|boolean
*/
public function get_item_permissions_check( $request ) {
if ( ! is_user_member_of_blog( get_current_user_id(), get_current_blog_id() ) ) {
return new WP_Error(
'rest_cannot_view',
esc_html__( 'Sorry, you cannot view this resource.', 'jetpack' ),
array( 'status' => 401 )
);
}
return true;
}
}
}

View File

@@ -0,0 +1,809 @@
/* Do not modify this file directly. It is concatenated from individual module CSS files. */
/* ==========================================================================
** Normalize
** ======================================================================== */
html {
direction: rtl;
}
body {
font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;
font-size: 16px;
line-height: 1.4em;
margin: 0;
}
/* Links */
a,
a:visited {
color: #0087be;
text-decoration: none;
}
a:hover,
a:focus,
a:active {
color: $link-highlight;
}
/* ==========================================================================
** Card
** ======================================================================= */
.card,
body {
display: block;
position: relative;
margin: 0 auto 10px auto;
padding: 16px;
box-sizing: border-box;
background: white;
box-shadow: 0 0 0 1px rgba(200, 215, 225, 0.5), 0 1px 2px #e9eff3;
}
body {
margin: 0;
background: #f5f5f5;
}
.card:after {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
.card:hover,
.card:focus {
box-shadow: 0 0 0 1px #999, 0 1px 2px #e9eff3;
}
.card .delete-field {
display: block;
float: left;
}
@media ( min-width: 481px ) {
.card {
margin-bottom: 16px;
padding: 24px;
}
body {
padding: 24px;
}
}
.card.is-compact {
margin-bottom: 1px;
}
@media ( min-width: 481px ) {
.card.is-compact {
margin-bottom: 1px;
padding: 16px 24px;
}
}
.card > div {
margin-top: 24px;
}
.card > div:first-child {
margin-top: 0;
}
/* ==========================================================================
** Labels
** ======================================================================= */
label {
display: block;
font-size: 14px;
font-weight: 600;
margin-bottom: 5px;
margin-top: 8px;
}
label:first-of-type {
margin-top: 4px;
}
/* ==========================================================================
** Text Inputs
** ======================================================================= */
input[type="text"],
input[type="tel"],
input[type="email"],
input[type="url"] {
border-radius: 0;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
box-sizing: border-box;
margin: 0;
padding: 7px 14px;
width: 100%;
color: #2e4453;
font-size: 16px;
line-height: 1.5;
border: 1px solid #c8d7e1;
background-color: #fff;
transition: all .15s ease-in-out;
box-shadow: none;
}
input[type="text"]:-ms-input-placeholder,
input[type="tel"]:-ms-input-placeholder,
input[type="email"]:-ms-input-placeholder,
input[type="url"]:-ms-input-placeholder {
color: #87a6bc;
}
input[type="text"]::placeholder,
input[type="tel"]::placeholder,
input[type="email"]::placeholder,
input[type="url"]::placeholder {
color: #87a6bc;
}
input[type="text"]:hover,
input[type="tel"]:hover,
input[type="email"]:hover,
input[type="url"]:hover {
border-color: #a8bece;
}
input[type="text"]:focus,
input[type="tel"]:focus,
input[type="email"]:focus,
input[type="url"]:focus {
border-color: #0087be;
outline: none;
box-shadow: 0 0 0 2px #78dcfa;
}
input[type="text"]:focus::-ms-clear,
input[type="tel"]:focus::-ms-clear,
input[type="email"]:focus::-ms-clear,
input[type="url"]:focus::-ms-clear {
display: none;
}
input[type="text"]:disabled,
input[type="tel"]:disabled,
input[type="email"]:disabled,
input[type="url"]:disabled {
background: #f3f6f8;
border-color: #e9eff3;
color: #a8bece;
-webkit-text-fill-color: #a8bece;
}
input[type="text"]:disabled:hover,
input[type="tel"]:disabled:hover,
input[type="email"]:disabled:hover,
input[type="url"]:disabled:hover {
cursor: default;
}
input[type="text"]:disabled:-ms-input-placeholder,
input[type="tel"]:disabled:-ms-input-placeholder,
input[type="email"]:disabled:-ms-input-placeholder,
input[type="url"]:disabled:-ms-input-placeholder {
color: #a8bece;
}
input[type="text"]:disabled::placeholder,
input[type="tel"]:disabled::placeholder,
input[type="email"]:disabled::placeholder,
input[type="url"]:disabled::placeholder {
color: #a8bece;
}
/* ==========================================================================
** Textareas
** ======================================================================= */
textarea {
border-radius: 0;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
box-sizing: border-box;
margin: 0;
padding: 7px 14px;
height: 92px;
width: 100%;
color: #2e4453;
font-size: 16px;
line-height: 1.5;
border: 1px solid #c8d7e1;
background-color: #fff;
transition: all .15s ease-in-out;
box-shadow: none;
}
textarea:-ms-input-placeholder {
color: #87a6bc;
}
textarea::placeholder {
color: #87a6bc;
}
textarea:hover {
border-color: #a8bece;
}
textarea:focus {
border-color: #0087be;
outline: none;
box-shadow: 0 0 0 2px #78dcfa;
}
textarea:focus::-ms-clear {
display: none;
}
textarea:disabled {
background: #f3f6f8;
border-color: #e9eff3;
color: #a8bece;
-webkit-text-fill-color: #a8bece;
}
textarea:disabled:hover {
cursor: default;
}
textarea:disabled:-ms-input-placeholder {
color: #a8bece;
}
textarea:disabled::placeholder {
color: #a8bece;
}
/* ==========================================================================
** Checkboxes
** ======================================================================= */
.checkbox,
input[type="checkbox"] {
-webkit-appearance: none;
display: inline-block;
box-sizing: border-box;
margin: 2px 0 0;
padding: 7px 14px;
width: 16px;
height: 16px;
float: right;
outline: 0;
padding: 0;
box-shadow: none;
background-color: #fff;
border: 1px solid #c8d7e1;
color: #2e4453;
font-size: 16px;
line-height: 0;
text-align: center;
vertical-align: middle;
-moz-appearance: none;
appearance: none;
transition: all .15s ease-in-out;
clear: none;
cursor: pointer;
}
.checkbox:checked:before,
input[type="checkbox"]:checked:before {
content: '\f147';
font-family: Dashicons;
margin: -3px -4px 0 0;
float: right;
display: inline-block;
vertical-align: middle;
width: 16px;
font-size: 20px;
line-height: 1;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
speak: none;
color: #00aadc;
}
.checkbox:disabled:checked:before,
input[type="checkbox"]:disabled:checked:before {
color: #a8bece;
}
.checkbox:hover,
input[type="checkbox"]:hover {
border-color: #a8bece;
}
.checkbox:focus,
input[type="checkbox"]:focus {
border-color: #0087be;
outline: none;
box-shadow: 0 0 0 2px #78dcfa;
}
.checkbox:disabled,
input[type="checkbox"]:disabled {
background: #f3f6f8;
border-color: #e9eff3;
color: #a8bece;
opacity: 1;
}
.checkbox:disabled:hover,
input[type="checkbox"]:disabled:hover {
cursor: default;
}
.checkbox + span,
input[type="checkbox"] + span {
display: block;
font-weight: normal;
margin-right: 24px;
}
/* ==========================================================================
** Radio buttons
** ======================================================================== */
.radio-button,
input[type=radio] {
color: #2e4453;
font-size: 16px;
border: 1px solid #c8d7e1;
background-color: #fff;
transition: all .15s ease-in-out;
box-sizing: border-box;
-webkit-appearance: none;
clear: none;
cursor: pointer;
display: inline-block;
line-height: 0;
height: 16px;
margin: 2px 0 0 4px;
float: right;
outline: 0;
padding: 0;
text-align: center;
vertical-align: middle;
width: 16px;
min-width: 16px;
-moz-appearance: none;
appearance: none;
border-radius: 50%;
line-height: 10px;
}
.radio-button:hover,
input[type="radio"]:hover {
border-color: #a8bece;
}
.radio-button:focus,
input[type="radio"]:focus {
border-color: #0087be;
outline: none;
box-shadow: 0 0 0 2px #78dcfa;
}
.radio-button:focus::-ms-clear,
input[type="radio"]:focus::-ms-clear {
display: none;
}
.radio-button:checked:before,
input[type="radio"]:checked:before {
float: right;
display: inline-block;
content: '\2022';
margin: 3px;
width: 8px;
height: 8px;
text-indent: -9999px;
background: #00aadc;
vertical-align: middle;
border-radius: 50%;
animation: grow .2s ease-in-out;
}
.radio-button:disabled,
input[type="radio"]:disabled {
background: #f3f6f8;
border-color: #e9eff3;
color: #a8bece;
opacity: 1;
-webkit-text-fill-color: #a8bece;
}
.radio-button:disabled:hover,
input[type="radio"]:disabled:hover {
cursor: default;
}
.radio-button:disabled:-ms-input-placeholder,
input[type="radio"]:disabled:-ms-input-placeholder {
color: #a8bece;
}
.radio-button:disabled::placeholder,
input[type="radio"]:disabled::placeholder {
color: #a8bece;
}
.radio-button:disabled:checked::before,
input[type="radio"]:disabled:checked:before {
background: #e9eff3;
}
.radio-button + span,
input[type="radio"] + span {
display: block;
font-weight: normal;
margin-right: 24px;
}
@keyframes grow {
0% {
transform: scale(0.3);
}
60% {
transform: scale(1.15);
}
100% {
transform: scale(1);
}
}
@keyframes grow {
0% {
transform: scale(0.3);
}
60% {
transform: scale(1.15);
}
100% {
transform: scale(1);
}
}
/* ==========================================================================
** Selects
** ======================================================================== */
select {
background: #fff url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PHN2ZyB3aWR0aD0iMjBweCIgaGVpZ2h0PSIyMHB4IiB2aWV3Qm94PSIwIDAgMjAgMjAiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6c2tldGNoPSJodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2gvbnMiPiAgICAgICAgPHRpdGxlPmFycm93LWRvd248L3RpdGxlPiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4gICAgPGRlZnM+PC9kZWZzPiAgICA8ZyBpZD0iUGFnZS0xIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiBza2V0Y2g6dHlwZT0iTVNQYWdlIj4gICAgICAgIDxnIGlkPSJhcnJvdy1kb3duIiBza2V0Y2g6dHlwZT0iTVNBcnRib2FyZEdyb3VwIiBmaWxsPSIjQzhEN0UxIj4gICAgICAgICAgICA8cGF0aCBkPSJNMTUuNSw2IEwxNyw3LjUgTDEwLjI1LDE0LjI1IEwzLjUsNy41IEw1LDYgTDEwLjI1LDExLjI1IEwxNS41LDYgWiIgaWQ9IkRvd24tQXJyb3ciIHNrZXRjaDp0eXBlPSJNU1NoYXBlR3JvdXAiPjwvcGF0aD4gICAgICAgIDwvZz4gICAgPC9nPjwvc3ZnPg==) no-repeat left 10px center;
border-color: #c8d7e1;
border-style: solid;
border-radius: 4px;
border-width: 1px 1px 2px;
color: #2e4453;
cursor: pointer;
display: inline-block;
margin: 0;
outline: 0;
overflow: hidden;
font-size: 14px;
line-height: 21px;
font-weight: 600;
text-overflow: ellipsis;
text-decoration: none;
vertical-align: top;
white-space: nowrap;
box-sizing: border-box;
padding: 7px 14px 9px 32px; // Aligns the text to the 8px baseline grid and adds padding on right to allow for the arrow.
-webkit-appearance: none;
-moz-appearance: none;
-webkit-appearance: none;
appearance: none;
}
select:hover {
background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PHN2ZyB3aWR0aD0iMjBweCIgaGVpZ2h0PSIyMHB4IiB2aWV3Qm94PSIwIDAgMjAgMjAiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6c2tldGNoPSJodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2gvbnMiPiAgICAgICAgPHRpdGxlPmFycm93LWRvd248L3RpdGxlPiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4gICAgPGRlZnM+PC9kZWZzPiAgICA8ZyBpZD0iUGFnZS0xIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiBza2V0Y2g6dHlwZT0iTVNQYWdlIj4gICAgICAgIDxnIGlkPSJhcnJvdy1kb3duIiBza2V0Y2g6dHlwZT0iTVNBcnRib2FyZEdyb3VwIiBmaWxsPSIjYThiZWNlIj4gICAgICAgICAgICA8cGF0aCBkPSJNMTUuNSw2IEwxNyw3LjUgTDEwLjI1LDE0LjI1IEwzLjUsNy41IEw1LDYgTDEwLjI1LDExLjI1IEwxNS41LDYgWiIgaWQ9IkRvd24tQXJyb3ciIHNrZXRjaDp0eXBlPSJNU1NoYXBlR3JvdXAiPjwvcGF0aD4gICAgICAgIDwvZz4gICAgPC9nPjwvc3ZnPg==);
}
select:focus {
background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PHN2ZyB3aWR0aD0iMjBweCIgaGVpZ2h0PSIyMHB4IiB2aWV3Qm94PSIwIDAgMjAgMjAiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6c2tldGNoPSJodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2gvbnMiPiA8dGl0bGU+YXJyb3ctZG93bjwvdGl0bGU+IDxkZXNjPkNyZWF0ZWQgd2l0aCBTa2V0Y2guPC9kZXNjPiA8ZGVmcz48L2RlZnM+IDxnIGlkPSJQYWdlLTEiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHNrZXRjaDp0eXBlPSJNU1BhZ2UiPiA8ZyBpZD0iYXJyb3ctZG93biIgc2tldGNoOnR5cGU9Ik1TQXJ0Ym9hcmRHcm91cCIgZmlsbD0iIzJlNDQ1MyI+IDxwYXRoIGQ9Ik0xNS41LDYgTDE3LDcuNSBMMTAuMjUsMTQuMjUgTDMuNSw3LjUgTDUsNiBMMTAuMjUsMTEuMjUgTDE1LjUsNiBaIiBpZD0iRG93bi1BcnJvdyIgc2tldGNoOnR5cGU9Ik1TU2hhcGVHcm91cCI+PC9wYXRoPiA8L2c+IDwvZz48L3N2Zz4=);
border-color: #00aadc;
box-shadow: 0 0 0 2px #78dcfa;
outline: 0;
-moz-outline:none;
-moz-user-focus:ignore;
}
select:disabled,
select:hover:disabled {
background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PHN2ZyB3aWR0aD0iMjBweCIgaGVpZ2h0PSIyMHB4IiB2aWV3Qm94PSIwIDAgMjAgMjAiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6c2tldGNoPSJodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2gvbnMiPiAgICAgICAgPHRpdGxlPmFycm93LWRvd248L3RpdGxlPiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4gICAgPGRlZnM+PC9kZWZzPiAgICA8ZyBpZD0iUGFnZS0xIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiBza2V0Y2g6dHlwZT0iTVNQYWdlIj4gICAgICAgIDxnIGlkPSJhcnJvdy1kb3duIiBza2V0Y2g6dHlwZT0iTVNBcnRib2FyZEdyb3VwIiBmaWxsPSIjZTllZmYzIj4gICAgICAgICAgICA8cGF0aCBkPSJNMTUuNSw2IEwxNyw3LjUgTDEwLjI1LDE0LjI1IEwzLjUsNy41IEw1LDYgTDEwLjI1LDExLjI1IEwxNS41LDYgWiIgaWQ9IkRvd24tQXJyb3ciIHNrZXRjaDp0eXBlPSJNU1NoYXBlR3JvdXAiPjwvcGF0aD4gICAgICAgIDwvZz4gICAgPC9nPjwvc3ZnPg==) no-repeat left 10px center;;
}
select.is-compact {
min-width: 0;
padding: 0 6px 2px 20px;
margin: 0 4px;
background-position: left 5px center;
background-size: 12px 12px;
}
/* Make it display:block when it follows a label */
label select,
label + select {
display: block;
min-width: 200px;
}
label select.is-compact,
label + select.is-compact {
display: inline-block;
min-width: 0;
}
/* IE: Remove the default arrow */
select::-ms-expand {
display: none;
}
/* IE: Remove default background and color styles on focus */
select::-ms-value {
background: none;
color: #2e4453;
}
/* Firefox: Remove the focus outline, see http://stackoverflow.com/questions/3773430/remove-outline-from-select-box-in-ff/18853002#18853002 */
select:-moz-focusring {
color: transparent;
text-shadow: 0 0 0 #2e4453;
}
/* ==========================================================================
** Buttons
** ======================================================================== */
input[type="submit"] {
padding: 0;
font-size: 14px;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
vertical-align: baseline;
background: white;
border-color: #c8d7e1;
border-style: solid;
border-width: 1px 1px 2px;
color: #2e4453;
cursor: pointer;
display: inline-block;
margin: 24px 0 0;
outline: 0;
overflow: hidden;
font-weight: 500;
text-overflow: ellipsis;
text-decoration: none;
vertical-align: top;
box-sizing: border-box;
font-size: 14px;
line-height: 21px;
border-radius: 4px;
padding: 7px 14px 9px;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
}
input[type="submit"]:hover {
border-color: #a8bece;
color: #2e4453;
}
input[type="submit"]:active {
border-width: 2px 1px 1px;
}
input[type="submit"]:visited {
color: #2e4453;
}
input[type="submit"][disabled],
input[type="submit"]:disabled {
color: #e9eff3;
background: white;
border-color: #e9eff3;
cursor: default;
}
input[type="submit"][disabled]:active,
input[type="submit"]:disabled:active {
border-width: 1px 1px 2px;
}
input[type="submit"]:focus {
border-color: #00aadc;
box-shadow: 0 0 0 2px #78dcfa;
}
input[type="submit"].hidden {
display: none;
}
input[type="submit"] .gridicon {
position: relative;
top: 4px;
margin-top: -2px;
width: 18px;
height: 18px;
}
input[type="submit"].button-primary {
background: #00aadc;
border-color: #008ab3;
color: white;
}
input[type="submit"].button-primary:hover,
input[type="submit"].button-primary:focus {
border-color: #005082;
color: white;
}
input[type="submit"].button-primary[disabled],
input[type="submit"].button-primary:disabled {
background: #bceefd;
border-color: #8cc9e2;
color: white;
}
input[type="submit"].button-primary {
color: white;
}
/* ==========================================================================
** Inline editor styles
** ======================================================================== */
.ui-sortable-handle {
cursor: move;
}
.grunion-section-header {
font-size: 21px;
margin-top: 32px;
font-weight: 600;
}
.grunion-form-settings:hover {
box-shadow: 0 0 0 1px rgba(200, 215, 225, 0.5), 0 1px 2px #e9eff3;
}
.grunion-section-header:first-child {
margin-top: 0;
}
.grunion-type-options {
display: -ms-flexbox;
display: flex;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
}
.grunion-type {
-ms-flex-positive: 0;
flex-grow: 0;
-ms-flex-negative: 0;
flex-shrink: 0;
}
.grunion-type select {
-webkit-appearance: none;
width: 100%;
}
.grunion-required {
padding: 27px 16px 0 0;
-ms-flex-positive: 0;
flex-grow: 0;
-ms-flex-negative: 0;
flex-shrink: 0;
}
.grunion-options {
padding-top: 16px;
}
.grunion-options ol {
list-style: none;
padding: 0;
margin: 8px 0 0;
}
.grunion-options li {
display: -ms-flexbox;
display: flex;
margin-bottom: 16px;
}
.grunion-field-edit .grunion-options {
display: none;
}
.delete-option,
.delete-field {
color: #0087be;
text-decoration: none;
width: 40px;
line-height: 40px;
font-size: 21px;
text-align: center;
font-weight: 600;
}
.delete-field {
position: absolute;
top: 0;
left: 0;
}
.grunion-controls {
display: -ms-flexbox;
display: flex;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
}
.grunion-update-controls {
text-align: left;
-ms-flex-positive: 1;
flex-grow: 1;
}
#add-field {
-ms-flex-positive: 0;
flex-grow: 0;
}
.delete-option:before,
.delete-field:before {
font-family: Dashicons;
/* content: "\f158"; /* This is the bolder X */
content: "\f335"; /* This is the thinner X */
display: inline-block;
speak: none;
}
.grunion-field-edit.grunion-field-checkbox-multiple .grunion-options,
.grunion-field-edit.grunion-field-radio .grunion-options,
.grunion-field-edit.grunion-field-select .grunion-options {
display: block;
}
.screen-reader-text {
position: absolute;
margin: -1px;
padding: 0;
height: 1px;
width: 1px;
overflow: hidden;
clip: rect(0 0 0 0);
border: 0;
word-wrap: normal !important; /* many screen reader and browser combinations announce broken words as they would appear visually */
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,763 @@
/* ==========================================================================
** Normalize
** ======================================================================== */
html {
direction: ltr;
}
body {
font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;
font-size: 16px;
line-height: 1.4em;
margin: 0;
}
/* Links */
a,
a:visited {
color: #0087be;
text-decoration: none;
}
a:hover,
a:focus,
a:active {
color: $link-highlight;
}
/* ==========================================================================
** Card
** ======================================================================= */
.card,
body {
display: block;
position: relative;
margin: 0 auto 10px auto;
padding: 16px;
box-sizing: border-box;
background: white;
box-shadow: 0 0 0 1px rgba(200, 215, 225, 0.5), 0 1px 2px #e9eff3;
}
body {
margin: 0;
background: #f5f5f5;
}
.card:after {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
.card:hover,
.card:focus {
box-shadow: 0 0 0 1px #999, 0 1px 2px #e9eff3;
}
.card .delete-field {
display: block;
float: right;
}
@media ( min-width: 481px ) {
.card {
margin-bottom: 16px;
padding: 24px;
}
body {
padding: 24px;
}
}
.card.is-compact {
margin-bottom: 1px;
}
@media ( min-width: 481px ) {
.card.is-compact {
margin-bottom: 1px;
padding: 16px 24px;
}
}
.card > div {
margin-top: 24px;
}
.card > div:first-child {
margin-top: 0;
}
/* ==========================================================================
** Labels
** ======================================================================= */
label {
display: block;
font-size: 14px;
font-weight: 600;
margin-bottom: 5px;
margin-top: 8px;
}
label:first-of-type {
margin-top: 4px;
}
/* ==========================================================================
** Text Inputs
** ======================================================================= */
input[type="text"],
input[type="tel"],
input[type="email"],
input[type="url"] {
border-radius: 0;
appearance: none;
box-sizing: border-box;
margin: 0;
padding: 7px 14px;
width: 100%;
color: #2e4453;
font-size: 16px;
line-height: 1.5;
border: 1px solid #c8d7e1;
background-color: #fff;
transition: all .15s ease-in-out;
box-shadow: none;
}
input[type="text"]::placeholder,
input[type="tel"]::placeholder,
input[type="email"]::placeholder,
input[type="url"]::placeholder {
color: #87a6bc;
}
input[type="text"]:hover,
input[type="tel"]:hover,
input[type="email"]:hover,
input[type="url"]:hover {
border-color: #a8bece;
}
input[type="text"]:focus,
input[type="tel"]:focus,
input[type="email"]:focus,
input[type="url"]:focus {
border-color: #0087be;
outline: none;
box-shadow: 0 0 0 2px #78dcfa;
}
input[type="text"]:focus::-ms-clear,
input[type="tel"]:focus::-ms-clear,
input[type="email"]:focus::-ms-clear,
input[type="url"]:focus::-ms-clear {
display: none;
}
input[type="text"]:disabled,
input[type="tel"]:disabled,
input[type="email"]:disabled,
input[type="url"]:disabled {
background: #f3f6f8;
border-color: #e9eff3;
color: #a8bece;
-webkit-text-fill-color: #a8bece;
}
input[type="text"]:disabled:hover,
input[type="tel"]:disabled:hover,
input[type="email"]:disabled:hover,
input[type="url"]:disabled:hover {
cursor: default;
}
input[type="text"]:disabled::placeholder,
input[type="tel"]:disabled::placeholder,
input[type="email"]:disabled::placeholder,
input[type="url"]:disabled::placeholder {
color: #a8bece;
}
/* ==========================================================================
** Textareas
** ======================================================================= */
textarea {
border-radius: 0;
appearance: none;
box-sizing: border-box;
margin: 0;
padding: 7px 14px;
height: 92px;
width: 100%;
color: #2e4453;
font-size: 16px;
line-height: 1.5;
border: 1px solid #c8d7e1;
background-color: #fff;
transition: all .15s ease-in-out;
box-shadow: none;
}
textarea::placeholder {
color: #87a6bc;
}
textarea:hover {
border-color: #a8bece;
}
textarea:focus {
border-color: #0087be;
outline: none;
box-shadow: 0 0 0 2px #78dcfa;
}
textarea:focus::-ms-clear {
display: none;
}
textarea:disabled {
background: #f3f6f8;
border-color: #e9eff3;
color: #a8bece;
-webkit-text-fill-color: #a8bece;
}
textarea:disabled:hover {
cursor: default;
}
textarea:disabled::placeholder {
color: #a8bece;
}
/* ==========================================================================
** Checkboxes
** ======================================================================= */
.checkbox,
input[type="checkbox"] {
-webkit-appearance: none;
display: inline-block;
box-sizing: border-box;
margin: 2px 0 0;
padding: 7px 14px;
width: 16px;
height: 16px;
float: left;
outline: 0;
padding: 0;
box-shadow: none;
background-color: #fff;
border: 1px solid #c8d7e1;
color: #2e4453;
font-size: 16px;
line-height: 0;
text-align: center;
vertical-align: middle;
appearance: none;
transition: all .15s ease-in-out;
clear: none;
cursor: pointer;
}
.checkbox:checked:before,
input[type="checkbox"]:checked:before {
content: '\f147';
font-family: Dashicons;
margin: -3px 0 0 -4px;
float: left;
display: inline-block;
vertical-align: middle;
width: 16px;
font-size: 20px;
line-height: 1;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
speak: none;
color: #00aadc;
}
.checkbox:disabled:checked:before,
input[type="checkbox"]:disabled:checked:before {
color: #a8bece;
}
.checkbox:hover,
input[type="checkbox"]:hover {
border-color: #a8bece;
}
.checkbox:focus,
input[type="checkbox"]:focus {
border-color: #0087be;
outline: none;
box-shadow: 0 0 0 2px #78dcfa;
}
.checkbox:disabled,
input[type="checkbox"]:disabled {
background: #f3f6f8;
border-color: #e9eff3;
color: #a8bece;
opacity: 1;
}
.checkbox:disabled:hover,
input[type="checkbox"]:disabled:hover {
cursor: default;
}
.checkbox + span,
input[type="checkbox"] + span {
display: block;
font-weight: normal;
margin-left: 24px;
}
/* ==========================================================================
** Radio buttons
** ======================================================================== */
.radio-button,
input[type=radio] {
color: #2e4453;
font-size: 16px;
border: 1px solid #c8d7e1;
background-color: #fff;
transition: all .15s ease-in-out;
box-sizing: border-box;
-webkit-appearance: none;
clear: none;
cursor: pointer;
display: inline-block;
line-height: 0;
height: 16px;
margin: 2px 4px 0 0;
float: left;
outline: 0;
padding: 0;
text-align: center;
vertical-align: middle;
width: 16px;
min-width: 16px;
appearance: none;
border-radius: 50%;
line-height: 10px;
}
.radio-button:hover,
input[type="radio"]:hover {
border-color: #a8bece;
}
.radio-button:focus,
input[type="radio"]:focus {
border-color: #0087be;
outline: none;
box-shadow: 0 0 0 2px #78dcfa;
}
.radio-button:focus::-ms-clear,
input[type="radio"]:focus::-ms-clear {
display: none;
}
.radio-button:checked:before,
input[type="radio"]:checked:before {
float: left;
display: inline-block;
content: '\2022';
margin: 3px;
width: 8px;
height: 8px;
text-indent: -9999px;
background: #00aadc;
vertical-align: middle;
border-radius: 50%;
animation: grow .2s ease-in-out;
}
.radio-button:disabled,
input[type="radio"]:disabled {
background: #f3f6f8;
border-color: #e9eff3;
color: #a8bece;
opacity: 1;
-webkit-text-fill-color: #a8bece;
}
.radio-button:disabled:hover,
input[type="radio"]:disabled:hover {
cursor: default;
}
.radio-button:disabled::placeholder,
input[type="radio"]:disabled::placeholder {
color: #a8bece;
}
.radio-button:disabled:checked::before,
input[type="radio"]:disabled:checked:before {
background: #e9eff3;
}
.radio-button + span,
input[type="radio"] + span {
display: block;
font-weight: normal;
margin-left: 24px;
}
@keyframes grow {
0% {
transform: scale(0.3);
}
60% {
transform: scale(1.15);
}
100% {
transform: scale(1);
}
}
@keyframes grow {
0% {
transform: scale(0.3);
}
60% {
transform: scale(1.15);
}
100% {
transform: scale(1);
}
}
/* ==========================================================================
** Selects
** ======================================================================== */
select {
background: #fff url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PHN2ZyB3aWR0aD0iMjBweCIgaGVpZ2h0PSIyMHB4IiB2aWV3Qm94PSIwIDAgMjAgMjAiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6c2tldGNoPSJodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2gvbnMiPiAgICAgICAgPHRpdGxlPmFycm93LWRvd248L3RpdGxlPiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4gICAgPGRlZnM+PC9kZWZzPiAgICA8ZyBpZD0iUGFnZS0xIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiBza2V0Y2g6dHlwZT0iTVNQYWdlIj4gICAgICAgIDxnIGlkPSJhcnJvdy1kb3duIiBza2V0Y2g6dHlwZT0iTVNBcnRib2FyZEdyb3VwIiBmaWxsPSIjQzhEN0UxIj4gICAgICAgICAgICA8cGF0aCBkPSJNMTUuNSw2IEwxNyw3LjUgTDEwLjI1LDE0LjI1IEwzLjUsNy41IEw1LDYgTDEwLjI1LDExLjI1IEwxNS41LDYgWiIgaWQ9IkRvd24tQXJyb3ciIHNrZXRjaDp0eXBlPSJNU1NoYXBlR3JvdXAiPjwvcGF0aD4gICAgICAgIDwvZz4gICAgPC9nPjwvc3ZnPg==) no-repeat right 10px center;
border-color: #c8d7e1;
border-style: solid;
border-radius: 4px;
border-width: 1px 1px 2px;
color: #2e4453;
cursor: pointer;
display: inline-block;
margin: 0;
outline: 0;
overflow: hidden;
font-size: 14px;
line-height: 21px;
font-weight: 600;
text-overflow: ellipsis;
text-decoration: none;
vertical-align: top;
white-space: nowrap;
box-sizing: border-box;
padding: 7px 32px 9px 14px; // Aligns the text to the 8px baseline grid and adds padding on right to allow for the arrow.
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
}
select:hover {
background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PHN2ZyB3aWR0aD0iMjBweCIgaGVpZ2h0PSIyMHB4IiB2aWV3Qm94PSIwIDAgMjAgMjAiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6c2tldGNoPSJodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2gvbnMiPiAgICAgICAgPHRpdGxlPmFycm93LWRvd248L3RpdGxlPiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4gICAgPGRlZnM+PC9kZWZzPiAgICA8ZyBpZD0iUGFnZS0xIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiBza2V0Y2g6dHlwZT0iTVNQYWdlIj4gICAgICAgIDxnIGlkPSJhcnJvdy1kb3duIiBza2V0Y2g6dHlwZT0iTVNBcnRib2FyZEdyb3VwIiBmaWxsPSIjYThiZWNlIj4gICAgICAgICAgICA8cGF0aCBkPSJNMTUuNSw2IEwxNyw3LjUgTDEwLjI1LDE0LjI1IEwzLjUsNy41IEw1LDYgTDEwLjI1LDExLjI1IEwxNS41LDYgWiIgaWQ9IkRvd24tQXJyb3ciIHNrZXRjaDp0eXBlPSJNU1NoYXBlR3JvdXAiPjwvcGF0aD4gICAgICAgIDwvZz4gICAgPC9nPjwvc3ZnPg==);
}
select:focus {
background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PHN2ZyB3aWR0aD0iMjBweCIgaGVpZ2h0PSIyMHB4IiB2aWV3Qm94PSIwIDAgMjAgMjAiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6c2tldGNoPSJodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2gvbnMiPiA8dGl0bGU+YXJyb3ctZG93bjwvdGl0bGU+IDxkZXNjPkNyZWF0ZWQgd2l0aCBTa2V0Y2guPC9kZXNjPiA8ZGVmcz48L2RlZnM+IDxnIGlkPSJQYWdlLTEiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHNrZXRjaDp0eXBlPSJNU1BhZ2UiPiA8ZyBpZD0iYXJyb3ctZG93biIgc2tldGNoOnR5cGU9Ik1TQXJ0Ym9hcmRHcm91cCIgZmlsbD0iIzJlNDQ1MyI+IDxwYXRoIGQ9Ik0xNS41LDYgTDE3LDcuNSBMMTAuMjUsMTQuMjUgTDMuNSw3LjUgTDUsNiBMMTAuMjUsMTEuMjUgTDE1LjUsNiBaIiBpZD0iRG93bi1BcnJvdyIgc2tldGNoOnR5cGU9Ik1TU2hhcGVHcm91cCI+PC9wYXRoPiA8L2c+IDwvZz48L3N2Zz4=);
border-color: #00aadc;
box-shadow: 0 0 0 2px #78dcfa;
outline: 0;
-moz-outline:none;
-moz-user-focus:ignore;
}
select:disabled,
select:hover:disabled {
background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PHN2ZyB3aWR0aD0iMjBweCIgaGVpZ2h0PSIyMHB4IiB2aWV3Qm94PSIwIDAgMjAgMjAiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6c2tldGNoPSJodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2gvbnMiPiAgICAgICAgPHRpdGxlPmFycm93LWRvd248L3RpdGxlPiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4gICAgPGRlZnM+PC9kZWZzPiAgICA8ZyBpZD0iUGFnZS0xIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiBza2V0Y2g6dHlwZT0iTVNQYWdlIj4gICAgICAgIDxnIGlkPSJhcnJvdy1kb3duIiBza2V0Y2g6dHlwZT0iTVNBcnRib2FyZEdyb3VwIiBmaWxsPSIjZTllZmYzIj4gICAgICAgICAgICA8cGF0aCBkPSJNMTUuNSw2IEwxNyw3LjUgTDEwLjI1LDE0LjI1IEwzLjUsNy41IEw1LDYgTDEwLjI1LDExLjI1IEwxNS41LDYgWiIgaWQ9IkRvd24tQXJyb3ciIHNrZXRjaDp0eXBlPSJNU1NoYXBlR3JvdXAiPjwvcGF0aD4gICAgICAgIDwvZz4gICAgPC9nPjwvc3ZnPg==) no-repeat right 10px center;;
}
select.is-compact {
min-width: 0;
padding: 0 20px 2px 6px;
margin: 0 4px;
background-position: right 5px center;
background-size: 12px 12px;
}
/* Make it display:block when it follows a label */
label select,
label + select {
display: block;
min-width: 200px;
}
label select.is-compact,
label + select.is-compact {
display: inline-block;
min-width: 0;
}
/* IE: Remove the default arrow */
select::-ms-expand {
display: none;
}
/* IE: Remove default background and color styles on focus */
select::-ms-value {
background: none;
color: #2e4453;
}
/* Firefox: Remove the focus outline, see http://stackoverflow.com/questions/3773430/remove-outline-from-select-box-in-ff/18853002#18853002 */
select:-moz-focusring {
color: transparent;
text-shadow: 0 0 0 #2e4453;
}
/* ==========================================================================
** Buttons
** ======================================================================== */
input[type="submit"] {
padding: 0;
font-size: 14px;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
vertical-align: baseline;
background: white;
border-color: #c8d7e1;
border-style: solid;
border-width: 1px 1px 2px;
color: #2e4453;
cursor: pointer;
display: inline-block;
margin: 24px 0 0;
outline: 0;
overflow: hidden;
font-weight: 500;
text-overflow: ellipsis;
text-decoration: none;
vertical-align: top;
box-sizing: border-box;
font-size: 14px;
line-height: 21px;
border-radius: 4px;
padding: 7px 14px 9px;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
}
input[type="submit"]:hover {
border-color: #a8bece;
color: #2e4453;
}
input[type="submit"]:active {
border-width: 2px 1px 1px;
}
input[type="submit"]:visited {
color: #2e4453;
}
input[type="submit"][disabled],
input[type="submit"]:disabled {
color: #e9eff3;
background: white;
border-color: #e9eff3;
cursor: default;
}
input[type="submit"][disabled]:active,
input[type="submit"]:disabled:active {
border-width: 1px 1px 2px;
}
input[type="submit"]:focus {
border-color: #00aadc;
box-shadow: 0 0 0 2px #78dcfa;
}
input[type="submit"].hidden {
display: none;
}
input[type="submit"] .gridicon {
position: relative;
top: 4px;
margin-top: -2px;
width: 18px;
height: 18px;
}
input[type="submit"].button-primary {
background: #00aadc;
border-color: #008ab3;
color: white;
}
input[type="submit"].button-primary:hover,
input[type="submit"].button-primary:focus {
border-color: #005082;
color: white;
}
input[type="submit"].button-primary[disabled],
input[type="submit"].button-primary:disabled {
background: #bceefd;
border-color: #8cc9e2;
color: white;
}
input[type="submit"].button-primary {
color: white;
}
/* ==========================================================================
** Inline editor styles
** ======================================================================== */
.ui-sortable-handle {
cursor: move;
}
.grunion-section-header {
font-size: 21px;
margin-top: 32px;
font-weight: 600;
}
.grunion-form-settings:hover {
box-shadow: 0 0 0 1px rgba(200, 215, 225, 0.5), 0 1px 2px #e9eff3;
}
.grunion-section-header:first-child {
margin-top: 0;
}
.grunion-type-options {
display: flex;
flex-wrap: wrap;
}
.grunion-type {
flex-grow: 0;
flex-shrink: 0;
}
.grunion-type select {
-webkit-appearance: none;
width: 100%;
}
.grunion-required {
padding: 27px 0 0 16px;
flex-grow: 0;
flex-shrink: 0;
}
.grunion-options {
padding-top: 16px;
}
.grunion-options ol {
list-style: none;
padding: 0;
margin: 8px 0 0;
}
.grunion-options li {
display: flex;
margin-bottom: 16px;
}
.grunion-field-edit .grunion-options {
display: none;
}
.delete-option,
.delete-field {
color: #0087be;
text-decoration: none;
width: 40px;
line-height: 40px;
font-size: 21px;
text-align: center;
font-weight: 600;
}
.delete-field {
position: absolute;
top: 0;
right: 0;
}
.grunion-controls {
display: flex;
flex-wrap: wrap;
}
.grunion-update-controls {
text-align: right;
flex-grow: 1;
}
#add-field {
flex-grow: 0;
}
.delete-option:before,
.delete-field:before {
font-family: Dashicons;
/* content: "\f158"; /* This is the bolder X */
content: "\f335"; /* This is the thinner X */
display: inline-block;
speak: none;
}
.grunion-field-edit.grunion-field-checkbox-multiple .grunion-options,
.grunion-field-edit.grunion-field-radio .grunion-options,
.grunion-field-edit.grunion-field-select .grunion-options {
display: block;
}
.screen-reader-text {
position: absolute;
margin: -1px;
padding: 0;
height: 1px;
width: 1px;
overflow: hidden;
clip: rect(0 0 0 0);
border: 0;
word-wrap: normal !important; /* many screen reader and browser combinations announce broken words as they would appear visually */
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,587 @@
/* Do not modify this file directly. It is concatenated from individual module CSS files. */
/* ==========================================================================
** Normalize
** ======================================================================== */
body,
label {
font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;
font-size: 16px;
line-height: 1.4em;
}
/* ==========================================================================
** Card
** ======================================================================= */
.card {
display: block;
position: relative;
margin: 0 auto;
padding: 16px;
box-sizing: border-box;
background: white;
box-shadow: 0 0 0 1px rgba(200, 215, 225, 0.5), 0 1px 2px #e9eff3;
}
.card:after {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
@media ( min-width: 481px ) {
.card {
padding: 24px;
}
}
.card > div {
margin-top: 24px;
}
.card > div:first-child {
margin-top: 0;
}
/* ==========================================================================
** Labels
** ======================================================================= */
label {
display: block;
font-size: 14px;
font-weight: 600;
margin-bottom: 5px;
}
/* ==========================================================================
** Text Inputs
** ======================================================================= */
input[type="text"],
input[type="tel"],
input[type="email"],
input[type="url"] {
border-radius: 0;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
box-sizing: border-box;
margin: 0;
padding: 7px 14px;
width: 100%;
color: #2e4453;
font-size: 16px;
line-height: 1.5;
border: 1px solid #c8d7e1;
background-color: #fff;
transition: all .15s ease-in-out;
box-shadow: none;
}
input[type="text"]:-ms-input-placeholder,
input[type="tel"]:-ms-input-placeholder,
input[type="email"]:-ms-input-placeholder,
input[type="url"]:-ms-input-placeholder {
color: #87a6bc;
}
input[type="text"]::placeholder,
input[type="tel"]::placeholder,
input[type="email"]::placeholder,
input[type="url"]::placeholder {
color: #87a6bc;
}
input[type="text"]:hover,
input[type="tel"]:hover,
input[type="email"]:hover,
input[type="url"]:hover {
border-color: #a8bece;
}
input[type="text"]:focus,
input[type="tel"]:focus,
input[type="email"]:focus,
input[type="url"]:focus {
border-color: #0087be;
outline: none;
box-shadow: 0 0 0 2px #78dcfa;
}
input[type="text"]:focus::-ms-clear,
input[type="tel"]:focus::-ms-clear,
input[type="email"]:focus::-ms-clear,
input[type="url"]:focus::-ms-clear {
display: none;
}
input[type="text"]:disabled,
input[type="tel"]:disabled,
input[type="email"]:disabled,
input[type="url"]:disabled {
background: #f3f6f8;
border-color: #e9eff3;
color: #a8bece;
-webkit-text-fill-color: #a8bece;
}
input[type="text"]:disabled:hover,
input[type="tel"]:disabled:hover,
input[type="email"]:disabled:hover,
input[type="url"]:disabled:hover {
cursor: default;
}
input[type="text"]:disabled:-ms-input-placeholder,
input[type="tel"]:disabled:-ms-input-placeholder,
input[type="email"]:disabled:-ms-input-placeholder,
input[type="url"]:disabled:-ms-input-placeholder {
color: #a8bece;
}
input[type="text"]:disabled::placeholder,
input[type="tel"]:disabled::placeholder,
input[type="email"]:disabled::placeholder,
input[type="url"]:disabled::placeholder {
color: #a8bece;
}
/* ==========================================================================
** Textareas
** ======================================================================= */
textarea {
border-radius: 0;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
box-sizing: border-box;
margin: 0;
padding: 7px 14px;
height: 92px;
width: 100%;
color: #2e4453;
font-size: 16px;
line-height: 1.5;
border: 1px solid #c8d7e1;
background-color: #fff;
transition: all .15s ease-in-out;
box-shadow: none;
}
textarea:-ms-input-placeholder {
color: #87a6bc;
}
textarea::placeholder {
color: #87a6bc;
}
textarea:hover {
border-color: #a8bece;
}
textarea:focus {
border-color: #0087be;
outline: none;
box-shadow: 0 0 0 2px #78dcfa;
}
textarea:focus::-ms-clear {
display: none;
}
textarea:disabled {
background: #f3f6f8;
border-color: #e9eff3;
color: #a8bece;
-webkit-text-fill-color: #a8bece;
}
textarea:disabled:hover {
cursor: default;
}
textarea:disabled:-ms-input-placeholder {
color: #a8bece;
}
textarea:disabled::placeholder {
color: #a8bece;
}
/* ==========================================================================
** Checkboxes
** ======================================================================= */
input[type="checkbox"] {
-webkit-appearance: none;
display: inline-block;
box-sizing: border-box;
margin: 2px 0 0;
padding: 7px 14px;
width: 16px;
height: 16px;
float: right;
outline: 0;
padding: 0;
box-shadow: none;
background-color: #fff;
border: 1px solid #c8d7e1;
color: #2e4453;
font-size: 16px;
line-height: 0;
text-align: center;
vertical-align: middle;
-moz-appearance: none;
appearance: none;
transition: all .15s ease-in-out;
clear: none;
cursor: pointer;
}
input[type="checkbox"]:checked:before {
content: '\f147';
font-family: Dashicons;
margin: -3px -4px 0 0;
float: right;
display: inline-block;
vertical-align: middle;
width: 16px;
font-size: 20px;
line-height: 1;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
speak: none;
color: #00aadc;
}
input[type="checkbox"]:disabled:checked:before {
color: #a8bece;
}
input[type="checkbox"]:hover {
border-color: #a8bece;
}
input[type="checkbox"]:focus {
border-color: #0087be;
outline: none;
box-shadow: 0 0 0 2px #78dcfa;
}
input[type="checkbox"]:disabled {
background: #f3f6f8;
border-color: #e9eff3;
color: #a8bece;
opacity: 1;
}
input[type="checkbox"]:disabled:hover {
cursor: default;
}
input[type="checkbox"] + span {
display: block;
font-weight: normal;
margin-right: 24px;
}
/* ==========================================================================
** Radio buttons
** ======================================================================== */
input[type=radio] {
color: #2e4453;
font-size: 16px;
border: 1px solid #c8d7e1;
background-color: #fff;
transition: all .15s ease-in-out;
box-sizing: border-box;
-webkit-appearance: none;
clear: none;
cursor: pointer;
display: inline-block;
line-height: 0;
height: 16px;
margin: 2px 0 0 4px;
float: right;
outline: 0;
padding: 0;
text-align: center;
vertical-align: middle;
width: 16px;
min-width: 16px;
-moz-appearance: none;
appearance: none;
border-radius: 50%;
line-height: 10px;
}
input[type="radio"]:hover {
border-color: #a8bece;
}
input[type="radio"]:focus {
border-color: #0087be;
outline: none;
box-shadow: 0 0 0 2px #78dcfa;
}
input[type="radio"]:focus::-ms-clear {
display: none;
}
input[type="radio"]:checked:before {
float: right;
display: inline-block;
content: '\2022';
margin: 3px;
width: 8px;
height: 8px;
text-indent: -9999px;
background: #00aadc;
vertical-align: middle;
border-radius: 50%;
animation: grow .2s ease-in-out;
}
input[type="radio"]:disabled {
background: #f3f6f8;
border-color: #e9eff3;
color: #a8bece;
opacity: 1;
-webkit-text-fill-color: #a8bece;
}
input[type="radio"]:disabled:hover {
cursor: default;
}
input[type="radio"]:disabled:-ms-input-placeholder {
color: #a8bece;
}
input[type="radio"]:disabled::placeholder {
color: #a8bece;
}
input[type="radio"]:disabled:checked:before {
background: #e9eff3;
}
input[type="radio"] + span {
display: block;
font-weight: normal;
margin-right: 24px;
}
@keyframes grow {
0% {
transform: scale(0.3);
}
60% {
transform: scale(1.15);
}
100% {
transform: scale(1);
}
}
@keyframes grow {
0% {
transform: scale(0.3);
}
60% {
transform: scale(1.15);
}
100% {
transform: scale(1);
}
}
/* ==========================================================================
** Selects
** ======================================================================== */
select {
background: #fff url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PHN2ZyB3aWR0aD0iMjBweCIgaGVpZ2h0PSIyMHB4IiB2aWV3Qm94PSIwIDAgMjAgMjAiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6c2tldGNoPSJodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2gvbnMiPiAgICAgICAgPHRpdGxlPmFycm93LWRvd248L3RpdGxlPiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4gICAgPGRlZnM+PC9kZWZzPiAgICA8ZyBpZD0iUGFnZS0xIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiBza2V0Y2g6dHlwZT0iTVNQYWdlIj4gICAgICAgIDxnIGlkPSJhcnJvdy1kb3duIiBza2V0Y2g6dHlwZT0iTVNBcnRib2FyZEdyb3VwIiBmaWxsPSIjQzhEN0UxIj4gICAgICAgICAgICA8cGF0aCBkPSJNMTUuNSw2IEwxNyw3LjUgTDEwLjI1LDE0LjI1IEwzLjUsNy41IEw1LDYgTDEwLjI1LDExLjI1IEwxNS41LDYgWiIgaWQ9IkRvd24tQXJyb3ciIHNrZXRjaDp0eXBlPSJNU1NoYXBlR3JvdXAiPjwvcGF0aD4gICAgICAgIDwvZz4gICAgPC9nPjwvc3ZnPg==) no-repeat left 10px center;
border-color: #c8d7e1;
border-style: solid;
border-radius: 4px;
border-width: 1px 1px 2px;
color: #2e4453;
cursor: pointer;
display: inline-block;
margin: 0;
outline: 0;
overflow: hidden;
font-size: 14px;
line-height: 21px;
font-weight: 600;
text-overflow: ellipsis;
text-decoration: none;
vertical-align: top;
white-space: nowrap;
box-sizing: border-box;
padding: 7px 14px 9px 32px; // Aligns the text to the 8px baseline grid and adds padding on right to allow for the arrow.
-webkit-appearance: none;
-moz-appearance: none;
-webkit-appearance: none;
appearance: none;
}
select:hover {
background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PHN2ZyB3aWR0aD0iMjBweCIgaGVpZ2h0PSIyMHB4IiB2aWV3Qm94PSIwIDAgMjAgMjAiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6c2tldGNoPSJodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2gvbnMiPiAgICAgICAgPHRpdGxlPmFycm93LWRvd248L3RpdGxlPiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4gICAgPGRlZnM+PC9kZWZzPiAgICA8ZyBpZD0iUGFnZS0xIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiBza2V0Y2g6dHlwZT0iTVNQYWdlIj4gICAgICAgIDxnIGlkPSJhcnJvdy1kb3duIiBza2V0Y2g6dHlwZT0iTVNBcnRib2FyZEdyb3VwIiBmaWxsPSIjYThiZWNlIj4gICAgICAgICAgICA8cGF0aCBkPSJNMTUuNSw2IEwxNyw3LjUgTDEwLjI1LDE0LjI1IEwzLjUsNy41IEw1LDYgTDEwLjI1LDExLjI1IEwxNS41LDYgWiIgaWQ9IkRvd24tQXJyb3ciIHNrZXRjaDp0eXBlPSJNU1NoYXBlR3JvdXAiPjwvcGF0aD4gICAgICAgIDwvZz4gICAgPC9nPjwvc3ZnPg==);
}
select:focus {
background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PHN2ZyB3aWR0aD0iMjBweCIgaGVpZ2h0PSIyMHB4IiB2aWV3Qm94PSIwIDAgMjAgMjAiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6c2tldGNoPSJodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2gvbnMiPiA8dGl0bGU+YXJyb3ctZG93bjwvdGl0bGU+IDxkZXNjPkNyZWF0ZWQgd2l0aCBTa2V0Y2guPC9kZXNjPiA8ZGVmcz48L2RlZnM+IDxnIGlkPSJQYWdlLTEiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHNrZXRjaDp0eXBlPSJNU1BhZ2UiPiA8ZyBpZD0iYXJyb3ctZG93biIgc2tldGNoOnR5cGU9Ik1TQXJ0Ym9hcmRHcm91cCIgZmlsbD0iIzJlNDQ1MyI+IDxwYXRoIGQ9Ik0xNS41LDYgTDE3LDcuNSBMMTAuMjUsMTQuMjUgTDMuNSw3LjUgTDUsNiBMMTAuMjUsMTEuMjUgTDE1LjUsNiBaIiBpZD0iRG93bi1BcnJvdyIgc2tldGNoOnR5cGU9Ik1TU2hhcGVHcm91cCI+PC9wYXRoPiA8L2c+IDwvZz48L3N2Zz4=);
border-color: #00aadc;
box-shadow: 0 0 0 2px #78dcfa;
outline: 0;
-moz-outline:none;
-moz-user-focus:ignore;
}
select:disabled,
select:hover:disabled {
background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PHN2ZyB3aWR0aD0iMjBweCIgaGVpZ2h0PSIyMHB4IiB2aWV3Qm94PSIwIDAgMjAgMjAiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6c2tldGNoPSJodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2gvbnMiPiAgICAgICAgPHRpdGxlPmFycm93LWRvd248L3RpdGxlPiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4gICAgPGRlZnM+PC9kZWZzPiAgICA8ZyBpZD0iUGFnZS0xIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiBza2V0Y2g6dHlwZT0iTVNQYWdlIj4gICAgICAgIDxnIGlkPSJhcnJvdy1kb3duIiBza2V0Y2g6dHlwZT0iTVNBcnRib2FyZEdyb3VwIiBmaWxsPSIjZTllZmYzIj4gICAgICAgICAgICA8cGF0aCBkPSJNMTUuNSw2IEwxNyw3LjUgTDEwLjI1LDE0LjI1IEwzLjUsNy41IEw1LDYgTDEwLjI1LDExLjI1IEwxNS41LDYgWiIgaWQ9IkRvd24tQXJyb3ciIHNrZXRjaDp0eXBlPSJNU1NoYXBlR3JvdXAiPjwvcGF0aD4gICAgICAgIDwvZz4gICAgPC9nPjwvc3ZnPg==) no-repeat left 10px center;;
}
select.is-compact {
min-width: 0;
padding: 0 6px 2px 20px;
margin: 0 4px;
background-position: left 5px center;
background-size: 12px 12px;
}
/* Make it display:block when it follows a label */
label select,
label + select {
display: block;
min-width: 200px;
}
label select.is-compact,
label + select.is-compact {
display: inline-block;
min-width: 0;
}
/* IE: Remove the default arrow */
select::-ms-expand {
display: none;
}
/* IE: Remove default background and color styles on focus */
select::-ms-value {
background: none;
color: #2e4453;
}
/* Firefox: Remove the focus outline, see http://stackoverflow.com/questions/3773430/remove-outline-from-select-box-in-ff/18853002#18853002 */
select:-moz-focusring {
color: transparent;
text-shadow: 0 0 0 #2e4453;
}
/* ==========================================================================
** Buttons
** ======================================================================== */
input[type="submit"] {
padding: 0;
font-size: 14px;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
vertical-align: baseline;
background: white;
border-color: #c8d7e1;
border-style: solid;
border-width: 1px 1px 2px;
color: #2e4453;
cursor: pointer;
display: inline-block;
margin: 24px 0 0;
outline: 0;
overflow: hidden;
font-weight: 500;
text-overflow: ellipsis;
text-decoration: none;
vertical-align: top;
box-sizing: border-box;
font-size: 14px;
line-height: 21px;
border-radius: 4px;
padding: 7px 14px 9px;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
}
input[type="submit"]:hover {
border-color: #a8bece;
color: #2e4453;
}
input[type="submit"]:active {
border-width: 2px 1px 1px;
}
input[type="submit"]:visited {
color: #2e4453;
}
input[type="submit"][disabled],
input[type="submit"]:disabled {
color: #e9eff3;
background: white;
border-color: #e9eff3;
cursor: default;
}
input[type="submit"][disabled]:active,
input[type="submit"]:disabled:active {
border-width: 1px 1px 2px;
}
input[type="submit"]:focus {
border-color: #00aadc;
box-shadow: 0 0 0 2px #78dcfa;
}
/* ==========================================================================
** Preview styles
** ======================================================================== */
.wpview.wpview-wrap[data-wpview-type=contact-form] iframe.inline-edit-contact-form {
width: 100%;
min-height: 500px;
border: 0;
overflow: hidden;
margin-bottom: 0;
display: block;
}
.contact-submit.contact-submit {
margin-top: 0;
margin-bottom: 0;
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,553 @@
/* ==========================================================================
** Normalize
** ======================================================================== */
body,
label {
font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;
font-size: 16px;
line-height: 1.4em;
}
/* ==========================================================================
** Card
** ======================================================================= */
.card {
display: block;
position: relative;
margin: 0 auto;
padding: 16px;
box-sizing: border-box;
background: white;
box-shadow: 0 0 0 1px rgba(200, 215, 225, 0.5), 0 1px 2px #e9eff3;
}
.card:after {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
@media ( min-width: 481px ) {
.card {
padding: 24px;
}
}
.card > div {
margin-top: 24px;
}
.card > div:first-child {
margin-top: 0;
}
/* ==========================================================================
** Labels
** ======================================================================= */
label {
display: block;
font-size: 14px;
font-weight: 600;
margin-bottom: 5px;
}
/* ==========================================================================
** Text Inputs
** ======================================================================= */
input[type="text"],
input[type="tel"],
input[type="email"],
input[type="url"] {
border-radius: 0;
appearance: none;
box-sizing: border-box;
margin: 0;
padding: 7px 14px;
width: 100%;
color: #2e4453;
font-size: 16px;
line-height: 1.5;
border: 1px solid #c8d7e1;
background-color: #fff;
transition: all .15s ease-in-out;
box-shadow: none;
}
input[type="text"]::placeholder,
input[type="tel"]::placeholder,
input[type="email"]::placeholder,
input[type="url"]::placeholder {
color: #87a6bc;
}
input[type="text"]:hover,
input[type="tel"]:hover,
input[type="email"]:hover,
input[type="url"]:hover {
border-color: #a8bece;
}
input[type="text"]:focus,
input[type="tel"]:focus,
input[type="email"]:focus,
input[type="url"]:focus {
border-color: #0087be;
outline: none;
box-shadow: 0 0 0 2px #78dcfa;
}
input[type="text"]:focus::-ms-clear,
input[type="tel"]:focus::-ms-clear,
input[type="email"]:focus::-ms-clear,
input[type="url"]:focus::-ms-clear {
display: none;
}
input[type="text"]:disabled,
input[type="tel"]:disabled,
input[type="email"]:disabled,
input[type="url"]:disabled {
background: #f3f6f8;
border-color: #e9eff3;
color: #a8bece;
-webkit-text-fill-color: #a8bece;
}
input[type="text"]:disabled:hover,
input[type="tel"]:disabled:hover,
input[type="email"]:disabled:hover,
input[type="url"]:disabled:hover {
cursor: default;
}
input[type="text"]:disabled::placeholder,
input[type="tel"]:disabled::placeholder,
input[type="email"]:disabled::placeholder,
input[type="url"]:disabled::placeholder {
color: #a8bece;
}
/* ==========================================================================
** Textareas
** ======================================================================= */
textarea {
border-radius: 0;
appearance: none;
box-sizing: border-box;
margin: 0;
padding: 7px 14px;
height: 92px;
width: 100%;
color: #2e4453;
font-size: 16px;
line-height: 1.5;
border: 1px solid #c8d7e1;
background-color: #fff;
transition: all .15s ease-in-out;
box-shadow: none;
}
textarea::placeholder {
color: #87a6bc;
}
textarea:hover {
border-color: #a8bece;
}
textarea:focus {
border-color: #0087be;
outline: none;
box-shadow: 0 0 0 2px #78dcfa;
}
textarea:focus::-ms-clear {
display: none;
}
textarea:disabled {
background: #f3f6f8;
border-color: #e9eff3;
color: #a8bece;
-webkit-text-fill-color: #a8bece;
}
textarea:disabled:hover {
cursor: default;
}
textarea:disabled::placeholder {
color: #a8bece;
}
/* ==========================================================================
** Checkboxes
** ======================================================================= */
input[type="checkbox"] {
-webkit-appearance: none;
display: inline-block;
box-sizing: border-box;
margin: 2px 0 0;
padding: 7px 14px;
width: 16px;
height: 16px;
float: left;
outline: 0;
padding: 0;
box-shadow: none;
background-color: #fff;
border: 1px solid #c8d7e1;
color: #2e4453;
font-size: 16px;
line-height: 0;
text-align: center;
vertical-align: middle;
appearance: none;
transition: all .15s ease-in-out;
clear: none;
cursor: pointer;
}
input[type="checkbox"]:checked:before {
content: '\f147';
font-family: Dashicons;
margin: -3px 0 0 -4px;
float: left;
display: inline-block;
vertical-align: middle;
width: 16px;
font-size: 20px;
line-height: 1;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
speak: none;
color: #00aadc;
}
input[type="checkbox"]:disabled:checked:before {
color: #a8bece;
}
input[type="checkbox"]:hover {
border-color: #a8bece;
}
input[type="checkbox"]:focus {
border-color: #0087be;
outline: none;
box-shadow: 0 0 0 2px #78dcfa;
}
input[type="checkbox"]:disabled {
background: #f3f6f8;
border-color: #e9eff3;
color: #a8bece;
opacity: 1;
}
input[type="checkbox"]:disabled:hover {
cursor: default;
}
input[type="checkbox"] + span {
display: block;
font-weight: normal;
margin-left: 24px;
}
/* ==========================================================================
** Radio buttons
** ======================================================================== */
input[type=radio] {
color: #2e4453;
font-size: 16px;
border: 1px solid #c8d7e1;
background-color: #fff;
transition: all .15s ease-in-out;
box-sizing: border-box;
-webkit-appearance: none;
clear: none;
cursor: pointer;
display: inline-block;
line-height: 0;
height: 16px;
margin: 2px 4px 0 0;
float: left;
outline: 0;
padding: 0;
text-align: center;
vertical-align: middle;
width: 16px;
min-width: 16px;
appearance: none;
border-radius: 50%;
line-height: 10px;
}
input[type="radio"]:hover {
border-color: #a8bece;
}
input[type="radio"]:focus {
border-color: #0087be;
outline: none;
box-shadow: 0 0 0 2px #78dcfa;
}
input[type="radio"]:focus::-ms-clear {
display: none;
}
input[type="radio"]:checked:before {
float: left;
display: inline-block;
content: '\2022';
margin: 3px;
width: 8px;
height: 8px;
text-indent: -9999px;
background: #00aadc;
vertical-align: middle;
border-radius: 50%;
animation: grow .2s ease-in-out;
}
input[type="radio"]:disabled {
background: #f3f6f8;
border-color: #e9eff3;
color: #a8bece;
opacity: 1;
-webkit-text-fill-color: #a8bece;
}
input[type="radio"]:disabled:hover {
cursor: default;
}
input[type="radio"]:disabled::placeholder {
color: #a8bece;
}
input[type="radio"]:disabled:checked:before {
background: #e9eff3;
}
input[type="radio"] + span {
display: block;
font-weight: normal;
margin-left: 24px;
}
@keyframes grow {
0% {
transform: scale(0.3);
}
60% {
transform: scale(1.15);
}
100% {
transform: scale(1);
}
}
@keyframes grow {
0% {
transform: scale(0.3);
}
60% {
transform: scale(1.15);
}
100% {
transform: scale(1);
}
}
/* ==========================================================================
** Selects
** ======================================================================== */
select {
background: #fff url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PHN2ZyB3aWR0aD0iMjBweCIgaGVpZ2h0PSIyMHB4IiB2aWV3Qm94PSIwIDAgMjAgMjAiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6c2tldGNoPSJodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2gvbnMiPiAgICAgICAgPHRpdGxlPmFycm93LWRvd248L3RpdGxlPiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4gICAgPGRlZnM+PC9kZWZzPiAgICA8ZyBpZD0iUGFnZS0xIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiBza2V0Y2g6dHlwZT0iTVNQYWdlIj4gICAgICAgIDxnIGlkPSJhcnJvdy1kb3duIiBza2V0Y2g6dHlwZT0iTVNBcnRib2FyZEdyb3VwIiBmaWxsPSIjQzhEN0UxIj4gICAgICAgICAgICA8cGF0aCBkPSJNMTUuNSw2IEwxNyw3LjUgTDEwLjI1LDE0LjI1IEwzLjUsNy41IEw1LDYgTDEwLjI1LDExLjI1IEwxNS41LDYgWiIgaWQ9IkRvd24tQXJyb3ciIHNrZXRjaDp0eXBlPSJNU1NoYXBlR3JvdXAiPjwvcGF0aD4gICAgICAgIDwvZz4gICAgPC9nPjwvc3ZnPg==) no-repeat right 10px center;
border-color: #c8d7e1;
border-style: solid;
border-radius: 4px;
border-width: 1px 1px 2px;
color: #2e4453;
cursor: pointer;
display: inline-block;
margin: 0;
outline: 0;
overflow: hidden;
font-size: 14px;
line-height: 21px;
font-weight: 600;
text-overflow: ellipsis;
text-decoration: none;
vertical-align: top;
white-space: nowrap;
box-sizing: border-box;
padding: 7px 32px 9px 14px; // Aligns the text to the 8px baseline grid and adds padding on right to allow for the arrow.
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
}
select:hover {
background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PHN2ZyB3aWR0aD0iMjBweCIgaGVpZ2h0PSIyMHB4IiB2aWV3Qm94PSIwIDAgMjAgMjAiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6c2tldGNoPSJodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2gvbnMiPiAgICAgICAgPHRpdGxlPmFycm93LWRvd248L3RpdGxlPiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4gICAgPGRlZnM+PC9kZWZzPiAgICA8ZyBpZD0iUGFnZS0xIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiBza2V0Y2g6dHlwZT0iTVNQYWdlIj4gICAgICAgIDxnIGlkPSJhcnJvdy1kb3duIiBza2V0Y2g6dHlwZT0iTVNBcnRib2FyZEdyb3VwIiBmaWxsPSIjYThiZWNlIj4gICAgICAgICAgICA8cGF0aCBkPSJNMTUuNSw2IEwxNyw3LjUgTDEwLjI1LDE0LjI1IEwzLjUsNy41IEw1LDYgTDEwLjI1LDExLjI1IEwxNS41LDYgWiIgaWQ9IkRvd24tQXJyb3ciIHNrZXRjaDp0eXBlPSJNU1NoYXBlR3JvdXAiPjwvcGF0aD4gICAgICAgIDwvZz4gICAgPC9nPjwvc3ZnPg==);
}
select:focus {
background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PHN2ZyB3aWR0aD0iMjBweCIgaGVpZ2h0PSIyMHB4IiB2aWV3Qm94PSIwIDAgMjAgMjAiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6c2tldGNoPSJodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2gvbnMiPiA8dGl0bGU+YXJyb3ctZG93bjwvdGl0bGU+IDxkZXNjPkNyZWF0ZWQgd2l0aCBTa2V0Y2guPC9kZXNjPiA8ZGVmcz48L2RlZnM+IDxnIGlkPSJQYWdlLTEiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHNrZXRjaDp0eXBlPSJNU1BhZ2UiPiA8ZyBpZD0iYXJyb3ctZG93biIgc2tldGNoOnR5cGU9Ik1TQXJ0Ym9hcmRHcm91cCIgZmlsbD0iIzJlNDQ1MyI+IDxwYXRoIGQ9Ik0xNS41LDYgTDE3LDcuNSBMMTAuMjUsMTQuMjUgTDMuNSw3LjUgTDUsNiBMMTAuMjUsMTEuMjUgTDE1LjUsNiBaIiBpZD0iRG93bi1BcnJvdyIgc2tldGNoOnR5cGU9Ik1TU2hhcGVHcm91cCI+PC9wYXRoPiA8L2c+IDwvZz48L3N2Zz4=);
border-color: #00aadc;
box-shadow: 0 0 0 2px #78dcfa;
outline: 0;
-moz-outline:none;
-moz-user-focus:ignore;
}
select:disabled,
select:hover:disabled {
background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PHN2ZyB3aWR0aD0iMjBweCIgaGVpZ2h0PSIyMHB4IiB2aWV3Qm94PSIwIDAgMjAgMjAiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6c2tldGNoPSJodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2gvbnMiPiAgICAgICAgPHRpdGxlPmFycm93LWRvd248L3RpdGxlPiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4gICAgPGRlZnM+PC9kZWZzPiAgICA8ZyBpZD0iUGFnZS0xIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiBza2V0Y2g6dHlwZT0iTVNQYWdlIj4gICAgICAgIDxnIGlkPSJhcnJvdy1kb3duIiBza2V0Y2g6dHlwZT0iTVNBcnRib2FyZEdyb3VwIiBmaWxsPSIjZTllZmYzIj4gICAgICAgICAgICA8cGF0aCBkPSJNMTUuNSw2IEwxNyw3LjUgTDEwLjI1LDE0LjI1IEwzLjUsNy41IEw1LDYgTDEwLjI1LDExLjI1IEwxNS41LDYgWiIgaWQ9IkRvd24tQXJyb3ciIHNrZXRjaDp0eXBlPSJNU1NoYXBlR3JvdXAiPjwvcGF0aD4gICAgICAgIDwvZz4gICAgPC9nPjwvc3ZnPg==) no-repeat right 10px center;;
}
select.is-compact {
min-width: 0;
padding: 0 20px 2px 6px;
margin: 0 4px;
background-position: right 5px center;
background-size: 12px 12px;
}
/* Make it display:block when it follows a label */
label select,
label + select {
display: block;
min-width: 200px;
}
label select.is-compact,
label + select.is-compact {
display: inline-block;
min-width: 0;
}
/* IE: Remove the default arrow */
select::-ms-expand {
display: none;
}
/* IE: Remove default background and color styles on focus */
select::-ms-value {
background: none;
color: #2e4453;
}
/* Firefox: Remove the focus outline, see http://stackoverflow.com/questions/3773430/remove-outline-from-select-box-in-ff/18853002#18853002 */
select:-moz-focusring {
color: transparent;
text-shadow: 0 0 0 #2e4453;
}
/* ==========================================================================
** Buttons
** ======================================================================== */
input[type="submit"] {
padding: 0;
font-size: 14px;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
vertical-align: baseline;
background: white;
border-color: #c8d7e1;
border-style: solid;
border-width: 1px 1px 2px;
color: #2e4453;
cursor: pointer;
display: inline-block;
margin: 24px 0 0;
outline: 0;
overflow: hidden;
font-weight: 500;
text-overflow: ellipsis;
text-decoration: none;
vertical-align: top;
box-sizing: border-box;
font-size: 14px;
line-height: 21px;
border-radius: 4px;
padding: 7px 14px 9px;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
}
input[type="submit"]:hover {
border-color: #a8bece;
color: #2e4453;
}
input[type="submit"]:active {
border-width: 2px 1px 1px;
}
input[type="submit"]:visited {
color: #2e4453;
}
input[type="submit"][disabled],
input[type="submit"]:disabled {
color: #e9eff3;
background: white;
border-color: #e9eff3;
cursor: default;
}
input[type="submit"][disabled]:active,
input[type="submit"]:disabled:active {
border-width: 1px 1px 2px;
}
input[type="submit"]:focus {
border-color: #00aadc;
box-shadow: 0 0 0 2px #78dcfa;
}
/* ==========================================================================
** Preview styles
** ======================================================================== */
.wpview.wpview-wrap[data-wpview-type=contact-form] iframe.inline-edit-contact-form {
width: 100%;
min-height: 500px;
border: 0;
overflow: hidden;
margin-bottom: 0;
display: block;
}
.contact-submit.contact-submit {
margin-top: 0;
margin-bottom: 0;
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,19 @@
/* Do not modify this file directly. It is concatenated from individual module CSS files. */
i.mce-i-grunion {
font-family: dashicons;
font-size: 20px;
}
i.mce-i-grunion:before,
.jetpack-contact-form-icon:before {
content: "\f175";
vertical-align: top;
}
.jetpack-contact-form-icon {
opacity: 0.7;
vertical-align: text-top;
display: inline-block;
height: 18px;
font: 18px/1 dashicons;
}

View File

@@ -0,0 +1 @@
i.mce-i-grunion{font-family:dashicons;font-size:20px}.jetpack-contact-form-icon:before,i.mce-i-grunion:before{content:"\f175";vertical-align:top}.jetpack-contact-form-icon{opacity:.7;vertical-align:text-top;display:inline-block;height:18px;font:18px/1 dashicons}

View File

@@ -0,0 +1,18 @@
i.mce-i-grunion {
font-family: dashicons;
font-size: 20px;
}
i.mce-i-grunion:before,
.jetpack-contact-form-icon:before {
content: "\f175";
vertical-align: top;
}
.jetpack-contact-form-icon {
opacity: 0.7;
vertical-align: text-top;
display: inline-block;
height: 18px;
font: 18px/1 dashicons;
}

View File

@@ -0,0 +1,2 @@
/* Do not modify this file directly. It is concatenated from individual module CSS files. */
i.mce-i-grunion{font-family:dashicons;font-size:20px}.jetpack-contact-form-icon:before,i.mce-i-grunion:before{content:"\f175";vertical-align:top}.jetpack-contact-form-icon{opacity:.7;vertical-align:text-top;display:inline-block;height:18px;font:18px/1 dashicons}

View File

@@ -0,0 +1 @@
.contact-form .clear-form{clear:both}.contact-form input[type=email],.contact-form input[type=text],.contact-form input[type=url]{width:300px;max-width:98%;margin-bottom:13px}.contact-form select{margin-bottom:13px}.contact-form textarea{height:200px;width:80%;float:none;margin-bottom:13px}.contact-form input[type=checkbox],.contact-form input[type=radio]{float:none;margin-bottom:13px}.contact-form label{margin-bottom:3px;float:none;font-weight:700;display:block}.contact-form label.checkbox,.contact-form label.radio{margin-bottom:3px;float:none;font-weight:700;display:inline-block}.contact-form label span{color:#aaa;margin-right:4px;font-weight:400}.contact-form-submission{margin-bottom:4em;padding:1.5em 1em}.contact-form-submission p{margin:0 auto}.form-errors .form-error-message{color:red}.textwidget .contact-form input[type=email],.textwidget .contact-form input[type=text],.textwidget .contact-form input[type=url],.textwidget .contact-form textarea{width:250px;max-width:100%;box-sizing:border-box}#jetpack-check-feedback-spam{margin:1px 0 0 8px}.jetpack-check-feedback-spam-spinner{display:inline-block;margin-top:7px}

View File

@@ -0,0 +1,80 @@
.contact-form .clear-form {
clear: both;
}
.contact-form input[type='text'],
.contact-form input[type='email'],
.contact-form input[type='url'] {
width: 300px;
max-width: 98%;
margin-bottom: 13px;
}
.contact-form select {
margin-bottom: 13px;
}
.contact-form textarea {
height: 200px;
width: 80%;
float: none;
margin-bottom: 13px;
}
.contact-form input[type='radio'],
.contact-form input[type='checkbox'] {
float: none;
margin-bottom: 13px;
}
.contact-form label {
margin-bottom: 3px;
float: none;
font-weight: bold;
display: block;
}
.contact-form label.checkbox,
.contact-form label.radio {
margin-bottom: 3px;
float: none;
font-weight: bold;
display: inline-block;
}
.contact-form label span {
color: #AAA;
margin-left: 4px;
font-weight: normal;
}
.contact-form-submission {
margin-bottom: 4em;
padding: 1.5em 1em;
}
.contact-form-submission p {
margin: 0 auto;
}
.form-errors .form-error-message {
color: red;
}
.textwidget .contact-form input[type='text'],
.textwidget .contact-form input[type='email'],
.textwidget .contact-form input[type='url'],
.textwidget .contact-form textarea {
width: 250px;
max-width: 100%;
box-sizing: border-box;
}
#jetpack-check-feedback-spam {
margin: 1px 8px 0px 0px;
}
.jetpack-check-feedback-spam-spinner {
display: inline-block;
margin-top: 7px;
}

View File

@@ -0,0 +1,160 @@
.ui-datepicker {
padding: 0;
margin: 0;
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0;
background-color: #fff;
border: 1px solid #dfdfdf;
border-top: none;
-webkit-box-shadow: 0 3px 6px rgba(0, 0, 0, 0.075);
box-shadow: 0 3px 6px rgba(0, 0, 0, 0.075);
width: auto;
}
.ui-datepicker * {
padding: 0;
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0;
}
.ui-datepicker table {
width: auto;
margin: 0;
border: none;
border-collapse: collapse;
}
.ui-datepicker .ui-widget-header,
.ui-datepicker .ui-datepicker-header {
background-image: none;
border: none;
font-weight: normal;
}
.ui-datepicker .ui-datepicker-header .ui-state-hover {
background: transparent;
border-color: transparent;
cursor: pointer;
}
.ui-datepicker .ui-datepicker-title {
margin: 0;
padding: 10px 0;
font-size: 14px;
line-height: 14px;
text-align: center;
}
.ui-datepicker .ui-datepicker-prev,
.ui-datepicker .ui-datepicker-next {
position: relative;
top: 0;
height: 34px;
width: 34px;
}
.ui-datepicker .ui-state-hover.ui-datepicker-prev,
.ui-datepicker .ui-state-hover.ui-datepicker-next {
border: none;
}
.ui-datepicker .ui-datepicker-prev,
.ui-datepicker .ui-datepicker-prev-hover {
left: 0;
}
.ui-datepicker .ui-datepicker-next,
.ui-datepicker .ui-datepicker-next-hover {
right: 0;
}
.ui-datepicker .ui-datepicker-next span,
.ui-datepicker .ui-datepicker-prev span {
display: none;
}
.ui-datepicker .ui-datepicker-prev {
float: left;
}
.ui-datepicker .ui-datepicker-next {
float: right;
}
.ui-datepicker .ui-datepicker-prev:before,
.ui-datepicker .ui-datepicker-next:before {
font: normal 20px/34px 'dashicons';
padding-left: 7px;
speak: none;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
width: 34px;
height: 34px;
}
.ui-datepicker .ui-datepicker-prev:before {
content: '\f341';
}
.ui-datepicker .ui-datepicker-next:before {
content: '\f345';
}
.ui-datepicker .ui-datepicker-prev-hover:before,
.ui-datepicker .ui-datepicker-next-hover:before {
opacity: 0.7;
}
.ui-datepicker select.ui-datepicker-month,
.ui-datepicker select.ui-datepicker-year {
width: 33%;
}
.ui-datepicker thead {
font-weight: 600;
}
.ui-datepicker th {
padding: 10px;
border-width: 1px;
}
.ui-datepicker td {
padding: 0;
border: 1px solid #f4f4f4;
}
.ui-datepicker td.ui-datepicker-other-month {
border: transparent;
}
.ui-datepicker td.ui-datepicker-week-end {
background-color: #f4f4f4;
border: 1px solid #f4f4f4;
}
.ui-datepicker td.ui-datepicker-today {
background-color: #f0f0c0;
}
.ui-datepicker td.ui-datepicker-current-day {
background: #bbdd88;
}
.ui-datepicker td .ui-state-default {
background: transparent;
border: none;
text-align: center;
text-decoration: none;
width: auto;
display: block;
padding: 5px 10px;
font-weight: normal;
color: #444;
}
.ui-datepicker td.ui-state-disabled .ui-state-default {
opacity: 0.5;
}

View File

@@ -0,0 +1,297 @@
<?php
/*
* A prototype to allow inline editing / editor views for contact forms.\
*
* Originally developed in: http://github.com/automattic/gm2016-grunion-editor
* Authors: Michael Arestad, Andrew Ozz, and George Stephanis
*/
class Grunion_Editor_View {
/**
* Add hooks according to screen.
*
* @param WP_Screen $screen Data about current screen.
*/
public static function add_hooks( $screen ) {
if ( isset( $screen->base ) && 'post' === $screen->base ) {
add_action( 'admin_notices', array( __CLASS__, 'handle_editor_view_js' ) );
add_action( 'admin_head', array( __CLASS__, 'admin_head' ) );
}
}
public static function admin_head() {
remove_action( 'media_buttons', 'grunion_media_button', 999 );
add_action( 'media_buttons', array( __CLASS__, 'grunion_media_button' ), 999 );
}
public static function grunion_media_button() {
$title = __( 'Add Contact Form', 'jetpack' );
?>
<button type="button" id="insert-jetpack-contact-form" class="button" title="<?php echo esc_attr( $title ); ?>" href="javascript:;">
<span class="jetpack-contact-form-icon"></span>
<?php echo esc_html( $title ); ?>
</button>
<?php
}
public static function mce_external_plugins( $plugin_array ) {
$plugin_array['grunion_form'] = Jetpack::get_file_url_for_environment(
'_inc/build/contact-form/js/tinymce-plugin-form-button.min.js',
'modules/contact-form/js/tinymce-plugin-form-button.js'
);
return $plugin_array;
}
public static function mce_buttons( $buttons ) {
$size = sizeof( $buttons );
$buttons1 = array_slice( $buttons, 0, $size - 1 );
$buttons2 = array_slice( $buttons, $size - 1 );
return array_merge(
$buttons1,
array( 'grunion' ),
$buttons2
);
}
/**
* WordPress Shortcode Editor View JS Code
*/
public static function handle_editor_view_js() {
add_action( 'admin_print_footer_scripts', array( __CLASS__, 'editor_view_js_templates' ), 1 );
add_filter( 'mce_external_plugins', array( __CLASS__, 'mce_external_plugins' ) );
add_filter( 'mce_buttons', array( __CLASS__, 'mce_buttons' ) );
wp_enqueue_style( 'grunion-editor-ui', plugins_url( 'css/editor-ui.css', __FILE__ ) );
wp_style_add_data( 'grunion-editor-ui', 'rtl', 'replace' );
wp_enqueue_script(
'grunion-editor-view',
Jetpack::get_file_url_for_environment(
'_inc/build/contact-form/js/editor-view.min.js',
'modules/contact-form/js/editor-view.js'
),
array( 'wp-util', 'jquery', 'quicktags' ),
false,
true
);
wp_localize_script( 'grunion-editor-view', 'grunionEditorView', array(
'inline_editing_style' => plugins_url( 'css/editor-inline-editing-style.css', __FILE__ ),
'inline_editing_style_rtl' => plugins_url( 'css/editor-inline-editing-style-rtl.css', __FILE__ ),
'dashicons_css_url' => includes_url( 'css/dashicons.css' ),
'default_form' => '[contact-field label="' . __( 'Name', 'jetpack' ) . '" type="name" required="true" /]' .
'[contact-field label="' . __( 'Email', 'jetpack' ) . '" type="email" required="true" /]' .
'[contact-field label="' . __( 'Website', 'jetpack' ) . '" type="url" /]' .
'[contact-field label="' . __( 'Message', 'jetpack' ) . '" type="textarea" /]',
'labels' => array(
'submit_button_text' => __( 'Submit', 'jetpack' ),
/** This filter is documented in modules/contact-form/grunion-contact-form.php */
'required_field_text' => apply_filters( 'jetpack_required_field_text', __( '(required)', 'jetpack' ) ),
'edit_close_ays' => __( 'Are you sure you\'d like to stop editing this form without saving your changes?', 'jetpack' ),
'quicktags_label' => __( 'contact form', 'jetpack' ),
'tinymce_label' => __( 'Add contact form', 'jetpack' ),
)
) );
add_editor_style( plugin_dir_url( __FILE__ ) . 'css/editor-style.css' );
}
/**
* JS Templates.
*/
public static function editor_view_js_templates() {
?>
<script type="text/html" id="tmpl-grunion-contact-form">
<form class="card" action='#' method='post' class='contact-form commentsblock' onsubmit="return false;">
{{{ data.body }}}
<p class='contact-submit'>
<input type='submit' value='{{ data.submit_button_text }}' class='pushbutton-wide'/>
</p>
</form>
</script>
<script type="text/html" id="tmpl-grunion-field-email">
<div>
<label for='{{ data.id }}' class='grunion-field-label email'>{{ data.label }}<# if ( data.required ) print( " <span>" + data.required + "</span>" ) #></label>
<input type='email' name='{{ data.id }}' id='{{ data.id }}' value='{{ data.value }}' class='{{ data.class }}' placeholder='{{ data.placeholder }}' />
</div>
</script>
<script type="text/html" id="tmpl-grunion-field-telephone">
<div>
<label for='{{ data.id }}' class='grunion-field-label telephone'>{{ data.label }}<# if ( data.required ) print( " <span>" + data.required + "</span>" ) #></label>
<input type='tel' name='{{ data.id }}' id='{{ data.id }}' value='{{ data.value }}' class='{{ data.class }}' placeholder='{{ data.placeholder }}' />
</div>
</script>
<script type="text/html" id="tmpl-grunion-field-textarea">
<div>
<label for='contact-form-comment-{{ data.id }}' class='grunion-field-label textarea'>{{ data.label }}<# if ( data.required ) print( " <span>" + data.required + "</span>" ) #></label>
<textarea name='{{ data.id }}' id='contact-form-comment-{{ data.id }}' rows='20' class='{{ data.class }}' placeholder='{{ data.placeholder }}'>{{ data.value }}</textarea>
</div>
</script>
<script type="text/html" id="tmpl-grunion-field-radio">
<div>
<label class='grunion-field-label'>{{ data.label }}<# if ( data.required ) print( " <span>" + data.required + "</span>" ) #></label>
<# _.each( data.options, function( option ) { #>
<label class='grunion-radio-label radio'>
<input type='radio' name='{{ data.id }}' value='{{ option }}' class="{{ data.class }}" <# if ( option === data.value ) print( "checked='checked'" ) #> />
<span>{{ option }}</span>
</label>
<# }); #>
<div class='clear-form'></div>
</div>
</script>
<script type="text/html" id="tmpl-grunion-field-checkbox">
<div>
<label class='grunion-field-label checkbox'>
<input type='checkbox' name='{{ data.id }}' value='<?php esc_attr__( 'Yes', 'jetpack' ); ?>' class="{{ data.class }}" <# if ( data.value ) print( 'checked="checked"' ) #> />
<span>{{ data.label }}</span><# if ( data.required ) print( " <span>" + data.required + "</span>" ) #>
</label>
<div class='clear-form'></div>
</div>
</script>
<script type="text/html" id="tmpl-grunion-field-checkbox-multiple">
<div>
<label class='grunion-field-label'>{{ data.label }}<# if ( data.required ) print( " <span>" + data.required + "</span>" ) #></label>
<# _.each( data.options, function( option ) { #>
<label class='grunion-checkbox-multiple-label checkbox-multiple'>
<input type='checkbox' name='{{ data.id }}[]' value='{{ option }}' class="{{ data.class }}" <# if ( option === data.value || _.contains( data.value, option ) ) print( "checked='checked'" ) #> />
<span>{{ option }}</span>
</label>
<# }); #>
<div class='clear-form'></div>
</div>
</script>
<script type="text/html" id="tmpl-grunion-field-select">
<div>
<label for='{{ data.id }}' class='grunion-field-label select'>{{ data.label }}<# if ( data.required ) print( " <span>" + data.required + "</span>" ) #></label>
<select name='{{ data.id }}' id='{{ data.id }}' class="{{ data.class }}">
<# _.each( data.options, function( option ) { #>
<option <# if ( option === data.value ) print( "selected='selected'" ) #>>{{ option }}</option>
<# }); #>
</select>
</div>
</script>
<script type="text/html" id="tmpl-grunion-field-date">
<div>
<label for='{{ data.id }}' class='grunion-field-label {{ data.type }}'>{{ data.label }}<# if ( data.required ) print( " <span>" + data.required + "</span>" ) #></label>
<input type='text' name='{{ data.id }}' id='{{ data.id }}' value='{{ data.value }}' class="{{ data.class }}" />
</div>
</script>
<script type="text/html" id="tmpl-grunion-field-text">
<div>
<label for='{{ data.id }}' class='grunion-field-label {{ data.type }}'>{{ data.label }}<# if ( data.required ) print( " <span>" + data.required + "</span>" ) #></label>
<input type='text' name='{{ data.id }}' id='{{ data.id }}' value='{{ data.value }}' class='{{ data.class }}' placeholder='{{ data.placeholder }}' />
</div>
</script>
<script type="text/html" id="tmpl-grunion-field-url">
<div>
<label for='{{ data.id }}' class='grunion-field-label {{ data.type }}'>{{ data.label }}<# if ( data.required ) print( " <span>" + data.required + "</span>" ) #></label>
<input type='url' name='{{ data.id }}' id='{{ data.id }}' value='{{ data.value }}' class='{{ data.class }}' placeholder='{{ data.placeholder }}' />
</div>
</script>
<script type="text/html" id="tmpl-grunion-field-edit">
<div class="card is-compact grunion-field-edit grunion-field-{{ data.type }}" aria-label="<?php esc_attr_e( 'Form Field', 'jetpack' ); ?>">
<label class="grunion-name">
<span><?php esc_html_e( 'Field Label', 'jetpack' ); ?></span>
<input type="text" name="label" placeholder="<?php esc_attr_e( 'Label', 'jetpack' ); ?>" value="{{ data.label }}"/>
</label>
<?php
$grunion_field_types = array(
'text' => __( 'Text', 'jetpack' ),
'name' => __( 'Name', 'jetpack' ),
'email' => __( 'Email', 'jetpack' ),
'url' => __( 'Website', 'jetpack' ),
'textarea' => __( 'Textarea', 'jetpack' ),
'checkbox' => __( 'Checkbox', 'jetpack' ),
'checkbox-multiple' => __( 'Checkbox with Multiple Items', 'jetpack' ),
'select' => __( 'Drop down', 'jetpack' ),
'radio' => __( 'Radio', 'jetpack' ),
'date' => __( 'Date', 'jetpack' ),
);
?>
<div class="grunion-type-options">
<label class="grunion-type">
<?php esc_html_e( 'Field Type', 'jetpack' ); ?>
<select name="type">
<?php foreach ( $grunion_field_types as $type => $label ) : ?>
<option <# if ( '<?php echo esc_js( $type ); ?>' === data.type ) print( "selected='selected'" ) #> value="<?php echo esc_attr( $type ); ?>">
<?php echo esc_html( $label ); ?>
</option>
<?php endforeach; ?>
</select>
</label>
<label class="grunion-required">
<input type="checkbox" name="required" value="1" <# if ( data.required ) print( 'checked="checked"' ) #> />
<span><?php esc_html_e( 'Required?', 'jetpack' ); ?></span>
</label>
</div>
<label class="grunion-options">
<?php esc_html_e( 'Options', 'jetpack' ); ?>
<ol>
<# if ( data.options ) { #>
<# _.each( data.options, function( option ) { #>
<li><input type="text" name="option" value="{{ option }}" /> <a class="delete-option" href="javascript:;"><span class="screen-reader-text"><?php esc_html_e( 'Delete Option', 'jetpack' ); ?></span></a></li>
<# }); #>
<# } else { #>
<li><input type="text" name="option" /> <a class="delete-option" href="javascript:;"><span class="screen-reader-text"><?php esc_html_e( 'Delete Option', 'jetpack' ); ?></span></a></li>
<li><input type="text" name="option" /> <a class="delete-option" href="javascript:;"><span class="screen-reader-text"><?php esc_html_e( 'Delete Option', 'jetpack' ); ?></span></a></li>
<li><input type="text" name="option" /> <a class="delete-option" href="javascript:;"><span class="screen-reader-text"><?php esc_html_e( 'Delete Option', 'jetpack' ); ?></span></a></li>
<# } #>
<li><a class="add-option" href="javascript:;"><?php esc_html_e( 'Add new option...', 'jetpack' ); ?></a></li>
</ol>
</label>
<a href="javascript:;" class="delete-field"><span class="screen-reader-text"><?php esc_html_e( 'Delete Field', 'jetpack' ); ?></span></a>
</div>
</script>
<script type="text/html" id="tmpl-grunion-field-edit-option">
<li><input type="text" name="option" /> <a class="delete-option" href="javascript:;"><span class="screen-reader-text"><?php esc_html_e( 'Delete Option', 'jetpack' ); ?></span></a></li>
</script>
<script type="text/html" id="tmpl-grunion-editor-inline">
<h1 id="form-settings-header" class="grunion-section-header"><?php esc_html_e( 'Contact form information', 'jetpack' ); ?></h1>
<section class="card grunion-form-settings" aria-labelledby="form-settings-header">
<label><?php esc_html_e( 'What would you like the subject of the email to be?', 'jetpack' ); ?>
<input type="text" name="subject" value="{{ data.subject }}" />
</label>
<label><?php esc_html_e( 'Which email address should we send the submissions to?', 'jetpack' ); ?>
<input type="text" name="to" value="{{ data.to }}" />
</label>
</section>
<h1 id="form-fields-header" class="grunion-section-header"><?php esc_html_e( 'Contact form fields', 'jetpack' ); ?></h1>
<section class="grunion-fields" aria-labelledby="form-fields-header">
{{{ data.fields }}}
</section>
<section class="grunion-controls">
<?php submit_button( esc_html__( 'Add Field', 'jetpack' ), 'secondary', 'add-field', false ); ?>
<div class="grunion-update-controls">
<?php submit_button( esc_html__( 'Cancel', 'jetpack' ), 'delete', 'cancel', false ); ?>
<?php submit_button( esc_html__( 'Update Form', 'jetpack' ), 'primary', 'submit', false ); ?>
</div>
</section>
</script>
</div>
<?php
}
}
add_action( 'current_screen', array( 'Grunion_Editor_View', 'add_hooks' ) );

View File

@@ -0,0 +1,251 @@
<?php
/**
* Template for form builder
*/
/**
* Filter to modify the limit of 5 additional contact form fields.
*
* @module contact-form
*
* @since 3.2.0
*
* @param int 5 Maximum number of additional fields.
*/
$max_new_fields = apply_filters( 'grunion_max_new_fields', 5 );
wp_register_script(
'grunion',
Jetpack::get_file_url_for_environment(
'_inc/build/contact-form/js/grunion.min.js',
'modules/contact-form/js/grunion.js'
),
array( 'jquery-ui-sortable', 'jquery-ui-draggable' ),
JETPACK__VERSION
);
wp_localize_script( 'grunion', 'GrunionFB_i18n', array(
'nameLabel' => esc_attr( _x( 'Name', 'Label for HTML form "Name" field in contact form builder', 'jetpack' ) ),
'emailLabel' => esc_attr( _x( 'Email', 'Label for HTML form "Email" field in contact form builder', 'jetpack' ) ),
'urlLabel' => esc_attr( _x( 'Website', 'Label for HTML form "URL/Website" field in contact form builder', 'jetpack' ) ),
'commentLabel' => esc_attr( _x( 'Comment', 'noun', 'jetpack' ) ),
'newLabel' => esc_attr( _x( 'New Field', 'Default label for new HTML form field in contact form builder', 'jetpack' ) ),
'optionsLabel' => esc_attr( _x( 'Options', 'Label for the set of options to be included in a user-created dropdown in contact form builder', 'jetpack' ) ),
'optionsLabel' => esc_attr( _x( 'Option', 'Label for an option to be included in a user-created dropdown in contact form builder', 'jetpack' ) ),
'firstOptionLabel' => esc_attr( _x( 'First option', 'Default label for the first option to be included in a user-created dropdown in contact form builder', 'jetpack' ) ),
'problemGeneratingForm' => esc_attr( _x( "Oops, there was a problem generating your form. You'll likely need to try again.", 'error message in contact form builder', 'jetpack' ) ),
'moveInstructions' => esc_attr__( "Drag up or down\nto re-arrange", 'jetpack' ),
'moveLabel' => esc_attr( _x( 'move', 'Label to drag HTML form fields around to change their order in contact form builder', 'jetpack' ) ),
'editLabel' => esc_attr( _x( 'edit', 'Link to edit an HTML form field in contact form builder', 'jetpack' ) ),
'savedMessage' => esc_attr__( 'Saved successfully', 'jetpack' ),
'requiredLabel' => esc_attr( _x( '(required)', 'This HTML form field is marked as required by the user in contact form builder', 'jetpack' ) ),
'exitConfirmMessage' => esc_attr__( 'Are you sure you want to exit the form editor without saving? Any changes you have made will be lost.', 'jetpack' ),
'maxNewFields' => intval( $max_new_fields ),
) );
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title><?php esc_html_e( 'Contact Form', 'jetpack' ); ?></title>
<script type="text/javascript">
var ajaxurl = '<?php echo admin_url('admin-ajax.php'); ?>';
var postId = <?php echo absint( $_GET['post_id'] ); ?>;
var ajax_nonce_shortcode = '<?php echo wp_create_nonce( 'grunion_shortcode' ); ?>';
var ajax_nonce_json = '<?php echo wp_create_nonce( 'grunion_shortcode_to_json' ); ?>';
</script>
<?php wp_print_scripts( 'grunion' ); ?>
<script type="text/javascript">
jQuery(document).ready(function () {
FB.ContactForm.init();
FB.ContactForm.resizePop();
});
jQuery(window).resize(function() {
setTimeout(function () { FB.ContactForm.resizePop(); }, 50);
});
</script>
<style>
/* Reset */
html { height: 100%; }
body, div, ul, ol, li, h1, h2, h3, h4, h5, h6, form, fieldset, legend, input, button, textarea, p, blockquote, th, td { margin: 0; padding: 0; }
body { background: #F9F9F9; font-family:"Lucida Grande",Verdana,Arial,"Bitstream Vera Sans",sans-serif; font-size:12px; color: #333; line-height:1.5em; height: 100%; width: 100%; padding-bottom: 20px !important; }
a { color: #21759B; text-decoration: none; }
a:hover { text-decoration: underline; text-shadow: none !important; }
h1 { font-size: 21px; color:#5A5A5A; font-family:Georgia,"Times New Roman",Times,serif; font-weight:normal; margin-bottom: 21px; }
h3 { font-size: 13px; color: #666; margin-bottom: 18px; }
input { width: 301px; }
input[type='text'] { padding: 3px 5px; margin-right: 4px; -moz-border-radius:3px; border-radius:3px; -webkit-border-radius:3px; }
input[type='text']:focus { border: 2px solid #80B8D9; outline: 0 !important; }
input[type='checkbox'], input[type='radio'] { width: auto !important; float: left; margin-top: 3px; margin-right: 8px; }
input.fieldError, select.fieldError, textarea.fieldError { border: 2px solid #D56F55; }
img { border: none; }
label { color: #222; font-weight: bold; display: block; margin-bottom: 4px; }
label.radio { width: auto; margin: -2px 0 0 5px; }
label span.label-required { color: #AAA; margin-left: 4px; font-weight: normal; }
td { vertical-align: top; }
select { width: 300px; }
textarea { height: 100px; width: 311px; }
/* Core */
#media-upload-header { border-bottom: 1px solid #DFDFDF; font-weight:bold; margin:0; padding:3px 5px 0 5px; position:relative; background: #FFF; }
#sidemenu { bottom:-1px; font-size:12px; list-style:none outside none; padding-left:10px; position:relative; left:0; margin:0 5px; overflow:hidden; }
#sidemenu a { text-decoration:none; border-top: 1px solid #FFF; display:block; float:left; line-height:28px; padding:0 13px; outline: none; }
#sidemenu a.current { background-color:#F9F9F9; border-color:#DFDFDF #DFDFDF #F9F9F9; color:#D54E21; -moz-border-radius:4px 4px 0 0; border-radius:4px 4px 0 0; -webkit-border-radius:4px 4px 0 0; border-style:solid; border-width:1px; font-weight:normal; }
#sidemenu li { display:inline; margin-bottom:6px; line-height:200%; list-style:none outside none; margin:0; padding:0; text-align:center; white-space:nowrap; }
.button { background-color:#f2f2f2; border-color:#BBBBBB; min-width:80px; text-align:center; color:#464646; text-shadow:0 1px 0 #FFFFFF; border-style:solid; border-width:1px; cursor:pointer; width: auto; font-size:11px !important; line-height:13px; padding:3px 11px; margin-top: 12px; text-decoration:none; -moz-border-radius:11px; border-radius:11px; -webkit-border-radius:11px }
.button-primary { background-color:#21759B; font-weight: bold; border-color:#298CBA; text-align:center; color:#EAF2FA; text-shadow:0 -1px 0 rgba(0, 0, 0, 0.3); border-style:solid; border-width:1px; cursor:pointer; width: auto; font-size:11px !important; line-height:13px; padding:3px 11px; margin-top: 21px; text-decoration:none; -moz-border-radius:11px; border-radius:11px; -webkit-border-radius:11px }
.clear { clear: both; }
.fb-add-field { padding-left: 10px; }
.fb-add-option { margin: 0 0 14px 100px; }
.fb-container { margin: 21px; padding-bottom: 20px; }
.fb-desc, #fb-add-field { margin-top: 34px; }
.fb-extra-fields { margin-bottom: 2px; }
.fb-form-case { background: #FFF; padding: 13px; border: 1px solid #E2E2E2; width: 336px; -moz-border-radius:4px; border-radius:4px; -webkit-border-radius:4px }
.fb-form-case a { outline: none; }
.fb-form-case input[type='text'], .fb-form-case textarea { background: #E1E1E1; }
.fb-radio-label { display: inline-block; float: left; width: 290px; }
.fb-new-fields { position: relative; border: 1px dashed #FFF; background: #FFF; padding: 4px 10px 10px; cursor: default; }
.fb-new-fields:hover { border: 1px dashed #BBDBEA; background: #F7FBFD; }
.fb-options { width: 170px !important; }
.fb-remove { background: url('<?php echo GRUNION_PLUGIN_URL; ?>/images/grunion-remove-field.gif') no-repeat; position: absolute; cursor: pointer !important; right: -26px; top: 27px; width: 20px; height: 23px; }
.fb-remove:hover { background: url('<?php echo GRUNION_PLUGIN_URL; ?>/images/grunion-remove-field-hover.gif') no-repeat; }
.fb-remove-small { top: 2px !important; }
.fb-remove-option { position: absolute; top: 1px; right: 10px; width: 20px; height: 23px; background: url('<?php echo GRUNION_PLUGIN_URL; ?>/images/grunion-remove-option.gif') no-repeat; }
.fb-remove-option:hover { background: url('<?php echo GRUNION_PLUGIN_URL; ?>/images/grunion-remove-option-hover.gif') no-repeat; }
.fb-reorder { cursor: move; position: relative; }
.fb-reorder:hover div { display: block !important; width: 130px !important; position: absolute; top: 0; right: 0; z-index: 200; padding: 5px 10px; color: #555; font-size: 11px; background: #FFF; border: 1px solid #CCC; -moz-border-radius:4px; border-radius:4px; -webkit-border-radius:4px; }
.fb-right { position: absolute; right: 0; top: 0; width: 315px; margin: 57px 21px 0 0; }
.fb-right .fb-new-fields { border: none; background: #F9F9F9; padding: 0; }
.fb-right input[type='text'] { width: 195px; margin-bottom: 14px; }
.fb-right label { color: #444; width: 100px; float: left; font-weight: normal; }
.fb-right select { width: 195px !important; margin-bottom: 14px; }
.fb-right textarea { margin-bottom: 13px; }
.fb-right p { color: #999; line-height: 19px; }
.fb-settings input[type='text'], .fb-settings textarea { background-image: none !important; }
.fb-success { position: absolute; top: -3px; right: 100px; padding: 6px 23px 4px 23px; background: #FFFFE0; font-weight: normal; border: 1px solid #E6DB55; color: #333; -moz-border-radius:4px; border-radius:4px; -webkit-border-radius:4px; }
.right { float: right; }
/* rtl */
body.rtl{ direction: rtl; font-family:Tahoma,Arial,sans-serif}
.rtl input[type='text'] { margin-left: 4px; margin-right: 0; }
.rtl input[type='checkbox'], .rtl input[type='radio'] { float: right; }
.rtl input[type='radio'] { margin-left: 8px; margin-right: 0; }
.rtl label.radio { margin: -2px 5px 0 0; }
.rtl label span.label-required { margin-right: 4px; margin-left:0 }
.rtl #sidemenu { padding-right:10px; padding-left: 0; left:auto; right: 0; }
.rtl #sidemenu a { float:right; }
.rtl .fb-add-field { padding-right: 10px; padding-left: 0; }
.rtl .fb-add-option { margin: 0 100px 14px 0; }
.rtl .fb-radio-label { margin-right: 8px; margin-left: 0; float: right; }
.rtl .fb-remove { right: auto; left: -26px; transform: scaleX(-1); }
.rtl .fb-remove-option { right: auto; left: 10px; }
.rtl .fb-reorder:hover div { left: 0; right: auto; }
.rtl .fb-right { left: 0; right: auto; margin: 57px 0 0 21px; }
.rtl .fb-right label { float: right; }
.rtl .fb-success { right: auto; left: 100px;}
.rtl .right { float: left; }
@media only screen and (min--moz-device-pixel-ratio: 1.5), only screen and (-o-min-device-pixel-ratio: 3/2), only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min-device-pixel-ratio: 1.5) {
.fb-remove { background: url('<?php echo GRUNION_PLUGIN_URL; ?>/images/grunion-remove-field-2x.png') no-repeat; background-size: 20px 23px; }
.fb-remove:hover { background: url('<?php echo GRUNION_PLUGIN_URL; ?>/images/grunion-remove-field-hover-2x.png') no-repeat; background-size: 20px 23px; }
.fb-remove-option { background: url('<?php echo GRUNION_PLUGIN_URL; ?>/images/grunion-remove-option-2x.png') no-repeat; background-size: 20px 23px; }
.fb-remove-option:hover { background: url('<?php echo GRUNION_PLUGIN_URL; ?>/images/grunion-remove-option-hover-2x.png') no-repeat; background-size: 20px 23px; }
}
</style>
</head>
<body <?php if ( is_rtl() ) { echo 'class="rtl"'; }?>>
<div id="media-upload-header">
<div id="fb-success" class="fb-success" style="display: none;"><?php esc_html_e( 'Your new field was saved successfully', 'jetpack' ); ?></div>
<ul id="sidemenu">
<li id="tab-preview"><a class="current" href=""><?php esc_html_e( 'Form builder', 'jetpack' ); ?></a></li>
<li id="tab-settings"><a href=""><?php esc_html_e( 'Email notifications', 'jetpack' ); ?></a></li>
</ul>
</div>
<div class="fb-right">
<div id="fb-desc" class="fb-desc">
<h3><?php esc_html_e( 'How does this work?', 'jetpack' ); ?></h3>
<p><?php esc_html_e( 'By adding a contact form, your readers will be able to submit feedback to you. All feedback is automatically scanned for spam, and the legitimate feedback will be emailed to you.', 'jetpack' ); ?></p>
<h3 style="margin-top: 21px;"><?php esc_html_e( 'Can I add more fields?', 'jetpack' ); ?></h3>
<p><?php printf(
esc_html( _x( 'Sure thing. %1$s to add a new text box, textarea, radio, checkbox, or dropdown field.', '%1$s = "Click here" in an HTML link', 'jetpack' ) ),
'<a href="#" class="fb-add-field" style="padding-left: 0;">' . esc_html__( 'Click here', 'jetpack' ) . '</a>'
); ?></p>
<h3 style="margin-top: 21px;"><?php esc_html_e( 'Can I view my feedback within WordPress?', 'jetpack' ); ?></h3>
<p><?php printf(
esc_html( _x( 'Yep, you can read your feedback at any time by clicking the "%1$s" link in the admin menu.', '%1$s = "Feedback" in an HTML link', 'jetpack' ) ),
'<a id="fb-feedback" href="' . admin_url( 'edit.php?post_type=feedback' ) . '">' . esc_html__( 'Feedback', 'jetpack' ) . '</a>'
); ?></p>
<div class="clear"></div>
</div>
<div id="fb-email-desc" class="fb-desc" style="display: none;">
<h3><?php esc_html_e( 'Do I need to fill this out?', 'jetpack' ); ?></h3>
<p><?php esc_html_e( 'Nope. However, if you&#8217;d like to modify where your feedback is sent, or the subject line you can. If you don&#8217;t make any changes here, feedback will be sent to the author of the page/post and the subject will be the name of this page/post.', 'jetpack' ); ?></p>
<h3 style="margin-top: 21px;"><?php esc_html_e( 'Can I send a notification to more than one person?', 'jetpack' ); ?></h3>
<p><?php esc_html_e( 'Yep. You can enter multiple email addresses in the Email address field, and separate them with commas. A notification email will then be sent to each email address.', 'jetpack' ); ?></p>
<div class="clear"></div>
</div>
<div id="fb-add-field" style="display: none;">
<h3><?php esc_html_e( 'Edit this new field', 'jetpack' ); ?></h3>
<label for="fb-new-label"><?php esc_html_e( 'Label', 'jetpack' ); ?></label>
<input type="text" id="fb-new-label" value="<?php esc_attr_e( 'New field', 'jetpack' ); ?>" />
<label for="fb-new-label"><?php esc_html_e( 'Field type', 'jetpack' ); ?></label>
<select id="fb-new-type">
<option value="checkbox"><?php esc_html_e( 'Checkbox', 'jetpack' ); ?></option>
<option value="checkbox-multiple"><?php esc_html_e( 'Checkbox with Multiple Items', 'jetpack' ); ?></option>
<option value="select"><?php esc_html_e( 'Drop down', 'jetpack' ); ?></option>
<option value="email"><?php esc_html_e( 'Email', 'jetpack' ); ?></option>
<option value="name"><?php esc_html_e( 'Name', 'jetpack' ); ?></option>
<option value="radio"><?php esc_html_e( 'Radio', 'jetpack' ); ?></option>
<option value="text" selected="selected"><?php esc_html_e( 'Text', 'jetpack' ); ?></option>
<option value="textarea"><?php esc_html_e( 'Textarea', 'jetpack' ); ?></option>
<option value="url"><?php esc_html_e( 'Website', 'jetpack' ); ?></option>
</select>
<div class="clear"></div>
<div id="fb-options" style="display: none;">
<div id="fb-new-options">
<label for="fb-option0"><?php esc_html_e( 'Options', 'jetpack' ); ?></label>
<input type="text" id="fb-option0" optionid="0" value="<?php esc_attr_e( 'First option', 'jetpack' ); ?>" class="fb-options" />
</div>
<div id="fb-add-option" class="fb-add-option">
<a href="#" id="fb-another-option"><?php esc_html_e( 'Add another option', 'jetpack' ); ?></a>
</div>
</div>
<div class="fb-required">
<label for="fb-new-label"></label>
<input type="checkbox" id="fb-new-required" />
<label for="fb-new-label" class="fb-radio-label"><?php esc_html_e( 'Required?', 'jetpack' ); ?></label>
<div class="clear"></div>
</div>
<input type="hidden" id="fb-field-id" />
<input type="submit" class="button" value="<?php esc_attr_e( 'Save this field', 'jetpack' ); ?>" id="fb-save-field" name="save">
</div>
</div>
<form id="fb-preview">
<div id="fb-preview-form" class="fb-container">
<h1><?php esc_html_e( 'Here&#8217;s what your form will look like', 'jetpack' ); ?></h1>
<div id="sortable" class="fb-form-case">
<div id="fb-extra-fields" class="fb-extra-fields"></div>
<a href="#" id="fb-new-field" class="fb-add-field"><?php esc_html_e( 'Add a new field', 'jetpack' ); ?></a>
</div>
<input type="submit" class="button-primary" tabindex="4" value="<?php esc_attr_e( 'Add this form to my post', 'jetpack' ); ?>" id="fb-save-form" name="save">
</div>
<div id="fb-email-settings" class="fb-container" style="display: none;">
<h1><?php esc_html_e( 'Email settings', 'jetpack' ); ?></h1>
<div class="fb-form-case fb-settings">
<label for="fb-fieldname"><?php esc_html_e( 'Enter your email address', 'jetpack' ); ?></label>
<input type="text" id="fb-field-my-email" style="background: #FFF !important;" />
<label for="fb-fieldemail" style="margin-top: 14px;"><?php esc_html_e( 'What should the subject line be?', 'jetpack' ); ?></label>
<input type="text" id="fb-field-subject" style="background: #FFF !important;" />
</div>
<input type="submit" class="button-primary" value="<?php esc_attr_e( 'Save and go back to form builder', 'jetpack' ); ?>" id="fb-prev-form" name="save">
</div>
</form>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 B

View File

@@ -0,0 +1,238 @@
/* global grunionEditorView, tinyMCE, QTags, wp */
( function( $, wp, grunionEditorView ) {
wp.mce = wp.mce || {};
if ( 'undefined' === typeof wp.mce.views ) {
return;
}
wp.mce.grunion_wp_view_renderer = {
shortcode_string : 'contact-form',
template : wp.template( 'grunion-contact-form' ),
field_templates: {
email : wp.template( 'grunion-field-email' ),
telephone : wp.template( 'grunion-field-telephone' ),
textarea : wp.template( 'grunion-field-textarea' ),
radio : wp.template( 'grunion-field-radio' ),
checkbox : wp.template( 'grunion-field-checkbox' ),
'checkbox-multiple' : wp.template( 'grunion-field-checkbox-multiple' ),
select : wp.template( 'grunion-field-select' ),
date : wp.template( 'grunion-field-date' ),
text : wp.template( 'grunion-field-text' ),
name : wp.template( 'grunion-field-text' ),
url : wp.template( 'grunion-field-url' )
},
edit_template : wp.template( 'grunion-field-edit' ),
editor_inline : wp.template( 'grunion-editor-inline' ),
editor_option : wp.template( 'grunion-field-edit-option' ),
getContent : function() {
var content = this.shortcode.content,
index = 0,
field, named,
body = '';
// If it's the legacy `[contact-form /]` syntax, populate default fields.
if ( ! content ) {
content = grunionEditorView.default_form;
}
// Render the fields.
while ( ( field = wp.shortcode.next( 'contact-field', content, index ) ) ) {
index = field.index + field.content.length;
named = field.shortcode.attrs.named;
if ( ! named.type || ! this.field_templates[ named.type ] ) {
named.type = 'text';
}
if ( named.required ) {
named.required = grunionEditorView.labels.required_field_text;
}
if ( named.options && 'string' === typeof named.options ) {
named.options = named.options.split( ',' );
}
body += this.field_templates[ named.type ]( named );
}
var options = {
body : body,
submit_button_text : grunionEditorView.labels.submit_button_text
};
return this.template( options );
},
edit: function( data, update_callback ) {
var shortcode_data = wp.shortcode.next( this.shortcode_string, data ),
shortcode = shortcode_data.shortcode,
$tinyMCE_document = $( tinyMCE.activeEditor.getDoc() ),
$view = $tinyMCE_document.find( '.wpview.wpview-wrap' ).filter( function() {
return $( this ).attr( 'data-mce-selected' );
} ),
$editframe = $( '<iframe scrolling="no" class="inline-edit-contact-form" />' ),
index = 0,
named,
fields = '',
field;
if ( ! shortcode.content ) {
shortcode.content = grunionEditorView.default_form;
}
// Render the fields.
while ( ( field = wp.shortcode.next( 'contact-field', shortcode.content, index ) ) ) {
index = field.index + field.content.length;
named = field.shortcode.attrs.named;
if ( named.options && 'string' === typeof named.options ) {
named.options = named.options.split( ',' );
}
fields += this.edit_template( named );
}
$editframe.on( 'checkheight', function() {
var innerDoc = ( this.contentDocument ) ? this.contentDocument : this.contentWindow.document;
this.style.height = '10px';
this.style.height = ( 5 + innerDoc.body.scrollHeight ) + 'px';
tinyMCE.activeEditor.execCommand( 'wpAutoResize' );
} );
$editframe.on( 'load', function() {
var stylesheet_url = ( 1 === window.isRtl ) ? grunionEditorView.inline_editing_style_rtl : grunionEditorView.inline_editing_style,
$stylesheet = $( '<link rel="stylesheet" href="' + stylesheet_url + '" />' ),
$dashicons_css = $( '<link rel="stylesheet" href="' + grunionEditorView.dashicons_css_url + '" />' );
$stylesheet.on( 'load', function() {
$editframe.contents().find( 'body' ).css( 'visibility', 'visible' );
$editframe.trigger( 'checkheight' );
} );
$editframe.contents().find( 'head' ).append( $stylesheet ).append( $dashicons_css );
$editframe.contents().find( 'body' ).html( wp.mce.grunion_wp_view_renderer.editor_inline( {
to : shortcode.attrs.named.to,
subject : shortcode.attrs.named.subject,
fields : fields
} ) ).css( 'visibility', 'hidden' );
$editframe.contents().find( 'input:first' ).focus();
setTimeout( function(){
$editframe.trigger( 'checkheight' );
}, 250 );
// Add a second timeout for super long forms racing, and to not slow it down for shorter forms unnecessarily.
setTimeout( function(){
$editframe.trigger( 'checkheight' );
}, 500 );
var $editfields = $editframe.contents().find( '.grunion-fields' ),
$buttons = $editframe.contents().find( '.grunion-controls' );
$editfields.sortable();
// Now, add all the listeners!
$editfields.on( 'change select', 'select[name=type]', function() {
$( this ).closest( '.grunion-field-edit' )[ 0 ].className =
'card is-compact grunion-field-edit grunion-field-' + $( this ).val();
$editframe.trigger( 'checkheight' );
} );
$editfields.on( 'click', '.delete-option', function( e ) {
e.preventDefault();
$( this ).closest( 'li' ).remove();
$editframe.trigger( 'checkheight' );
} );
$editfields.on( 'click', '.add-option', function( e ) {
var $new_option = $( wp.mce.grunion_wp_view_renderer.editor_option() );
e.preventDefault();
$( this ).closest( 'li' ).before( $new_option );
$editframe.trigger( 'checkheight' );
$new_option.find( 'input:first' ).focus();
} );
$editfields.on( 'click', '.delete-field', function( e ) {
e.preventDefault();
$( this ).closest( '.card' ).remove();
$editframe.trigger( 'checkheight' );
} );
$buttons.find( 'input[name=submit]' ).on( 'click', function(){
var new_data = shortcode;
new_data.type = 'closed';
new_data.attrs = {};
new_data.content = '';
$editfields.children().each( function() {
var field_shortcode = {
tag : 'contact-field',
type : 'single',
attrs : {
label : $( this ).find( 'input[name=label]' ).val(),
type : $( this ).find( 'select[name=type]' ).val()
}
},
options = [];
if ( $( this ).find( 'input[name=required]:checked' ).length ) {
field_shortcode.attrs.required = '1';
}
$( this ).find( 'input[name=option]' ).each( function() {
if ( $( this ).val() ) {
options.push( $( this ).val() );
}
} );
if ( options.length ) {
field_shortcode.attrs.options = options.join( ',' );
}
new_data.content += wp.shortcode.string( field_shortcode );
} );
if ( $editframe.contents().find( 'input[name=to]' ).val() ) {
new_data.attrs.to = $editframe.contents().find( 'input[name=to]' ).val();
}
if ( $editframe.contents().find( 'input[name=subject]' ).val() ) {
new_data.attrs.subject = $editframe.contents().find( 'input[name=subject]' ).val();
}
update_callback( wp.shortcode.string( new_data ) );
} );
$buttons.find( 'input[name=cancel]' ).on( 'click', function() {
update_callback( wp.shortcode.string( shortcode ) );
} );
$buttons.find( 'input[name=add-field]' ).on( 'click', function() {
var $new_field = $( wp.mce.grunion_wp_view_renderer.edit_template( {} ) );
$editfields.append( $new_field );
$editfields.sortable( 'refresh' );
$editframe.trigger( 'checkheight' );
$new_field.find( 'input:first' ).focus();
} );
} );
$view.html( $editframe );
}
};
wp.mce.views.register( 'contact-form', wp.mce.grunion_wp_view_renderer );
// Add the 'text' editor button.
QTags.addButton(
'grunion_shortcode',
grunionEditorView.labels.quicktags_label,
function() {
QTags.insertContent( '[contact-form]' + grunionEditorView.default_form + '[/contact-form]' );
}
);
var $wp_content_wrap = $( '#wp-content-wrap' );
$( '#insert-jetpack-contact-form' ).on( 'click', function( e ) {
e.preventDefault();
if ( $wp_content_wrap.hasClass( 'tmce-active' ) ) {
tinyMCE.execCommand( 'grunion_add_form' );
} else if ( $wp_content_wrap.hasClass( 'html-active' ) ) {
QTags.insertContent( '[contact-form]' + grunionEditorView.default_form + '[/contact-form]' );
} else {
window.console.error( 'Neither TinyMCE nor QuickTags is active. Unable to insert form.' );
}
} );
}( jQuery, wp, grunionEditorView ) );

View File

@@ -0,0 +1,29 @@
/* global ajaxurl */
jQuery( function ( $ ) {
$( document ).on( 'click', '#jetpack-check-feedback-spam:not(.button-disabled)', function( e ) {
e.preventDefault();
$( '#jetpack-check-feedback-spam:not(.button-disabled)' ).addClass( 'button-disabled' );
$( '.jetpack-check-feedback-spam-spinner' ).addClass( 'spinner' ).show();
grunion_check_for_spam( 0, 100 );
} );
function grunion_check_for_spam( offset, limit ) {
$.post(
ajaxurl,
{
'action' : 'grunion_recheck_queue',
'offset' : offset,
'limit' : limit
},
function ( result ) {
if ( result.processed < limit ) {
window.location.reload();
}
else {
grunion_check_for_spam( offset + limit, limit );
}
}
);
}
} );

View File

@@ -0,0 +1,3 @@
jQuery( function ( $ ) {
$( '.contact-form input.jp-contact-form-date' ).datepicker();
} );

View File

@@ -0,0 +1,813 @@
/* jshint onevar: false, devel: true, smarttabs: true */
/* global GrunionFB_i18n: true, FB, ajax_nonce_shortcode, ajax_nonce_json, ajaxurl, postId */
if ( ! window.FB ) {
window.FB = {};
}
GrunionFB_i18n = jQuery.extend( {
nameLabel: 'Name',
emailLabel: 'Email',
urlLabel: 'Website',
commentLabel: 'Comment',
newLabel: 'New Field',
optionsLabel: 'Options',
optionLabel: 'Option',
firstOptionLabel: 'First option',
problemGeneratingForm: 'Oops, there was a problem generating your form. You\'ll likely need to try again.',
moveInstructions: 'Drag up or down\nto re-arrange',
moveLabel: 'move',
editLabel: 'edit',
savedMessage: 'Saved successfully',
requiredLabel: '(required)',
exitConfirmMessage: 'Are you sure you want to exit the form editor without saving? Any changes you have made will be lost.',
maxNewFields: 5,
invalidEmail: ' is an invalid email address.'
}, GrunionFB_i18n );
GrunionFB_i18n.moveInstructions = GrunionFB_i18n.moveInstructions.replace( '\n', '<br />' );
FB.span = jQuery( '<span>' );
FB.esc_html = function( string ) {
return FB.span.text( string ).html();
};
FB.esc_attr = function( string ) {
string = FB.esc_html( string );
return string.replace( '"', '&quot;' ).replace( '\'', '&#039;' );
};
FB.ContactForm = (function() {
var fbForm = { // Main object that generated shortcode via AJAX call
'action' : 'grunion_shortcode',
'_ajax_nonce' : ajax_nonce_shortcode,
'to' : '',
'subject' : '',
'fields' : {}
};
var defaultFields = {
'name': {
'label' : GrunionFB_i18n.nameLabel,
'type' : 'name',
'required' : true,
'options' : [],
'order' : '1'
},
'email': {
'label' : GrunionFB_i18n.emailLabel,
'type' : 'email',
'required' : true,
'options' : [],
'order' : '2'
},
'url': {
'label' : GrunionFB_i18n.urlLabel,
'type' : 'url',
'required' : false,
'options' : [],
'order' : '3'
},
'comment': {
'label' : GrunionFB_i18n.commentLabel,
'type' : 'textarea',
'required' : true,
'options' : [],
'order' : '4'
}
};
var debug = false; // will print errors to log if true
var grunionNewCount = 0; // increment for new fields
var maxNewFields = GrunionFB_i18n.maxNewFields; // See filter in ../grunion-form-view.php
var optionsCache = {};
var optionsCount = 0; // increment for options
var shortcode;
function addField () {
try {
grunionNewCount++;
if (grunionNewCount <= maxNewFields) {
// Add to preview
jQuery('#fb-extra-fields').append('<div id="fb-new-field' + grunionNewCount + '" fieldid="' + grunionNewCount + '" class="fb-new-fields"><div class="fb-fields"><div id="' + grunionNewCount + '" class="fb-remove"></div><label fieldid="' + grunionNewCount + '" for="fb-field' + grunionNewCount + '"><span class="label-text">' + GrunionFB_i18n.newLabel + '</span> </label><input type="text" id="fb-field' + grunionNewCount + '" disabled="disabled" /></div></div>');
// Add to form object
fbForm.fields[grunionNewCount] = {
'label' : GrunionFB_i18n.newLabel,
'type' : 'text',
'required' : false,
'options' : [],
'order' : '5'
};
if (grunionNewCount === maxNewFields) {
jQuery('#fb-new-field').hide();
}
// Reset form for this new field
optionsCount = 0;
optionsCache = {};
jQuery('#fb-new-options').html('<label for="fb-option0">' + GrunionFB_i18n.optionsLabel + '</label><input type="text" id="fb-option0" optionid="0" value="' + GrunionFB_i18n.firstOptionLabel + '" class="fb-options" />');
jQuery('#fb-options').hide();
jQuery('#fb-new-label').val( GrunionFB_i18n.newLabel );
jQuery('#fb-new-type').val('text');
jQuery('#fb-field-id').val(grunionNewCount);
setTimeout(function () { jQuery('#fb-new-label').focus().select(); }, 100);
} else {
jQuery('#fb-new-field').hide();
}
} catch(e) {
if (debug) {
console.log('addField(): ' + e);
}
}
}
function addOption () {
try {
optionsCount = jQuery( '#fb-new-options .fb-options' ).length;
var thisId = jQuery('#fb-field-id').val();
var thisType = jQuery('#fb-new-type').val();
if (thisType === 'radio') {
// Add to right col
jQuery('#fb-new-options').append('<div id="fb-option-box-' + optionsCount + '" class="fb-new-fields"><span optionid="' + optionsCount + '" class="fb-remove-option"></span><label></label><input type="text" id="fb-option' + optionsCount + '" optionid="' + optionsCount + '" value="' + GrunionFB_i18n.optionLabel + '" class="fb-options" /><div>');
// Add to preview
jQuery('#fb-new-field' + thisId + ' .fb-fields').append('<div id="fb-radio-' + thisId + '-' + optionsCount + '"><input type="radio" disabled="disabled" id="fb-field' + thisId + '" name="radio-' + thisId + '" /><span>' + GrunionFB_i18n.optionLabel + '</span><div class="clear"></div></div>');
} else if ( 'checkbox-multiple' === thisType ) {
// Add to right col
jQuery('#fb-new-options').append('<div id="fb-option-box-' + optionsCount + '" class="fb-new-fields"><span optionid="' + optionsCount + '" class="fb-remove-option"></span><label></label><input type="text" id="fb-option' + optionsCount + '" optionid="' + optionsCount + '" value="' + GrunionFB_i18n.optionLabel + '" class="fb-options" /><div>');
// Add to preview
jQuery('#fb-new-field' + thisId + ' .fb-fields').append('<div id="fb-checkbox-multiple-' + thisId + '-' + optionsCount + '"><input type="checkbox" disabled="disabled" id="fb-field' + thisId + '" name="checkbox-multiple-' + thisId + '" /><span>' + GrunionFB_i18n.optionLabel + '</span><div class="clear"></div></div>');
} else {
// Add to right col
jQuery('#fb-new-options').append('<div id="fb-option-box-' + optionsCount + '" class="fb-new-fields"><span optionid="' + optionsCount + '" class="fb-remove-option"></span><label></label><input type="text" id="fb-option' + optionsCount + '" optionid="' + optionsCount + '" value="" class="fb-options" /><div>');
// Add to preview
jQuery('#fb-field'+ thisId).append('<option id="fb-' + thisId + '-' + optionsCount + '" value="' + thisId + '-' + optionsCount + '"></option>');
}
// Add to fbForm object
fbForm.fields[thisId].options[optionsCount] = '';
// Add focus to new field
jQuery('#fb-option' + optionsCount).focus().select();
} catch(e) {
if (debug) {
console.log('addOption(): ' + e);
}
}
}
function buildPreview () {
try {
if (fbForm.to) { jQuery('#fb-field-my-email').val(fbForm.to); }
if (fbForm.subject) { jQuery('#fb-field-subject').val(fbForm.subject); }
// Loop over and add fields
jQuery.each(fbForm.fields, function(index, value) {
jQuery('#fb-extra-fields').before('<div class="fb-new-fields ui-state-default" fieldid="' + index + '" id="fb-new-field' + index + '"><div class="fb-fields"></div></div>');
jQuery('#fb-field-id').val(index);
optionsCache[index] = {};
optionsCache[index].options = [];
if ( 'radio' === value.type || 'select' === value.type || 'checkbox-multiple' === value.type ) {
jQuery.each(value.options, function(i, value) {
optionsCache[index].options[i] = value;
});
}
updateType(value.type, value.label, value.required);
});
} catch(e) {
if (debug) {
console.log('buildPreview(): ' + e);
}
}
}
function customOptions (id, thisType) {
try {
var thisOptions = '';
for (var i=0; i<optionsCache[id].options.length; i++) {
if (optionsCache[id].options[i] !== undefined) {
if (thisType === 'radio') {
thisOptions = thisOptions + '<div id="fb-radio-' + id + '-' + i + '"><input type="radio" id="fb-field' + id + '" name="radio-' + id + '" /><span>' + FB.esc_html( optionsCache[id].options[i] ) + '</span><div class="clear"></div></div>';
} else if ( 'checkbox-multiple' === thisType ) {
thisOptions = thisOptions + '<div id="fb-checkbox-multiple-' + id + '-' + i + '"><input type="checkbox" id="fb-field' + id + '" name="checkbox-multiple-' + id + '" /><span>' + FB.esc_html( optionsCache[id].options[i] ) + '</span><div class="clear"></div></div>';
} else {
thisOptions = thisOptions + '<option id="fb-' + id + '-' + i + '" value="' + id + '-' + i + '">' + FB.esc_html( optionsCache[id].options[i] ) + '</option>';
}
}
}
return thisOptions;
} catch(e) {
if (debug) {
console.log('customOptions(): ' + e);
}
}
}
function deleteField (that) {
try {
grunionNewCount--;
var thisId = that.attr('id');
delete fbForm.fields[thisId];
jQuery('#' + thisId).parent().parent().remove();
if (grunionNewCount <= maxNewFields) {
jQuery('#fb-new-field').show();
}
} catch(e) {
if (debug) {
console.log('deleteField(): ' + e);
}
}
}
function editField (that) {
try {
scroll(0,0);
setTimeout(function () { jQuery('#fb-new-label').focus().select(); }, 100);
var thisId = that.parent().attr('fieldid');
loadFieldEditor(thisId);
} catch(e) {
if (debug) {
console.log('editField(): ' + e);
}
}
}
function grabShortcode () {
try {
// Takes fbForm object and returns shortcode syntax
jQuery.post(ajaxurl, fbForm, function(response) {
shortcode = response;
});
} catch(e) {
alert( GrunionFB_i18n.problemGeneratingForm );
if (debug) {
console.log('grabShortcode(): ' + e);
}
}
}
function hideDesc () {
jQuery('#fb-desc').hide();
jQuery('#fb-add-field').show();
}
function hidePopup () {
try {
// copied from wp-includes/js/thickbox/thickbox.js
jQuery('#TB_imageOff', window.parent.document).unbind('click');
jQuery('#TB_closeWindowButton', window.parent.document).unbind('click');
jQuery('#TB_window', window.parent.document).fadeOut('fast');
jQuery('body', window.parent.document).removeClass('modal-open');
jQuery('#TB_window,#TB_overlay,#TB_HideSelect', window.parent.document).trigger('unload').unbind().remove();
jQuery('#TB_load', window.parent.document).remove();
if (typeof window.parent.document.body.style.maxHeight === 'undefined') {//if IE 6
jQuery('body', 'html', window.parent.document).css({height: 'auto', width: 'auto'});
jQuery('html', window.parent.document).css('overflow', '');
}
window.parent.document.onkeydown = '';
window.parent.document.onkeyup = '';
return false;
} catch(e) {
if (debug) {
console.log('hidePopup(): ' + e);
}
}
}
function hideShowEditLink (whichType, that) {
try {
if (whichType === 'show') {
// Prevents showing links twice
if (jQuery('.fb-edit-field').is(':visible')) {
jQuery('.fb-edit-field').remove();
}
that.find('label').prepend('<span class="right fb-edit-field" style="font-weight: normal;"><a href="" class="fb-reorder"><div style="display: none;">' + GrunionFB_i18n.moveInstructions + '</div>' + GrunionFB_i18n.moveLabel + '</a>&nbsp;&nbsp;<span style="color: #C7D8DE;">|</span>&nbsp;&nbsp;<a href="" class="fb-edit">' + GrunionFB_i18n.editLabel + '</a></span>');
} else {
jQuery('.fb-edit-field').remove();
}
} catch(e) {
if (debug) {
console.log('hideShowEditLink(): ' + e);
}
}
}
function loadFieldEditor (id) {
try {
var thisType = fbForm.fields[id].type;
jQuery('#fb-options').hide();
// Reset hidden field ID
jQuery('#fb-field-id').val(id);
// Load label
jQuery('#fb-new-label').val(fbForm.fields[id].label);
// Load type
jQuery('#fb-new-type').val(fbForm.fields[id].type);
// Load required
if (fbForm.fields[id].required) {
jQuery('#fb-new-required').prop('checked', true);
} else {
jQuery('#fb-new-required').prop('checked', false);
}
// Load options if there are any
if ( 'select' === thisType || 'radio' === thisType || 'checkbox-multiple' === thisType ) {
var thisOptions = fbForm.fields[id].options;
jQuery('#fb-options').show();
jQuery('#fb-new-options').html(''); // Clear it all out
for (var i=0; i<thisOptions.length; i++) {
if (thisOptions[i] !== undefined) {
if (thisType === 'radio') {
jQuery('#fb-new-options').append('<div id="fb-option-box-' + i + '" class="fb-new-fields"><span optionid="' + i + '" class="fb-remove-option"></span><label></label><input type="text" id="fb-option' + i + '" optionid="' + i + '" value="' + FB.esc_attr( fbForm.fields[id].options[i] ) + '" class="fb-options" /><div>');
} else {
jQuery('#fb-new-options').append('<div id="fb-option-box-' + i + '" class="fb-new-fields"><span optionid="' + i + '" class="fb-remove-option"></span><label></label><input type="text" id="fb-option' + i + '" optionid="' + i + '" value="' + FB.esc_attr( fbForm.fields[id].options[i] ) + '" class="fb-options" /><div>');
}
}
}
}
// Load editor & hide description
hideDesc();
} catch(e) {
if (debug) {
console.log('loadFieldEditor(): ' + e);
}
}
}
function parseShortcode (data) {
try {
// Clean up fields by resetting them
fbForm.fields = {};
// Add new fields
if (!data) {
fbForm.fields = defaultFields;
} else {
jQuery.each(data.fields, function(index, value) {
if ( 1 === parseInt(value.required, 10) ) {
value.required = 'true';
}
fbForm.fields[index] = value;
});
fbForm.to = data.to;
fbForm.subject = data.subject;
}
} catch(e) {
if (debug) {
console.log('parseShortcode(): ' + e);
}
}
}
function removeOption (optionId) {
try {
var thisId = jQuery('#fb-field-id').val();
var thisVal = jQuery('#fb-option' + optionId).val();
var thisType = jQuery('#fb-new-type').val();
// Remove from right
jQuery('#fb-option-box-' + optionId).remove();
// Remove from preview
if (thisType === 'radio') {
jQuery('#fb-radio-' + thisId + '-' + optionId).remove();
} else if ( 'checkbox-multiple' === thisType ) {
jQuery('#fb-checkbox-multiple-' + thisId + '-' + optionId).remove();
} else {
jQuery('#fb-' + thisId + '-' + optionId).remove();
}
// Remove from fbForm object
var idx = fbForm.fields[thisId].options.indexOf(thisVal);
if (idx !== -1) { fbForm.fields[thisId].options.splice(idx, 1); }
} catch(e) {
if (debug) {
console.log('removeOption(): ' + e);
}
}
}
function removeOptions () {
try {
var thisId = jQuery('#fb-field-id').val();
jQuery('#fb-options').hide();
if (optionsCache[thisId] === undefined) { optionsCache[thisId] = {}; }
optionsCache[thisId].options = fbForm.fields[thisId].options; // Save options in case they change their mind
fbForm.fields[thisId].options = []; // Removes all options
} catch(e) {
if (debug) {
console.log('removeOptions(): ' + e);
}
}
}
function sendShortcodeToEditor () {
try {
// Serialize fields
jQuery('div#sortable div.fb-new-fields').each(function(index) {
var thisId = jQuery(this).attr('fieldid');
fbForm.fields[thisId].order = index;
});
// Export to WYSIWYG editor
jQuery.post(ajaxurl, fbForm, function(response) {
var isVisual = jQuery('#edButtonPreview', window.parent.document).hasClass('active');
/* WP 3.3+ */
if ( !isVisual ) {
isVisual = jQuery( '#wp-content-wrap', window.parent.document ).hasClass( 'tmce-active' );
}
var win = window.dialogArguments || opener || parent || top;
var currentCode;
if (isVisual) {
currentCode = win.tinyMCE.activeEditor.getContent();
} else {
currentCode = jQuery('#editorcontainer textarea', window.parent.document).val();
/* WP 3.3+ */
if ( typeof currentCode !== 'string' ) {
currentCode = jQuery( '.wp-editor-area', window.parent.document ).val();
}
}
var regexp = new RegExp('\\[contact-form\\b.*?\\/?\\](?:[\\s\\S]+?\\[\\/contact-form\\])?');
// Remove new lines that cause BR tags to show up
response = response.replace(/\n/g,' ');
// Convert characters to comma
response = response.replace( /%26#x002c;/g , ',' );
// Add new shortcode
if (currentCode.match(regexp)) {
if (isVisual) {
win.tinyMCE.activeEditor.execCommand('mceSetContent', false, currentCode.replace(regexp, response));
} else {
// looks like the visual editor is disabled,
// update the contents of the post directly
jQuery( '#content', window.parent.document ).val( currentCode.replace( regexp, response ) );
}
} else {
try {
win.send_to_editor( response );
} catch ( e ) {
if (isVisual) {
win.tinyMCE.activeEditor.execCommand('mceInsertContent', false, response);
} else {
// looks like the visual editor is disabled,
// update the contents of the post directly
jQuery( '#content', window.parent.document ).val( currentCode + response );
}
}
}
hidePopup();
});
} catch(e) {
if (debug) {
console.log('sendShortcodeToEditor(): ' + e);
}
}
}
function showDesc () {
jQuery('#fb-desc').show();
jQuery('#fb-add-field').hide();
}
function showAndHideMessage (message) {
try {
var newMessage = (!message) ? GrunionFB_i18n.savedMessage : message;
jQuery('#fb-success').text(newMessage);
jQuery('#fb-success').slideDown('fast');
setTimeout(function () {
jQuery('#fb-success').slideUp('fast');
}, 2500);
} catch(e) {
if (debug) {
console.log('showAndHideMessage(): ' + e);
}
}
}
function switchTabs (whichType) {
try {
if (whichType === 'preview') {
if ( ! validateEmails( jQuery( '#fb-field-my-email' ).val() ) ) {
return;
}
jQuery('#tab-preview a').addClass('current');
jQuery('#tab-settings a').removeClass('current');
jQuery('#fb-preview-form, #fb-desc').show();
jQuery('#fb-email-settings, #fb-email-desc').hide();
showAndHideMessage( GrunionFB_i18n.savedMessage );
} else {
jQuery('#tab-preview a').removeClass('current');
jQuery('#tab-settings a').addClass('current');
jQuery('#fb-preview-form, #fb-desc, #fb-add-field').hide();
jQuery('#fb-email-settings, #fb-email-desc').show();
jQuery('#fb-field-my-email').focus().select();
}
} catch(e) {
if (debug) {
console.log('switchTabs(): ' + e);
}
}
}
function validateEmails( emails ) {
// Field is allowed to be empty :)
if ( 0 === emails.length ) {
return true;
}
var $e, emailList = emails.split( ',' );
for ( $e = 0 ; $e < emailList.length ; $e++ ) {
if ( false === validateEmail( emailList[ $e ] ) ) {
alert( emailList[ $e ] + GrunionFB_i18n.invalidEmail );
return false;
}
}
return true;
}
/* Uses The Official Standard: RFC 5322 -- http://www.regular-expressions.info/email.html */
function validateEmail( email ) {
var re = /[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/i;
return re.test( email );
}
function updateLabel () {
try {
var thisId = jQuery('#fb-field-id').val();
var thisLabel = jQuery('#fb-new-label').val();
// Update preview
if (thisLabel.length === 0) {
jQuery('#fb-new-field' + thisId + ' label .label-text').text( GrunionFB_i18n.newLabel );
} else {
jQuery('#fb-new-field' + thisId + ' label .label-text').text( thisLabel );
}
// Update fbForm object
fbForm.fields[thisId].label = thisLabel;
} catch(e) {
if (debug) {
console.log('updateLabel(): ' + e);
}
}
}
function updateMyEmail () {
try {
var thisEmail = jQuery('#fb-field-my-email').val();
fbForm.to = thisEmail;
} catch(e) {
if (debug) {
console.log('updateMyEmail(): ' + e);
}
}
}
function updateOption (that) {
try {
var thisId = jQuery('#fb-field-id').val();
var thisOptionid = that.attr('optionid');
var thisOptionValue = that.val();
var thisType = jQuery('#fb-new-type').val();
// Update preview
if (thisType === 'radio') {
jQuery('#fb-radio-' + thisId + '-' + thisOptionid + ' span').text(thisOptionValue);
} else if ( 'checkbox-multiple' === thisType ) {
jQuery('#fb-checkbox-multiple-' + thisId + '-' + thisOptionid + ' span').text(thisOptionValue);
} else {
jQuery('#fb-' + thisId + '-' + thisOptionid).text(thisOptionValue);
}
// Update fbForm object
fbForm.fields[thisId].options[thisOptionid] = thisOptionValue;
} catch(e) {
if (debug) {
console.log('updateOption(): ' + e);
}
}
}
function updateRequired () {
try {
var thisId = jQuery('#fb-field-id').val();
var thisChecked = jQuery('#fb-new-required').is(':checked');
// Update object and preview
if (thisChecked) {
fbForm.fields[thisId].required = true;
jQuery('#fb-new-field' + thisId + ' label').append('<span class="label-required">' + GrunionFB_i18n.requiredLabel + '</span>');
} else {
fbForm.fields[thisId].required = false;
jQuery('#fb-new-field' + thisId + ' label .label-required').remove();
}
} catch(e) {
if (debug) {
console.log('updateRequired(): ' + e);
}
}
}
function updateSubject () {
try {
var thisSubject = jQuery('#fb-field-subject').val();
fbForm.subject = thisSubject;
} catch(e) {
if (debug) {
console.log('updateSubject(): ' + e);
}
}
}
function updateType(thisType, thisLabelText, thisRequired) {
try {
var thisId = jQuery('#fb-field-id').val();
if (!thisType) { thisType = jQuery('#fb-new-type').val(); }
if (!thisLabelText) { thisLabelText = jQuery('#fb-new-field' + thisId + ' .label-text').text(); }
var isRequired = (thisRequired) ? '<span class="label-required">' + GrunionFB_i18n.requiredLabel + '</span>' : '';
var thisLabel = '<label fieldid="' + thisId + '" for="fb-field' + thisId + '"><span class="label-text">' + FB.esc_html( thisLabelText ) + '</span>' + isRequired + '</label>';
var thisRadio = '<input type="radio" name="radio-' + thisId + '" id="fb-field' + thisId + ' "disabled="disabled" />';
var thisRadioLabel = '<label fieldid="' + thisId + '" for="fb-field' + thisId + '" class="fb-radio-label"><span class="label-text">' + FB.esc_html( thisLabelText ) + '</span>' + isRequired + '</label>';
var thisRadioRemove = '<div class="fb-remove fb-remove-small" id="' + thisId + '"></div>';
var thisRemove = '<div class="fb-remove" id="' + thisId + '"></div>';
var thisCheckbox = '<input type="checkbox" id="fb-field' + thisId + '" "disabled="disabled" />';
var thisCheckboxMultiple = '<input type="checkbox" id="fb-field' + thisId + '" "disabled="disabled" />';
var thisCheckboxMultipleRemove = '<div class="fb-remove fb-remove-small" id="' + thisId + '"></div>';
var thisText = '<input type="text" id="fb-field' + thisId + '" "disabled="disabled" />';
var thisTextarea = '<textarea id="fb-field' + thisId + '" "disabled="disabled"></textarea>';
var thisClear = '<div class="clear"></div>';
var thisSelect = '<select id="fb-field' + thisId + '" fieldid="' + thisId + '"><option id="fb-' + thisId + '-' + optionsCount + '" value="' + thisId + '-' + optionsCount + '">' + GrunionFB_i18n.firstOptionLabel + '</option></select>';
switch (thisType) {
case 'checkbox':
removeOptions();
jQuery('#fb-new-field' + thisId + ' .fb-fields').html(thisRadioRemove + thisCheckbox + thisRadioLabel + thisClear);
break;
case 'checkbox-multiple':
jQuery('#fb-new-field' + thisId + ' .fb-fields').html(thisLabel + thisCheckboxMultipleRemove + '<div fieldid="' + thisId + '" id="fb-custom-checkbox-multiple' + thisId + '"></div>');
if (optionsCache[thisId] !== undefined && optionsCache[thisId].options.length !== 0) {
fbForm.fields[thisId].options = optionsCache[thisId].options;
jQuery('#fb-custom-checkbox-multiple' + thisId).append(customOptions(thisId, thisType));
} else {
jQuery('#fb-new-options').html('<label for="fb-option0">' + GrunionFB_i18n.optionsLabel + '</label><input type="text" id="fb-option0" optionid="0" value="' + GrunionFB_i18n.firstOptionLabel + '" class="fb-options" />');
jQuery('#fb-custom-checkbox-multiple' + thisId).append('<div id="fb-checkbox-multiple-' + thisId + '-0">' + thisCheckboxMultiple + '<span>' + GrunionFB_i18n.firstOptionLabel + '</span>' + thisClear + '</div>');
fbForm.fields[thisId].options[optionsCount] = GrunionFB_i18n.firstOptionLabel;
}
jQuery('#fb-options').show();
setTimeout(function () { jQuery('#fb-option0').focus().select(); }, 100);
break;
case 'email':
removeOptions();
jQuery('#fb-new-field' + thisId + ' .fb-fields').html(thisRemove + thisLabel + thisText);
break;
case 'name':
removeOptions();
jQuery('#fb-new-field' + thisId + ' .fb-fields').html(thisRemove + thisLabel + thisText);
break;
case 'radio':
jQuery('#fb-new-field' + thisId + ' .fb-fields').html(thisLabel + thisRadioRemove + '<div fieldid="' + thisId + '" id="fb-custom-radio' + thisId + '"></div>');
if (optionsCache[thisId] !== undefined && optionsCache[thisId].options.length !== 0) {
fbForm.fields[thisId].options = optionsCache[thisId].options;
jQuery('#fb-custom-radio' + thisId).append(customOptions(thisId, thisType));
} else {
jQuery('#fb-new-options').html('<label for="fb-option0">' + GrunionFB_i18n.optionsLabel + '</label><input type="text" id="fb-option0" optionid="0" value="' + GrunionFB_i18n.firstOptionLabel + '" class="fb-options" />');
jQuery('#fb-custom-radio' + thisId).append('<div id="fb-radio-' + thisId + '-0">' + thisRadio + '<span>' + GrunionFB_i18n.firstOptionLabel + '</span>' + thisClear + '</div>');
fbForm.fields[thisId].options[optionsCount] = GrunionFB_i18n.firstOptionLabel;
}
jQuery('#fb-options').show();
setTimeout(function () { jQuery('#fb-option0').focus().select(); }, 100);
break;
case 'select':
jQuery('#fb-new-field' + thisId + ' .fb-fields').html(thisRemove + thisLabel + thisSelect);
if (optionsCache[thisId] !== undefined && optionsCache[thisId].options.length !== 0) {
fbForm.fields[thisId].options = optionsCache[thisId].options;
jQuery('#fb-field' + thisId).html(customOptions(thisId, thisType));
} else {
jQuery('#fb-new-options').html('<label for="fb-option0">' + GrunionFB_i18n.optionsLabel + '</label><input type="text" id="fb-option0" optionid="0" value="' + GrunionFB_i18n.firstOptionLabel + '" class="fb-options" />');
fbForm.fields[thisId].options[optionsCount] = GrunionFB_i18n.firstOptionLabel;
}
jQuery('#fb-options').show();
setTimeout(function () { jQuery('#fb-option0').focus().select(); }, 100);
break;
case 'text':
removeOptions();
jQuery('#fb-new-field' + thisId + ' .fb-fields').html(thisRemove + thisLabel + thisText);
break;
case 'textarea':
removeOptions();
jQuery('#fb-new-field' + thisId + ' .fb-fields').html(thisRemove + thisLabel + thisTextarea);
break;
case 'url':
removeOptions();
jQuery('#fb-new-field' + thisId + ' .fb-fields').html(thisRemove + thisLabel + thisText);
break;
}
// update object
fbForm.fields[thisId].type = thisType;
} catch(e) {
if (debug) {
console.log('updateType(): ' + e);
}
}
}
return {
resizePop: function () {
try {
//Thickbox won't resize for some reason, we are manually doing it here
var totalWidth = jQuery('body', window.parent.document).width();
var totalHeight = jQuery('body', window.parent.document).height();
var isIE6 = typeof document.body.style.maxHeight === 'undefined';
jQuery('#TB_window, #TB_iframeContent', window.parent.document).css('width', '768px');
jQuery('#TB_window', window.parent.document).css({ left: (totalWidth-768)/2 + 'px', top: '23px', position: 'absolute', marginLeft: '0' });
if ( ! isIE6 ) { // take away IE6
jQuery('#TB_window, #TB_iframeContent', window.parent.document).css('height', (totalHeight-73) + 'px');
}
} catch(e) {
if (debug) {
console.log('resizePop(): ' + e);
}
}
},
init: function () {
// Scroll to top of page
window.parent.scroll(0,0);
//Check for existing form data
var contentSource;
if (jQuery('#edButtonPreview', window.parent.document).hasClass('active') || jQuery( '#wp-content-wrap', window.parent.document ).hasClass( 'tmce-active' ) ) {
var win = window.dialogArguments || opener || parent || top;
contentSource = win.tinyMCE.activeEditor.getContent();
} else {
contentSource = jQuery('#content', window.parent.document).val();
}
var data = {
action: 'grunion_shortcode_to_json',
'_ajax_nonce' : ajax_nonce_json,
post_id: postId,
content: contentSource
};
var $doc = jQuery(document);
jQuery.post(ajaxurl, data, function(response) {
// Setup fbForm
parseShortcode(jQuery.parseJSON(response));
// Now build out the preview form
buildPreview();
});
// actions
jQuery('.fb-add-field').click(function () {
addField();
hideDesc();
return false;
});
jQuery('#fb-new-label').keyup(function () {
updateLabel();
});
jQuery('#fb-new-type').change(function () {
updateType();
});
jQuery('#fb-new-required').click(function () {
updateRequired();
});
$doc.on('click', '.fb-remove', function () {
showDesc();
deleteField(jQuery(this));
grabShortcode();
});
jQuery('#fb-preview').submit(function () {
sendShortcodeToEditor();
return false;
});
jQuery('#TB_overlay, #TB_closeWindowButton', window.parent.document).mousedown(function () {
if(confirm( GrunionFB_i18n.exitConfirmMessage )) {
hidePopup();
}
});
$doc.on('click', '#fb-another-option', function () {
addOption();
});
$doc.on('keyup', '.fb-options', function () {
updateOption(jQuery(this));
});
$doc.on('click', '.fb-remove-option', function () {
removeOption(jQuery(this).attr('optionid'));
});
jQuery('#tab-preview a').click(function () {
switchTabs('preview');
return false;
});
jQuery('#fb-prev-form').click(function () {
switchTabs('preview');
return false;
});
jQuery('#tab-settings a').click(function () {
switchTabs();
return false;
});
jQuery('#fb-field-my-email').blur(function () {
updateMyEmail();
});
jQuery('#fb-field-subject').blur(function () {
updateSubject();
});
$doc.on('mouseenter', '.fb-form-case .fb-new-fields', function () {
hideShowEditLink('show', jQuery(this));
});
$doc.on('mouseleave', '.fb-form-case .fb-new-fields', function () {
hideShowEditLink('hide');
return false;
});
$doc.on('click', '.fb-edit-field', function () {
editField(jQuery(this));
return false;
});
$doc.on('click', '.fb-edit-field .fb-reorder', function () {
return false;
});
$doc.on('click', '#fb-save-field', function () {
showDesc();
showAndHideMessage();
return false;
});
jQuery('#fb-feedback').click(function () {
var thisHref = jQuery(this).attr('href');
window.parent.location = thisHref;
return false;
});
jQuery('#sortable').sortable({
axis: 'y',
handle: '.fb-reorder',
revert: true,
start: function() { jQuery('.fb-edit-field').hide(); }
});
jQuery('#draggable').draggable({
axis: 'y',
handle: '.fb-reorder',
connectToSortable: '#sortable',
helper: 'clone',
revert: 'invalid'
});
}
};
})();

View File

@@ -0,0 +1,34 @@
/* global grunionEditorView, tinymce */
(function() {
tinymce.create( 'tinymce.plugins.grunion_form', {
init : function( editor ) {
editor.addButton( 'grunion', {
title : grunionEditorView.labels.tinymce_label,
cmd : 'grunion_add_form',
icon : 'grunion'
});
editor.addCommand('grunion_add_form', function() {
if ( grunionEditorView.default_form ) {
editor.execCommand( 'mceInsertContent', 0, '[contact-form]' + grunionEditorView.default_form + '[/contact-form]' );
} else {
editor.execCommand( 'mceInsertContent', 0, '[contact-form /]' );
}
});
},
createControl : function() {
return null;
},
getInfo : function() {
return {
longname : 'Grunion Contact Form',
author : 'Automattic',
version : '1'
};
}
});
tinymce.PluginManager.add( 'grunion_form', tinymce.plugins.grunion_form );
})();

View File

@@ -0,0 +1,53 @@
<?php
/**
* Module Name: Custom content types
* Module Description: Display different types of content on your site with custom content types.
* First Introduced: 3.1
* Requires Connection: No
* Auto Activate: Yes
* Module Tags: Writing
* Sort Order: 34
* Feature: Writing
* Additional Search Queries: cpt, custom post types, portfolio, portfolios, testimonial, testimonials
*/
function jetpack_load_custom_post_types() {
include dirname( __FILE__ ) . "/custom-post-types/portfolios.php";
}
function jetpack_custom_post_types_loaded() {
Jetpack::enable_module_configurable( __FILE__ );
Jetpack::module_configuration_load( __FILE__, 'jetpack_custom_post_types_configuration_load' );
}
add_action( 'jetpack_modules_loaded', 'jetpack_custom_post_types_loaded' );
function jetpack_custom_post_types_configuration_load() {
wp_safe_redirect( admin_url( 'options-writing.php#cpt-options' ) );
exit;
}
// Add Settings Section for CPT
function jetpack_cpt_settings_api_init() {
add_settings_section(
'jetpack_cpt_section',
'<span id="cpt-options">' . __( 'Your Custom Content Types', 'jetpack' ) . '</span>',
'jetpack_cpt_section_callback',
'writing'
);
}
add_action( 'admin_init', 'jetpack_cpt_settings_api_init' );
/*
* Settings Description
*/
function jetpack_cpt_section_callback() {
?>
<p>
<?php esc_html_e( 'Use these settings to display different types of content on your site.', 'jetpack' ); ?>
<a target="_blank" href="http://jetpack.com/support/custom-content-types/"><?php esc_html_e( 'Learn More', 'jetpack' ); ?></a>
</p>
<?php
}
jetpack_load_custom_post_types();

View File

@@ -0,0 +1,70 @@
<?php
/**
* Module Name: Custom CSS
* Module Description: Tweak your sites CSS without modifying your theme.
* Sort Order: 2
* First Introduced: 1.7
* Requires Connection: No
* Auto Activate: Yes
* Module Tags: Appearance
* Feature: Appearance
* Additional Search Queries: css, customize, custom, style, editor, less, sass, preprocessor, font, mobile, appearance, theme, stylesheet
*/
function jetpack_load_custom_css() {
// If WordPress has the core version of Custom CSS, load our new version.
// @see https://core.trac.wordpress.org/changeset/38829
if ( function_exists( 'wp_get_custom_css' ) ) {
if ( ! function_exists( 'wp_update_custom_css_post' ) ) {
wp_die( 'Please run a SVN up to get the latest version of trunk, or update to at least 4.7 RC1' );
}
if ( ! Jetpack_Options::get_option( 'custom_css_4.7_migration' ) ) {
include_once dirname( __FILE__ ) . '/custom-css/migrate-to-core.php';
}
// TODO: DELETE THIS
else {
if ( defined( 'WP_CLI' ) && WP_CLI ) {
function jetpack_custom_css_undo_data_migration_cli() {
Jetpack_Options::delete_option( 'custom_css_4.7_migration' );
WP_CLI::success( __( 'Option deleted, re-migrate via `wp jetpack custom-css migrate`.', 'jetpack' ) );
}
WP_CLI::add_command( 'jetpack custom-css undo-migrate', 'jetpack_custom_css_undo_data_migration_cli' );
}
}
// TODO: END DELETE THIS
include_once dirname( __FILE__ ) . '/custom-css/custom-css/preprocessors.php';
include_once dirname( __FILE__ ) . '/custom-css/custom-css-4.7.php';
return;
}
include_once dirname( __FILE__ ) . "/custom-css/custom-css.php";
add_action( 'init', array( 'Jetpack_Custom_CSS', 'init' ) );
}
add_action( 'jetpack_modules_loaded', 'custom_css_loaded' );
function custom_css_loaded() {
Jetpack::enable_module_configurable( __FILE__ );
Jetpack::module_configuration_load( __FILE__, 'custom_css_configuration_load' );
}
function custom_css_configuration_load() {
// Redirect to Core's CSS editor in the customizer if the feature is available.
if ( function_exists( 'wp_get_custom_css' ) ) {
$configuration_link = Jetpack_Custom_CSS_Enhancements::customizer_link(
array(
'return_url' => wp_get_referer(),
)
);
} else {
$configuration_link = admin_url( 'themes.php?page=editcss#settingsdiv' );
}
wp_safe_redirect( $configuration_link );
exit;
}
jetpack_load_custom_css();

View File

@@ -0,0 +1,46 @@
<?php
/**
* CSSTidy - CSS Parser and Optimiser
*
* CSS ctype functions
* Defines some functions that can be not defined.
*
* This file is part of CSSTidy.
*
* CSSTidy 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.
*
* CSSTidy 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 CSSTidy; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
* @package csstidy
* @author Nikolay Matsievsky (speed at webo dot name) 2009-2010
* @version 1.0
*/
/* ctype_space Check for whitespace character(s) */
if (!function_exists('ctype_space')) {
function ctype_space($text) {
return!preg_match("/[^\s\r\n\t\f]/", $text);
}
}
/* ctype_alpha Check for alphabetic character(s) */
if (!function_exists('ctype_alpha')) {
function ctype_alpha($text) {
return preg_match("/[a-zA-Z]/", $text);
}
}
?>

View File

@@ -0,0 +1,938 @@
<?php
/**
* CSSTidy - CSS Parser and Optimiser
*
* CSS Optimising Class
* This class optimises CSS data generated by csstidy.
*
* Copyright 2005, 2006, 2007 Florian Schmitz
*
* This file is part of CSSTidy.
*
* CSSTidy is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* CSSTidy 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @license http://opensource.org/licenses/lgpl-license.php GNU Lesser General Public License
* @package csstidy
* @author Florian Schmitz (floele at gmail dot com) 2005-2007
* @author Brett Zamir (brettz9 at yahoo dot com) 2007
* @author Nikolay Matsievsky (speed at webo dot name) 2009-2010
*/
/**
* CSS Optimising Class
*
* This class optimises CSS data generated by csstidy.
*
* @package csstidy
* @author Florian Schmitz (floele at gmail dot com) 2005-2006
* @version 1.0
*/
class csstidy_optimise {
/**
* Constructor
* @param array $css contains the class csstidy
* @access private
* @version 1.0
*/
function __construct(&$css) {
$this->parser = & $css;
$this->css = & $css->css;
$this->sub_value = & $css->sub_value;
$this->at = & $css->at;
$this->selector = & $css->selector;
$this->property = & $css->property;
$this->value = & $css->value;
}
function csstidy_optimise(&$css) {
$this->__construct($css);
}
/**
* Optimises $css after parsing
* @access public
* @version 1.0
*/
function postparse() {
if ($this->parser->get_cfg('preserve_css')) {
return;
}
if ($this->parser->get_cfg('merge_selectors') === 2) {
foreach ($this->css as $medium => $value) {
$this->merge_selectors($this->css[$medium]);
}
}
if ($this->parser->get_cfg('discard_invalid_selectors')) {
foreach ($this->css as $medium => $value) {
$this->discard_invalid_selectors($this->css[$medium]);
}
}
if ($this->parser->get_cfg('optimise_shorthands') > 0) {
foreach ($this->css as $medium => $value) {
foreach ($value as $selector => $value1) {
$this->css[$medium][$selector] = csstidy_optimise::merge_4value_shorthands($this->css[$medium][$selector]);
if ($this->parser->get_cfg('optimise_shorthands') < 2) {
continue;
}
$this->css[$medium][$selector] = csstidy_optimise::merge_font($this->css[$medium][$selector]);
if ($this->parser->get_cfg('optimise_shorthands') < 3) {
continue;
}
$this->css[$medium][$selector] = csstidy_optimise::merge_bg($this->css[$medium][$selector]);
if (empty($this->css[$medium][$selector])) {
unset($this->css[$medium][$selector]);
}
}
}
}
}
/**
* Optimises values
* @access public
* @version 1.0
*/
function value() {
$shorthands = & $GLOBALS['csstidy']['shorthands'];
// optimise shorthand properties
if (isset($shorthands[$this->property])) {
$temp = csstidy_optimise::shorthand($this->value); // FIXME - move
if ($temp != $this->value) {
$this->parser->log('Optimised shorthand notation (' . $this->property . '): Changed "' . $this->value . '" to "' . $temp . '"', 'Information');
}
$this->value = $temp;
}
// Remove whitespace at ! important
if ($this->value != $this->compress_important($this->value)) {
$this->parser->log('Optimised !important', 'Information');
}
}
/**
* Optimises shorthands
* @access public
* @version 1.0
*/
function shorthands() {
$shorthands = & $GLOBALS['csstidy']['shorthands'];
if (!$this->parser->get_cfg('optimise_shorthands') || $this->parser->get_cfg('preserve_css')) {
return;
}
if ($this->property === 'font' && $this->parser->get_cfg('optimise_shorthands') > 1) {
$this->css[$this->at][$this->selector]['font']='';
$this->parser->merge_css_blocks($this->at, $this->selector, csstidy_optimise::dissolve_short_font($this->value));
}
if ($this->property === 'background' && $this->parser->get_cfg('optimise_shorthands') > 2) {
$this->css[$this->at][$this->selector]['background']='';
$this->parser->merge_css_blocks($this->at, $this->selector, csstidy_optimise::dissolve_short_bg($this->value));
}
if (isset($shorthands[$this->property])) {
$this->parser->merge_css_blocks($this->at, $this->selector, csstidy_optimise::dissolve_4value_shorthands($this->property, $this->value));
if (is_array($shorthands[$this->property])) {
$this->css[$this->at][$this->selector][$this->property] = '';
}
}
}
/**
* Optimises a sub-value
* @access public
* @version 1.0
*/
function subvalue() {
$replace_colors = & $GLOBALS['csstidy']['replace_colors'];
$this->sub_value = trim($this->sub_value);
if ($this->sub_value == '') { // caution : '0'
return;
}
$important = '';
if (csstidy::is_important($this->sub_value)) {
$important = '!important';
}
$this->sub_value = csstidy::gvw_important($this->sub_value);
// Compress font-weight
if ($this->property === 'font-weight' && $this->parser->get_cfg('compress_font-weight')) {
if ($this->sub_value === 'bold') {
$this->sub_value = '700';
$this->parser->log('Optimised font-weight: Changed "bold" to "700"', 'Information');
} else if ($this->sub_value === 'normal') {
$this->sub_value = '400';
$this->parser->log('Optimised font-weight: Changed "normal" to "400"', 'Information');
}
}
$temp = $this->compress_numbers($this->sub_value);
if (strcasecmp($temp, $this->sub_value) !== 0) {
if (strlen($temp) > strlen($this->sub_value)) {
$this->parser->log('Fixed invalid number: Changed "' . $this->sub_value . '" to "' . $temp . '"', 'Warning');
} else {
$this->parser->log('Optimised number: Changed "' . $this->sub_value . '" to "' . $temp . '"', 'Information');
}
$this->sub_value = $temp;
}
if ($this->parser->get_cfg('compress_colors')) {
$temp = $this->cut_color($this->sub_value);
if ($temp !== $this->sub_value) {
if (isset($replace_colors[$this->sub_value])) {
$this->parser->log('Fixed invalid color name: Changed "' . $this->sub_value . '" to "' . $temp . '"', 'Warning');
} else {
$this->parser->log('Optimised color: Changed "' . $this->sub_value . '" to "' . $temp . '"', 'Information');
}
$this->sub_value = $temp;
}
}
$this->sub_value .= $important;
}
/**
* Compresses shorthand values. Example: margin:1px 1px 1px 1px -> margin:1px
* @param string $value
* @access public
* @return string
* @version 1.0
*/
static function shorthand($value) {
$important = '';
if (csstidy::is_important($value)) {
$values = csstidy::gvw_important($value);
$important = '!important';
}
else
$values = $value;
$values = explode(' ', $values);
switch (count($values)) {
case 4:
if ($values[0] == $values[1] && $values[0] == $values[2] && $values[0] == $values[3]) {
return $values[0] . $important;
} elseif ($values[1] == $values[3] && $values[0] == $values[2]) {
return $values[0] . ' ' . $values[1] . $important;
} elseif ($values[1] == $values[3]) {
return $values[0] . ' ' . $values[1] . ' ' . $values[2] . $important;
}
break;
case 3:
if ($values[0] == $values[1] && $values[0] == $values[2]) {
return $values[0] . $important;
} elseif ($values[0] == $values[2]) {
return $values[0] . ' ' . $values[1] . $important;
}
break;
case 2:
if ($values[0] == $values[1]) {
return $values[0] . $important;
}
break;
}
return $value;
}
/**
* Removes unnecessary whitespace in ! important
* @param string $string
* @return string
* @access public
* @version 1.1
*/
function compress_important(&$string) {
if (csstidy::is_important($string)) {
$string = csstidy::gvw_important($string) . ' !important'; }
return $string;
}
/**
* Color compression function. Converts all rgb() values to #-values and uses the short-form if possible. Also replaces 4 color names by #-values.
* @param string $color
* @return string
* @version 1.1
*/
function cut_color($color) {
$replace_colors = & $GLOBALS['csstidy']['replace_colors'];
// rgb(0,0,0) -> #000000 (or #000 in this case later)
if (strtolower(substr($color, 0, 4)) === 'rgb(') {
$color_tmp = substr($color, 4, strlen($color) - 5);
$color_tmp = explode(',', $color_tmp);
for ($i = 0; $i < count($color_tmp); $i++) {
$color_tmp[$i] = trim($color_tmp[$i]);
if (substr($color_tmp[$i], -1) === '%') {
$color_tmp[$i] = round((255 * $color_tmp[$i]) / 100);
}
if ($color_tmp[$i] > 255)
$color_tmp[$i] = 255;
}
$color = '#';
for ($i = 0; $i < 3; $i++) {
if ($color_tmp[$i] < 16) {
$color .= '0' . dechex($color_tmp[$i]);
} else {
$color .= dechex($color_tmp[$i]);
}
}
}
// Fix bad color names
if (isset($replace_colors[strtolower($color)])) {
$color = $replace_colors[strtolower($color)];
}
// #aabbcc -> #abc
if (strlen($color) == 7) {
$color_temp = strtolower($color);
if ($color_temp{0} === '#' && $color_temp{1} == $color_temp{2} && $color_temp{3} == $color_temp{4} && $color_temp{5} == $color_temp{6}) {
$color = '#' . $color{1} . $color{3} . $color{5};
}
}
switch (strtolower($color)) {
/* color name -> hex code */
case 'black': return '#000';
case 'fuchsia': return '#f0f';
case 'white': return '#fff';
case 'yellow': return '#ff0';
/* hex code -> color name */
case '#800000': return 'maroon';
case '#ffa500': return 'orange';
case '#808000': return 'olive';
case '#800080': return 'purple';
case '#008000': return 'green';
case '#000080': return 'navy';
case '#008080': return 'teal';
case '#c0c0c0': return 'silver';
case '#808080': return 'gray';
case '#f00': return 'red';
}
return $color;
}
/**
* Compresses numbers (ie. 1.0 becomes 1 or 1.100 becomes 1.1 )
* @param string $subvalue
* @return string
* @version 1.2
*/
function compress_numbers($subvalue) {
$unit_values = & $GLOBALS['csstidy']['unit_values'];
$color_values = & $GLOBALS['csstidy']['color_values'];
// for font:1em/1em sans-serif...;
if ($this->property === 'font') {
$temp = explode('/', $subvalue);
} else {
$temp = array($subvalue);
}
for ($l = 0; $l < count($temp); $l++) {
// if we are not dealing with a number at this point, do not optimise anything
$number = $this->AnalyseCssNumber($temp[$l]);
if ($number === false) {
return $subvalue;
}
// Fix bad colors
if (in_array($this->property, $color_values)) {
if (strlen($temp[$l]) == 3 || strlen($temp[$l]) == 6) {
$temp[$l] = '#' . $temp[$l];
}
else {
$temp[$l] = "0";
}
continue;
}
if (abs($number[0]) > 0) {
if ($number[1] == '' && in_array($this->property, $unit_values, true)) {
$number[1] = 'px';
}
} else {
$number[1] = '';
}
$temp[$l] = $number[0] . $number[1];
}
return ((count($temp) > 1) ? $temp[0] . '/' . $temp[1] : $temp[0]);
}
/**
* Checks if a given string is a CSS valid number. If it is,
* an array containing the value and unit is returned
* @param string $string
* @return array ('unit' if unit is found or '' if no unit exists, number value) or false if no number
*/
function AnalyseCssNumber($string) {
// most simple checks first
if (strlen($string) == 0 || ctype_alpha($string{0})) {
return false;
}
$units = & $GLOBALS['csstidy']['units'];
$return = array(0, '');
$return[0] = floatval($string);
if (abs($return[0]) > 0 && abs($return[0]) < 1) {
if ($return[0] < 0) {
$return[0] = '-' . ltrim(substr($return[0], 1), '0');
} else {
$return[0] = ltrim($return[0], '0');
}
}
// Look for unit and split from value if exists
foreach ($units as $unit) {
$expectUnitAt = strlen($string) - strlen($unit);
if (!($unitInString = stristr($string, $unit))) { // mb_strpos() fails with "false"
continue;
}
$actualPosition = strpos($string, $unitInString);
if ($expectUnitAt === $actualPosition) {
$return[1] = $unit;
$string = substr($string, 0, - strlen($unit));
break;
}
}
if (!is_numeric($string)) {
return false;
}
return $return;
}
/**
* Merges selectors with same properties. Example: a{color:red} b{color:red} -> a,b{color:red}
* Very basic and has at least one bug. Hopefully there is a replacement soon.
* @param array $array
* @return array
* @access public
* @version 1.2
*/
function merge_selectors(&$array) {
$css = $array;
foreach ($css as $key => $value) {
if (!isset($css[$key])) {
continue;
}
$newsel = '';
// Check if properties also exist in another selector
$keys = array();
// PHP bug (?) without $css = $array; here
foreach ($css as $selector => $vali) {
if ($selector == $key) {
continue;
}
if ($css[$key] === $vali) {
$keys[] = $selector;
}
}
if (!empty($keys)) {
$newsel = $key;
unset($css[$key]);
foreach ($keys as $selector) {
unset($css[$selector]);
$newsel .= ',' . $selector;
}
$css[$newsel] = $value;
}
}
$array = $css;
}
/**
* Removes invalid selectors and their corresponding rule-sets as
* defined by 4.1.7 in REC-CSS2. This is a very rudimentary check
* and should be replaced by a full-blown parsing algorithm or
* regular expression
* @version 1.4
*/
function discard_invalid_selectors(&$array) {
$invalid = array('+' => true, '~' => true, ',' => true, '>' => true);
foreach ($array as $selector => $decls) {
$ok = true;
$selectors = array_map('trim', explode(',', $selector));
foreach ($selectors as $s) {
$simple_selectors = preg_split('/\s*[+>~\s]\s*/', $s);
foreach ($simple_selectors as $ss) {
if ($ss === '')
$ok = false;
// could also check $ss for internal structure,
// but that probably would be too slow
}
}
if (!$ok)
unset($array[$selector]);
}
}
/**
* Dissolves properties like padding:10px 10px 10px to padding-top:10px;padding-bottom:10px;...
* @param string $property
* @param string $value
* @return array
* @version 1.0
* @see merge_4value_shorthands()
*/
static function dissolve_4value_shorthands($property, $value) {
$shorthands = & $GLOBALS['csstidy']['shorthands'];
if (!is_array($shorthands[$property])) {
$return[$property] = $value;
return $return;
}
$important = '';
if (csstidy::is_important($value)) {
$value = csstidy::gvw_important($value);
$important = '!important';
}
$values = explode(' ', $value);
$return = array();
if (count($values) == 4) {
for ($i = 0; $i < 4; $i++) {
$return[$shorthands[$property][$i]] = $values[$i] . $important;
}
} elseif (count($values) == 3) {
$return[$shorthands[$property][0]] = $values[0] . $important;
$return[$shorthands[$property][1]] = $values[1] . $important;
$return[$shorthands[$property][3]] = $values[1] . $important;
$return[$shorthands[$property][2]] = $values[2] . $important;
} elseif (count($values) == 2) {
for ($i = 0; $i < 4; $i++) {
$return[$shorthands[$property][$i]] = (($i % 2 != 0)) ? $values[1] . $important : $values[0] . $important;
}
} else {
for ($i = 0; $i < 4; $i++) {
$return[$shorthands[$property][$i]] = $values[0] . $important;
}
}
return $return;
}
/**
* Explodes a string as explode() does, however, not if $sep is escaped or within a string.
* @param string $sep seperator
* @param string $string
* @return array
* @version 1.0
*/
static function explode_ws($sep, $string) {
$status = 'st';
$to = '';
$output = array();
$num = 0;
for ($i = 0, $len = strlen($string); $i < $len; $i++) {
switch ($status) {
case 'st':
if ($string{$i} == $sep && !csstidy::escaped($string, $i)) {
++$num;
} elseif ($string{$i} === '"' || $string{$i} === '\'' || $string{$i} === '(' && !csstidy::escaped($string, $i)) {
$status = 'str';
$to = ($string{$i} === '(') ? ')' : $string{$i};
(isset($output[$num])) ? $output[$num] .= $string{$i} : $output[$num] = $string{$i};
} else {
(isset($output[$num])) ? $output[$num] .= $string{$i} : $output[$num] = $string{$i};
}
break;
case 'str':
if ($string{$i} == $to && !csstidy::escaped($string, $i)) {
$status = 'st';
}
(isset($output[$num])) ? $output[$num] .= $string{$i} : $output[$num] = $string{$i};
break;
}
}
if (isset($output[0])) {
return $output;
} else {
return array($output);
}
}
/**
* Merges Shorthand properties again, the opposite of dissolve_4value_shorthands()
* @param array $array
* @return array
* @version 1.2
* @see dissolve_4value_shorthands()
*/
static function merge_4value_shorthands($array) {
$return = $array;
$shorthands = & $GLOBALS['csstidy']['shorthands'];
foreach ($shorthands as $key => $value) {
if (isset($array[$value[0]]) && isset($array[$value[1]])
&& isset($array[$value[2]]) && isset($array[$value[3]]) && $value !== 0) {
$return[$key] = '';
$important = '';
for ($i = 0; $i < 4; $i++) {
$val = $array[$value[$i]];
if (csstidy::is_important($val)) {
$important = '!important';
$return[$key] .= csstidy::gvw_important($val) . ' ';
} else {
$return[$key] .= $val . ' ';
}
unset($return[$value[$i]]);
}
$return[$key] = csstidy_optimise::shorthand(trim($return[$key] . $important));
}
}
return $return;
}
/**
* Dissolve background property
* @param string $str_value
* @return array
* @version 1.0
* @see merge_bg()
* @todo full CSS 3 compliance
*/
static function dissolve_short_bg($str_value) {
// don't try to explose background gradient !
if (stripos($str_value, "gradient(")!==FALSE)
return array('background'=>$str_value);
$background_prop_default = & $GLOBALS['csstidy']['background_prop_default'];
$repeat = array('repeat', 'repeat-x', 'repeat-y', 'no-repeat', 'space');
$attachment = array('scroll', 'fixed', 'local');
$clip = array('border', 'padding');
$origin = array('border', 'padding', 'content');
$pos = array('top', 'center', 'bottom', 'left', 'right');
$important = '';
$return = array('background-image' => null, 'background-size' => null, 'background-repeat' => null, 'background-position' => null, 'background-attachment' => null, 'background-clip' => null, 'background-origin' => null, 'background-color' => null);
if (csstidy::is_important($str_value)) {
$important = ' !important';
$str_value = csstidy::gvw_important($str_value);
}
$str_value = csstidy_optimise::explode_ws(',', $str_value);
for ($i = 0; $i < count($str_value); $i++) {
$have['clip'] = false;
$have['pos'] = false;
$have['color'] = false;
$have['bg'] = false;
if (is_array($str_value[$i])) {
$str_value[$i] = $str_value[$i][0];
}
$str_value[$i] = csstidy_optimise::explode_ws(' ', trim($str_value[$i]));
for ($j = 0; $j < count($str_value[$i]); $j++) {
if ($have['bg'] === false && (substr($str_value[$i][$j], 0, 4) === 'url(' || $str_value[$i][$j] === 'none')) {
$return['background-image'] .= $str_value[$i][$j] . ',';
$have['bg'] = true;
} elseif (in_array($str_value[$i][$j], $repeat, true)) {
$return['background-repeat'] .= $str_value[$i][$j] . ',';
} elseif (in_array($str_value[$i][$j], $attachment, true)) {
$return['background-attachment'] .= $str_value[$i][$j] . ',';
} elseif (in_array($str_value[$i][$j], $clip, true) && !$have['clip']) {
$return['background-clip'] .= $str_value[$i][$j] . ',';
$have['clip'] = true;
} elseif (in_array($str_value[$i][$j], $origin, true)) {
$return['background-origin'] .= $str_value[$i][$j] . ',';
} elseif ($str_value[$i][$j]{0} === '(') {
$return['background-size'] .= substr($str_value[$i][$j], 1, -1) . ',';
} elseif (in_array($str_value[$i][$j], $pos, true) || is_numeric($str_value[$i][$j]{0}) || $str_value[$i][$j]{0} === null || $str_value[$i][$j]{0} === '-' || $str_value[$i][$j]{0} === '.') {
$return['background-position'] .= $str_value[$i][$j];
if (!$have['pos'])
$return['background-position'] .= ' '; else
$return['background-position'].= ',';
$have['pos'] = true;
}
elseif (!$have['color']) {
$return['background-color'] .= $str_value[$i][$j] . ',';
$have['color'] = true;
}
}
}
foreach ($background_prop_default as $bg_prop => $default_value) {
if ($return[$bg_prop] !== null) {
$return[$bg_prop] = substr($return[$bg_prop], 0, -1) . $important;
}
else
$return[$bg_prop] = $default_value . $important;
}
return $return;
}
/**
* Merges all background properties
* @param array $input_css
* @return array
* @version 1.0
* @see dissolve_short_bg()
* @todo full CSS 3 compliance
*/
static function merge_bg($input_css) {
$background_prop_default = & $GLOBALS['csstidy']['background_prop_default'];
// Max number of background images. CSS3 not yet fully implemented
$number_of_values = @max(count(csstidy_optimise::explode_ws(',', $input_css['background-image'])), count(csstidy_optimise::explode_ws(',', $input_css['background-color'])), 1);
// Array with background images to check if BG image exists
$bg_img_array = @csstidy_optimise::explode_ws(',', csstidy::gvw_important($input_css['background-image']));
$new_bg_value = '';
$important = '';
// if background properties is here and not empty, don't try anything
if (isset($input_css['background']) AND $input_css['background'])
return $input_css;
for ($i = 0; $i < $number_of_values; $i++) {
foreach ($background_prop_default as $bg_property => $default_value) {
// Skip if property does not exist
if (!isset($input_css[$bg_property])) {
continue;
}
$cur_value = $input_css[$bg_property];
// skip all optimisation if gradient() somewhere
if (stripos($cur_value, "gradient(")!==FALSE)
return $input_css;
// Skip some properties if there is no background image
if ((!isset($bg_img_array[$i]) || $bg_img_array[$i] === 'none')
&& ($bg_property === 'background-size' || $bg_property === 'background-position'
|| $bg_property === 'background-attachment' || $bg_property === 'background-repeat')) {
continue;
}
// Remove !important
if (csstidy::is_important($cur_value)) {
$important = ' !important';
$cur_value = csstidy::gvw_important($cur_value);
}
// Do not add default values
if ($cur_value === $default_value) {
continue;
}
$temp = csstidy_optimise::explode_ws(',', $cur_value);
if (isset($temp[$i])) {
if ($bg_property === 'background-size') {
$new_bg_value .= '(' . $temp[$i] . ') ';
} else {
$new_bg_value .= $temp[$i] . ' ';
}
}
}
$new_bg_value = trim($new_bg_value);
if ($i != $number_of_values - 1)
$new_bg_value .= ',';
}
// Delete all background-properties
foreach ($background_prop_default as $bg_property => $default_value) {
unset($input_css[$bg_property]);
}
// Add new background property
if ($new_bg_value !== '')
$input_css['background'] = $new_bg_value . $important;
elseif(isset ($input_css['background']))
$input_css['background'] = 'none';
return $input_css;
}
/**
* Dissolve font property
* @param string $str_value
* @return array
* @version 1.3
* @see merge_font()
*/
static function dissolve_short_font($str_value) {
$font_prop_default = & $GLOBALS['csstidy']['font_prop_default'];
$font_weight = array('normal', 'bold', 'bolder', 'lighter', 100, 200, 300, 400, 500, 600, 700, 800, 900);
$font_variant = array('normal', 'small-caps');
$font_style = array('normal', 'italic', 'oblique');
$important = '';
$return = array('font-style' => null, 'font-variant' => null, 'font-weight' => null, 'font-size' => null, 'line-height' => null, 'font-family' => null);
if (csstidy::is_important($str_value)) {
$important = '!important';
$str_value = csstidy::gvw_important($str_value);
}
$have['style'] = false;
$have['variant'] = false;
$have['weight'] = false;
$have['size'] = false;
// Detects if font-family consists of several words w/o quotes
$multiwords = false;
// Workaround with multiple font-family
$str_value = csstidy_optimise::explode_ws(',', trim($str_value));
$str_value[0] = csstidy_optimise::explode_ws(' ', trim($str_value[0]));
for ($j = 0; $j < count($str_value[0]); $j++) {
if ($have['weight'] === false && in_array($str_value[0][$j], $font_weight)) {
$return['font-weight'] = $str_value[0][$j];
$have['weight'] = true;
} elseif ($have['variant'] === false && in_array($str_value[0][$j], $font_variant)) {
$return['font-variant'] = $str_value[0][$j];
$have['variant'] = true;
} elseif ($have['style'] === false && in_array($str_value[0][$j], $font_style)) {
$return['font-style'] = $str_value[0][$j];
$have['style'] = true;
} elseif ($have['size'] === false && (is_numeric($str_value[0][$j]{0}) || $str_value[0][$j]{0} === null || $str_value[0][$j]{0} === '.')) {
$size = csstidy_optimise::explode_ws('/', trim($str_value[0][$j]));
$return['font-size'] = $size[0];
if (isset($size[1])) {
$return['line-height'] = $size[1];
} else {
$return['line-height'] = ''; // don't add 'normal' !
}
$have['size'] = true;
} else {
if (isset($return['font-family'])) {
$return['font-family'] .= ' ' . $str_value[0][$j];
$multiwords = true;
} else {
$return['font-family'] = $str_value[0][$j];
}
}
}
// add quotes if we have several qords in font-family
if ($multiwords !== false) {
$return['font-family'] = '"' . $return['font-family'] . '"';
}
$i = 1;
while (isset($str_value[$i])) {
$return['font-family'] .= ',' . trim($str_value[$i]);
$i++;
}
// Fix for 100 and more font-size
if ($have['size'] === false && isset($return['font-weight']) &&
is_numeric($return['font-weight']{0})) {
$return['font-size'] = $return['font-weight'];
unset($return['font-weight']);
}
foreach ($font_prop_default as $font_prop => $default_value) {
if ($return[$font_prop] !== null) {
$return[$font_prop] = $return[$font_prop] . $important;
}
else
$return[$font_prop] = $default_value . $important;
}
return $return;
}
/**
* Merges all fonts properties
* @param array $input_css
* @return array
* @version 1.3
* @see dissolve_short_font()
*/
static function merge_font($input_css) {
$font_prop_default = & $GLOBALS['csstidy']['font_prop_default'];
$new_font_value = '';
$important = '';
// Skip if not font-family and font-size set
if (isset($input_css['font-family']) && isset($input_css['font-size'])) {
// fix several words in font-family - add quotes
if (isset($input_css['font-family'])) {
$families = explode(",", $input_css['font-family']);
$result_families = array();
foreach ($families as $family) {
$family = trim($family);
$len = strlen($family);
if (strpos($family, " ") &&
!(($family{0} == '"' && $family{$len - 1} == '"') ||
($family{0} == "'" && $family{$len - 1} == "'"))) {
$family = '"' . $family . '"';
}
$result_families[] = $family;
}
$input_css['font-family'] = implode(",", $result_families);
}
foreach ($font_prop_default as $font_property => $default_value) {
// Skip if property does not exist
if (!isset($input_css[$font_property])) {
continue;
}
$cur_value = $input_css[$font_property];
// Skip if default value is used
if ($cur_value === $default_value) {
continue;
}
// Remove !important
if (csstidy::is_important($cur_value)) {
$important = '!important';
$cur_value = csstidy::gvw_important($cur_value);
}
$new_font_value .= $cur_value;
// Add delimiter
$new_font_value .= ( $font_property === 'font-size' &&
isset($input_css['line-height'])) ? '/' : ' ';
}
$new_font_value = trim($new_font_value);
// Delete all font-properties
foreach ($font_prop_default as $font_property => $default_value) {
if ($font_property!=='font' OR !$new_font_value)
unset($input_css[$font_property]);
}
// Add new font property
if ($new_font_value !== '') {
$input_css['font'] = $new_font_value . $important;
}
}
return $input_css;
}
}

View File

@@ -0,0 +1,412 @@
<?php
/**
* CSSTidy - CSS Parser and Optimiser
*
* CSS Printing class
* This class prints CSS data generated by csstidy.
*
* Copyright 2005, 2006, 2007 Florian Schmitz
*
* This file is part of CSSTidy.
*
* CSSTidy is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* CSSTidy 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @license http://opensource.org/licenses/lgpl-license.php GNU Lesser General Public License
* @package csstidy
* @author Florian Schmitz (floele at gmail dot com) 2005-2007
* @author Brett Zamir (brettz9 at yahoo dot com) 2007
* @author Cedric Morin (cedric at yterium dot com) 2010
*/
/**
* CSS Printing class
*
* This class prints CSS data generated by csstidy.
*
* @package csstidy
* @author Florian Schmitz (floele at gmail dot com) 2005-2006
* @version 1.0.1
*/
class csstidy_print {
/**
* Saves the input CSS string
* @var string
* @access private
*/
public $input_css = '';
/**
* Saves the formatted CSS string
* @var string
* @access public
*/
public $output_css = '';
/**
* Saves the formatted CSS string (plain text)
* @var string
* @access public
*/
public $output_css_plain = '';
/**
* Constructor
* @param array $css contains the class csstidy
* @access private
* @version 1.0
*/
function __construct(&$css) {
$this->parser = & $css;
$this->css = & $css->css;
$this->template = & $css->template;
$this->tokens = & $css->tokens;
$this->charset = & $css->charset;
$this->import = & $css->import;
$this->namespace = & $css->namespace;
}
function csstidy_print(&$css) {
$this->__construct($css);
}
/**
* Resets output_css and output_css_plain (new css code)
* @access private
* @version 1.0
*/
function _reset() {
$this->output_css = '';
$this->output_css_plain = '';
}
/**
* Returns the CSS code as plain text
* @param string $default_media default @media to add to selectors without any @media
* @return string
* @access public
* @version 1.0
*/
function plain($default_media='') {
$this->_print(true, $default_media);
return $this->output_css_plain;
}
/**
* Returns the formatted CSS code
* @param string $default_media default @media to add to selectors without any @media
* @return string
* @access public
* @version 1.0
*/
function formatted($default_media='') {
$this->_print(false, $default_media);
return $this->output_css;
}
/**
* Returns the formatted CSS code to make a complete webpage
* @param string $doctype shorthand for the document type
* @param bool $externalcss indicates whether styles to be attached internally or as an external stylesheet
* @param string $title title to be added in the head of the document
* @param string $lang two-letter language code to be added to the output
* @return string
* @access public
* @version 1.4
*/
function formatted_page($doctype='xhtml1.1', $externalcss=true, $title='', $lang='en') {
switch ($doctype) {
case 'xhtml1.0strict':
$doctype_output = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">';
break;
case 'xhtml1.1':
default:
$doctype_output = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">';
break;
}
$output = $cssparsed = '';
$this->output_css_plain = & $output;
$output .= $doctype_output . "\n" . '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="' . $lang . '"';
$output .= ( $doctype === 'xhtml1.1') ? '>' : ' lang="' . $lang . '">';
$output .= "\n<head>\n <title>$title</title>";
if ($externalcss) {
$output .= "\n <style type=\"text/css\">\n";
$cssparsed = file_get_contents('cssparsed.css');
$output .= $cssparsed; // Adds an invisible BOM or something, but not in css_optimised.php
$output .= "\n</style>";
} else {
$output .= "\n" . ' <link rel="stylesheet" type="text/css" href="cssparsed.css" />';
// }
}
$output .= "\n</head>\n<body><code id=\"copytext\">";
$output .= $this->formatted();
$output .= '</code>' . "\n" . '</body></html>';
return $this->output_css_plain;
}
/**
* Returns the formatted CSS Code and saves it into $this->output_css and $this->output_css_plain
* @param bool $plain plain text or not
* @param string $default_media default @media to add to selectors without any @media
* @access private
* @version 2.0
*/
function _print($plain = false, $default_media='') {
if ($this->output_css && $this->output_css_plain) {
return;
}
$output = '';
if (!$this->parser->get_cfg('preserve_css')) {
$this->_convert_raw_css($default_media);
}
$template = & $this->template;
if ($plain) {
$template = array_map('strip_tags', $template);
}
if ($this->parser->get_cfg('timestamp')) {
array_unshift($this->tokens, array(COMMENT, ' CSSTidy ' . $this->parser->version . ': ' . date('r') . ' '));
}
if (!empty($this->charset)) {
$output .= $template[0] . '@charset ' . $template[5] . $this->charset . $template[6];
}
if (!empty($this->import)) {
for ($i = 0, $size = count($this->import); $i < $size; $i++) {
$import_components = explode(' ', $this->import[$i]);
if (substr($import_components[0], 0, 4) === 'url(' && substr($import_components[0], -1, 1) === ')') {
$import_components[0] = '\'' . trim(substr($import_components[0], 4, -1), "'\"") . '\'';
$this->import[$i] = implode(' ', $import_components);
$this->parser->log('Optimised @import : Removed "url("', 'Information');
}
$output .= $template[0] . '@import ' . $template[5] . $this->import[$i] . $template[6];
}
}
if (!empty($this->namespace)) {
if (substr($this->namespace, 0, 4) === 'url(' && substr($this->namespace, -1, 1) === ')') {
$this->namespace = '\'' . substr($this->namespace, 4, -1) . '\'';
$this->parser->log('Optimised @namespace : Removed "url("', 'Information');
}
$output .= $template[0] . '@namespace ' . $template[5] . $this->namespace . $template[6];
}
$output .= $template[13];
$in_at_out = '';
$out = & $output;
foreach ($this->tokens as $key => $token) {
switch ($token[0]) {
case AT_START:
$out .= $template[0] . $this->_htmlsp($token[1], $plain) . $template[1];
$out = & $in_at_out;
break;
case SEL_START:
if ($this->parser->get_cfg('lowercase_s'))
$token[1] = strtolower($token[1]);
$out .= ( $token[1]{0} !== '@') ? $template[2] . $this->_htmlsp($token[1], $plain) : $template[0] . $this->_htmlsp($token[1], $plain);
$out .= $template[3];
break;
case PROPERTY:
if ($this->parser->get_cfg('case_properties') === 2) {
$token[1] = strtoupper($token[1]);
} elseif ($this->parser->get_cfg('case_properties') === 1) {
$token[1] = strtolower($token[1]);
}
$out .= $template[4] . $this->_htmlsp($token[1], $plain) . ':' . $template[5];
break;
case VALUE:
$out .= $this->_htmlsp($token[1], $plain);
if ($this->_seeknocomment($key, 1) == SEL_END && $this->parser->get_cfg('remove_last_;')) {
$out .= str_replace(';', '', $template[6]);
} else {
$out .= $template[6];
}
break;
case SEL_END:
$out .= $template[7];
if ($this->_seeknocomment($key, 1) != AT_END)
$out .= $template[8];
break;
case AT_END:
$out = & $output;
$out .= $template[10] . str_replace("\n", "\n" . $template[10], $in_at_out);
$in_at_out = '';
$out .= $template[9];
break;
case COMMENT:
$out .= $template[11] . '/*' . $this->_htmlsp($token[1], $plain) . '*/' . $template[12];
break;
}
}
$output = trim($output);
if (!$plain) {
$this->output_css = $output;
$this->_print(true);
} else {
// If using spaces in the template, don't want these to appear in the plain output
$this->output_css_plain = str_replace('&#160;', '', $output);
}
}
/**
* Gets the next token type which is $move away from $key, excluding comments
* @param integer $key current position
* @param integer $move move this far
* @return mixed a token type
* @access private
* @version 1.0
*/
function _seeknocomment($key, $move) {
$go = ($move > 0) ? 1 : -1;
for ($i = $key + 1; abs($key - $i) - 1 < abs($move); $i += $go) {
if (!isset($this->tokens[$i])) {
return;
}
if ($this->tokens[$i][0] == COMMENT) {
$move += 1;
continue;
}
return $this->tokens[$i][0];
}
}
/**
* Converts $this->css array to a raw array ($this->tokens)
* @param string $default_media default @media to add to selectors without any @media
* @access private
* @version 1.0
*/
function _convert_raw_css($default_media='') {
$this->tokens = array();
foreach ($this->css as $medium => $val) {
if ($this->parser->get_cfg('sort_selectors'))
ksort($val);
if (intval($medium) < DEFAULT_AT) {
$this->parser->_add_token(AT_START, $medium, true);
}
elseif ($default_media) {
$this->parser->_add_token(AT_START, $default_media, true);
}
foreach ($val as $selector => $vali) {
if ($this->parser->get_cfg('sort_properties'))
ksort($vali);
$this->parser->_add_token(SEL_START, $selector, true);
foreach ($vali as $property => $valj) {
$this->parser->_add_token(PROPERTY, $property, true);
$this->parser->_add_token(VALUE, $valj, true);
}
$this->parser->_add_token(SEL_END, $selector, true);
}
if (intval($medium) < DEFAULT_AT) {
$this->parser->_add_token(AT_END, $medium, true);
}
elseif ($default_media) {
$this->parser->_add_token(AT_END, $default_media, true);
}
}
}
/**
* Same as htmlspecialchars, only that chars are not replaced if $plain !== true. This makes print_code() cleaner.
* @param string $string
* @param bool $plain
* @return string
* @see csstidy_print::_print()
* @access private
* @version 1.0
*/
function _htmlsp($string, $plain) {
if (!$plain) {
return htmlspecialchars($string, ENT_QUOTES, 'utf-8');
}
return $string;
}
/**
* Get compression ratio
* @access public
* @return float
* @version 1.2
*/
function get_ratio() {
if (!$this->output_css_plain) {
$this->formatted();
}
return round((strlen($this->input_css) - strlen($this->output_css_plain)) / strlen($this->input_css), 3) * 100;
}
/**
* Get difference between the old and new code in bytes and prints the code if necessary.
* @access public
* @return string
* @version 1.1
*/
function get_diff() {
if (!$this->output_css_plain) {
$this->formatted();
}
$diff = strlen($this->output_css_plain) - strlen($this->input_css);
if ($diff > 0) {
return '+' . $diff;
} elseif ($diff == 0) {
return '+-' . $diff;
}
return $diff;
}
/**
* Get the size of either input or output CSS in KB
* @param string $loc default is "output"
* @access public
* @return integer
* @version 1.0
*/
function size($loc = 'output') {
if ($loc === 'output' && !$this->output_css) {
$this->formatted();
}
if ($loc === 'input') {
return (strlen($this->input_css) / 1000);
} else {
return (strlen($this->output_css_plain) / 1000);
}
}
}

View File

@@ -0,0 +1,119 @@
/* Do not modify this file directly. It is concatenated from individual module CSS files. */
@import url("modules/custom-css/csstidy/cssparsed.css");
html, body {
font:0.8em Verdana,Helvetica,sans-serif;
background:#F8F8F6;
}
code {
font-size:1.2em;
}
div#rightcol {
padding-right:32em;
}
fieldset {
display:block;
margin:0.5em 0;
padding:1em;
border:solid #7284AB 2px;
}
fieldset.code_output {
display:inline;
}
h1 {
font-size:2em;
}
small {
font-size:0.7em;
}
fieldset#field_input {
float:right;
margin:0 0 1em 0.5em;
}
fieldset#options,fieldset#code_layout {
width:31em;
}
input#submit {
clear:both;
display:block;
margin:1em;
}
select {
margin:2px 0 0;
}
label.block {
display:block;
}
legend {
background:#c4E1C3;
padding:2px 4px;
border:dashed 1px;
}
textarea#css_text {
width:27em;
height:370px;
display:block;
margin-left:1em;
}
.help {
cursor:help;
}
p.important {
border:solid 1px red;
font-weight:bold;
padding:1em;
background:white;
}
p {
margin:1em 0;
}
dl {
padding-right:0.5em;
}
dt {
font-weight:bold;
margin:0;
float:right;
clear:both;
height:1.5em;
}
dd {
margin:0 4em 0 0;
height:1.5em;
}
fieldset#messages {
background:white;
padding:0 1em 0 0;
}
fieldset#messages div {
height:10em;
overflow:auto;
}
dd.Warning {
color:orange;
}
dd.Information {
color:green;
}

View File

@@ -0,0 +1 @@
code#copytext{white-space:pre;font-family:Verdana}.at{color:#00008b}.format{color:gray}.property{color:green}.selector{color:#00f}.value{color:red;left:500px}.comment{color:orange}body,html{font:.8em Verdana,Helvetica,sans-serif;background:#f8f8f6}code{font-size:1.2em}div#rightcol{padding-right:32em}fieldset{display:block;margin:.5em 0;padding:1em;border:solid #7284ab 2px}fieldset.code_output{display:inline}h1{font-size:2em}small{font-size:.7em}fieldset#field_input{float:right;margin:0 0 1em .5em}fieldset#code_layout,fieldset#options{width:31em}input#submit{clear:both;display:block;margin:1em}select{margin:2px 0 0}label.block{display:block}legend{background:#c4e1c3;padding:2px 4px;border:dashed 1px}textarea#css_text{width:27em;height:370px;display:block;margin-left:1em}.help{cursor:help}p.important{border:solid 1px red;font-weight:700;padding:1em;background:#fff}p{margin:1em 0}dl{padding-right:.5em}dt{font-weight:700;margin:0;float:right;clear:both;height:1.5em}dd{margin:0 4em 0 0;height:1.5em}fieldset#messages{background:#fff;padding:0 1em 0 0}fieldset#messages div{height:10em;overflow:auto}dd.Warning{color:orange}dd.Information{color:green}

View File

@@ -0,0 +1,118 @@
@import url("modules/custom-css/csstidy/cssparsed.css");
html, body {
font:0.8em Verdana,Helvetica,sans-serif;
background:#F8F8F6;
}
code {
font-size:1.2em;
}
div#rightcol {
padding-left:32em;
}
fieldset {
display:block;
margin:0.5em 0;
padding:1em;
border:solid #7284AB 2px;
}
fieldset.code_output {
display:inline;
}
h1 {
font-size:2em;
}
small {
font-size:0.7em;
}
fieldset#field_input {
float:left;
margin:0 0.5em 1em 0;
}
fieldset#options,fieldset#code_layout {
width:31em;
}
input#submit {
clear:both;
display:block;
margin:1em;
}
select {
margin:2px 0 0;
}
label.block {
display:block;
}
legend {
background:#c4E1C3;
padding:2px 4px;
border:dashed 1px;
}
textarea#css_text {
width:27em;
height:370px;
display:block;
margin-right:1em;
}
.help {
cursor:help;
}
p.important {
border:solid 1px red;
font-weight:bold;
padding:1em;
background:white;
}
p {
margin:1em 0;
}
dl {
padding-left:0.5em;
}
dt {
font-weight:bold;
margin:0;
float:left;
clear:both;
height:1.5em;
}
dd {
margin:0 0 0 4em;
height:1.5em;
}
fieldset#messages {
background:white;
padding:0 0 0 1em;
}
fieldset#messages div {
height:10em;
overflow:auto;
}
dd.Warning {
color:orange;
}
dd.Information {
color:green;
}

View File

@@ -0,0 +1,2 @@
/* Do not modify this file directly. It is concatenated from individual module CSS files. */
code#copytext{white-space:pre;font-family:Verdana}.at{color:#00008b}.format{color:gray}.property{color:green}.selector{color:#00f}.value{color:red;left:500px}.comment{color:orange}body,html{font:.8em Verdana,Helvetica,sans-serif;background:#f8f8f6}code{font-size:1.2em}div#rightcol{padding-left:32em}fieldset{display:block;margin:.5em 0;padding:1em;border:solid #7284ab 2px}fieldset.code_output{display:inline}h1{font-size:2em}small{font-size:.7em}fieldset#field_input{float:left;margin:0 .5em 1em 0}fieldset#code_layout,fieldset#options{width:31em}input#submit{clear:both;display:block;margin:1em}select{margin:2px 0 0}label.block{display:block}legend{background:#c4e1c3;padding:2px 4px;border:dashed 1px}textarea#css_text{width:27em;height:370px;display:block;margin-right:1em}.help{cursor:help}p.important{border:solid 1px red;font-weight:700;padding:1em;background:#fff}p{margin:1em 0}dl{padding-left:.5em}dt{font-weight:700;margin:0;float:left;clear:both;height:1.5em}dd{margin:0 0 0 4em;height:1.5em}fieldset#messages{background:#fff;padding:0 0 0 1em}fieldset#messages div{height:10em;overflow:auto}dd.Warning{color:orange}dd.Information{color:green}

View File

@@ -0,0 +1,30 @@
/* Do not modify this file directly. It is concatenated from individual module CSS files. */
code#copytext {
white-space: pre;
font-family: Verdana;
}
.at {
color:darkblue;
}
.format {
color:gray;
}
.property {
color:green;
}
.selector {
color:blue;
}
.value {
color:red;
right: 500px;
}
.comment {
color:orange;
}

View File

@@ -0,0 +1 @@
code#copytext{white-space:pre;font-family:Verdana}.at{color:#00008b}.format{color:gray}.property{color:green}.selector{color:#00f}.value{color:red;right:500px}.comment{color:orange}

View File

@@ -0,0 +1,29 @@
code#copytext {
white-space: pre;
font-family: Verdana;
}
.at {
color:darkblue;
}
.format {
color:gray;
}
.property {
color:green;
}
.selector {
color:blue;
}
.value {
color:red;
left: 500px;
}
.comment {
color:orange;
}

View File

@@ -0,0 +1,2 @@
/* Do not modify this file directly. It is concatenated from individual module CSS files. */
code#copytext{white-space:pre;font-family:Verdana}.at{color:#00008b}.format{color:gray}.property{color:green}.selector{color:#00f}.value{color:red;left:500px}.comment{color:orange}

View File

@@ -0,0 +1,102 @@
<?php
unset( $GLOBALS['csstidy']['all_properties']['binding'] );
$GLOBALS['csstidy']['all_properties']['text-size-adjust'] = 'CSS3.0';
// Support browser prefixes for properties only in the latest CSS draft
foreach ( $GLOBALS['csstidy']['all_properties'] as $property => $levels ) {
if ( strpos( $levels, "," ) === false ) {
$GLOBALS['csstidy']['all_properties']['-moz-' . $property] = $levels;
$GLOBALS['csstidy']['all_properties']['-webkit-' . $property] = $levels;
$GLOBALS['csstidy']['all_properties']['-ms-' . $property] = $levels;
$GLOBALS['csstidy']['all_properties']['-o-' . $property] = $levels;
$GLOBALS['csstidy']['all_properties']['-khtml-' . $property] = $levels;
if ( in_array( $property, $GLOBALS['csstidy']['unit_values'] ) ) {
$GLOBALS['csstidy']['unit_values'][] = '-moz-' . $property;
$GLOBALS['csstidy']['unit_values'][] = '-webkit-' . $property;
$GLOBALS['csstidy']['unit_values'][] = '-ms-' . $property;
$GLOBALS['csstidy']['unit_values'][] = '-o-' . $property;
$GLOBALS['csstidy']['unit_values'][] = '-khtml-' . $property;
}
if ( in_array( $property, $GLOBALS['csstidy']['color_values'] ) ) {
$GLOBALS['csstidy']['color_values'][] = '-moz-' . $property;
$GLOBALS['csstidy']['color_values'][] = '-webkit-' . $property;
$GLOBALS['csstidy']['color_values'][] = '-ms-' . $property;
$GLOBALS['csstidy']['color_values'][] = '-o-' . $property;
$GLOBALS['csstidy']['color_values'][] = '-khtml-' . $property;
}
}
}
// Add `display` to the list of properties that can be used multiple times in a single selector
$GLOBALS['csstidy']['multiple_properties'][] = 'display';
// Allow vendor prefixes for any property that is allowed to be used multiple times inside a single selector
foreach ( $GLOBALS['csstidy']['multiple_properties'] as $property ) {
if ( '-' != $property[0] ) {
$GLOBALS['csstidy']['multiple_properties'][] = '-o-' . $property;
$GLOBALS['csstidy']['multiple_properties'][] = '-ms-' . $property;
$GLOBALS['csstidy']['multiple_properties'][] = '-webkit-' . $property;
$GLOBALS['csstidy']['multiple_properties'][] = '-moz-' . $property;
$GLOBALS['csstidy']['multiple_properties'][] = '-khtml-' . $property;
}
}
/**
* CSS Animation
*
* @see https://developer.mozilla.org/en/CSS/CSS_animations
*/
$GLOBALS['csstidy']['at_rules']['-webkit-keyframes'] = 'at';
$GLOBALS['csstidy']['at_rules']['-moz-keyframes'] = 'at';
$GLOBALS['csstidy']['at_rules']['-ms-keyframes'] = 'at';
$GLOBALS['csstidy']['at_rules']['-o-keyframes'] = 'at';
/**
* Non-standard viewport rule.
*/
$GLOBALS['csstidy']['at_rules']['viewport'] = 'is';
$GLOBALS['csstidy']['at_rules']['-webkit-viewport'] = 'is';
$GLOBALS['csstidy']['at_rules']['-moz-viewport'] = 'is';
$GLOBALS['csstidy']['at_rules']['-ms-viewport'] = 'is';
/**
* Non-standard CSS properties. They're not part of any spec, but we say
* they're in all of them so that we can support them.
*/
$GLOBALS['csstidy']['all_properties']['-webkit-filter'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['-moz-filter'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['-ms-filter'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['filter'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['scrollbar-face-color'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['-ms-interpolation-mode'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['text-rendering'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['-webkit-transform-origin-x'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['-webkit-transform-origin-y'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['-webkit-transform-origin-z'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['-webkit-font-smoothing'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['-moz-osx-font-smoothing'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['-font-smooth'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['-o-object-fit'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['object-fit'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['-o-object-position'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['object-position'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['text-overflow'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['zoom'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['pointer-events'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['font-feature-settings'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['font-kerning'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['font-language-override'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['font-synthesis'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['font-variant-alternates'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['font-variant-caps'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['font-variant-east-asian'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['font-variant-ligatures'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['font-variant-numeric'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['font-variant-position'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['font-variation-settings'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['line-height-step'] = 'CSS3.0';

View File

@@ -0,0 +1,693 @@
<?php
/**
* Various CSS Data for CSSTidy
*
* This file is part of CSSTidy.
*
* CSSTidy 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.
*
* CSSTidy 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 CSSTidy; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
* @package csstidy
* @author Florian Schmitz (floele at gmail dot com) 2005
* @author Nikolay Matsievsky (speed at webo dot name) 2010
*/
define('AT_START', 1);
define('AT_END', 2);
define('SEL_START', 3);
define('SEL_END', 4);
define('PROPERTY', 5);
define('VALUE', 6);
define('COMMENT', 7);
define('DEFAULT_AT', 41);
/**
* All whitespace allowed in CSS
*
* @global array $GLOBALS['csstidy']['whitespace']
* @version 1.0
*/
$GLOBALS['csstidy']['whitespace'] = array(' ',"\n","\t","\r","\x0B");
/**
* All CSS tokens used by csstidy
*
* @global string $GLOBALS['csstidy']['tokens']
* @version 1.0
*/
$GLOBALS['csstidy']['tokens'] = '/@}{;:=\'"(,\\!$%&)*+.<>?[]^`|~';
/**
* All CSS units (CSS 3 units included)
*
* @see compress_numbers()
* @global array $GLOBALS['csstidy']['units']
* @version 1.0
*/
$GLOBALS['csstidy']['units'] = array('in','cm','mm','pt','pc','px','rem','em','%','ex','gd','vw','vh','vm','deg','grad','rad','ms','s','khz','hz');
/**
* Available at-rules
*
* @global array $GLOBALS['csstidy']['at_rules']
* @version 1.0
*/
$GLOBALS['csstidy']['at_rules'] = array('page' => 'is','font-face' => 'is','charset' => 'iv', 'import' => 'iv','namespace' => 'iv','media' => 'at','keyframes' => 'at', 'supports' => 'at');
/**
* Properties that need a value with unit
*
* @todo CSS3 properties
* @see compress_numbers();
* @global array $GLOBALS['csstidy']['unit_values']
* @version 1.2
*/
$GLOBALS['csstidy']['unit_values'] = array ('background', 'background-position', 'background-size', 'border', 'border-top', 'border-right', 'border-bottom', 'border-left', 'border-width',
'border-top-width', 'border-right-width', 'border-left-width', 'border-bottom-width', 'bottom', 'border-spacing', 'column-gap', 'column-width',
'font-size', 'height', 'left', 'margin', 'margin-top', 'margin-right', 'margin-bottom', 'margin-left', 'max-height',
'max-width', 'min-height', 'min-width', 'outline', 'outline-width', 'padding', 'padding-top', 'padding-right',
'padding-bottom', 'padding-left', 'perspective', 'right', 'top', 'text-indent', 'letter-spacing', 'word-spacing', 'width');
/**
* Properties that allow <color> as value
*
* @todo CSS3 properties
* @see compress_numbers();
* @global array $GLOBALS['csstidy']['color_values']
* @version 1.0
*/
$GLOBALS['csstidy']['color_values'] = array();
$GLOBALS['csstidy']['color_values'][] = 'background-color';
$GLOBALS['csstidy']['color_values'][] = 'border-color';
$GLOBALS['csstidy']['color_values'][] = 'border-top-color';
$GLOBALS['csstidy']['color_values'][] = 'border-right-color';
$GLOBALS['csstidy']['color_values'][] = 'border-bottom-color';
$GLOBALS['csstidy']['color_values'][] = 'border-left-color';
$GLOBALS['csstidy']['color_values'][] = 'color';
$GLOBALS['csstidy']['color_values'][] = 'outline-color';
$GLOBALS['csstidy']['color_values'][] = 'column-rule-color';
/**
* Default values for the background properties
*
* @todo Possibly property names will change during CSS3 development
* @global array $GLOBALS['csstidy']['background_prop_default']
* @see dissolve_short_bg()
* @see merge_bg()
* @version 1.0
*/
$GLOBALS['csstidy']['background_prop_default'] = array();
$GLOBALS['csstidy']['background_prop_default']['background-image'] = 'none';
$GLOBALS['csstidy']['background_prop_default']['background-size'] = 'auto';
$GLOBALS['csstidy']['background_prop_default']['background-repeat'] = 'repeat';
$GLOBALS['csstidy']['background_prop_default']['background-position'] = '0 0';
$GLOBALS['csstidy']['background_prop_default']['background-attachment'] = 'scroll';
$GLOBALS['csstidy']['background_prop_default']['background-clip'] = 'border';
$GLOBALS['csstidy']['background_prop_default']['background-origin'] = 'padding';
$GLOBALS['csstidy']['background_prop_default']['background-color'] = 'transparent';
/**
* Default values for the font properties
*
* @global array $GLOBALS['csstidy']['font_prop_default']
* @see merge_fonts()
* @version 1.3
*/
$GLOBALS['csstidy']['font_prop_default'] = array();
$GLOBALS['csstidy']['font_prop_default']['font-style'] = 'normal';
$GLOBALS['csstidy']['font_prop_default']['font-variant'] = 'normal';
$GLOBALS['csstidy']['font_prop_default']['font-weight'] = 'normal';
$GLOBALS['csstidy']['font_prop_default']['font-size'] = '';
$GLOBALS['csstidy']['font_prop_default']['line-height'] = '';
$GLOBALS['csstidy']['font_prop_default']['font-family'] = '';
/**
* A list of non-W3C color names which get replaced by their hex-codes
*
* @global array $GLOBALS['csstidy']['replace_colors']
* @see cut_color()
* @version 1.0
*/
$GLOBALS['csstidy']['replace_colors'] = array();
$GLOBALS['csstidy']['replace_colors']['aliceblue'] = '#f0f8ff';
$GLOBALS['csstidy']['replace_colors']['antiquewhite'] = '#faebd7';
$GLOBALS['csstidy']['replace_colors']['aquamarine'] = '#7fffd4';
$GLOBALS['csstidy']['replace_colors']['azure'] = '#f0ffff';
$GLOBALS['csstidy']['replace_colors']['beige'] = '#f5f5dc';
$GLOBALS['csstidy']['replace_colors']['bisque'] = '#ffe4c4';
$GLOBALS['csstidy']['replace_colors']['blanchedalmond'] = '#ffebcd';
$GLOBALS['csstidy']['replace_colors']['blueviolet'] = '#8a2be2';
$GLOBALS['csstidy']['replace_colors']['brown'] = '#a52a2a';
$GLOBALS['csstidy']['replace_colors']['burlywood'] = '#deb887';
$GLOBALS['csstidy']['replace_colors']['cadetblue'] = '#5f9ea0';
$GLOBALS['csstidy']['replace_colors']['chartreuse'] = '#7fff00';
$GLOBALS['csstidy']['replace_colors']['chocolate'] = '#d2691e';
$GLOBALS['csstidy']['replace_colors']['coral'] = '#ff7f50';
$GLOBALS['csstidy']['replace_colors']['cornflowerblue'] = '#6495ed';
$GLOBALS['csstidy']['replace_colors']['cornsilk'] = '#fff8dc';
$GLOBALS['csstidy']['replace_colors']['crimson'] = '#dc143c';
$GLOBALS['csstidy']['replace_colors']['cyan'] = '#00ffff';
$GLOBALS['csstidy']['replace_colors']['darkblue'] = '#00008b';
$GLOBALS['csstidy']['replace_colors']['darkcyan'] = '#008b8b';
$GLOBALS['csstidy']['replace_colors']['darkgoldenrod'] = '#b8860b';
$GLOBALS['csstidy']['replace_colors']['darkgray'] = '#a9a9a9';
$GLOBALS['csstidy']['replace_colors']['darkgreen'] = '#006400';
$GLOBALS['csstidy']['replace_colors']['darkkhaki'] = '#bdb76b';
$GLOBALS['csstidy']['replace_colors']['darkmagenta'] = '#8b008b';
$GLOBALS['csstidy']['replace_colors']['darkolivegreen'] = '#556b2f';
$GLOBALS['csstidy']['replace_colors']['darkorange'] = '#ff8c00';
$GLOBALS['csstidy']['replace_colors']['darkorchid'] = '#9932cc';
$GLOBALS['csstidy']['replace_colors']['darkred'] = '#8b0000';
$GLOBALS['csstidy']['replace_colors']['darksalmon'] = '#e9967a';
$GLOBALS['csstidy']['replace_colors']['darkseagreen'] = '#8fbc8f';
$GLOBALS['csstidy']['replace_colors']['darkslateblue'] = '#483d8b';
$GLOBALS['csstidy']['replace_colors']['darkslategray'] = '#2f4f4f';
$GLOBALS['csstidy']['replace_colors']['darkturquoise'] = '#00ced1';
$GLOBALS['csstidy']['replace_colors']['darkviolet'] = '#9400d3';
$GLOBALS['csstidy']['replace_colors']['deeppink'] = '#ff1493';
$GLOBALS['csstidy']['replace_colors']['deepskyblue'] = '#00bfff';
$GLOBALS['csstidy']['replace_colors']['dimgray'] = '#696969';
$GLOBALS['csstidy']['replace_colors']['dodgerblue'] = '#1e90ff';
$GLOBALS['csstidy']['replace_colors']['feldspar'] = '#d19275';
$GLOBALS['csstidy']['replace_colors']['firebrick'] = '#b22222';
$GLOBALS['csstidy']['replace_colors']['floralwhite'] = '#fffaf0';
$GLOBALS['csstidy']['replace_colors']['forestgreen'] = '#228b22';
$GLOBALS['csstidy']['replace_colors']['gainsboro'] = '#dcdcdc';
$GLOBALS['csstidy']['replace_colors']['ghostwhite'] = '#f8f8ff';
$GLOBALS['csstidy']['replace_colors']['gold'] = '#ffd700';
$GLOBALS['csstidy']['replace_colors']['goldenrod'] = '#daa520';
$GLOBALS['csstidy']['replace_colors']['greenyellow'] = '#adff2f';
$GLOBALS['csstidy']['replace_colors']['honeydew'] = '#f0fff0';
$GLOBALS['csstidy']['replace_colors']['hotpink'] = '#ff69b4';
$GLOBALS['csstidy']['replace_colors']['indianred'] = '#cd5c5c';
$GLOBALS['csstidy']['replace_colors']['indigo'] = '#4b0082';
$GLOBALS['csstidy']['replace_colors']['ivory'] = '#fffff0';
$GLOBALS['csstidy']['replace_colors']['khaki'] = '#f0e68c';
$GLOBALS['csstidy']['replace_colors']['lavender'] = '#e6e6fa';
$GLOBALS['csstidy']['replace_colors']['lavenderblush'] = '#fff0f5';
$GLOBALS['csstidy']['replace_colors']['lawngreen'] = '#7cfc00';
$GLOBALS['csstidy']['replace_colors']['lemonchiffon'] = '#fffacd';
$GLOBALS['csstidy']['replace_colors']['lightblue'] = '#add8e6';
$GLOBALS['csstidy']['replace_colors']['lightcoral'] = '#f08080';
$GLOBALS['csstidy']['replace_colors']['lightcyan'] = '#e0ffff';
$GLOBALS['csstidy']['replace_colors']['lightgoldenrodyellow'] = '#fafad2';
$GLOBALS['csstidy']['replace_colors']['lightgrey'] = '#d3d3d3';
$GLOBALS['csstidy']['replace_colors']['lightgreen'] = '#90ee90';
$GLOBALS['csstidy']['replace_colors']['lightpink'] = '#ffb6c1';
$GLOBALS['csstidy']['replace_colors']['lightsalmon'] = '#ffa07a';
$GLOBALS['csstidy']['replace_colors']['lightseagreen'] = '#20b2aa';
$GLOBALS['csstidy']['replace_colors']['lightskyblue'] = '#87cefa';
$GLOBALS['csstidy']['replace_colors']['lightslateblue'] = '#8470ff';
$GLOBALS['csstidy']['replace_colors']['lightslategray'] = '#778899';
$GLOBALS['csstidy']['replace_colors']['lightsteelblue'] = '#b0c4de';
$GLOBALS['csstidy']['replace_colors']['lightyellow'] = '#ffffe0';
$GLOBALS['csstidy']['replace_colors']['limegreen'] = '#32cd32';
$GLOBALS['csstidy']['replace_colors']['linen'] = '#faf0e6';
$GLOBALS['csstidy']['replace_colors']['magenta'] = '#ff00ff';
$GLOBALS['csstidy']['replace_colors']['mediumaquamarine'] = '#66cdaa';
$GLOBALS['csstidy']['replace_colors']['mediumblue'] = '#0000cd';
$GLOBALS['csstidy']['replace_colors']['mediumorchid'] = '#ba55d3';
$GLOBALS['csstidy']['replace_colors']['mediumpurple'] = '#9370d8';
$GLOBALS['csstidy']['replace_colors']['mediumseagreen'] = '#3cb371';
$GLOBALS['csstidy']['replace_colors']['mediumslateblue'] = '#7b68ee';
$GLOBALS['csstidy']['replace_colors']['mediumspringgreen'] = '#00fa9a';
$GLOBALS['csstidy']['replace_colors']['mediumturquoise'] = '#48d1cc';
$GLOBALS['csstidy']['replace_colors']['mediumvioletred'] = '#c71585';
$GLOBALS['csstidy']['replace_colors']['midnightblue'] = '#191970';
$GLOBALS['csstidy']['replace_colors']['mintcream'] = '#f5fffa';
$GLOBALS['csstidy']['replace_colors']['mistyrose'] = '#ffe4e1';
$GLOBALS['csstidy']['replace_colors']['moccasin'] = '#ffe4b5';
$GLOBALS['csstidy']['replace_colors']['navajowhite'] = '#ffdead';
$GLOBALS['csstidy']['replace_colors']['oldlace'] = '#fdf5e6';
$GLOBALS['csstidy']['replace_colors']['olivedrab'] = '#6b8e23';
$GLOBALS['csstidy']['replace_colors']['orangered'] = '#ff4500';
$GLOBALS['csstidy']['replace_colors']['orchid'] = '#da70d6';
$GLOBALS['csstidy']['replace_colors']['palegoldenrod'] = '#eee8aa';
$GLOBALS['csstidy']['replace_colors']['palegreen'] = '#98fb98';
$GLOBALS['csstidy']['replace_colors']['paleturquoise'] = '#afeeee';
$GLOBALS['csstidy']['replace_colors']['palevioletred'] = '#d87093';
$GLOBALS['csstidy']['replace_colors']['papayawhip'] = '#ffefd5';
$GLOBALS['csstidy']['replace_colors']['peachpuff'] = '#ffdab9';
$GLOBALS['csstidy']['replace_colors']['peru'] = '#cd853f';
$GLOBALS['csstidy']['replace_colors']['pink'] = '#ffc0cb';
$GLOBALS['csstidy']['replace_colors']['plum'] = '#dda0dd';
$GLOBALS['csstidy']['replace_colors']['powderblue'] = '#b0e0e6';
$GLOBALS['csstidy']['replace_colors']['rosybrown'] = '#bc8f8f';
$GLOBALS['csstidy']['replace_colors']['royalblue'] = '#4169e1';
$GLOBALS['csstidy']['replace_colors']['saddlebrown'] = '#8b4513';
$GLOBALS['csstidy']['replace_colors']['salmon'] = '#fa8072';
$GLOBALS['csstidy']['replace_colors']['sandybrown'] = '#f4a460';
$GLOBALS['csstidy']['replace_colors']['seagreen'] = '#2e8b57';
$GLOBALS['csstidy']['replace_colors']['seashell'] = '#fff5ee';
$GLOBALS['csstidy']['replace_colors']['sienna'] = '#a0522d';
$GLOBALS['csstidy']['replace_colors']['skyblue'] = '#87ceeb';
$GLOBALS['csstidy']['replace_colors']['slateblue'] = '#6a5acd';
$GLOBALS['csstidy']['replace_colors']['slategray'] = '#708090';
$GLOBALS['csstidy']['replace_colors']['snow'] = '#fffafa';
$GLOBALS['csstidy']['replace_colors']['springgreen'] = '#00ff7f';
$GLOBALS['csstidy']['replace_colors']['steelblue'] = '#4682b4';
$GLOBALS['csstidy']['replace_colors']['tan'] = '#d2b48c';
$GLOBALS['csstidy']['replace_colors']['thistle'] = '#d8bfd8';
$GLOBALS['csstidy']['replace_colors']['tomato'] = '#ff6347';
$GLOBALS['csstidy']['replace_colors']['turquoise'] = '#40e0d0';
$GLOBALS['csstidy']['replace_colors']['violet'] = '#ee82ee';
$GLOBALS['csstidy']['replace_colors']['violetred'] = '#d02090';
$GLOBALS['csstidy']['replace_colors']['wheat'] = '#f5deb3';
$GLOBALS['csstidy']['replace_colors']['whitesmoke'] = '#f5f5f5';
$GLOBALS['csstidy']['replace_colors']['yellowgreen'] = '#9acd32';
/**
* A list of all shorthand properties that are divided into four properties and/or have four subvalues
*
* @global array $GLOBALS['csstidy']['shorthands']
* @todo Are there new ones in CSS3?
* @see dissolve_4value_shorthands()
* @see merge_4value_shorthands()
* @version 1.0
*/
$GLOBALS['csstidy']['shorthands'] = array();
$GLOBALS['csstidy']['shorthands']['border-color'] = array('border-top-color','border-right-color','border-bottom-color','border-left-color');
$GLOBALS['csstidy']['shorthands']['border-style'] = array('border-top-style','border-right-style','border-bottom-style','border-left-style');
$GLOBALS['csstidy']['shorthands']['border-width'] = array('border-top-width','border-right-width','border-bottom-width','border-left-width');
$GLOBALS['csstidy']['shorthands']['margin'] = array('margin-top','margin-right','margin-bottom','margin-left');
$GLOBALS['csstidy']['shorthands']['padding'] = array('padding-top','padding-right','padding-bottom','padding-left');
$GLOBALS['csstidy']['shorthands']['-moz-border-radius'] = 0;
/**
* All CSS Properties. Needed for csstidy::property_is_next()
*
* @global array $GLOBALS['csstidy']['all_properties']
* @todo Add CSS3 properties
* @version 1.0
* @see csstidy::property_is_next()
*/
$GLOBALS['csstidy']['all_properties']['align-content'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['align-items'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['align-self'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['alignment-adjust'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['alignment-baseline'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['animation'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['animation-delay'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['animation-direction'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['animation-duration'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['animation-fill-mode'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['animation-iteration-count'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['animation-name'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['animation-play-state'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['animation-timing-function'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['appearance'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['azimuth'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['backface-visibility'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['background'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['background-attachment'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['background-clip'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['background-color'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['background-image'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['background-origin'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['background-position'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['background-repeat'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['background-size'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['baseline-shift'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['binding'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['bleed'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['bookmark-label'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['bookmark-level'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['bookmark-state'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['bookmark-target'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['border'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['border-bottom'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['border-bottom-color'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['border-bottom-left-radius'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['border-bottom-right-radius'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['border-bottom-style'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['border-bottom-width'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['border-collapse'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['border-color'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['border-image'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['border-image-outset'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['border-image-repeat'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['border-image-slice'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['border-image-source'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['border-image-width'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['border-left'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['border-left-color'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['border-left-style'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['border-left-width'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['border-radius'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['border-right'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['border-right-color'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['border-right-style'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['border-right-width'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['border-spacing'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['border-style'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['border-top'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['border-top-color'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['border-top-left-radius'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['border-top-right-radius'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['border-top-style'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['border-top-width'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['border-width'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['bottom'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['box-decoration-break'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['box-shadow'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['box-sizing'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['break-after'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['break-before'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['break-inside'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['caption-side'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['clear'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['clip'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['color'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['color-profile'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['column-count'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['column-fill'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['column-gap'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['column-rule'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['column-rule-color'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['column-rule-style'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['column-rule-width'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['column-span'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['column-width'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['columns'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['content'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['counter-increment'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['counter-reset'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['crop'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['cue'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['cue-after'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['cue-before'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['cursor'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['direction'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['display'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['dominant-baseline'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['drop-initial-after-adjust'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['drop-initial-after-align'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['drop-initial-before-adjust'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['drop-initial-before-align'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['drop-initial-size'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['drop-initial-value'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['elevation'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['empty-cells'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['fill'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['fit'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['fit-position'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['flex'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['flex-align'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['flex-basis'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['flex-direction'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['flex-flow'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['flex-grow'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['flex-line-pack'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['flex-order'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['flex-pack'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['flex-shrink'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['flex-wrap'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['float'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['float-offset'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['font'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['font-family'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['font-size'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['font-size-adjust'] = 'CSS2.0,CSS3.0';
$GLOBALS['csstidy']['all_properties']['font-stretch'] = 'CSS2.0,CSS3.0';
$GLOBALS['csstidy']['all_properties']['font-style'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['font-variant'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['font-weight'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['grid'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['grid-area'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['grid-auto-columns'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['grid-auto-flow'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['grid-auto-rows'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['grid-column'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['grid-columns'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['grid-column-end'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['grid-column-gap'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['grid-column-start'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['grid-gap'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['grid-row'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['grid-rows'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['grid-row-end'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['grid-row-gap'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['grid-row-start'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['grid-template'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['grid-template-areas'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['grid-template-columns'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['grid-template-rows'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['hanging-punctuation'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['height'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['hyphenate-after'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['hyphenate-before'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['hyphenate-character'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['hyphenate-lines'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['hyphenate-resource'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['hyphens'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['icon'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['image-orientation'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['image-rendering'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['image-resolution'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['inline-box-align'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['justify-content'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['justify-items'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['justify-self'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['left'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['letter-spacing'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['line-break'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['line-height'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['line-stacking'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['line-stacking-ruby'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['line-stacking-shift'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['line-stacking-strategy'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['list-style'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['list-style-image'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['list-style-position'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['list-style-type'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['margin'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['margin-bottom'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['margin-left'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['margin-right'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['margin-top'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['marker-offset'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['marks'] = 'CSS2.0,CSS3.0';
$GLOBALS['csstidy']['all_properties']['marquee-direction'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['marquee-loop'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['marquee-play-count'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['marquee-speed'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['marquee-style'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['max-height'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['max-width'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['min-height'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['min-width'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['move-to'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['nav-down'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['nav-index'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['nav-left'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['nav-right'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['nav-up'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['opacity'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['order'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['orphans'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['outline'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['outline-color'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['outline-offset'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['outline-style'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['outline-width'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['overflow'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['overflow-style'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['overflow-wrap'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['overflow-x'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['overflow-y'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['padding'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['padding-bottom'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['padding-left'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['padding-right'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['padding-top'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['page'] = 'CSS2.0,CSS3.0';
$GLOBALS['csstidy']['all_properties']['page-break-after'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['page-break-before'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['page-break-inside'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['page-policy'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['pause'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['pause-after'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['pause-before'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['perspective'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['perspective-origin'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['phonemes'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['pitch'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['pitch-range'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['play-during'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['position'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['presentation-level'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['punctuation-trim'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['quotes'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['rendering-intent'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['resize'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['rest'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['rest-after'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['rest-before'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['richness'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['right'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['rotation'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['rotation-point'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['ruby-align'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['ruby-overhang'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['ruby-position'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['ruby-span'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['size'] = 'CSS2.0,CSS3.0';
$GLOBALS['csstidy']['all_properties']['speak'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['speak-header'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['speak-numeral'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['speak-punctuation'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['speech-rate'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['src'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['stress'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['string-set'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['stroke'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['tab-size'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['table-layout'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['target'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['target-name'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['target-new'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['target-position'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['text-align'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['text-align-last'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['text-decoration'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['text-decoration-color'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['text-decoration-line'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['text-decoration-skip'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['text-decoration-style'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['text-emphasis'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['text-emphasis-color'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['text-emphasis-position'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['text-emphasis-style'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['text-height'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['text-indent'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['text-justify'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['text-outline'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['text-shadow'] = 'CSS2.0,CSS3.0';
$GLOBALS['csstidy']['all_properties']['text-space-collapse'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['text-transform'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['text-underline-position'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['text-wrap'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['top'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['transform'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['transform-origin'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['transform-style'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['transition'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['transition-delay'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['transition-duration'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['transition-property'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['transition-timing-function'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['unicode-bidi'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['vertical-align'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['visibility'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['voice-balance'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['voice-duration'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['voice-family'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['voice-pitch'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['voice-pitch-range'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['voice-rate'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['voice-stress'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['voice-volume'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['volume'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['white-space'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['widows'] = 'CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['width'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['word-break'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['word-spacing'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
$GLOBALS['csstidy']['all_properties']['word-wrap'] = 'CSS3.0';
$GLOBALS['csstidy']['all_properties']['z-index'] = 'CSS2.0,CSS2.1,CSS3.0';
/**
* An array containing all properties that can accept a quoted string as a value.
*
* @global array $GLOBALS['csstidy']['quoted_string_properties']
*/
$GLOBALS['csstidy']['quoted_string_properties'] = array('content', 'font', 'font-family', 'quotes');
/**
* An array containing all properties that can be defined multiple times without being overwritten.
* All unit values are included so that units like rem can be supported with fallbacks to px or em.
*
* @global array $GLOBALS['csstidy']['quoted_string_properties']
*/
$GLOBALS['csstidy']['multiple_properties'] = array_merge( $GLOBALS['csstidy']['color_values'], $GLOBALS['csstidy']['unit_values'], array( 'transition', 'background-image', 'border-image', 'list-style-image' ) );
/**
* An array containing all predefined templates.
*
* @global array $GLOBALS['csstidy']['predefined_templates']
* @version 1.0
* @see csstidy::load_template()
*/
$GLOBALS['csstidy']['predefined_templates']['default'][] = '<span class="at">'; //string before @rule
$GLOBALS['csstidy']['predefined_templates']['default'][] = '</span> <span class="format">{</span>'."\n"; //bracket after @-rule
$GLOBALS['csstidy']['predefined_templates']['default'][] = '<span class="selector">'; //string before selector
$GLOBALS['csstidy']['predefined_templates']['default'][] = '</span> <span class="format">{</span>'."\n"; //bracket after selector
$GLOBALS['csstidy']['predefined_templates']['default'][] = '<span class="property">'; //string before property
$GLOBALS['csstidy']['predefined_templates']['default'][] = '</span><span class="value">'; //string after property+before value
$GLOBALS['csstidy']['predefined_templates']['default'][] = '</span><span class="format">;</span>'."\n"; //string after value
$GLOBALS['csstidy']['predefined_templates']['default'][] = '<span class="format">}</span>'; //closing bracket - selector
$GLOBALS['csstidy']['predefined_templates']['default'][] = "\n\n"; //space between blocks {...}
$GLOBALS['csstidy']['predefined_templates']['default'][] = "\n".'<span class="format">}</span>'. "\n\n"; //closing bracket @-rule
$GLOBALS['csstidy']['predefined_templates']['default'][] = ''; //indent in @-rule
$GLOBALS['csstidy']['predefined_templates']['default'][] = '<span class="comment">'; // before comment
$GLOBALS['csstidy']['predefined_templates']['default'][] = '</span>'."\n"; // after comment
$GLOBALS['csstidy']['predefined_templates']['default'][] = "\n"; // after last line @-rule
$GLOBALS['csstidy']['predefined_templates']['high_compression'][] = '<span class="at">';
$GLOBALS['csstidy']['predefined_templates']['high_compression'][] = '</span> <span class="format">{</span>'."\n";
$GLOBALS['csstidy']['predefined_templates']['high_compression'][] = '<span class="selector">';
$GLOBALS['csstidy']['predefined_templates']['high_compression'][] = '</span><span class="format">{</span>';
$GLOBALS['csstidy']['predefined_templates']['high_compression'][] = '<span class="property">';
$GLOBALS['csstidy']['predefined_templates']['high_compression'][] = '</span><span class="value">';
$GLOBALS['csstidy']['predefined_templates']['high_compression'][] = '</span><span class="format">;</span>';
$GLOBALS['csstidy']['predefined_templates']['high_compression'][] = '<span class="format">}</span>';
$GLOBALS['csstidy']['predefined_templates']['high_compression'][] = "\n";
$GLOBALS['csstidy']['predefined_templates']['high_compression'][] = "\n". '<span class="format">}'."\n".'</span>';
$GLOBALS['csstidy']['predefined_templates']['high_compression'][] = '';
$GLOBALS['csstidy']['predefined_templates']['high_compression'][] = '<span class="comment">'; // before comment
$GLOBALS['csstidy']['predefined_templates']['high_compression'][] = '</span>'; // after comment
$GLOBALS['csstidy']['predefined_templates']['high_compression'][] = "\n";
$GLOBALS['csstidy']['predefined_templates']['highest_compression'][] = '<span class="at">';
$GLOBALS['csstidy']['predefined_templates']['highest_compression'][] = '</span><span class="format">{</span>';
$GLOBALS['csstidy']['predefined_templates']['highest_compression'][] = '<span class="selector">';
$GLOBALS['csstidy']['predefined_templates']['highest_compression'][] = '</span><span class="format">{</span>';
$GLOBALS['csstidy']['predefined_templates']['highest_compression'][] = '<span class="property">';
$GLOBALS['csstidy']['predefined_templates']['highest_compression'][] = '</span><span class="value">';
$GLOBALS['csstidy']['predefined_templates']['highest_compression'][] = '</span><span class="format">;</span>';
$GLOBALS['csstidy']['predefined_templates']['highest_compression'][] = '<span class="format">}</span>';
$GLOBALS['csstidy']['predefined_templates']['highest_compression'][] = '';
$GLOBALS['csstidy']['predefined_templates']['highest_compression'][] = '<span class="format">}</span>';
$GLOBALS['csstidy']['predefined_templates']['highest_compression'][] = '';
$GLOBALS['csstidy']['predefined_templates']['highest_compression'][] = '<span class="comment">'; // before comment
$GLOBALS['csstidy']['predefined_templates']['highest_compression'][] = '</span>'; // after comment
$GLOBALS['csstidy']['predefined_templates']['highest_compression'][] = '';
$GLOBALS['csstidy']['predefined_templates']['low_compression'][] = '<span class="at">';
$GLOBALS['csstidy']['predefined_templates']['low_compression'][] = '</span> <span class="format">{</span>'."\n";
$GLOBALS['csstidy']['predefined_templates']['low_compression'][] = '<span class="selector">';
$GLOBALS['csstidy']['predefined_templates']['low_compression'][] = '</span>'."\n".'<span class="format">{</span>'."\n";
$GLOBALS['csstidy']['predefined_templates']['low_compression'][] = ' <span class="property">';
$GLOBALS['csstidy']['predefined_templates']['low_compression'][] = '</span><span class="value">';
$GLOBALS['csstidy']['predefined_templates']['low_compression'][] = '</span><span class="format">;</span>'."\n";
$GLOBALS['csstidy']['predefined_templates']['low_compression'][] = '<span class="format">}</span>';
$GLOBALS['csstidy']['predefined_templates']['low_compression'][] = "\n\n";
$GLOBALS['csstidy']['predefined_templates']['low_compression'][] = "\n".'<span class="format">}</span>'."\n\n";
$GLOBALS['csstidy']['predefined_templates']['low_compression'][] = ' ';
$GLOBALS['csstidy']['predefined_templates']['low_compression'][] = '<span class="comment">'; // before comment
$GLOBALS['csstidy']['predefined_templates']['low_compression'][] = '</span>'."\n"; // after comment
$GLOBALS['csstidy']['predefined_templates']['low_compression'][] = "\n";
require dirname( __FILE__ ) . '/data-wp.inc.php';

View File

@@ -0,0 +1,308 @@
<?php
/**
* Localization of CSS Optimiser Interface of CSSTidy
*
* Copyright 2005, 2006, 2007 Florian Schmitz
*
* This file is part of CSSTidy.
*
* CSSTidy is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* CSSTidy 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @license http://opensource.org/licenses/lgpl-license.php GNU Lesser General Public License
* @package csstidy
* @author Florian Schmitz (floele at gmail dot com) 2005-2007
* @author Brett Zamir (brettz9 at yahoo dot com) 2007
*/
if ( isset( $_GET['lang'] ) ) {
$l = $_GET['lang'];
} elseif ( isset( $_SERVER['HTTP_ACCEPT_LANGUAGE'] ) ) {
$l = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
$l = strtolower( substr( $l, 0, 2 ) );
} else {
$l = '';
}
$l = ( in_array( $l, array( 'de', 'fr', 'zh' ) ) ) ? $l : 'en';
// note 5 in all but French, and 40 in all are orphaned
$lang = array();
$lang['en'][0] = 'CSS Formatter and Optimiser/Optimizer (based on CSSTidy ';
$lang['en'][1] = 'CSS Formatter and Optimiser';
$lang['en'][2] = '(based on';
$lang['en'][3] = '(plaintext)';
$lang['en'][4] = 'Important Note:';
$lang['en'][6] = 'Your code should be well-formed. This is <strong>not a validator</strong> which points out errors in your CSS code. To make sure that your code is valid, use the <a href="http://jigsaw.w3.org/css-validator/">W3C Validator</a>.';
$lang['en'][7] = 'all comments are removed';
$lang['en'][8] = 'CSS Input:';
$lang['en'][9] = 'CSS-Code:';
$lang['en'][10] = 'CSS from URL:';
$lang['en'][11] = 'Code Layout:';
$lang['en'][12] = 'Compression&#160;(code&#160;layout):';
$lang['en'][13] = 'Highest (no readability, smallest size)';
$lang['en'][14] = 'High (moderate readability, smaller size)';
$lang['en'][15] = 'Standard (balance between readability and size)';
$lang['en'][16] = 'Low (higher readability)';
$lang['en'][17] = 'Custom (enter below)';
$lang['en'][18] = 'Custom <a href="http://csstidy.sourceforge.net/templates.php">template</a>';
$lang['en'][19] = 'Options';
$lang['en'][20] = 'Sort Selectors (caution)';
$lang['en'][21] = 'Sort Properties';
$lang['en'][22] = 'Regroup selectors';
$lang['en'][23] = 'Optimise shorthands';
$lang['en'][24] = 'Compress colors';
$lang['en'][25] = 'Lowercase selectors';
$lang['en'][26] = 'Case for properties:';
$lang['en'][27] = 'Lowercase';
$lang['en'][28] = 'No or invalid CSS input or wrong URL!';
$lang['en'][29] = 'Uppercase';
$lang['en'][30] = 'lowercase elementnames needed for XHTML';
$lang['en'][31] = 'Remove unnecessary backslashes';
$lang['en'][32] = 'convert !important-hack';
$lang['en'][33] = 'Output as file';
$lang['en'][34] = 'Bigger compression because of smaller newlines (copy &#38; paste doesn\'t work)';
$lang['en'][35] = 'Process CSS';
$lang['en'][36] = 'Compression Ratio';
$lang['en'][37] = 'Input';
$lang['en'][38] = 'Output';
$lang['en'][39] = 'Language';
$lang['en'][41] = 'Attention: This may change the behaviour of your CSS Code!';
$lang['en'][42] = 'Remove last ;';
$lang['en'][43] = 'Discard invalid properties';
$lang['en'][44] = 'Only safe optimisations';
$lang['en'][45] = 'Compress font-weight';
$lang['en'][46] = 'Save comments';
$lang['en'][47] = 'Do not change anything';
$lang['en'][48] = 'Only separate selectors (split at ,)';
$lang['en'][49] = 'Merge selectors with the same properties (fast)';
$lang['en'][50] = 'Merge selectors intelligently (slow)';
$lang['en'][51] = 'Preserve CSS';
$lang['en'][52] = 'Save comments, hacks, etc. Most optimisations can *not* be applied if this is enabled.';
$lang['en'][53] = 'None';
$lang['en'][54] = 'Don\'t optimise';
$lang['en'][55] = 'Safe optimisations';
$lang['en'][56] = 'All optimisations';
$lang['en'][57] = 'Add timestamp';
$lang['en'][58] = 'Copy to clipboard';
$lang['en'][59] = 'Back to top';
$lang['en'][60] = 'Your browser doesn\'t support copy to clipboard.';
$lang['en'][61] = 'For bugs and suggestions feel free to';
$lang['en'][62] = 'contact me';
$lang['en'][63] = 'Output CSS code as complete HTML document';
$lang['en'][64] = 'Code';
$lang['en'][65] = 'CSS to style CSS output';
$lang['en'][66] = 'You need to go to about:config in your URL bar, select \'signed.applets.codebase_principal_support\' in the filter field, and set its value to true in order to use this feature; however, be aware that doing so increases security risks.';
$lang['de'][0] = 'CSS Formatierer und Optimierer (basierend auf CSSTidy ';
$lang['de'][1] = 'CSS Formatierer und Optimierer';
$lang['de'][2] = '(basierend auf';
$lang['de'][3] = '(Textversion)';
$lang['de'][4] = 'Wichtiger Hinweis:';
$lang['de'][6] = 'Der CSS Code sollte wohlgeformt sein. Der CSS Code wird <strong>nicht auf Gültigkeit überprüft</strong>. Um sicherzugehen dass dein Code valide ist, benutze den <a href="http://jigsaw.w3.org/css-validator/">W3C Validierungsservice</a>.';
$lang['de'][7] = 'alle Kommentare werden entfernt';
$lang['de'][8] = 'CSS Eingabe:';
$lang['de'][9] = 'CSS-Code:';
$lang['de'][10] = 'CSS von URL:';
$lang['de'][11] = 'Code Layout:';
$lang['de'][12] = 'Komprimierung&#160;(Code&#160;Layout):';
$lang['de'][13] = 'Höchste (keine Lesbarkeit, niedrigste Größe)';
$lang['de'][14] = 'Hoch (mittelmäßige Lesbarkeit, geringe Größe)';
$lang['de'][15] = 'Standard (Kompromiss zwischen Lesbarkeit und Größe)';
$lang['de'][16] = 'Niedrig (höhere Lesbarkeit)';
$lang['de'][17] = 'Benutzerdefiniert (unten eingeben)';
$lang['de'][18] = 'Benutzerdefinierte <a href="http://csstidy.sourceforge.net/templates.php">Vorlage</a>';
$lang['de'][19] = 'Optionen';
$lang['de'][20] = 'Selektoren sortieren (Vorsicht)';
$lang['de'][21] = 'Eigenschaften sortieren';
$lang['de'][22] = 'Selektoren umgruppieren';
$lang['de'][23] = 'Shorthands optimieren';
$lang['de'][24] = 'Farben komprimieren';
$lang['de'][25] = 'Selektoren in Kleinbuchstaben';
$lang['de'][26] = 'Groß-/Kleinschreibung für Eigenschaften';
$lang['de'][27] = 'Kleinbuchstaben';
$lang['de'][28] = 'Keine oder ungültige CSS Eingabe oder falsche URL!';
$lang['de'][29] = 'Großbuchstaben';
$lang['de'][30] = 'kleingeschriebene Elementnamen benötigt für XHTML';
$lang['de'][31] = 'Unnötige Backslashes entfernen';
$lang['de'][32] = '!important-Hack konvertieren';
$lang['de'][33] = 'Als Datei ausgeben';
$lang['de'][34] = 'Größere Komprimierung augrund von kleineren Neuezeile-Zeichen';
$lang['de'][35] = 'CSS verarbeiten';
$lang['de'][36] = 'Komprimierungsrate';
$lang['de'][37] = 'Eingabe';
$lang['de'][38] = 'Ausgabe';
$lang['de'][39] = 'Sprache';
$lang['de'][41] = 'Achtung: Dies könnte das Verhalten ihres CSS-Codes verändern!';
$lang['de'][42] = 'Letztes ; entfernen';
$lang['de'][43] = 'Ungültige Eigenschaften entfernen';
$lang['de'][44] = 'Nur sichere Optimierungen';
$lang['de'][45] = 'font-weight komprimieren';
$lang['de'][46] = 'Kommentare beibehalten';
$lang['de'][47] = 'Nichts ändern';
$lang['de'][48] = 'Selektoren nur trennen (am Komma)';
$lang['de'][49] = 'Selektoren mit gleichen Eigenschaften zusammenfassen (schnell)';
$lang['de'][50] = 'Selektoren intelligent zusammenfassen (langsam!)';
$lang['de'][51] = 'CSS erhalten';
$lang['de'][52] = 'Kommentare, Hacks, etc. speichern. Viele Optimierungen sind dann aber nicht mehr möglich.';
$lang['de'][53] = 'Keine';
$lang['de'][54] = 'Nicht optimieren';
$lang['de'][55] = 'Sichere Optimierungen';
$lang['de'][56] = 'Alle Optimierungen';
$lang['de'][57] = 'Zeitstempel hinzufügen';
$lang['de'][58] = 'Copy to clipboard';
$lang['de'][59] = 'Back to top';
$lang['de'][60] = 'Your browser doesn\'t support copy to clipboard.';
$lang['de'][61] = 'For bugs and suggestions feel free to';
$lang['de'][62] = 'contact me';
$lang['de'][63] = 'Output CSS code as complete HTML document';
$lang['de'][64] = 'Code';
$lang['de'][65] = 'CSS to style CSS output';
$lang['de'][66] = 'You need to go to about:config in your URL bar, select \'signed.applets.codebase_principal_support\' in the filter field, and set its value to true in order to use this feature; however, be aware that doing so increases security risks.';
$lang['fr'][0] = 'CSS Formatteur et Optimiseur (basé sur CSSTidy ';
$lang['fr'][1] = 'CSS Formatteur et Optimiseur';
$lang['fr'][2] = '(basé sur ';
$lang['fr'][3] = '(Version texte)';
$lang['fr'][4] = 'Note Importante&#160;:';
$lang['fr'][6] = 'Votre code doit être valide. Ce nest <strong>pas un validateur</strong> qui signale les erreurs dans votre code CSS. Pour être sûr que votre code est correct, utilisez le validateur&#160;: <a href="http://jigsaw.w3.org/css-validator/">W3C Validator</a>.';
$lang['fr'][7] = 'tous les commentaires sont enlevés';
$lang['fr'][8] = 'Champ CSS&#160;:';
$lang['fr'][9] = 'Code CSS&#160;:';
$lang['fr'][10] = 'CSS en provenance dune URL&#160;:<br />';
$lang['fr'][11] = 'Mise en page du code&#160;:';
$lang['fr'][12] = 'Compression (mise en page du code)&#160;:';
$lang['fr'][13] = 'La plus élevée (aucune lisibilité, taille minimale)';
$lang['fr'][14] = 'Élevée (lisibilité modérée, petite taille)';
$lang['fr'][15] = 'Normale (équilibre entre lisibilité et taille)';
$lang['fr'][16] = 'Faible (lisibilité élevée)';
$lang['fr'][17] = 'Sur mesure (entrer ci-dessous)';
$lang['fr'][18] = '<a href="http://csstidy.sourceforge.net/templates.php">Gabarit</a> sur mesure';
$lang['fr'][19] = 'Options';
$lang['fr'][20] = 'Trier les sélecteurs (attention)';
$lang['fr'][21] = 'Trier les propriétés';
$lang['fr'][22] = 'Regrouper les sélecteurs';
$lang['fr'][23] = 'Propriétés raccourcies';
$lang['fr'][24] = 'Compresser les couleurs';
$lang['fr'][25] = 'Sélecteurs en minuscules';
$lang['fr'][26] = 'Case pour les propriétés&#160;:';
$lang['fr'][27] = 'Minuscule';
$lang['fr'][28] = 'CSS non valide ou URL incorrecte&#160;!';
$lang['fr'][29] = 'Majuscule';
$lang['fr'][30] = 'les noms des éléments en minuscules (indispensables pour XHTML)';
$lang['fr'][31] = 'enlever les antislashs inutiles';
$lang['fr'][32] = 'convertir !important-hack';
$lang['fr'][33] = 'Sauver en tant que fichier';
$lang['fr'][34] = 'Meilleure compression grâce aux caractères de saut de ligne plus petits (copier &#38; coller ne marche pas)';
$lang['fr'][35] = 'Compresser la CSS';
$lang['fr'][36] = 'Facteur de Compression';
$lang['fr'][37] = 'Entrée';
$lang['fr'][38] = 'Sortie';
$lang['fr'][39] = 'Langue';
$lang['fr'][41] = 'Attention&#160;: ceci peut changer le comportement de votre code CSS&#160;!';
$lang['fr'][42] = 'Enlever le dernier ;';
$lang['fr'][43] = 'Supprimer les propriétés non valide';
$lang['fr'][44] = 'Seulement les optimisations sûres';
$lang['fr'][45] = 'Compresser font-weight';
$lang['fr'][46] = 'Sauvegarder les commentaires ';
$lang['fr'][47] = 'Ne rien changer';
$lang['fr'][48] = 'Sépare les sélecteurs (sépare au niveau de ,)';
$lang['fr'][49] = 'Fusionne les sélecteurs avec les mêmes propriétés (rapide)';
$lang['fr'][50] = 'Fusionne les sélecteurs intelligemment (lent)';
$lang['fr'][51] = 'Préserver la CSS';
$lang['fr'][52] = 'Sauvegarder les commentaires, hacks, etc. La plupart des optimisations ne peuvent *pas* être appliquées si cela est activé.';
$lang['fr'][53] = 'Aucun';
$lang['fr'][54] = 'Ne pas optimiser';
$lang['fr'][55] = 'Optimisations sûres';
$lang['fr'][56] = 'Toutes les optimisations';
$lang['fr'][57] = 'Ajouter un timestamp';
$lang['fr'][58] = 'Copier dans le presse-papiers';
$lang['fr'][59] = 'Retour en haut';
$lang['fr'][60] = 'Votre navigateur ne suporte pas la copie vers le presse-papiers.';
$lang['fr'][61] = 'Pour signaler des bugs ou pour des suggestions,';
$lang['fr'][62] = 'contactez-moi';
$lang['fr'][63] = 'Sauver le code CSS comme document complet HTML';
$lang['fr'][64] = 'Code';
$lang['fr'][65] = 'CSS pour colorier la sortie CSS';
$lang['fr'][66] = 'Vous devez aller dans about:config dans votre barre dadresse, selectionner \'signed.applets.codebase_principal_support\' dans le champ Filtre et attribuez-lui la valeur \'true\' pour utiliser cette fonctionnalité; toutefois, soyez conscient que cela augmente les risques de sécurité.';
$lang['zh'][0] = 'CSS整形與最佳化工具(使用 CSSTidy ';
$lang['zh'][1] = 'CSS整形與最佳化工具';
$lang['zh'][2] = '(使用';
$lang['zh'][3] = '(純文字)';
$lang['zh'][4] = '重要事項:';
$lang['zh'][6] = '你的原始碼必須是良構的(well-formed). 這個工具<strong>沒有內建驗證器(validator)</strong>. 驗證器能夠指出你CSS原始碼裡的錯誤. 請使用 <a href="http://jigsaw.w3.org/css-validator/">W3C 驗證器</a>, 確保你的原始碼合乎規範.';
$lang['zh'][7] = '所有註解都移除了';
$lang['zh'][8] = 'CSS 輸入:';
$lang['zh'][9] = 'CSS 原始碼:';
$lang['zh'][10] = 'CSS 檔案網址(URL):';
$lang['zh'][11] = '原始碼規劃:';
$lang['zh'][12] = '壓縮程度(原始碼規劃):';
$lang['zh'][13] = '最高 (沒有辦法讀, 檔案最小)';
$lang['zh'][14] = '高 (適度的可讀性, 檔案小)';
$lang['zh'][15] = '標準 (兼顧可讀性與檔案大小)';
$lang['zh'][16] = '低 (注重可讀性)';
$lang['zh'][17] = '自訂 (在下方設定)';
$lang['zh'][18] = '自訂<a href="http://csstidy.sourceforge.net/templates.php">樣板</a>';
$lang['zh'][19] = '選項';
$lang['zh'][20] = '整理選擇符(請謹慎使用)';
$lang['zh'][21] = '整理屬性';
$lang['zh'][22] = '重組選擇符';
$lang['zh'][23] = '速記法(shorthand)最佳化';
$lang['zh'][24] = '壓縮色彩語法';
$lang['zh'][25] = '改用小寫選擇符';
$lang['zh'][26] = '屬性的字形:';
$lang['zh'][27] = '小寫';
$lang['zh'][28] = '沒有輸入CSS, 語法不符合規定, 或是網址錯誤!';
$lang['zh'][29] = '大寫';
$lang['zh'][30] = 'XHTML必須使用小寫的元素名稱';
$lang['zh'][31] = '移除不必要的反斜線';
$lang['zh'][32] = '轉換 !important-hack';
$lang['zh'][33] = '輸出成檔案形式';
$lang['zh'][34] = '由於比較少換行字元, 會有更大的壓縮比率(複製&#38;貼上沒有用)';
$lang['zh'][35] = '執行';
$lang['zh'][36] = '壓縮比率';
$lang['zh'][37] = '輸入';
$lang['zh'][38] = '輸出';
$lang['zh'][39] = '語言';
$lang['zh'][41] = '注意: 這或許會變更你CSS原始碼的行為!';
$lang['zh'][42] = '除去最後一個分號';
$lang['zh'][43] = '拋棄不符合規定的屬性';
$lang['zh'][44] = '只安全地最佳化';
$lang['zh'][45] = '壓縮 font-weight';
$lang['zh'][46] = '保留註解';
$lang['zh'][47] = '什麼都不要改';
$lang['zh'][48] = '只分開原本用逗號分隔的選擇符';
$lang['zh'][49] = '合併有相同屬性的選擇符(快速)';
$lang['zh'][50] = '聰明地合併選擇符(慢速)';
$lang['zh'][51] = '保護CSS';
$lang['zh'][52] = '保留註解與 hack 等等. 如果啟用這個選項, 大多數的最佳化程序都不會執行.';
$lang['zh'][53] = '不改變';
$lang['zh'][54] = '不做最佳化';
$lang['zh'][55] = '安全地最佳化';
$lang['zh'][56] = '全部最佳化';
$lang['zh'][57] = '加上時間戳記';
$lang['zh'][58] = '复制到剪贴板';
$lang['zh'][59] = '回到页面上方';
$lang['zh'][60] = '你的浏览器不支持复制到剪贴板。';
$lang['zh'][61] = '如果程序有错误或你有建议,欢迎';
$lang['zh'][62] = '和我联系';
$lang['zh'][63] = 'Output CSS code as complete HTML document';
$lang['zh'][64] = '代码';
$lang['zh'][65] = 'CSS to style CSS output';
$lang['zh'][66] = 'You need to go to about:config in your URL bar, select \'signed.applets.codebase_principal_support\' in the filter field, and set its value to true in order to use this feature; however, be aware that doing so increases security risks.';

View File

@@ -0,0 +1,10 @@
| {
|| {
| | |;
|}|
|
}
| ||
|

Some files were not shown because too many files have changed in this diff Show More