Version Description
Fixed admin notice and "add to form" button, improved Contact Form 7 integration.
Download this release
Release Info
| Developer | DvanKooten |
| Plugin | |
| Version | 1.5.4 |
| Comparing to | |
| See all releases | |
Code changes from version 1.5.2 to 1.5.4
- assets/js/admin.js +233 -145
- assets/js/beautify-html.js +839 -0
- includes/class-admin.php +3 -2
- includes/class-checkbox.php +27 -4
- includes/class-form.php +6 -2
- includes/class-plugin.php +1 -1
- includes/views/form-settings.php +5 -1
- includes/views/parts/admin-field-wizard.php +2 -1
- mailchimp-for-wp.php +3 -2
- readme.txt +20 -1
assets/js/admin.js
CHANGED
|
@@ -40,97 +40,120 @@
|
|
| 40 |
var $placeholder = $("#mc4wp-fw-placeholder");
|
| 41 |
var $required = $("#mc4wp-fw-required");
|
| 42 |
var $wrapp = $("#mc4wp-fw-wrap-p");
|
| 43 |
-
var
|
| 44 |
-
'type': 'text',
|
| 45 |
-
'name': ''
|
| 46 |
-
};
|
| 47 |
var $codePreview = $("#mc4wp-fw-preview");
|
| 48 |
// functions
|
| 49 |
|
| 50 |
// set the fields the user can choose from
|
| 51 |
-
function
|
| 52 |
{
|
| 53 |
-
// show notice if no lists selecteed
|
| 54 |
-
var $selectedLists = $lists.filter(':checked');
|
| 55 |
-
$(".no-lists-selected").toggle(($selectedLists.length == 0));
|
| 56 |
-
|
| 57 |
-
|
| 58 |
// empty field select
|
| 59 |
$mailchimpFields.find('option').not('.default').remove();
|
| 60 |
|
| 61 |
// loop through checked lists
|
| 62 |
-
$
|
| 63 |
-
var
|
| 64 |
-
var
|
| 65 |
|
| 66 |
// loop through merge fields from this list
|
| 67 |
-
for(var i = 0; i <
|
| 68 |
-
var
|
| 69 |
|
| 70 |
// add field to select if no similar option exists yet
|
| 71 |
-
if($mailchimpMergeFields.find("option[value='"+
|
| 72 |
|
| 73 |
-
var text = (
|
| 74 |
-
if(
|
| 75 |
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 81 |
}
|
| 82 |
-
|
| 83 |
$mailchimpMergeFields.append($option);
|
| 84 |
}
|
| 85 |
}
|
| 86 |
|
| 87 |
// loop through interest groupings
|
| 88 |
-
for(var i = 0, groupingsCount =
|
| 89 |
-
var
|
| 90 |
-
|
| 91 |
// add field to select if no similar option exists yet
|
| 92 |
-
if($mailchimpGroupings.find("option[value='"+
|
| 93 |
-
var text = (
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 94 |
|
| 95 |
// only show 1 grouping
|
| 96 |
-
if(i
|
| 97 |
-
|
| 98 |
-
|
| 99 |
-
|
| 100 |
}
|
| 101 |
|
| 102 |
$mailchimpGroupings.append($option);
|
| 103 |
}
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
|
| 107 |
}
|
| 108 |
|
| 109 |
|
| 110 |
});
|
| 111 |
}
|
| 112 |
|
|
|
|
|
|
|
|
|
|
| 113 |
function setPresets()
|
| 114 |
{
|
| 115 |
resetFields();
|
| 116 |
|
| 117 |
var selected = $(this).find(':selected');
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
|
| 122 |
-
|
| 123 |
-
|
| 124 |
-
|
| 125 |
-
|
| 126 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 127 |
|
| 128 |
-
|
| 129 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 130 |
}
|
| 131 |
-
|
|
|
|
| 132 |
}
|
| 133 |
|
|
|
|
|
|
|
|
|
|
| 134 |
function resetFields() {
|
| 135 |
$wizardFields.find('.row :input').each(function() {
|
| 136 |
if($(this).is(":checkbox")) { this.checked = true; } else { this.value = ''; }
|
|
@@ -140,50 +163,98 @@
|
|
| 140 |
$multipleValues.find(':input').remove();
|
| 141 |
$wizardFields.show();
|
| 142 |
|
| 143 |
-
|
| 144 |
-
|
| 145 |
$valueLabel.html("Initial value <small>(optional)</small>");
|
| 146 |
}
|
| 147 |
|
|
|
|
|
|
|
|
|
|
| 148 |
function addGroupInputs(groups)
|
| 149 |
{
|
| 150 |
// add a text input to $multipleValues for each group
|
| 151 |
for(var i = 0, groupsCount = groups.length; i < groupsCount; i++) {
|
| 152 |
-
$("<input />").attr('type', 'text')
|
|
|
|
|
|
|
|
|
|
|
|
|
| 153 |
}
|
| 154 |
}
|
| 155 |
|
|
|
|
|
|
|
|
|
|
| 156 |
function setPresetsForGrouping(data)
|
| 157 |
{
|
| 158 |
$wizardFields.find('p.row').filter('.values, .label, .wrap-p').show();
|
| 159 |
$label.val(data.name + ":");
|
| 160 |
-
|
| 161 |
addGroupInputs(data.groups);
|
| 162 |
|
| 163 |
-
|
| 164 |
-
|
| 165 |
-
|
| 166 |
-
|
| 167 |
-
} else if(data.form_field == 'hidden') {
|
| 168 |
-
$wizardFields.find('p.row').filter('.values, .label, .wrap-p').hide();
|
| 169 |
-
$wizardFields.find('p.row.value').show();
|
| 170 |
-
field['type'] = 'hidden';
|
| 171 |
-
|
| 172 |
-
for(var i = 0, groupsCount = data.groups.length; i < groupsCount; i++) {
|
| 173 |
-
$value.val($value.val() + data.groups[i].name + ',');
|
| 174 |
-
}
|
| 175 |
|
| 176 |
-
|
| 177 |
-
|
| 178 |
-
|
| 179 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 180 |
|
| 181 |
// update code preview
|
| 182 |
updateCodePreview();
|
| 183 |
}
|
| 184 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 185 |
|
| 186 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 187 |
function setPresetsForField(data)
|
| 188 |
{
|
| 189 |
|
|
@@ -195,6 +266,7 @@
|
|
| 195 |
'date': [ 'label', 'required', 'wrap-p', 'value']
|
| 196 |
}
|
| 197 |
|
|
|
|
| 198 |
var fieldTypesMap = {
|
| 199 |
'text': 'text', 'email': 'email', 'phone': 'tel', 'address': 'text', 'number': 'number',
|
| 200 |
'dropdown': 'select', 'date': 'date', 'birthday': 'date', 'radio': 'radio', 'checkbox': 'checkbox'
|
|
@@ -217,11 +289,18 @@
|
|
| 217 |
}
|
| 218 |
|
| 219 |
// populate fields with preset values
|
| 220 |
-
|
| 221 |
-
|
|
|
|
|
|
|
| 222 |
$placeholder.val("Your " + data.name.toLowerCase());
|
|
|
|
|
|
|
| 223 |
$label.val(data.name + ":");
|
|
|
|
|
|
|
| 224 |
$required.attr('checked', data.req);
|
|
|
|
| 225 |
if($multipleValues.is(":visible") && data.choices) {
|
| 226 |
for(var i = 0, count = data.choices.length; i < count; i++) {
|
| 227 |
$("<input />").attr('type', 'text').addClass('widefat').data('value', data.choices[i]).attr('placeholder', 'Label for "' + data.choices[i] + '" (or leave empty)').attr('value', data.choices[i]).appendTo($multipleValues);
|
|
@@ -232,59 +311,91 @@
|
|
| 232 |
updateCodePreview();
|
| 233 |
}
|
| 234 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 235 |
function updateCodePreview()
|
| 236 |
{
|
| 237 |
var $code = $("<div></div>");
|
| 238 |
var inputs = [];
|
| 239 |
var $input;
|
| 240 |
|
| 241 |
-
|
| 242 |
-
|
| 243 |
-
|
| 244 |
-
|
| 245 |
-
// add options to select
|
| 246 |
-
$multipleValues.find(":input").each(function() {
|
| 247 |
-
if($(this).val().length > 0) {
|
| 248 |
-
$el = $("<option />").val($(this).data("value")).text($(this).val());
|
| 249 |
-
$el.appendTo($input);
|
| 250 |
-
}
|
| 251 |
-
});
|
| 252 |
-
|
| 253 |
-
} else if(field['type'] == 'radio' || field['type'] == 'checkbox') {
|
| 254 |
-
|
| 255 |
-
// build multiple input values
|
| 256 |
-
$multipleValues.find(":input").each(function() {
|
| 257 |
-
if($(this).val().length > 0) {
|
| 258 |
-
$input = $("<input />").attr('type', field['type']).attr('name', field.name).val($(this).data('value'));
|
| 259 |
|
| 260 |
-
|
| 261 |
-
|
| 262 |
-
|
| 263 |
-
|
| 264 |
-
$code.append($input);
|
| 265 |
-
|
| 266 |
-
$input.wrap("<label />");
|
| 267 |
-
$("<span />").text($(this).val() + ' ').insertAfter($input);
|
| 268 |
-
}
|
| 269 |
-
});
|
| 270 |
|
| 271 |
-
|
| 272 |
-
|
| 273 |
-
|
| 274 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 275 |
}
|
| 276 |
|
| 277 |
// only do this piece when we're not adding radio inputs
|
| 278 |
-
if(
|
| 279 |
|
| 280 |
// set name attribute
|
| 281 |
-
if(
|
| 282 |
-
$input.attr('name',
|
| 283 |
}
|
| 284 |
|
| 285 |
// set value
|
| 286 |
if($value.is(":visible") && $value.val().length > 0) {
|
| 287 |
-
if(
|
| 288 |
$input.text($value.val());
|
| 289 |
} else {
|
| 290 |
$input.attr('value', $value.val());
|
|
@@ -298,76 +409,53 @@
|
|
| 298 |
|
| 299 |
// add required attribute
|
| 300 |
if($required.is(':visible:checked')) {
|
| 301 |
-
$input.attr('required',
|
| 302 |
}
|
| 303 |
|
| 304 |
-
$code.append($input);
|
| 305 |
-
|
| 306 |
-
|
| 307 |
}
|
| 308 |
|
| 309 |
// build label
|
| 310 |
if($label.is(":visible") && $label.val().length > 0) {
|
| 311 |
$("<label />").text($label.val()).prependTo($code);
|
| 312 |
}
|
| 313 |
-
|
| 314 |
-
// start indenting and tabbing of code
|
| 315 |
-
var codePreview = $code.html();
|
| 316 |
|
|
|
|
| 317 |
if($wrapp.is(':visible:checked')) {
|
| 318 |
$code.wrapInner($("<p />"));
|
| 319 |
-
|
| 320 |
-
// indent code inside paragraphs (double tab)
|
| 321 |
-
codePreview = $code.html()
|
| 322 |
-
.replace(/<p>/gi, "<p>\n\t")
|
| 323 |
-
.replace(/<label><input /gi, "\n\t<label><input ")
|
| 324 |
-
.replace(/<\/label><input/gi, "</label> \n\t<input")
|
| 325 |
-
.replace(/<select /gi, "\n\t<select ")
|
| 326 |
-
.replace(/<\/select>/gi, "\n\t</select>")
|
| 327 |
-
.replace(/<\/span><\/label>/gi, "</span>\n\t</label> \n")
|
| 328 |
-
.replace(/<option /gi, "\n\t\t<option ")
|
| 329 |
-
.replace(/<label><input type="radio"/g, "<label>\n\t\t<input type=\"radio\"")
|
| 330 |
-
.replace(/<label><input type="checkbox"/g, "<label>\n\t\t<input type=\"checkbox\"")
|
| 331 |
-
.replace(/<span>/gi, "\n\t\t<span>")
|
| 332 |
-
} else {
|
| 333 |
-
// indent code, single tab
|
| 334 |
-
codePreview = codePreview
|
| 335 |
-
.replace(/<option /gi, "\n\t<option ")
|
| 336 |
-
.replace(/<label><input type="radio"/g, "<label>\n\t<input type=\"radio\"")
|
| 337 |
-
.replace(/<label><input type="checkbox"/g, "<label>\n\t<input type=\"checkbox\"")
|
| 338 |
-
.replace(/<span>/gi, "\n\t<span>");
|
| 339 |
}
|
| 340 |
-
|
| 341 |
-
|
| 342 |
-
|
| 343 |
-
|
| 344 |
-
// add code to codePreview textarea
|
| 345 |
-
$codePreview.val(codePreview);
|
| 346 |
}
|
| 347 |
|
|
|
|
|
|
|
|
|
|
| 348 |
function addCodeToFormMarkup() {
|
| 349 |
|
| 350 |
var result = false;
|
| 351 |
|
| 352 |
// try to insert in QuickTags editor at cursor position
|
| 353 |
-
if(typeof QTags !='undefined' && QTags.insertContent) {
|
| 354 |
result = QTags.insertContent($codePreview.val());
|
| 355 |
}
|
| 356 |
|
| 357 |
-
// fallback
|
| 358 |
if(!result) {
|
| 359 |
-
$
|
|
|
|
| 360 |
}
|
| 361 |
}
|
| 362 |
|
| 363 |
// setup events
|
| 364 |
-
$lists.change(
|
| 365 |
$mailchimpFields.change(setPresets);
|
| 366 |
$wizardFields.change(updateCodePreview);
|
| 367 |
$("#mc4wp-fw-add-to-form").click(addCodeToFormMarkup);
|
| 368 |
|
| 369 |
// init
|
| 370 |
-
|
| 371 |
|
| 372 |
})();
|
| 373 |
|
| 40 |
var $placeholder = $("#mc4wp-fw-placeholder");
|
| 41 |
var $required = $("#mc4wp-fw-required");
|
| 42 |
var $wrapp = $("#mc4wp-fw-wrap-p");
|
| 43 |
+
var fieldType, fieldName;
|
|
|
|
|
|
|
|
|
|
| 44 |
var $codePreview = $("#mc4wp-fw-preview");
|
| 45 |
// functions
|
| 46 |
|
| 47 |
// set the fields the user can choose from
|
| 48 |
+
function setMailChimpFields()
|
| 49 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 50 |
// empty field select
|
| 51 |
$mailchimpFields.find('option').not('.default').remove();
|
| 52 |
|
| 53 |
// loop through checked lists
|
| 54 |
+
$lists.filter(':checked').each(function() {
|
| 55 |
+
var listFields = $(this).data('list-fields');
|
| 56 |
+
var listGroupings = $(this).data('list-groupings');
|
| 57 |
|
| 58 |
// loop through merge fields from this list
|
| 59 |
+
for(var i = 0, fieldCount = listFields.length; i < fieldCount; i++) {
|
| 60 |
+
var listField = listFields[i];
|
| 61 |
|
| 62 |
// add field to select if no similar option exists yet
|
| 63 |
+
if($mailchimpMergeFields.find("option[value='"+ listField.tag +"']").length == 0) {
|
| 64 |
|
| 65 |
+
var text = (listField.name.length > 25) ? listField.name.substring(0, 25) + '..' : listField.name;
|
| 66 |
+
if(listField.req) { text += '*'; }
|
| 67 |
|
| 68 |
+
var $option = $("<option />")
|
| 69 |
+
.text(text)
|
| 70 |
+
.val(listField.tag)
|
| 71 |
+
.data('list-field', listField);
|
| 72 |
+
|
| 73 |
+
// only enable 3 fields
|
| 74 |
+
if(i > 3) {
|
| 75 |
+
$option.text("(PRO ONLY) " + text)
|
| 76 |
+
.attr('disabled', 'disabled')
|
| 77 |
+
.data('field', null);
|
| 78 |
}
|
| 79 |
+
|
| 80 |
$mailchimpMergeFields.append($option);
|
| 81 |
}
|
| 82 |
}
|
| 83 |
|
| 84 |
// loop through interest groupings
|
| 85 |
+
for(var i = 0, groupingsCount = listGroupings.length; i < groupingsCount; i++) {
|
| 86 |
+
var listGrouping = listGroupings[i];
|
| 87 |
+
|
| 88 |
// add field to select if no similar option exists yet
|
| 89 |
+
if($mailchimpGroupings.find("option[value='"+ listGrouping.id +"']").length == 0) {
|
| 90 |
+
var text = (listGrouping.name.length > 25) ? listGrouping.name.substring(0, 25) + '..' : listGrouping.name;
|
| 91 |
+
|
| 92 |
+
// build option HTML
|
| 93 |
+
var $option = $("<option />")
|
| 94 |
+
.text(text)
|
| 95 |
+
.val(listGrouping.id)
|
| 96 |
+
.data('list-grouping', listGrouping);
|
| 97 |
|
| 98 |
// only show 1 grouping
|
| 99 |
+
if(i >= 1) {
|
| 100 |
+
$option.text("(PRO ONLY) " + text)
|
| 101 |
+
.attr('disabled', 'disabled')
|
| 102 |
+
.data('list-grouping', null);
|
| 103 |
}
|
| 104 |
|
| 105 |
$mailchimpGroupings.append($option);
|
| 106 |
}
|
|
|
|
|
|
|
|
|
|
| 107 |
}
|
| 108 |
|
| 109 |
|
| 110 |
});
|
| 111 |
}
|
| 112 |
|
| 113 |
+
/**
|
| 114 |
+
* Set Presets
|
| 115 |
+
*/
|
| 116 |
function setPresets()
|
| 117 |
{
|
| 118 |
resetFields();
|
| 119 |
|
| 120 |
var selected = $(this).find(':selected');
|
| 121 |
+
switch( selected.val() ) {
|
| 122 |
+
|
| 123 |
+
case 'submit':
|
| 124 |
+
fieldType = 'submit';
|
| 125 |
+
$valueLabel.text("Button text");
|
| 126 |
+
$wizardFields.find('p.row').filter('.value, .wrap-p').show();
|
| 127 |
+
break;
|
| 128 |
+
|
| 129 |
+
case 'lists':
|
| 130 |
+
fieldType = 'lists';
|
| 131 |
+
$wizardFields.find('.wrap-p').show();
|
| 132 |
+
updateCodePreview();
|
| 133 |
+
break;
|
| 134 |
+
|
| 135 |
+
default:
|
| 136 |
+
// try data for MailChimp field
|
| 137 |
+
var data = selected.data('list-field');
|
| 138 |
+
if(data) {
|
| 139 |
+
return setPresetsForField(data);
|
| 140 |
+
}
|
| 141 |
|
| 142 |
+
// try data for interest grouping
|
| 143 |
+
var data = selected.data('list-grouping');
|
| 144 |
+
if(data) {
|
| 145 |
+
return setPresetsForGrouping(data);
|
| 146 |
+
}
|
| 147 |
+
|
| 148 |
+
break;
|
| 149 |
}
|
| 150 |
+
|
| 151 |
+
updateCodePreview();
|
| 152 |
}
|
| 153 |
|
| 154 |
+
/**
|
| 155 |
+
* Resets all wizard fields back to their default state
|
| 156 |
+
*/
|
| 157 |
function resetFields() {
|
| 158 |
$wizardFields.find('.row :input').each(function() {
|
| 159 |
if($(this).is(":checkbox")) { this.checked = true; } else { this.value = ''; }
|
| 163 |
$multipleValues.find(':input').remove();
|
| 164 |
$wizardFields.show();
|
| 165 |
|
| 166 |
+
fieldType = 'text';
|
| 167 |
+
fieldName = '';
|
| 168 |
$valueLabel.html("Initial value <small>(optional)</small>");
|
| 169 |
}
|
| 170 |
|
| 171 |
+
/**
|
| 172 |
+
* Add inputs for each group
|
| 173 |
+
*/
|
| 174 |
function addGroupInputs(groups)
|
| 175 |
{
|
| 176 |
// add a text input to $multipleValues for each group
|
| 177 |
for(var i = 0, groupsCount = groups.length; i < groupsCount; i++) {
|
| 178 |
+
$("<input />").attr('type', 'text')
|
| 179 |
+
.addClass('widefat').data('value', groups[i].name)
|
| 180 |
+
.attr('placeholder', 'Label for "' + groups[i].name + '" (or leave empty)')
|
| 181 |
+
.attr('value', groups[i].name)
|
| 182 |
+
.appendTo($multipleValues);
|
| 183 |
}
|
| 184 |
}
|
| 185 |
|
| 186 |
+
/**
|
| 187 |
+
* Set presets for interest groupings
|
| 188 |
+
*/
|
| 189 |
function setPresetsForGrouping(data)
|
| 190 |
{
|
| 191 |
$wizardFields.find('p.row').filter('.values, .label, .wrap-p').show();
|
| 192 |
$label.val(data.name + ":");
|
| 193 |
+
fieldName = 'GROUPINGS[' + data.id + ']';
|
| 194 |
addGroupInputs(data.groups);
|
| 195 |
|
| 196 |
+
switch(data.form_field) {
|
| 197 |
+
case 'radio':
|
| 198 |
+
fieldType = 'radio';
|
| 199 |
+
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 200 |
|
| 201 |
+
case 'hidden':
|
| 202 |
+
// hide all rows except value row
|
| 203 |
+
$wizardFields.find('p.row').filter('.values, .label, .wrap-p').hide();
|
| 204 |
+
$wizardFields.find('p.row.value').show();
|
| 205 |
+
|
| 206 |
+
// add group name to hidden input value
|
| 207 |
+
for(var i = 0, groupsCount = data.groups.length; i < groupsCount; i++) {
|
| 208 |
+
$value.val($value.val() + data.groups[i].name + ',');
|
| 209 |
+
}
|
| 210 |
+
|
| 211 |
+
fieldType = 'hidden';
|
| 212 |
+
break;
|
| 213 |
+
|
| 214 |
+
case 'dropdown':
|
| 215 |
+
fieldType = 'select';
|
| 216 |
+
break;
|
| 217 |
+
|
| 218 |
+
default:
|
| 219 |
+
fieldType = 'checkbox';
|
| 220 |
+
|
| 221 |
+
// turn field name into an array
|
| 222 |
+
fieldName += '[]';
|
| 223 |
+
break;
|
| 224 |
+
}
|
| 225 |
|
| 226 |
// update code preview
|
| 227 |
updateCodePreview();
|
| 228 |
}
|
| 229 |
|
| 230 |
+
/**
|
| 231 |
+
* Build list choice HTML
|
| 232 |
+
*/
|
| 233 |
+
function getListChoiceHTML()
|
| 234 |
+
{
|
| 235 |
+
var html = '';
|
| 236 |
+
$lists.each(function() {
|
| 237 |
+
var list_id = $(this).val();
|
| 238 |
+
var list_name = $(this).parent('label').text();
|
| 239 |
+
var attrs = '';
|
| 240 |
+
|
| 241 |
+
if($(this).is(':checked')) {
|
| 242 |
+
attrs += 'checked ';
|
| 243 |
+
}
|
| 244 |
+
|
| 245 |
+
html += '<label>' + "\n"
|
| 246 |
+
html += "\t" + '<input type="checkbox" name="_mc4wp_lists[]" value="' + list_id +'" '+ attrs + ' /> '+ list_name + "\n";
|
| 247 |
+
html += '</label>' + "\n";
|
| 248 |
+
});
|
| 249 |
|
| 250 |
+
return html;
|
| 251 |
+
}
|
| 252 |
+
|
| 253 |
+
|
| 254 |
+
|
| 255 |
+
/**
|
| 256 |
+
* Set presets for a fields
|
| 257 |
+
*/
|
| 258 |
function setPresetsForField(data)
|
| 259 |
{
|
| 260 |
|
| 266 |
'date': [ 'label', 'required', 'wrap-p', 'value']
|
| 267 |
}
|
| 268 |
|
| 269 |
+
// map MailChimp field types to HTML5 field type
|
| 270 |
var fieldTypesMap = {
|
| 271 |
'text': 'text', 'email': 'email', 'phone': 'tel', 'address': 'text', 'number': 'number',
|
| 272 |
'dropdown': 'select', 'date': 'date', 'birthday': 'date', 'radio': 'radio', 'checkbox': 'checkbox'
|
| 289 |
}
|
| 290 |
|
| 291 |
// populate fields with preset values
|
| 292 |
+
fieldType = fieldType;
|
| 293 |
+
fieldName = data.tag;
|
| 294 |
+
|
| 295 |
+
// set placeholder text
|
| 296 |
$placeholder.val("Your " + data.name.toLowerCase());
|
| 297 |
+
|
| 298 |
+
// set label text
|
| 299 |
$label.val(data.name + ":");
|
| 300 |
+
|
| 301 |
+
// set required attribute
|
| 302 |
$required.attr('checked', data.req);
|
| 303 |
+
|
| 304 |
if($multipleValues.is(":visible") && data.choices) {
|
| 305 |
for(var i = 0, count = data.choices.length; i < count; i++) {
|
| 306 |
$("<input />").attr('type', 'text').addClass('widefat').data('value', data.choices[i]).attr('placeholder', 'Label for "' + data.choices[i] + '" (or leave empty)').attr('value', data.choices[i]).appendTo($multipleValues);
|
| 311 |
updateCodePreview();
|
| 312 |
}
|
| 313 |
|
| 314 |
+
/**
|
| 315 |
+
* Format and indent the generated HTML
|
| 316 |
+
* Then add it to the code preview textarea
|
| 317 |
+
*/
|
| 318 |
+
function setCodePreview(html) {
|
| 319 |
+
html = html_beautify(html);
|
| 320 |
+
$codePreview.val(html);
|
| 321 |
+
}
|
| 322 |
+
|
| 323 |
+
|
| 324 |
+
/**
|
| 325 |
+
* Generate HTML based on the various field values
|
| 326 |
+
*/
|
| 327 |
function updateCodePreview()
|
| 328 |
{
|
| 329 |
var $code = $("<div></div>");
|
| 330 |
var inputs = [];
|
| 331 |
var $input;
|
| 332 |
|
| 333 |
+
switch(fieldType) {
|
| 334 |
+
// MailChimp lists
|
| 335 |
+
case 'lists':
|
| 336 |
+
var html = getListChoiceHTML();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 337 |
|
| 338 |
+
if($wrapp.is(':visible:checked')) {
|
| 339 |
+
html = "<p>" + html + "</p>";
|
| 340 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 341 |
|
| 342 |
+
return setCodePreview(html);
|
| 343 |
+
break;
|
| 344 |
+
|
| 345 |
+
// MailChimp dropdown
|
| 346 |
+
case 'select':
|
| 347 |
+
$input = $("<select />");
|
| 348 |
+
|
| 349 |
+
// add options to select
|
| 350 |
+
$multipleValues.find(":input").each(function() {
|
| 351 |
+
if($(this).val().length > 0) {
|
| 352 |
+
$el = $("<option />").val($(this).data("value")).text($(this).val());
|
| 353 |
+
$el.appendTo($input);
|
| 354 |
+
}
|
| 355 |
+
});
|
| 356 |
+
break;
|
| 357 |
+
|
| 358 |
+
// MailChimo choices
|
| 359 |
+
case 'radio':
|
| 360 |
+
case 'checkbox':
|
| 361 |
+
// build multiple input values
|
| 362 |
+
$multipleValues.find(":input").each(function() {
|
| 363 |
+
if($(this).val().length > 0) {
|
| 364 |
+
$input = $("<input />").attr('type', fieldType).attr('name', fieldName).val($(this).data('value'));
|
| 365 |
+
|
| 366 |
+
if($required.is(':visible:checked')) {
|
| 367 |
+
$input.attr('required', true);
|
| 368 |
+
}
|
| 369 |
+
|
| 370 |
+
$code.append($input);
|
| 371 |
+
|
| 372 |
+
$input.wrap("<label />");
|
| 373 |
+
$("<span />").text($(this).val() + ' ').insertAfter($input);
|
| 374 |
+
}
|
| 375 |
+
});
|
| 376 |
+
break;
|
| 377 |
+
|
| 378 |
+
// MailChimp long text
|
| 379 |
+
case 'textarea':
|
| 380 |
+
$input = $("<textarea />");
|
| 381 |
+
break;
|
| 382 |
+
|
| 383 |
+
default:
|
| 384 |
+
$input = $("<input />").attr('type', fieldType);
|
| 385 |
+
break;
|
| 386 |
}
|
| 387 |
|
| 388 |
// only do this piece when we're not adding radio inputs
|
| 389 |
+
if(fieldType != 'radio' && fieldType != 'checkbox') {
|
| 390 |
|
| 391 |
// set name attribute
|
| 392 |
+
if(fieldName.length > 0) {
|
| 393 |
+
$input.attr('name', fieldName);
|
| 394 |
}
|
| 395 |
|
| 396 |
// set value
|
| 397 |
if($value.is(":visible") && $value.val().length > 0) {
|
| 398 |
+
if(fieldType == 'textarea') {
|
| 399 |
$input.text($value.val());
|
| 400 |
} else {
|
| 401 |
$input.attr('value', $value.val());
|
| 409 |
|
| 410 |
// add required attribute
|
| 411 |
if($required.is(':visible:checked')) {
|
| 412 |
+
$input.attr('required', true);
|
| 413 |
}
|
| 414 |
|
| 415 |
+
$code.append($input);
|
|
|
|
|
|
|
| 416 |
}
|
| 417 |
|
| 418 |
// build label
|
| 419 |
if($label.is(":visible") && $label.val().length > 0) {
|
| 420 |
$("<label />").text($label.val()).prependTo($code);
|
| 421 |
}
|
|
|
|
|
|
|
|
|
|
| 422 |
|
| 423 |
+
// wrap in paragraphs?
|
| 424 |
if($wrapp.is(':visible:checked')) {
|
| 425 |
$code.wrapInner($("<p />"));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 426 |
}
|
| 427 |
+
|
| 428 |
+
var html = $code.html();
|
| 429 |
+
setCodePreview(html);
|
|
|
|
|
|
|
|
|
|
| 430 |
}
|
| 431 |
|
| 432 |
+
/**
|
| 433 |
+
* Transfer code preview field to form mark-up
|
| 434 |
+
*/
|
| 435 |
function addCodeToFormMarkup() {
|
| 436 |
|
| 437 |
var result = false;
|
| 438 |
|
| 439 |
// try to insert in QuickTags editor at cursor position
|
| 440 |
+
if(typeof wpActiveEditor != 'undefined' && typeof QTags != 'undefined' && QTags.insertContent) {
|
| 441 |
result = QTags.insertContent($codePreview.val());
|
| 442 |
}
|
| 443 |
|
| 444 |
+
// fallback, just append
|
| 445 |
if(!result) {
|
| 446 |
+
$formContent = $("#mc4wpformmarkup");
|
| 447 |
+
$formContent.val($formContent.val() + "\n" + $codePreview.val());
|
| 448 |
}
|
| 449 |
}
|
| 450 |
|
| 451 |
// setup events
|
| 452 |
+
$lists.change(setMailChimpFields);
|
| 453 |
$mailchimpFields.change(setPresets);
|
| 454 |
$wizardFields.change(updateCodePreview);
|
| 455 |
$("#mc4wp-fw-add-to-form").click(addCodeToFormMarkup);
|
| 456 |
|
| 457 |
// init
|
| 458 |
+
setMailChimpFields();
|
| 459 |
|
| 460 |
})();
|
| 461 |
|
assets/js/beautify-html.js
ADDED
|
@@ -0,0 +1,839 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/*jshint curly:true, eqeqeq:true, laxbreak:true, noempty:false */
|
| 2 |
+
/*
|
| 3 |
+
|
| 4 |
+
The MIT License (MIT)
|
| 5 |
+
|
| 6 |
+
Copyright (c) 2007-2013 Einar Lielmanis and contributors.
|
| 7 |
+
|
| 8 |
+
Permission is hereby granted, free of charge, to any person
|
| 9 |
+
obtaining a copy of this software and associated documentation files
|
| 10 |
+
(the "Software"), to deal in the Software without restriction,
|
| 11 |
+
including without limitation the rights to use, copy, modify, merge,
|
| 12 |
+
publish, distribute, sublicense, and/or sell copies of the Software,
|
| 13 |
+
and to permit persons to whom the Software is furnished to do so,
|
| 14 |
+
subject to the following conditions:
|
| 15 |
+
|
| 16 |
+
The above copyright notice and this permission notice shall be
|
| 17 |
+
included in all copies or substantial portions of the Software.
|
| 18 |
+
|
| 19 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
| 20 |
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
| 21 |
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
| 22 |
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
| 23 |
+
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
| 24 |
+
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
| 25 |
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
| 26 |
+
SOFTWARE.
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
Style HTML
|
| 30 |
+
---------------
|
| 31 |
+
|
| 32 |
+
Written by Nochum Sossonko, (nsossonko@hotmail.com)
|
| 33 |
+
|
| 34 |
+
Based on code initially developed by: Einar Lielmanis, <elfz@laacz.lv>
|
| 35 |
+
http://jsbeautifier.org/
|
| 36 |
+
|
| 37 |
+
Usage:
|
| 38 |
+
style_html(html_source);
|
| 39 |
+
|
| 40 |
+
style_html(html_source, options);
|
| 41 |
+
|
| 42 |
+
The options are:
|
| 43 |
+
indent_inner_html (default false) — indent <head> and <body> sections,
|
| 44 |
+
indent_size (default 4) — indentation size,
|
| 45 |
+
indent_char (default space) — character to indent with,
|
| 46 |
+
wrap_line_length (default 250) - maximum amount of characters per line (0 = disable)
|
| 47 |
+
brace_style (default "collapse") - "collapse" | "expand" | "end-expand"
|
| 48 |
+
put braces on the same line as control statements (default), or put braces on own line (Allman / ANSI style), or just put end braces on own line.
|
| 49 |
+
unformatted (defaults to inline tags) - list of tags, that shouldn't be reformatted
|
| 50 |
+
indent_scripts (default normal) - "keep"|"separate"|"normal"
|
| 51 |
+
preserve_newlines (default true) - whether existing line breaks before elements should be preserved
|
| 52 |
+
Only works before elements, not inside tags or for text.
|
| 53 |
+
max_preserve_newlines (default unlimited) - maximum number of line breaks to be preserved in one chunk
|
| 54 |
+
indent_handlebars (default false) - format and indent {{#foo}} and {{/foo}}
|
| 55 |
+
|
| 56 |
+
e.g.
|
| 57 |
+
|
| 58 |
+
style_html(html_source, {
|
| 59 |
+
'indent_inner_html': false,
|
| 60 |
+
'indent_size': 2,
|
| 61 |
+
'indent_char': ' ',
|
| 62 |
+
'wrap_line_length': 78,
|
| 63 |
+
'brace_style': 'expand',
|
| 64 |
+
'unformatted': ['a', 'sub', 'sup', 'b', 'i', 'u'],
|
| 65 |
+
'preserve_newlines': true,
|
| 66 |
+
'max_preserve_newlines': 5,
|
| 67 |
+
'indent_handlebars': false
|
| 68 |
+
});
|
| 69 |
+
*/
|
| 70 |
+
|
| 71 |
+
(function() {
|
| 72 |
+
|
| 73 |
+
function trim(s) {
|
| 74 |
+
return s.replace(/^\s+|\s+$/g, '');
|
| 75 |
+
}
|
| 76 |
+
|
| 77 |
+
function ltrim(s) {
|
| 78 |
+
return s.replace(/^\s+/g, '');
|
| 79 |
+
}
|
| 80 |
+
|
| 81 |
+
function style_html(html_source, options, js_beautify, css_beautify) {
|
| 82 |
+
//Wrapper function to invoke all the necessary constructors and deal with the output.
|
| 83 |
+
|
| 84 |
+
var multi_parser,
|
| 85 |
+
indent_inner_html,
|
| 86 |
+
indent_size,
|
| 87 |
+
indent_character,
|
| 88 |
+
wrap_line_length,
|
| 89 |
+
brace_style,
|
| 90 |
+
unformatted,
|
| 91 |
+
preserve_newlines,
|
| 92 |
+
max_preserve_newlines;
|
| 93 |
+
|
| 94 |
+
options = options || {};
|
| 95 |
+
|
| 96 |
+
// backwards compatibility to 1.3.4
|
| 97 |
+
if ((options.wrap_line_length === undefined || parseInt(options.wrap_line_length, 10) === 0) &&
|
| 98 |
+
(options.max_char === undefined || parseInt(options.max_char, 10) === 0)) {
|
| 99 |
+
options.wrap_line_length = options.max_char;
|
| 100 |
+
}
|
| 101 |
+
|
| 102 |
+
indent_inner_html = options.indent_inner_html || false;
|
| 103 |
+
indent_size = parseInt(options.indent_size || 4, 10);
|
| 104 |
+
indent_character = options.indent_char || ' ';
|
| 105 |
+
brace_style = options.brace_style || 'collapse';
|
| 106 |
+
wrap_line_length = parseInt(options.wrap_line_length, 10) === 0 ? 32786 : parseInt(options.wrap_line_length || 250, 10);
|
| 107 |
+
unformatted = options.unformatted || ['a', 'span', 'bdo', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'sub', 'sup', 'tt', 'i', 'b', 'big', 'small', 'u', 's', 'strike', 'font', 'ins', 'del', 'pre', 'address', 'dt', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'];
|
| 108 |
+
preserve_newlines = options.preserve_newlines || true;
|
| 109 |
+
max_preserve_newlines = preserve_newlines ? parseInt(options.max_preserve_newlines || 32786, 10) : 0;
|
| 110 |
+
indent_handlebars = options.indent_handlebars || false;
|
| 111 |
+
|
| 112 |
+
function Parser() {
|
| 113 |
+
|
| 114 |
+
this.pos = 0; //Parser position
|
| 115 |
+
this.token = '';
|
| 116 |
+
this.current_mode = 'CONTENT'; //reflects the current Parser mode: TAG/CONTENT
|
| 117 |
+
this.tags = { //An object to hold tags, their position, and their parent-tags, initiated with default values
|
| 118 |
+
parent: 'parent1',
|
| 119 |
+
parentcount: 1,
|
| 120 |
+
parent1: ''
|
| 121 |
+
};
|
| 122 |
+
this.tag_type = '';
|
| 123 |
+
this.token_text = this.last_token = this.last_text = this.token_type = '';
|
| 124 |
+
this.newlines = 0;
|
| 125 |
+
this.indent_content = indent_inner_html;
|
| 126 |
+
|
| 127 |
+
this.Utils = { //Uilities made available to the various functions
|
| 128 |
+
whitespace: "\n\r\t ".split(''),
|
| 129 |
+
single_token: 'br,input,link,meta,!doctype,basefont,base,area,hr,wbr,param,img,isindex,?xml,embed,?php,?,?='.split(','), //all the single tags for HTML
|
| 130 |
+
extra_liners: 'head,body,/html'.split(','), //for tags that need a line of whitespace before them
|
| 131 |
+
in_array: function(what, arr) {
|
| 132 |
+
for (var i = 0; i < arr.length; i++) {
|
| 133 |
+
if (what === arr[i]) {
|
| 134 |
+
return true;
|
| 135 |
+
}
|
| 136 |
+
}
|
| 137 |
+
return false;
|
| 138 |
+
}
|
| 139 |
+
};
|
| 140 |
+
|
| 141 |
+
this.traverse_whitespace = function() {
|
| 142 |
+
var input_char = '';
|
| 143 |
+
|
| 144 |
+
input_char = this.input.charAt(this.pos);
|
| 145 |
+
if (this.Utils.in_array(input_char, this.Utils.whitespace)) {
|
| 146 |
+
this.newlines = 0;
|
| 147 |
+
while (this.Utils.in_array(input_char, this.Utils.whitespace)) {
|
| 148 |
+
if (preserve_newlines && input_char === '\n' && this.newlines <= max_preserve_newlines) {
|
| 149 |
+
this.newlines += 1;
|
| 150 |
+
}
|
| 151 |
+
|
| 152 |
+
this.pos++;
|
| 153 |
+
input_char = this.input.charAt(this.pos);
|
| 154 |
+
}
|
| 155 |
+
return true;
|
| 156 |
+
}
|
| 157 |
+
return false;
|
| 158 |
+
};
|
| 159 |
+
|
| 160 |
+
this.get_content = function() { //function to capture regular content between tags
|
| 161 |
+
|
| 162 |
+
var input_char = '',
|
| 163 |
+
content = [],
|
| 164 |
+
space = false; //if a space is needed
|
| 165 |
+
|
| 166 |
+
while (this.input.charAt(this.pos) !== '<') {
|
| 167 |
+
if (this.pos >= this.input.length) {
|
| 168 |
+
return content.length ? content.join('') : ['', 'TK_EOF'];
|
| 169 |
+
}
|
| 170 |
+
|
| 171 |
+
if (this.traverse_whitespace()) {
|
| 172 |
+
if (content.length) {
|
| 173 |
+
space = true;
|
| 174 |
+
}
|
| 175 |
+
continue; //don't want to insert unnecessary space
|
| 176 |
+
}
|
| 177 |
+
|
| 178 |
+
if (indent_handlebars) {
|
| 179 |
+
// Handlebars parsing is complicated.
|
| 180 |
+
// {{#foo}} and {{/foo}} are formatted tags.
|
| 181 |
+
// {{something}} should get treated as content, except:
|
| 182 |
+
// {{else}} specifically behaves like {{#if}} and {{/if}}
|
| 183 |
+
var peek3 = this.input.substr(this.pos, 3);
|
| 184 |
+
if (peek3 === '{{#' || peek3 === '{{/') {
|
| 185 |
+
// These are tags and not content.
|
| 186 |
+
break;
|
| 187 |
+
} else if (this.input.substr(this.pos, 2) === '{{') {
|
| 188 |
+
if (this.get_tag(true) === '{{else}}') {
|
| 189 |
+
break;
|
| 190 |
+
}
|
| 191 |
+
}
|
| 192 |
+
}
|
| 193 |
+
|
| 194 |
+
input_char = this.input.charAt(this.pos);
|
| 195 |
+
this.pos++;
|
| 196 |
+
|
| 197 |
+
if (space) {
|
| 198 |
+
if (this.line_char_count >= this.wrap_line_length) { //insert a line when the wrap_line_length is reached
|
| 199 |
+
this.print_newline(false, content);
|
| 200 |
+
this.print_indentation(content);
|
| 201 |
+
} else {
|
| 202 |
+
this.line_char_count++;
|
| 203 |
+
content.push(' ');
|
| 204 |
+
}
|
| 205 |
+
space = false;
|
| 206 |
+
}
|
| 207 |
+
this.line_char_count++;
|
| 208 |
+
content.push(input_char); //letter at-a-time (or string) inserted to an array
|
| 209 |
+
}
|
| 210 |
+
return content.length ? content.join('') : '';
|
| 211 |
+
};
|
| 212 |
+
|
| 213 |
+
this.get_contents_to = function(name) { //get the full content of a script or style to pass to js_beautify
|
| 214 |
+
if (this.pos === this.input.length) {
|
| 215 |
+
return ['', 'TK_EOF'];
|
| 216 |
+
}
|
| 217 |
+
var input_char = '';
|
| 218 |
+
var content = '';
|
| 219 |
+
var reg_match = new RegExp('</' + name + '\\s*>', 'igm');
|
| 220 |
+
reg_match.lastIndex = this.pos;
|
| 221 |
+
var reg_array = reg_match.exec(this.input);
|
| 222 |
+
var end_script = reg_array ? reg_array.index : this.input.length; //absolute end of script
|
| 223 |
+
if (this.pos < end_script) { //get everything in between the script tags
|
| 224 |
+
content = this.input.substring(this.pos, end_script);
|
| 225 |
+
this.pos = end_script;
|
| 226 |
+
}
|
| 227 |
+
return content;
|
| 228 |
+
};
|
| 229 |
+
|
| 230 |
+
this.record_tag = function(tag) { //function to record a tag and its parent in this.tags Object
|
| 231 |
+
if (this.tags[tag + 'count']) { //check for the existence of this tag type
|
| 232 |
+
this.tags[tag + 'count']++;
|
| 233 |
+
this.tags[tag + this.tags[tag + 'count']] = this.indent_level; //and record the present indent level
|
| 234 |
+
} else { //otherwise initialize this tag type
|
| 235 |
+
this.tags[tag + 'count'] = 1;
|
| 236 |
+
this.tags[tag + this.tags[tag + 'count']] = this.indent_level; //and record the present indent level
|
| 237 |
+
}
|
| 238 |
+
this.tags[tag + this.tags[tag + 'count'] + 'parent'] = this.tags.parent; //set the parent (i.e. in the case of a div this.tags.div1parent)
|
| 239 |
+
this.tags.parent = tag + this.tags[tag + 'count']; //and make this the current parent (i.e. in the case of a div 'div1')
|
| 240 |
+
};
|
| 241 |
+
|
| 242 |
+
this.retrieve_tag = function(tag) { //function to retrieve the opening tag to the corresponding closer
|
| 243 |
+
if (this.tags[tag + 'count']) { //if the openener is not in the Object we ignore it
|
| 244 |
+
var temp_parent = this.tags.parent; //check to see if it's a closable tag.
|
| 245 |
+
while (temp_parent) { //till we reach '' (the initial value);
|
| 246 |
+
if (tag + this.tags[tag + 'count'] === temp_parent) { //if this is it use it
|
| 247 |
+
break;
|
| 248 |
+
}
|
| 249 |
+
temp_parent = this.tags[temp_parent + 'parent']; //otherwise keep on climbing up the DOM Tree
|
| 250 |
+
}
|
| 251 |
+
if (temp_parent) { //if we caught something
|
| 252 |
+
this.indent_level = this.tags[tag + this.tags[tag + 'count']]; //set the indent_level accordingly
|
| 253 |
+
this.tags.parent = this.tags[temp_parent + 'parent']; //and set the current parent
|
| 254 |
+
}
|
| 255 |
+
delete this.tags[tag + this.tags[tag + 'count'] + 'parent']; //delete the closed tags parent reference...
|
| 256 |
+
delete this.tags[tag + this.tags[tag + 'count']]; //...and the tag itself
|
| 257 |
+
if (this.tags[tag + 'count'] === 1) {
|
| 258 |
+
delete this.tags[tag + 'count'];
|
| 259 |
+
} else {
|
| 260 |
+
this.tags[tag + 'count']--;
|
| 261 |
+
}
|
| 262 |
+
}
|
| 263 |
+
};
|
| 264 |
+
|
| 265 |
+
this.indent_to_tag = function(tag) {
|
| 266 |
+
// Match the indentation level to the last use of this tag, but don't remove it.
|
| 267 |
+
if (!this.tags[tag + 'count']) {
|
| 268 |
+
return;
|
| 269 |
+
}
|
| 270 |
+
var temp_parent = this.tags.parent;
|
| 271 |
+
while (temp_parent) {
|
| 272 |
+
if (tag + this.tags[tag + 'count'] === temp_parent) {
|
| 273 |
+
break;
|
| 274 |
+
}
|
| 275 |
+
temp_parent = this.tags[temp_parent + 'parent'];
|
| 276 |
+
}
|
| 277 |
+
if (temp_parent) {
|
| 278 |
+
this.indent_level = this.tags[tag + this.tags[tag + 'count']];
|
| 279 |
+
}
|
| 280 |
+
};
|
| 281 |
+
|
| 282 |
+
this.get_tag = function(peek) { //function to get a full tag and parse its type
|
| 283 |
+
var input_char = '',
|
| 284 |
+
content = [],
|
| 285 |
+
comment = '',
|
| 286 |
+
space = false,
|
| 287 |
+
tag_start, tag_end,
|
| 288 |
+
tag_start_char,
|
| 289 |
+
orig_pos = this.pos,
|
| 290 |
+
orig_line_char_count = this.line_char_count;
|
| 291 |
+
|
| 292 |
+
peek = peek !== undefined ? peek : false;
|
| 293 |
+
|
| 294 |
+
do {
|
| 295 |
+
if (this.pos >= this.input.length) {
|
| 296 |
+
if (peek) {
|
| 297 |
+
this.pos = orig_pos;
|
| 298 |
+
this.line_char_count = orig_line_char_count;
|
| 299 |
+
}
|
| 300 |
+
return content.length ? content.join('') : ['', 'TK_EOF'];
|
| 301 |
+
}
|
| 302 |
+
|
| 303 |
+
input_char = this.input.charAt(this.pos);
|
| 304 |
+
this.pos++;
|
| 305 |
+
|
| 306 |
+
if (this.Utils.in_array(input_char, this.Utils.whitespace)) { //don't want to insert unnecessary space
|
| 307 |
+
space = true;
|
| 308 |
+
continue;
|
| 309 |
+
}
|
| 310 |
+
|
| 311 |
+
if (input_char === "'" || input_char === '"') {
|
| 312 |
+
input_char += this.get_unformatted(input_char);
|
| 313 |
+
space = true;
|
| 314 |
+
|
| 315 |
+
}
|
| 316 |
+
|
| 317 |
+
if (input_char === '=') { //no space before =
|
| 318 |
+
space = false;
|
| 319 |
+
}
|
| 320 |
+
|
| 321 |
+
if (content.length && content[content.length - 1] !== '=' && input_char !== '>' && space) {
|
| 322 |
+
//no space after = or before >
|
| 323 |
+
if (this.line_char_count >= this.wrap_line_length) {
|
| 324 |
+
this.print_newline(false, content);
|
| 325 |
+
this.print_indentation(content);
|
| 326 |
+
} else {
|
| 327 |
+
content.push(' ');
|
| 328 |
+
this.line_char_count++;
|
| 329 |
+
}
|
| 330 |
+
space = false;
|
| 331 |
+
}
|
| 332 |
+
|
| 333 |
+
if (indent_handlebars && tag_start_char === '<') {
|
| 334 |
+
// When inside an angle-bracket tag, put spaces around
|
| 335 |
+
// handlebars not inside of strings.
|
| 336 |
+
if ((input_char + this.input.charAt(this.pos)) === '{{') {
|
| 337 |
+
input_char += this.get_unformatted('}}');
|
| 338 |
+
if (content.length && content[content.length - 1] !== ' ' && content[content.length - 1] !== '<') {
|
| 339 |
+
input_char = ' ' + input_char;
|
| 340 |
+
}
|
| 341 |
+
space = true;
|
| 342 |
+
}
|
| 343 |
+
}
|
| 344 |
+
|
| 345 |
+
if (input_char === '<' && !tag_start_char) {
|
| 346 |
+
tag_start = this.pos - 1;
|
| 347 |
+
tag_start_char = '<';
|
| 348 |
+
}
|
| 349 |
+
|
| 350 |
+
if (indent_handlebars && !tag_start_char) {
|
| 351 |
+
if (content.length >= 2 && content[content.length - 1] === '{' && content[content.length - 2] == '{') {
|
| 352 |
+
if (input_char === '#' || input_char === '/') {
|
| 353 |
+
tag_start = this.pos - 3;
|
| 354 |
+
} else {
|
| 355 |
+
tag_start = this.pos - 2;
|
| 356 |
+
}
|
| 357 |
+
tag_start_char = '{';
|
| 358 |
+
}
|
| 359 |
+
}
|
| 360 |
+
|
| 361 |
+
this.line_char_count++;
|
| 362 |
+
content.push(input_char); //inserts character at-a-time (or string)
|
| 363 |
+
|
| 364 |
+
if (content[1] && content[1] === '!') { //if we're in a comment, do something special
|
| 365 |
+
// We treat all comments as literals, even more than preformatted tags
|
| 366 |
+
// we just look for the appropriate close tag
|
| 367 |
+
content = [this.get_comment(tag_start)];
|
| 368 |
+
break;
|
| 369 |
+
}
|
| 370 |
+
|
| 371 |
+
if (indent_handlebars && tag_start_char === '{' && content.length > 2 && content[content.length - 2] === '}' && content[content.length - 1] === '}') {
|
| 372 |
+
break;
|
| 373 |
+
}
|
| 374 |
+
} while (input_char !== '>');
|
| 375 |
+
|
| 376 |
+
var tag_complete = content.join('');
|
| 377 |
+
var tag_index;
|
| 378 |
+
var tag_offset;
|
| 379 |
+
|
| 380 |
+
if (tag_complete.indexOf(' ') !== -1) { //if there's whitespace, thats where the tag name ends
|
| 381 |
+
tag_index = tag_complete.indexOf(' ');
|
| 382 |
+
} else if (tag_complete[0] === '{') {
|
| 383 |
+
tag_index = tag_complete.indexOf('}');
|
| 384 |
+
} else { //otherwise go with the tag ending
|
| 385 |
+
tag_index = tag_complete.indexOf('>');
|
| 386 |
+
}
|
| 387 |
+
if (tag_complete[0] === '<' || !indent_handlebars) {
|
| 388 |
+
tag_offset = 1;
|
| 389 |
+
} else {
|
| 390 |
+
tag_offset = tag_complete[2] === '#' ? 3 : 2;
|
| 391 |
+
}
|
| 392 |
+
var tag_check = tag_complete.substring(tag_offset, tag_index).toLowerCase();
|
| 393 |
+
if (tag_complete.charAt(tag_complete.length - 2) === '/' ||
|
| 394 |
+
this.Utils.in_array(tag_check, this.Utils.single_token)) { //if this tag name is a single tag type (either in the list or has a closing /)
|
| 395 |
+
if (!peek) {
|
| 396 |
+
this.tag_type = 'SINGLE';
|
| 397 |
+
}
|
| 398 |
+
} else if (indent_handlebars && tag_complete[0] === '{' && tag_check === 'else') {
|
| 399 |
+
if (!peek) {
|
| 400 |
+
this.indent_to_tag('if');
|
| 401 |
+
this.tag_type = 'HANDLEBARS_ELSE';
|
| 402 |
+
this.indent_content = true;
|
| 403 |
+
this.traverse_whitespace();
|
| 404 |
+
}
|
| 405 |
+
} else if (tag_check === 'script') { //for later script handling
|
| 406 |
+
if (!peek) {
|
| 407 |
+
this.record_tag(tag_check);
|
| 408 |
+
this.tag_type = 'SCRIPT';
|
| 409 |
+
}
|
| 410 |
+
} else if (tag_check === 'style') { //for future style handling (for now it justs uses get_content)
|
| 411 |
+
if (!peek) {
|
| 412 |
+
this.record_tag(tag_check);
|
| 413 |
+
this.tag_type = 'STYLE';
|
| 414 |
+
}
|
| 415 |
+
} else if (this.is_unformatted(tag_check, unformatted)) { // do not reformat the "unformatted" tags
|
| 416 |
+
comment = this.get_unformatted('</' + tag_check + '>', tag_complete); //...delegate to get_unformatted function
|
| 417 |
+
content.push(comment);
|
| 418 |
+
// Preserve collapsed whitespace either before or after this tag.
|
| 419 |
+
if (tag_start > 0 && this.Utils.in_array(this.input.charAt(tag_start - 1), this.Utils.whitespace)) {
|
| 420 |
+
content.splice(0, 0, this.input.charAt(tag_start - 1));
|
| 421 |
+
}
|
| 422 |
+
tag_end = this.pos - 1;
|
| 423 |
+
if (this.Utils.in_array(this.input.charAt(tag_end + 1), this.Utils.whitespace)) {
|
| 424 |
+
content.push(this.input.charAt(tag_end + 1));
|
| 425 |
+
}
|
| 426 |
+
this.tag_type = 'SINGLE';
|
| 427 |
+
} else if (tag_check.charAt(0) === '!') { //peek for <! comment
|
| 428 |
+
// for comments content is already correct.
|
| 429 |
+
if (!peek) {
|
| 430 |
+
this.tag_type = 'SINGLE';
|
| 431 |
+
this.traverse_whitespace();
|
| 432 |
+
}
|
| 433 |
+
} else if (!peek) {
|
| 434 |
+
if (tag_check.charAt(0) === '/') { //this tag is a double tag so check for tag-ending
|
| 435 |
+
this.retrieve_tag(tag_check.substring(1)); //remove it and all ancestors
|
| 436 |
+
this.tag_type = 'END';
|
| 437 |
+
this.traverse_whitespace();
|
| 438 |
+
} else { //otherwise it's a start-tag
|
| 439 |
+
this.record_tag(tag_check); //push it on the tag stack
|
| 440 |
+
if (tag_check.toLowerCase() !== 'html') {
|
| 441 |
+
this.indent_content = true;
|
| 442 |
+
}
|
| 443 |
+
this.tag_type = 'START';
|
| 444 |
+
|
| 445 |
+
// Allow preserving of newlines after a start tag
|
| 446 |
+
this.traverse_whitespace();
|
| 447 |
+
}
|
| 448 |
+
if (this.Utils.in_array(tag_check, this.Utils.extra_liners)) { //check if this double needs an extra line
|
| 449 |
+
this.print_newline(false, this.output);
|
| 450 |
+
if (this.output.length && this.output[this.output.length - 2] !== '\n') {
|
| 451 |
+
this.print_newline(true, this.output);
|
| 452 |
+
}
|
| 453 |
+
}
|
| 454 |
+
}
|
| 455 |
+
|
| 456 |
+
if (peek) {
|
| 457 |
+
this.pos = orig_pos;
|
| 458 |
+
this.line_char_count = orig_line_char_count;
|
| 459 |
+
}
|
| 460 |
+
|
| 461 |
+
return content.join(''); //returns fully formatted tag
|
| 462 |
+
};
|
| 463 |
+
|
| 464 |
+
this.get_comment = function(start_pos) { //function to return comment content in its entirety
|
| 465 |
+
// this is will have very poor perf, but will work for now.
|
| 466 |
+
var comment = '',
|
| 467 |
+
delimiter = '>',
|
| 468 |
+
matched = false;
|
| 469 |
+
|
| 470 |
+
this.pos = start_pos;
|
| 471 |
+
input_char = this.input.charAt(this.pos);
|
| 472 |
+
this.pos++;
|
| 473 |
+
|
| 474 |
+
while (this.pos <= this.input.length) {
|
| 475 |
+
comment += input_char;
|
| 476 |
+
|
| 477 |
+
// only need to check for the delimiter if the last chars match
|
| 478 |
+
if (comment[comment.length - 1] === delimiter[delimiter.length - 1] &&
|
| 479 |
+
comment.indexOf(delimiter) !== -1) {
|
| 480 |
+
break;
|
| 481 |
+
}
|
| 482 |
+
|
| 483 |
+
// only need to search for custom delimiter for the first few characters
|
| 484 |
+
if (!matched && comment.length < 10) {
|
| 485 |
+
if (comment.indexOf('<![if') === 0) { //peek for <![if conditional comment
|
| 486 |
+
delimiter = '<![endif]>';
|
| 487 |
+
matched = true;
|
| 488 |
+
} else if (comment.indexOf('<![cdata[') === 0) { //if it's a <[cdata[ comment...
|
| 489 |
+
delimiter = ']]>';
|
| 490 |
+
matched = true;
|
| 491 |
+
} else if (comment.indexOf('<![') === 0) { // some other ![ comment? ...
|
| 492 |
+
delimiter = ']>';
|
| 493 |
+
matched = true;
|
| 494 |
+
} else if (comment.indexOf('<!--') === 0) { // <!-- comment ...
|
| 495 |
+
delimiter = '-->';
|
| 496 |
+
matched = true;
|
| 497 |
+
}
|
| 498 |
+
}
|
| 499 |
+
|
| 500 |
+
input_char = this.input.charAt(this.pos);
|
| 501 |
+
this.pos++;
|
| 502 |
+
}
|
| 503 |
+
|
| 504 |
+
return comment;
|
| 505 |
+
};
|
| 506 |
+
|
| 507 |
+
this.get_unformatted = function(delimiter, orig_tag) { //function to return unformatted content in its entirety
|
| 508 |
+
|
| 509 |
+
if (orig_tag && orig_tag.toLowerCase().indexOf(delimiter) !== -1) {
|
| 510 |
+
return '';
|
| 511 |
+
}
|
| 512 |
+
var input_char = '';
|
| 513 |
+
var content = '';
|
| 514 |
+
var min_index = 0;
|
| 515 |
+
var space = true;
|
| 516 |
+
do {
|
| 517 |
+
|
| 518 |
+
if (this.pos >= this.input.length) {
|
| 519 |
+
return content;
|
| 520 |
+
}
|
| 521 |
+
|
| 522 |
+
input_char = this.input.charAt(this.pos);
|
| 523 |
+
this.pos++;
|
| 524 |
+
|
| 525 |
+
if (this.Utils.in_array(input_char, this.Utils.whitespace)) {
|
| 526 |
+
if (!space) {
|
| 527 |
+
this.line_char_count--;
|
| 528 |
+
continue;
|
| 529 |
+
}
|
| 530 |
+
if (input_char === '\n' || input_char === '\r') {
|
| 531 |
+
content += '\n';
|
| 532 |
+
/* Don't change tab indention for unformatted blocks. If using code for html editing, this will greatly affect <pre> tags if they are specified in the 'unformatted array'
|
| 533 |
+
for (var i=0; i<this.indent_level; i++) {
|
| 534 |
+
content += this.indent_string;
|
| 535 |
+
}
|
| 536 |
+
space = false; //...and make sure other indentation is erased
|
| 537 |
+
*/
|
| 538 |
+
this.line_char_count = 0;
|
| 539 |
+
continue;
|
| 540 |
+
}
|
| 541 |
+
}
|
| 542 |
+
content += input_char;
|
| 543 |
+
this.line_char_count++;
|
| 544 |
+
space = true;
|
| 545 |
+
|
| 546 |
+
if (indent_handlebars && input_char === '{' && content.length && content[content.length - 2] === '{') {
|
| 547 |
+
// Handlebars expressions in strings should also be unformatted.
|
| 548 |
+
content += this.get_unformatted('}}');
|
| 549 |
+
// These expressions are opaque. Ignore delimiters found in them.
|
| 550 |
+
min_index = content.length;
|
| 551 |
+
}
|
| 552 |
+
} while (content.toLowerCase().indexOf(delimiter, min_index) === -1);
|
| 553 |
+
return content;
|
| 554 |
+
};
|
| 555 |
+
|
| 556 |
+
this.get_token = function() { //initial handler for token-retrieval
|
| 557 |
+
var token;
|
| 558 |
+
|
| 559 |
+
if (this.last_token === 'TK_TAG_SCRIPT' || this.last_token === 'TK_TAG_STYLE') { //check if we need to format javascript
|
| 560 |
+
var type = this.last_token.substr(7);
|
| 561 |
+
token = this.get_contents_to(type);
|
| 562 |
+
if (typeof token !== 'string') {
|
| 563 |
+
return token;
|
| 564 |
+
}
|
| 565 |
+
return [token, 'TK_' + type];
|
| 566 |
+
}
|
| 567 |
+
if (this.current_mode === 'CONTENT') {
|
| 568 |
+
token = this.get_content();
|
| 569 |
+
if (typeof token !== 'string') {
|
| 570 |
+
return token;
|
| 571 |
+
} else {
|
| 572 |
+
return [token, 'TK_CONTENT'];
|
| 573 |
+
}
|
| 574 |
+
}
|
| 575 |
+
|
| 576 |
+
if (this.current_mode === 'TAG') {
|
| 577 |
+
token = this.get_tag();
|
| 578 |
+
if (typeof token !== 'string') {
|
| 579 |
+
return token;
|
| 580 |
+
} else {
|
| 581 |
+
var tag_name_type = 'TK_TAG_' + this.tag_type;
|
| 582 |
+
return [token, tag_name_type];
|
| 583 |
+
}
|
| 584 |
+
}
|
| 585 |
+
};
|
| 586 |
+
|
| 587 |
+
this.get_full_indent = function(level) {
|
| 588 |
+
level = this.indent_level + level || 0;
|
| 589 |
+
if (level < 1) {
|
| 590 |
+
return '';
|
| 591 |
+
}
|
| 592 |
+
|
| 593 |
+
return Array(level + 1).join(this.indent_string);
|
| 594 |
+
};
|
| 595 |
+
|
| 596 |
+
this.is_unformatted = function(tag_check, unformatted) {
|
| 597 |
+
//is this an HTML5 block-level link?
|
| 598 |
+
if (!this.Utils.in_array(tag_check, unformatted)) {
|
| 599 |
+
return false;
|
| 600 |
+
}
|
| 601 |
+
|
| 602 |
+
if (tag_check.toLowerCase() !== 'a' || !this.Utils.in_array('a', unformatted)) {
|
| 603 |
+
return true;
|
| 604 |
+
}
|
| 605 |
+
|
| 606 |
+
//at this point we have an tag; is its first child something we want to remain
|
| 607 |
+
//unformatted?
|
| 608 |
+
var next_tag = this.get_tag(true /* peek. */ );
|
| 609 |
+
|
| 610 |
+
// test next_tag to see if it is just html tag (no external content)
|
| 611 |
+
var tag = (next_tag || "").match(/^\s*<\s*\/?([a-z]*)\s*[^>]*>\s*$/);
|
| 612 |
+
|
| 613 |
+
// if next_tag comes back but is not an isolated tag, then
|
| 614 |
+
// let's treat the 'a' tag as having content
|
| 615 |
+
// and respect the unformatted option
|
| 616 |
+
if (!tag || this.Utils.in_array(tag, unformatted)) {
|
| 617 |
+
return true;
|
| 618 |
+
} else {
|
| 619 |
+
return false;
|
| 620 |
+
}
|
| 621 |
+
};
|
| 622 |
+
|
| 623 |
+
this.printer = function(js_source, indent_character, indent_size, wrap_line_length, brace_style) { //handles input/output and some other printing functions
|
| 624 |
+
|
| 625 |
+
this.input = js_source || ''; //gets the input for the Parser
|
| 626 |
+
this.output = [];
|
| 627 |
+
this.indent_character = indent_character;
|
| 628 |
+
this.indent_string = '';
|
| 629 |
+
this.indent_size = indent_size;
|
| 630 |
+
this.brace_style = brace_style;
|
| 631 |
+
this.indent_level = 0;
|
| 632 |
+
this.wrap_line_length = wrap_line_length;
|
| 633 |
+
this.line_char_count = 0; //count to see if wrap_line_length was exceeded
|
| 634 |
+
|
| 635 |
+
for (var i = 0; i < this.indent_size; i++) {
|
| 636 |
+
this.indent_string += this.indent_character;
|
| 637 |
+
}
|
| 638 |
+
|
| 639 |
+
this.print_newline = function(force, arr) {
|
| 640 |
+
this.line_char_count = 0;
|
| 641 |
+
if (!arr || !arr.length) {
|
| 642 |
+
return;
|
| 643 |
+
}
|
| 644 |
+
if (force || (arr[arr.length - 1] !== '\n')) { //we might want the extra line
|
| 645 |
+
arr.push('\n');
|
| 646 |
+
}
|
| 647 |
+
};
|
| 648 |
+
|
| 649 |
+
this.print_indentation = function(arr) {
|
| 650 |
+
for (var i = 0; i < this.indent_level; i++) {
|
| 651 |
+
arr.push(this.indent_string);
|
| 652 |
+
this.line_char_count += this.indent_string.length;
|
| 653 |
+
}
|
| 654 |
+
};
|
| 655 |
+
|
| 656 |
+
this.print_token = function(text) {
|
| 657 |
+
if (text || text !== '') {
|
| 658 |
+
if (this.output.length && this.output[this.output.length - 1] === '\n') {
|
| 659 |
+
this.print_indentation(this.output);
|
| 660 |
+
text = ltrim(text);
|
| 661 |
+
}
|
| 662 |
+
}
|
| 663 |
+
this.print_token_raw(text);
|
| 664 |
+
};
|
| 665 |
+
|
| 666 |
+
this.print_token_raw = function(text) {
|
| 667 |
+
if (text && text !== '') {
|
| 668 |
+
if (text.length > 1 && text[text.length - 1] === '\n') {
|
| 669 |
+
// unformatted tags can grab newlines as their last character
|
| 670 |
+
this.output.push(text.slice(0, -1));
|
| 671 |
+
this.print_newline(false, this.output);
|
| 672 |
+
} else {
|
| 673 |
+
this.output.push(text);
|
| 674 |
+
}
|
| 675 |
+
}
|
| 676 |
+
|
| 677 |
+
for (var n = 0; n < this.newlines; n++) {
|
| 678 |
+
this.print_newline(n > 0, this.output);
|
| 679 |
+
}
|
| 680 |
+
this.newlines = 0;
|
| 681 |
+
};
|
| 682 |
+
|
| 683 |
+
this.indent = function() {
|
| 684 |
+
this.indent_level++;
|
| 685 |
+
};
|
| 686 |
+
|
| 687 |
+
this.unindent = function() {
|
| 688 |
+
if (this.indent_level > 0) {
|
| 689 |
+
this.indent_level--;
|
| 690 |
+
}
|
| 691 |
+
};
|
| 692 |
+
};
|
| 693 |
+
return this;
|
| 694 |
+
}
|
| 695 |
+
|
| 696 |
+
/*_____________________--------------------_____________________*/
|
| 697 |
+
|
| 698 |
+
multi_parser = new Parser(); //wrapping functions Parser
|
| 699 |
+
multi_parser.printer(html_source, indent_character, indent_size, wrap_line_length, brace_style); //initialize starting values
|
| 700 |
+
|
| 701 |
+
while (true) {
|
| 702 |
+
var t = multi_parser.get_token();
|
| 703 |
+
multi_parser.token_text = t[0];
|
| 704 |
+
multi_parser.token_type = t[1];
|
| 705 |
+
|
| 706 |
+
if (multi_parser.token_type === 'TK_EOF') {
|
| 707 |
+
break;
|
| 708 |
+
}
|
| 709 |
+
|
| 710 |
+
switch (multi_parser.token_type) {
|
| 711 |
+
case 'TK_TAG_START':
|
| 712 |
+
multi_parser.print_newline(false, multi_parser.output);
|
| 713 |
+
multi_parser.print_token(multi_parser.token_text);
|
| 714 |
+
if (multi_parser.indent_content) {
|
| 715 |
+
multi_parser.indent();
|
| 716 |
+
multi_parser.indent_content = false;
|
| 717 |
+
}
|
| 718 |
+
multi_parser.current_mode = 'CONTENT';
|
| 719 |
+
break;
|
| 720 |
+
case 'TK_TAG_STYLE':
|
| 721 |
+
case 'TK_TAG_SCRIPT':
|
| 722 |
+
multi_parser.print_newline(false, multi_parser.output);
|
| 723 |
+
multi_parser.print_token(multi_parser.token_text);
|
| 724 |
+
multi_parser.current_mode = 'CONTENT';
|
| 725 |
+
break;
|
| 726 |
+
case 'TK_TAG_END':
|
| 727 |
+
//Print new line only if the tag has no content and has child
|
| 728 |
+
if (multi_parser.last_token === 'TK_CONTENT' && multi_parser.last_text === '') {
|
| 729 |
+
var tag_name = multi_parser.token_text.match(/\w+/)[0];
|
| 730 |
+
var tag_extracted_from_last_output = null;
|
| 731 |
+
if (multi_parser.output.length) {
|
| 732 |
+
tag_extracted_from_last_output = multi_parser.output[multi_parser.output.length - 1].match(/(?:<|{{#)\s*(\w+)/);
|
| 733 |
+
}
|
| 734 |
+
if (tag_extracted_from_last_output === null ||
|
| 735 |
+
tag_extracted_from_last_output[1] !== tag_name) {
|
| 736 |
+
multi_parser.print_newline(false, multi_parser.output);
|
| 737 |
+
}
|
| 738 |
+
}
|
| 739 |
+
multi_parser.print_token(multi_parser.token_text);
|
| 740 |
+
multi_parser.current_mode = 'CONTENT';
|
| 741 |
+
break;
|
| 742 |
+
case 'TK_TAG_SINGLE':
|
| 743 |
+
// Don't add a newline before elements that should remain unformatted.
|
| 744 |
+
var tag_check = multi_parser.token_text.match(/^\s*<([a-z]+)/i);
|
| 745 |
+
if (!tag_check || !multi_parser.Utils.in_array(tag_check[1], unformatted)) {
|
| 746 |
+
multi_parser.print_newline(false, multi_parser.output);
|
| 747 |
+
}
|
| 748 |
+
multi_parser.print_token(multi_parser.token_text);
|
| 749 |
+
multi_parser.current_mode = 'CONTENT';
|
| 750 |
+
break;
|
| 751 |
+
case 'TK_TAG_HANDLEBARS_ELSE':
|
| 752 |
+
multi_parser.print_token(multi_parser.token_text);
|
| 753 |
+
if (multi_parser.indent_content) {
|
| 754 |
+
multi_parser.indent();
|
| 755 |
+
multi_parser.indent_content = false;
|
| 756 |
+
}
|
| 757 |
+
multi_parser.current_mode = 'CONTENT';
|
| 758 |
+
break;
|
| 759 |
+
case 'TK_CONTENT':
|
| 760 |
+
multi_parser.print_token(multi_parser.token_text);
|
| 761 |
+
multi_parser.current_mode = 'TAG';
|
| 762 |
+
break;
|
| 763 |
+
case 'TK_STYLE':
|
| 764 |
+
case 'TK_SCRIPT':
|
| 765 |
+
if (multi_parser.token_text !== '') {
|
| 766 |
+
multi_parser.print_newline(false, multi_parser.output);
|
| 767 |
+
var text = multi_parser.token_text,
|
| 768 |
+
_beautifier,
|
| 769 |
+
script_indent_level = 1;
|
| 770 |
+
if (multi_parser.token_type === 'TK_SCRIPT') {
|
| 771 |
+
_beautifier = typeof js_beautify === 'function' && js_beautify;
|
| 772 |
+
} else if (multi_parser.token_type === 'TK_STYLE') {
|
| 773 |
+
_beautifier = typeof css_beautify === 'function' && css_beautify;
|
| 774 |
+
}
|
| 775 |
+
|
| 776 |
+
if (options.indent_scripts === "keep") {
|
| 777 |
+
script_indent_level = 0;
|
| 778 |
+
} else if (options.indent_scripts === "separate") {
|
| 779 |
+
script_indent_level = -multi_parser.indent_level;
|
| 780 |
+
}
|
| 781 |
+
|
| 782 |
+
var indentation = multi_parser.get_full_indent(script_indent_level);
|
| 783 |
+
if (_beautifier) {
|
| 784 |
+
// call the Beautifier if avaliable
|
| 785 |
+
text = _beautifier(text.replace(/^\s*/, indentation), options);
|
| 786 |
+
} else {
|
| 787 |
+
// simply indent the string otherwise
|
| 788 |
+
var white = text.match(/^\s*/)[0];
|
| 789 |
+
var _level = white.match(/[^\n\r]*$/)[0].split(multi_parser.indent_string).length - 1;
|
| 790 |
+
var reindent = multi_parser.get_full_indent(script_indent_level - _level);
|
| 791 |
+
text = text.replace(/^\s*/, indentation)
|
| 792 |
+
.replace(/\r\n|\r|\n/g, '\n' + reindent)
|
| 793 |
+
.replace(/\s+$/, '');
|
| 794 |
+
}
|
| 795 |
+
if (text) {
|
| 796 |
+
multi_parser.print_token_raw(indentation + trim(text));
|
| 797 |
+
multi_parser.print_newline(false, multi_parser.output);
|
| 798 |
+
}
|
| 799 |
+
}
|
| 800 |
+
multi_parser.current_mode = 'TAG';
|
| 801 |
+
break;
|
| 802 |
+
}
|
| 803 |
+
multi_parser.last_token = multi_parser.token_type;
|
| 804 |
+
multi_parser.last_text = multi_parser.token_text;
|
| 805 |
+
}
|
| 806 |
+
return multi_parser.output.join('');
|
| 807 |
+
}
|
| 808 |
+
|
| 809 |
+
if (typeof define === "function") {
|
| 810 |
+
// Add support for require.js
|
| 811 |
+
define(["./beautify.js", "./beautify-css.js"], function(js_beautify, css_beautify) {
|
| 812 |
+
return {
|
| 813 |
+
html_beautify: function(html_source, options) {
|
| 814 |
+
return style_html(html_source, options, js_beautify, css_beautify);
|
| 815 |
+
}
|
| 816 |
+
};
|
| 817 |
+
});
|
| 818 |
+
} else if (typeof exports !== "undefined") {
|
| 819 |
+
// Add support for CommonJS. Just put this file somewhere on your require.paths
|
| 820 |
+
// and you will be able to `var html_beautify = require("beautify").html_beautify`.
|
| 821 |
+
var js_beautify = require('./beautify.js').js_beautify;
|
| 822 |
+
var css_beautify = require('./beautify-css.js').css_beautify;
|
| 823 |
+
|
| 824 |
+
exports.html_beautify = function(html_source, options) {
|
| 825 |
+
return style_html(html_source, options, js_beautify, css_beautify);
|
| 826 |
+
};
|
| 827 |
+
} else if (typeof window !== "undefined") {
|
| 828 |
+
// If we're running a web page and don't have either of the above, add our one global
|
| 829 |
+
window.html_beautify = function(html_source, options) {
|
| 830 |
+
return style_html(html_source, options, window.js_beautify, window.css_beautify);
|
| 831 |
+
};
|
| 832 |
+
} else if (typeof global !== "undefined") {
|
| 833 |
+
// If we don't even have window, try global.
|
| 834 |
+
global.html_beautify = function(html_source, options) {
|
| 835 |
+
return style_html(html_source, options, global.js_beautify, global.css_beautify);
|
| 836 |
+
};
|
| 837 |
+
}
|
| 838 |
+
|
| 839 |
+
}());
|
includes/class-admin.php
CHANGED
|
@@ -100,8 +100,9 @@ class MC4WP_Lite_Admin
|
|
| 100 |
wp_enqueue_style( 'mc4wp-admin-css', plugins_url('mailchimp-for-wp/assets/css/admin.css') );
|
| 101 |
|
| 102 |
// js
|
| 103 |
-
wp_register_script('mc4wp-
|
| 104 |
-
|
|
|
|
| 105 |
}
|
| 106 |
|
| 107 |
public function get_checkbox_compatible_plugins()
|
| 100 |
wp_enqueue_style( 'mc4wp-admin-css', plugins_url('mailchimp-for-wp/assets/css/admin.css') );
|
| 101 |
|
| 102 |
// js
|
| 103 |
+
wp_register_script( 'mc4wp-beautifyhtml', MC4WP_LITE_PLUGIN_URL . 'assets/js/beautify-html.js', array('jquery'), MC4WP_LITE_VERSION, true);
|
| 104 |
+
wp_register_script('mc4wp-admin-js', MC4WP_LITE_PLUGIN_URL . 'assets/js/admin.js', array('jquery'), false, true);
|
| 105 |
+
wp_enqueue_script( array('jquery', 'mc4wp-beautifyhtml', 'mc4wp-admin-js') );
|
| 106 |
}
|
| 107 |
|
| 108 |
public function get_checkbox_compatible_plugins()
|
includes/class-checkbox.php
CHANGED
|
@@ -80,8 +80,9 @@ class MC4WP_Lite_Checkbox
|
|
| 80 |
public function initialize()
|
| 81 |
{
|
| 82 |
if(function_exists("wpcf7_add_shortcode")) {
|
| 83 |
-
wpcf7_add_shortcode('mc4wp_checkbox', array($this, 'get_checkbox'));
|
| 84 |
-
add_action('
|
|
|
|
| 85 |
}
|
| 86 |
|
| 87 |
// catch-all (for manual integrations with third-party forms)
|
|
@@ -93,9 +94,22 @@ class MC4WP_Lite_Checkbox
|
|
| 93 |
public function get_checkbox($args = array())
|
| 94 |
{
|
| 95 |
$opts = mc4wp_get_options('checkbox');
|
|
|
|
| 96 |
$label = isset($args['labels'][0]) ? $args['labels'][0] : $opts['label'];
|
| 97 |
$checked = $opts['precheck'] ? "checked" : '';
|
| 98 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 99 |
$content = "\n<!-- Checkbox by MailChimp for WordPress plugin v". MC4WP_LITE_VERSION ." - http://dannyvankooten.com/mailchimp-for-wordpress/ -->\n";
|
| 100 |
|
| 101 |
do_action('mc4wp_before_checkbox');
|
|
@@ -228,9 +242,18 @@ class MC4WP_Lite_Checkbox
|
|
| 228 |
/* End Multisite functions */
|
| 229 |
|
| 230 |
/* Start Contact Form 7 functions */
|
| 231 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 232 |
{
|
| 233 |
-
if
|
|
|
|
|
|
|
|
|
|
| 234 |
|
| 235 |
$_POST['mc4wp-try-subscribe'] = 1;
|
| 236 |
unset($_POST['mc4wp-do-subscribe']);
|
| 80 |
public function initialize()
|
| 81 |
{
|
| 82 |
if(function_exists("wpcf7_add_shortcode")) {
|
| 83 |
+
wpcf7_add_shortcode( 'mc4wp_checkbox', array( $this, 'get_checkbox') );
|
| 84 |
+
add_action( 'wpcf7_posted_data', array( $this, 'alter_cf7_data') );
|
| 85 |
+
add_action( 'wpcf7_mail_sent', array( $this, 'subscribe_from_cf7' ) );
|
| 86 |
}
|
| 87 |
|
| 88 |
// catch-all (for manual integrations with third-party forms)
|
| 94 |
public function get_checkbox($args = array())
|
| 95 |
{
|
| 96 |
$opts = mc4wp_get_options('checkbox');
|
| 97 |
+
|
| 98 |
$label = isset($args['labels'][0]) ? $args['labels'][0] : $opts['label'];
|
| 99 |
$checked = $opts['precheck'] ? "checked" : '';
|
| 100 |
|
| 101 |
+
// CF7 checkbox?
|
| 102 |
+
if( is_array( $args ) && isset( $args['type'] ) ) {
|
| 103 |
+
|
| 104 |
+
// check for default:0 or default:1 to set the checked attribute
|
| 105 |
+
if( in_array( 'default:1', $args['options'] ) ) {
|
| 106 |
+
$checked = 'checked';
|
| 107 |
+
} else if( in_array( 'default:0', $args['options'] ) ) {
|
| 108 |
+
$checked = '';
|
| 109 |
+
}
|
| 110 |
+
|
| 111 |
+
}
|
| 112 |
+
|
| 113 |
$content = "\n<!-- Checkbox by MailChimp for WordPress plugin v". MC4WP_LITE_VERSION ." - http://dannyvankooten.com/mailchimp-for-wordpress/ -->\n";
|
| 114 |
|
| 115 |
do_action('mc4wp_before_checkbox');
|
| 242 |
/* End Multisite functions */
|
| 243 |
|
| 244 |
/* Start Contact Form 7 functions */
|
| 245 |
+
|
| 246 |
+
public function alter_cf7_data($data) {
|
| 247 |
+
$data['mc4wp_checkbox'] = ( isset( $_POST['mc4wp-do-subscribe'] ) && $_POST['mc4wp-do-subscribe'] == 1 ) ? __("Yes") : __("No");
|
| 248 |
+
return $data;
|
| 249 |
+
}
|
| 250 |
+
|
| 251 |
+
public function subscribe_from_cf7($args = null)
|
| 252 |
{
|
| 253 |
+
// check if CF7 "mc4wp" checkbox was checked
|
| 254 |
+
if(!isset($_POST['mc4wp-do-subscribe']) || !$_POST['mc4wp-do-subscribe']) {
|
| 255 |
+
return false;
|
| 256 |
+
}
|
| 257 |
|
| 258 |
$_POST['mc4wp-try-subscribe'] = 1;
|
| 259 |
unset($_POST['mc4wp-do-subscribe']);
|
includes/class-form.php
CHANGED
|
@@ -55,10 +55,10 @@ class MC4WP_Lite_Form {
|
|
| 55 |
public function initialize()
|
| 56 |
{
|
| 57 |
// register placeholder script, which will later be enqueued for IE only
|
| 58 |
-
wp_register_script( 'mc4wp-placeholders',
|
| 59 |
|
| 60 |
// register non-AJAX script (that handles form submissions)
|
| 61 |
-
wp_register_script( 'mc4wp-forms',
|
| 62 |
}
|
| 63 |
|
| 64 |
public function add_stylesheets($stylesheets) {
|
|
@@ -85,6 +85,8 @@ class MC4WP_Lite_Form {
|
|
| 85 |
$css_classes = 'form mc4wp-form ';
|
| 86 |
if ( $this->error ) $css_classes .= 'mc4wp-form-error ';
|
| 87 |
if ( $this->success ) $css_classes .= 'mc4wp-form-success ';
|
|
|
|
|
|
|
| 88 |
$css_classes = apply_filters( 'mc4wp_form_css_classes', $css_classes );
|
| 89 |
|
| 90 |
|
|
@@ -129,6 +131,8 @@ class MC4WP_Lite_Form {
|
|
| 129 |
|
| 130 |
$error_type = ($e == 'already_subscribed') ? 'notice' : 'error';
|
| 131 |
$error_message = isset($opts['text_' . $e]) ? $opts['text_' . $e] : $opts['text_error'];
|
|
|
|
|
|
|
| 132 |
$error_message = apply_filters('mc4wp_form_error_message', $error_message);
|
| 133 |
|
| 134 |
$content .= '<div class="mc4wp-alert mc4wp-'. $error_type .'">'. __($error_message, 'mailchimp-for-wp') . '</div>';
|
| 55 |
public function initialize()
|
| 56 |
{
|
| 57 |
// register placeholder script, which will later be enqueued for IE only
|
| 58 |
+
wp_register_script( 'mc4wp-placeholders', MC4WP_LITE_PLUGIN_URL . 'assets/js/placeholders.min.js', array(), MC4WP_LITE_VERSION, true );
|
| 59 |
|
| 60 |
// register non-AJAX script (that handles form submissions)
|
| 61 |
+
wp_register_script( 'mc4wp-forms', MC4WP_LITE_PLUGIN_URL . 'assets/js/forms.js', array(), MC4WP_LITE_VERSION, true );
|
| 62 |
}
|
| 63 |
|
| 64 |
public function add_stylesheets($stylesheets) {
|
| 85 |
$css_classes = 'form mc4wp-form ';
|
| 86 |
if ( $this->error ) $css_classes .= 'mc4wp-form-error ';
|
| 87 |
if ( $this->success ) $css_classes .= 'mc4wp-form-success ';
|
| 88 |
+
|
| 89 |
+
// allow developers to add css classes
|
| 90 |
$css_classes = apply_filters( 'mc4wp_form_css_classes', $css_classes );
|
| 91 |
|
| 92 |
|
| 131 |
|
| 132 |
$error_type = ($e == 'already_subscribed') ? 'notice' : 'error';
|
| 133 |
$error_message = isset($opts['text_' . $e]) ? $opts['text_' . $e] : $opts['text_error'];
|
| 134 |
+
|
| 135 |
+
// allow developers to customize error message
|
| 136 |
$error_message = apply_filters('mc4wp_form_error_message', $error_message);
|
| 137 |
|
| 138 |
$content .= '<div class="mc4wp-alert mc4wp-'. $error_type .'">'. __($error_message, 'mailchimp-for-wp') . '</div>';
|
includes/class-plugin.php
CHANGED
|
@@ -127,7 +127,7 @@ class MC4WP_Lite {
|
|
| 127 |
$stylesheets = apply_filters('mc4wp_stylesheets', array());
|
| 128 |
|
| 129 |
if(!empty($stylesheets)) {
|
| 130 |
-
$stylesheet_url = add_query_arg($stylesheets,
|
| 131 |
wp_enqueue_style( 'mailchimp-for-wp', $stylesheet_url, array(), MC4WP_LITE_VERSION);
|
| 132 |
}
|
| 133 |
}
|
| 127 |
$stylesheets = apply_filters('mc4wp_stylesheets', array());
|
| 128 |
|
| 129 |
if(!empty($stylesheets)) {
|
| 130 |
+
$stylesheet_url = add_query_arg($stylesheets, MC4WP_LITE_PLUGIN_URL . 'assets/css/css.php' );
|
| 131 |
wp_enqueue_style( 'mailchimp-for-wp', $stylesheet_url, array(), MC4WP_LITE_VERSION);
|
| 132 |
}
|
| 133 |
}
|
includes/views/form-settings.php
CHANGED
|
@@ -50,7 +50,11 @@ if( ! defined("MC4WP_LITE_VERSION") ) {
|
|
| 50 |
<td>
|
| 51 |
<ul id="mc4wp-lists">
|
| 52 |
<?php foreach($lists as $list) { ?>
|
| 53 |
-
<li
|
|
|
|
|
|
|
|
|
|
|
|
|
| 54 |
<?php } ?>
|
| 55 |
</ul>
|
| 56 |
</td>
|
| 50 |
<td>
|
| 51 |
<ul id="mc4wp-lists">
|
| 52 |
<?php foreach($lists as $list) { ?>
|
| 53 |
+
<li>
|
| 54 |
+
<label>
|
| 55 |
+
<input type="checkbox" name="mc4wp_lite_form[lists][<?php echo esc_attr($list->id); ?>]" value="<?php echo esc_attr($list->id); ?>" data-list-groupings="<?php echo esc_attr(json_encode($list->interest_groupings)); ?>" data-list-fields="<?php echo esc_attr(json_encode($list->merge_vars)); ?>" <?php if(array_key_exists($list->id, $opts['lists'])) echo 'checked="checked"'; ?>> <?php echo $list->name; ?>
|
| 56 |
+
</label>
|
| 57 |
+
</li>
|
| 58 |
<?php } ?>
|
| 59 |
</ul>
|
| 60 |
</td>
|
includes/views/parts/admin-field-wizard.php
CHANGED
|
@@ -19,7 +19,8 @@ if( ! defined("MC4WP_LITE_VERSION") ) {
|
|
| 19 |
<optgroup label="MailChimp merge fields" class="merge-fields"></optgroup>
|
| 20 |
<optgroup label="Interest groupings" class="groupings"></optgroup>
|
| 21 |
<optgroup label="Other" class="other">
|
| 22 |
-
<option class="default" value="submit">Submit button</option>
|
|
|
|
| 23 |
</optgroup>
|
| 24 |
</select>
|
| 25 |
</p>
|
| 19 |
<optgroup label="MailChimp merge fields" class="merge-fields"></optgroup>
|
| 20 |
<optgroup label="Interest groupings" class="groupings"></optgroup>
|
| 21 |
<optgroup label="Other" class="other">
|
| 22 |
+
<option class="default" value="submit">Submit button</option>
|
| 23 |
+
<option class="default" disabled>(PRO ONLY) Lists Choice</option>
|
| 24 |
</optgroup>
|
| 25 |
</select>
|
| 26 |
</p>
|
mailchimp-for-wp.php
CHANGED
|
@@ -3,7 +3,7 @@
|
|
| 3 |
Plugin Name: MailChimp for WordPress Lite
|
| 4 |
Plugin URI: http://dannyvankooten.com/mailchimp-for-wordpress/
|
| 5 |
Description: Lite version of MailChimp for WordPress. Adds various sign-up methods to your website.
|
| 6 |
-
Version: 1.5.
|
| 7 |
Author: Danny van Kooten
|
| 8 |
Author URI: http://dannyvanKooten.com
|
| 9 |
License: GPL v3
|
|
@@ -39,8 +39,9 @@ if(!function_exists('is_plugin_active')) {
|
|
| 39 |
if(!is_plugin_active('mailchimp-for-wp-pro/mailchimp-for-wp-pro.php')
|
| 40 |
&& !(is_admin() && isset($_GET['action']) && $_GET['action'] == 'activate' && isset($_GET['plugin']) && $_GET['plugin'] == 'mailchimp-for-wp-pro/mailchimp-for-wp-pro.php') ) {
|
| 41 |
|
| 42 |
-
define("MC4WP_LITE_VERSION", "1.5.
|
| 43 |
define("MC4WP_LITE_PLUGIN_DIR", plugin_dir_path(__FILE__));
|
|
|
|
| 44 |
|
| 45 |
require_once MC4WP_LITE_PLUGIN_DIR . 'includes/functions.php';
|
| 46 |
require_once MC4WP_LITE_PLUGIN_DIR . 'includes/class-plugin.php';
|
| 3 |
Plugin Name: MailChimp for WordPress Lite
|
| 4 |
Plugin URI: http://dannyvankooten.com/mailchimp-for-wordpress/
|
| 5 |
Description: Lite version of MailChimp for WordPress. Adds various sign-up methods to your website.
|
| 6 |
+
Version: 1.5.4
|
| 7 |
Author: Danny van Kooten
|
| 8 |
Author URI: http://dannyvanKooten.com
|
| 9 |
License: GPL v3
|
| 39 |
if(!is_plugin_active('mailchimp-for-wp-pro/mailchimp-for-wp-pro.php')
|
| 40 |
&& !(is_admin() && isset($_GET['action']) && $_GET['action'] == 'activate' && isset($_GET['plugin']) && $_GET['plugin'] == 'mailchimp-for-wp-pro/mailchimp-for-wp-pro.php') ) {
|
| 41 |
|
| 42 |
+
define("MC4WP_LITE_VERSION", "1.5.4");
|
| 43 |
define("MC4WP_LITE_PLUGIN_DIR", plugin_dir_path(__FILE__));
|
| 44 |
+
define("MC4WP_LITE_PLUGIN_URL", plugins_url( '/' , __FILE__ ) );
|
| 45 |
|
| 46 |
require_once MC4WP_LITE_PLUGIN_DIR . 'includes/functions.php';
|
| 47 |
require_once MC4WP_LITE_PLUGIN_DIR . 'includes/class-plugin.php';
|
readme.txt
CHANGED
|
@@ -4,7 +4,7 @@ Donate link: http://dannyvankooten.com/donate/
|
|
| 4 |
Tags: mailchimp,form,shortcode,widget,checkbox,comment,newsletter,buddypress,multisite,bbpress,woocommerce,easy digital downloads,contact form,contact form 7
|
| 5 |
Requires at least: 3.1
|
| 6 |
Tested up to: 3.8.1
|
| 7 |
-
Stable tag: 1.5.
|
| 8 |
License: GPLv2 or later
|
| 9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
| 10 |
|
|
@@ -133,6 +133,8 @@ Use the following shortcode in your CF7 form mark-up to display a sign-up checkb
|
|
| 133 |
|
| 134 |
`[mc4wp_checkbox "My custom label text"]`
|
| 135 |
|
|
|
|
|
|
|
| 136 |
If you need more data for your merge fields, prefix the field name with `mc4wp-`.
|
| 137 |
|
| 138 |
*Example CF7 template for MailChimp WEBSITE field*
|
|
@@ -196,6 +198,17 @@ Your theme folder can be found by browsing to `/wp-content/themes/your-theme-nam
|
|
| 196 |
|
| 197 |
== Changelog ==
|
| 198 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 199 |
= 1.5.2 - February 4, 2014 =
|
| 200 |
* Improved: Improved direct file access security
|
| 201 |
* Improved: Now using native WP function to catch SSL requests
|
|
@@ -446,6 +459,12 @@ Your theme folder can be found by browsing to `/wp-content/themes/your-theme-nam
|
|
| 446 |
|
| 447 |
== Upgrade Notice ==
|
| 448 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 449 |
= 1.4.8 =
|
| 450 |
WP 3.8 compatibility, better scroll to form and huge settings page performance improvement
|
| 451 |
|
| 4 |
Tags: mailchimp,form,shortcode,widget,checkbox,comment,newsletter,buddypress,multisite,bbpress,woocommerce,easy digital downloads,contact form,contact form 7
|
| 5 |
Requires at least: 3.1
|
| 6 |
Tested up to: 3.8.1
|
| 7 |
+
Stable tag: 1.5.4
|
| 8 |
License: GPLv2 or later
|
| 9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
| 10 |
|
| 133 |
|
| 134 |
`[mc4wp_checkbox "My custom label text"]`
|
| 135 |
|
| 136 |
+
You can then use `[mc4wp_checkbox]` inside your CF7 email templates, it will show "yes" or "no".
|
| 137 |
+
|
| 138 |
If you need more data for your merge fields, prefix the field name with `mc4wp-`.
|
| 139 |
|
| 140 |
*Example CF7 template for MailChimp WEBSITE field*
|
| 198 |
|
| 199 |
== Changelog ==
|
| 200 |
|
| 201 |
+
= 1.5.4 - February 17, 2014 =
|
| 202 |
+
* Fixed: "Add to form" button not working
|
| 203 |
+
* Improved: Plugin now compatible with custom plugin folder names
|
| 204 |
+
|
| 205 |
+
= 1.5.3 - February 16, 2014 =
|
| 206 |
+
* Fixed: Undefined constant notice on admin pages
|
| 207 |
+
* Fixed: "Add to form mark-up" button not working with CKEditor for WordPress
|
| 208 |
+
* Improved: Cleaned-up Admin JS
|
| 209 |
+
* Improved: You can now use `[mc4wp_checkbox]` inside your CF7 email templates
|
| 210 |
+
* Improved: You can now add `default:1` or `default:0` to the CF7 shortcode to check or uncheck the sign-up checkbox.
|
| 211 |
+
|
| 212 |
= 1.5.2 - February 4, 2014 =
|
| 213 |
* Improved: Improved direct file access security
|
| 214 |
* Improved: Now using native WP function to catch SSL requests
|
| 459 |
|
| 460 |
== Upgrade Notice ==
|
| 461 |
|
| 462 |
+
= 1.5.4 =
|
| 463 |
+
Fixed admin notice and "add to form" button, improved Contact Form 7 integration.
|
| 464 |
+
|
| 465 |
+
= 1.5.3 =
|
| 466 |
+
Fixed admin notice and improved Contact Form 7 integration.
|
| 467 |
+
|
| 468 |
= 1.4.8 =
|
| 469 |
WP 3.8 compatibility, better scroll to form and huge settings page performance improvement
|
| 470 |
|
