fork
This commit is contained in:
1152
js/src/crayon.js
Normal file
1152
js/src/crayon.js
Normal file
File diff suppressed because it is too large
Load Diff
579
js/src/crayon_admin.js
Normal file
579
js/src/crayon_admin.js
Normal file
@@ -0,0 +1,579 @@
|
||||
// Crayon Syntax Highlighter Admin JavaScript
|
||||
|
||||
(function ($) {
|
||||
|
||||
window.CrayonSyntaxAdmin = new function () {
|
||||
var base = this;
|
||||
|
||||
// Preview
|
||||
var preview, previewWrapper, previewInner, preview_info, preview_cbox, preview_delay_timer, preview_get, preview_loaded;
|
||||
// The DOM object ids that trigger a preview update
|
||||
var preview_obj_names = [];
|
||||
// The jQuery objects for these objects
|
||||
var preview_objs = [];
|
||||
var preview_last_values = [];
|
||||
// Alignment
|
||||
var align_drop, float;
|
||||
// Toolbar
|
||||
var overlay, toolbar;
|
||||
// Error
|
||||
var msg_cbox, msg;
|
||||
// Log
|
||||
var log_button, log_text, log_wrapper, change_button, change_code, plain, copy, clog, help;
|
||||
|
||||
var main_wrap, theme_editor_wrap, theme_editor_loading, theme_editor_edit_button, theme_editor_create_button, theme_editor_duplicate_button, theme_editor_delete_button, theme_editor_submit_button;
|
||||
var theme_select, theme_info, theme_ver, theme_author, theme_desc;
|
||||
|
||||
var settings = null;
|
||||
var strings = null;
|
||||
var adminSettings = null;
|
||||
var util = null;
|
||||
|
||||
base.init = function () {
|
||||
CrayonUtil.log('admin init');
|
||||
settings = CrayonSyntaxSettings;
|
||||
adminSettings = CrayonAdminSettings;
|
||||
strings = CrayonAdminStrings;
|
||||
util = CrayonUtil;
|
||||
|
||||
// Dialogs
|
||||
var dialogFunction = adminSettings.dialogFunction;
|
||||
dialogFunction = $.fn[dialogFunction] ? dialogFunction : 'dialog';
|
||||
$.fn.crayonDialog = $.fn[dialogFunction];
|
||||
|
||||
// Wraps
|
||||
main_wrap = $('#crayon-main-wrap');
|
||||
theme_editor_wrap = $('#crayon-theme-editor-wrap');
|
||||
|
||||
// Themes
|
||||
theme_select = $('#crayon-theme');
|
||||
theme_info = $('#crayon-theme-info');
|
||||
theme_ver = theme_info.find('.version').next('div');
|
||||
theme_author = theme_info.find('.author').next('div');
|
||||
theme_desc = theme_info.find('.desc');
|
||||
base.show_theme_info();
|
||||
theme_select.change(function () {
|
||||
base.show_theme_info();
|
||||
base.preview_update();
|
||||
});
|
||||
|
||||
theme_editor_edit_button = $('#crayon-theme-editor-edit-button');
|
||||
theme_editor_create_button = $('#crayon-theme-editor-create-button');
|
||||
theme_editor_duplicate_button = $('#crayon-theme-editor-duplicate-button');
|
||||
theme_editor_delete_button = $('#crayon-theme-editor-delete-button');
|
||||
theme_editor_submit_button = $('#crayon-theme-editor-submit-button');
|
||||
theme_editor_edit_button.click(function () {
|
||||
base.show_theme_editor(theme_editor_edit_button,
|
||||
true);
|
||||
});
|
||||
theme_editor_create_button.click(function () {
|
||||
base.show_theme_editor(theme_editor_create_button,
|
||||
false);
|
||||
});
|
||||
theme_editor_duplicate_button.click(function () {
|
||||
CrayonSyntaxThemeEditor.duplicate(adminSettings.currTheme, adminSettings.currThemeName);
|
||||
});
|
||||
theme_editor_delete_button.click(function () {
|
||||
if (!theme_editor_edit_button.attr('disabled')) {
|
||||
CrayonSyntaxThemeEditor.del(adminSettings.currTheme, adminSettings.currThemeName);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
theme_editor_submit_button.click(function () {
|
||||
CrayonSyntaxThemeEditor.submit(adminSettings.currTheme, adminSettings.currThemeName);
|
||||
});
|
||||
|
||||
// Help
|
||||
help = $('.crayon-help-close');
|
||||
help.click(function () {
|
||||
$('.crayon-help').hide();
|
||||
CrayonUtil.getAJAX({
|
||||
action: 'crayon-ajax',
|
||||
'hide-help': 1
|
||||
});
|
||||
});
|
||||
|
||||
// Preview
|
||||
preview = $('#crayon-live-preview');
|
||||
previewWrapper = $('#crayon-live-preview-wrapper');
|
||||
previewInner = $('#crayon-live-preview-inner');
|
||||
preview_info = $('#crayon-preview-info');
|
||||
preview_cbox = util.cssElem('#preview');
|
||||
if (preview.length != 0) {
|
||||
// Preview not needed in Tag Editor
|
||||
preview_register();
|
||||
preview.ready(function () {
|
||||
preview_toggle();
|
||||
});
|
||||
preview_cbox.change(function () {
|
||||
preview_toggle();
|
||||
});
|
||||
}
|
||||
|
||||
$('#show-posts').click(function () {
|
||||
CrayonUtil.getAJAX({
|
||||
action: 'crayon-show-posts'
|
||||
}, function (data) {
|
||||
$('#crayon-subsection-posts-info').html(data);
|
||||
});
|
||||
});
|
||||
|
||||
$('#show-langs').click(function () {
|
||||
CrayonUtil.getAJAX({
|
||||
action: 'crayon-show-langs'
|
||||
}, function (data) {
|
||||
$('#lang-info').hide();
|
||||
$('#crayon-subsection-langs-info').html(data);
|
||||
});
|
||||
});
|
||||
|
||||
// Convert
|
||||
$('#crayon-settings-form input').live(
|
||||
'focusin focusout mouseup',
|
||||
function () {
|
||||
$('#crayon-settings-form').data('lastSelected', $(this));
|
||||
});
|
||||
$('#crayon-settings-form')
|
||||
.submit(
|
||||
function () {
|
||||
var last = $(this).data('lastSelected').get(0);
|
||||
var target = $('#convert').get(0);
|
||||
if (last == target) {
|
||||
var r = confirm("Please BACKUP your database first! Converting will update your post content. Do you wish to continue?");
|
||||
return r;
|
||||
}
|
||||
});
|
||||
|
||||
// Alignment
|
||||
align_drop = util.cssElem('#h-align');
|
||||
float = $('#crayon-subsection-float');
|
||||
align_drop.change(function () {
|
||||
float_toggle();
|
||||
});
|
||||
align_drop.ready(function () {
|
||||
float_toggle();
|
||||
});
|
||||
|
||||
// Custom Error
|
||||
msg_cbox = util.cssElem('#error-msg-show');
|
||||
msg = util.cssElem('#error-msg');
|
||||
toggle_error();
|
||||
msg_cbox.change(function () {
|
||||
toggle_error();
|
||||
});
|
||||
|
||||
// Toolbar
|
||||
overlay = $('#crayon-subsection-toolbar');
|
||||
toolbar = util.cssElem('#toolbar');
|
||||
toggle_toolbar();
|
||||
toolbar.change(function () {
|
||||
toggle_toolbar();
|
||||
});
|
||||
|
||||
// Copy
|
||||
plain = util.cssElem('#plain');
|
||||
copy = $('#crayon-subsection-copy-check');
|
||||
plain.change(function () {
|
||||
if (plain.is(':checked')) {
|
||||
copy.show();
|
||||
} else {
|
||||
copy.hide();
|
||||
}
|
||||
});
|
||||
|
||||
// Log
|
||||
log_wrapper = $('#crayon-log-wrapper');
|
||||
log_button = $('#crayon-log-toggle');
|
||||
log_text = $('#crayon-log-text');
|
||||
var show_log = log_button.attr('show_txt');
|
||||
var hide_log = log_button.attr('hide_txt');
|
||||
clog = $('#crayon-log');
|
||||
log_button.val(show_log);
|
||||
log_button.click(function () {
|
||||
clog.width(log_wrapper.width());
|
||||
clog.toggle();
|
||||
// Scrolls content
|
||||
clog.scrollTop(log_text.height());
|
||||
var text = (log_button.val() == show_log ? hide_log
|
||||
: show_log);
|
||||
log_button.val(text);
|
||||
});
|
||||
|
||||
change_button = $('#crayon-change-code');
|
||||
change_button.click(function () {
|
||||
base.createDialog({
|
||||
title: strings.changeCode,
|
||||
html: '<textarea id="crayon-change-code-text"></textarea>',
|
||||
desc: null,
|
||||
value: '',
|
||||
options: {
|
||||
buttons: {
|
||||
"OK": function () {
|
||||
change_code = $('#crayon-change-code-text').val();
|
||||
base.preview_update();
|
||||
$(this).crayonDialog('close');
|
||||
},
|
||||
"Cancel": function () {
|
||||
$(this).crayonDialog('close');
|
||||
}
|
||||
},
|
||||
open: function () {
|
||||
if (change_code) {
|
||||
$('#crayon-change-code-text').val(change_code);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
$('#crayon-fallback-lang').change(function () {
|
||||
change_code = null;
|
||||
base.preview_update();
|
||||
});
|
||||
};
|
||||
|
||||
/* Whenever a control changes preview */
|
||||
base.preview_update = function (vars) {
|
||||
var val = 0;
|
||||
var obj;
|
||||
var getVars = $.extend({
|
||||
action: 'crayon-show-preview',
|
||||
theme: adminSettings.currTheme
|
||||
}, vars);
|
||||
if (change_code) {
|
||||
getVars[adminSettings.sampleCode] = change_code;
|
||||
}
|
||||
for (var i = 0; i < preview_obj_names.length; i++) {
|
||||
obj = preview_objs[i];
|
||||
if (obj.attr('type') == 'checkbox') {
|
||||
val = obj.is(':checked');
|
||||
} else {
|
||||
val = obj.val();
|
||||
}
|
||||
getVars[preview_obj_names[i]] = val;//CrayonUtil.escape(val);
|
||||
}
|
||||
|
||||
// Load Preview
|
||||
CrayonUtil.postAJAX(getVars, function (data) {
|
||||
preview.html(data);
|
||||
// Important! Calls the crayon.js init
|
||||
CrayonSyntax.init();
|
||||
base.preview_ready();
|
||||
});
|
||||
};
|
||||
|
||||
base.preview_ready = function () {
|
||||
if (!preview_loaded) {
|
||||
preview_loaded = true;
|
||||
if (window.GET['theme-editor']) {
|
||||
CrayonSyntaxAdmin.show_theme_editor(
|
||||
theme_editor_edit_button, true);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var preview_toggle = function () {
|
||||
// CrayonUtil.log('preview_toggle');
|
||||
if (preview_cbox.is(':checked')) {
|
||||
preview.show();
|
||||
preview_info.show();
|
||||
base.preview_update();
|
||||
} else {
|
||||
preview.hide();
|
||||
preview_info.hide();
|
||||
}
|
||||
};
|
||||
|
||||
var float_toggle = function () {
|
||||
if (align_drop.val() != 0) {
|
||||
float.show();
|
||||
} else {
|
||||
float.hide();
|
||||
}
|
||||
};
|
||||
|
||||
// List of callbacks
|
||||
var preview_callback;
|
||||
var preview_txt_change;
|
||||
var preview_txt_callback; // Only updates if text value changed
|
||||
var preview_txt_callback_delayed;
|
||||
// var height_set;
|
||||
|
||||
// Register all event handlers for preview objects
|
||||
var preview_register = function () {
|
||||
// Instant callback
|
||||
preview_callback = function () {
|
||||
base.preview_update();
|
||||
};
|
||||
|
||||
// Checks if the text input is changed, if so, runs the callback
|
||||
// with given event
|
||||
preview_txt_change = function (callback, event) {
|
||||
// CrayonUtil.log('checking if changed');
|
||||
var obj = event.target;
|
||||
var last = preview_last_values[obj.id];
|
||||
// CrayonUtil.log('last' + preview_last_values[obj.id]);
|
||||
|
||||
if (obj.value != last) {
|
||||
// CrayonUtil.log('changed');
|
||||
// Update last value to current
|
||||
preview_last_values[obj.id] = obj.value;
|
||||
// Run callback with event
|
||||
callback(event);
|
||||
}
|
||||
};
|
||||
|
||||
// Only updates when text is changed
|
||||
preview_txt_callback = function (event) {
|
||||
// CrayonUtil.log('txt callback');
|
||||
preview_txt_change(base.preview_update, event);
|
||||
};
|
||||
|
||||
// Only updates when text is changed, but callback
|
||||
preview_txt_callback_delayed = function (event) {
|
||||
preview_txt_change(function () {
|
||||
clearInterval(preview_delay_timer);
|
||||
preview_delay_timer = setInterval(function () {
|
||||
// CrayonUtil.log('delayed update');
|
||||
base.preview_update();
|
||||
clearInterval(preview_delay_timer);
|
||||
}, 500);
|
||||
}, event);
|
||||
};
|
||||
|
||||
// Retreive preview objects
|
||||
$('[crayon-preview="1"]').each(function (i) {
|
||||
var obj = $(this);
|
||||
var id = obj.attr('id');
|
||||
// XXX Remove prefix
|
||||
id = util.removePrefixFromID(id);
|
||||
preview_obj_names[i] = id;
|
||||
preview_objs[i] = obj;
|
||||
// To capture key up events when typing
|
||||
if (obj.attr('type') == 'text') {
|
||||
preview_last_values[obj.attr('id')] = obj.val();
|
||||
obj.bind('keyup', preview_txt_callback_delayed);
|
||||
obj.change(preview_txt_callback);
|
||||
} else {
|
||||
// For all other objects
|
||||
obj.change(preview_callback);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var toggle_error = function () {
|
||||
if (msg_cbox.is(':checked')) {
|
||||
msg.show();
|
||||
} else {
|
||||
msg.hide();
|
||||
}
|
||||
};
|
||||
|
||||
var toggle_toolbar = function () {
|
||||
if (toolbar.val() == 0) {
|
||||
overlay.show();
|
||||
} else {
|
||||
overlay.hide();
|
||||
}
|
||||
};
|
||||
|
||||
base.get_vars = function () {
|
||||
var vars = {};
|
||||
window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function (m, key, value) {
|
||||
vars[key] = value;
|
||||
});
|
||||
return vars;
|
||||
};
|
||||
|
||||
// Changing wrap views
|
||||
base.show_main = function () {
|
||||
theme_editor_wrap.hide();
|
||||
main_wrap.show();
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
base.refresh_theme_info = function (callback) {
|
||||
adminSettings.currTheme = theme_select.val();
|
||||
adminSettings.currThemeName = theme_select.find('option:selected').attr('data-value');
|
||||
adminSettings.currThemeIsUser = adminSettings.currTheme in adminSettings.userThemes;
|
||||
var url = adminSettings.currThemeIsUser ? adminSettings.userThemesURL : adminSettings.themesURL;
|
||||
adminSettings.currThemeURL = base.get_theme_url(adminSettings.currTheme);
|
||||
// Load the theme file
|
||||
|
||||
$.ajax({
|
||||
url: adminSettings.currThemeURL,
|
||||
success: function (data) {
|
||||
adminSettings.currThemeCSS = data;
|
||||
// var fields = {
|
||||
// 'Version': theme_ver,
|
||||
// 'Author': theme_author,
|
||||
// 'URL': null,
|
||||
// 'Description': theme_desc
|
||||
// };
|
||||
// for (field in fields) {
|
||||
// var re = new RegExp('(?:^|[\\r\\n]\\s*)\\b' + field
|
||||
// + '\\s*:\\s*([^\\r\\n]+)', 'gmi');
|
||||
// var match = re.exec(data);
|
||||
// var val = fields[field];
|
||||
// if (match) {
|
||||
// if (val != null) {
|
||||
// val.html(match[1].escape().linkify('_blank'));
|
||||
// } else if (field == 'Author URI') {
|
||||
// theme_author.html('<a href="' + match[1]
|
||||
// + '" target="_blank">'
|
||||
// + theme_author.text() + '</a>');
|
||||
// }
|
||||
// } else if (val != null) {
|
||||
// val.text('N/A');
|
||||
// }
|
||||
// }
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
},
|
||||
cache: false
|
||||
});
|
||||
|
||||
adminSettings.currThemeCSS = '';
|
||||
};
|
||||
|
||||
base.get_theme_url = function ($id) {
|
||||
var url = $id in adminSettings.userThemes ? adminSettings.userThemesURL : adminSettings.themesURL;
|
||||
return url + $id + '/' + $id + '.css';
|
||||
};
|
||||
|
||||
base.show_theme_info = function (callback) {
|
||||
base.refresh_theme_info(function () {
|
||||
var info = CrayonSyntaxThemeEditor.readCSSInfo(adminSettings.currThemeCSS);
|
||||
var infoHTML = '';
|
||||
for (id in info) {
|
||||
if (id != 'name') {
|
||||
infoHTML += '<div class="fieldset">';
|
||||
if (id != 'description') {
|
||||
infoHTML += '<div class="' + id + ' field">' + CrayonSyntaxThemeEditor.getFieldName(id) + ':</div>';
|
||||
}
|
||||
infoHTML += '<div class="' + id + ' value">' + info[id].linkify('_blank') + '</div></div>';
|
||||
}
|
||||
}
|
||||
var type, typeName;
|
||||
if (adminSettings.currThemeIsUser) {
|
||||
type = 'user';
|
||||
typeName = CrayonThemeEditorStrings.userTheme;
|
||||
} else {
|
||||
type = 'stock';
|
||||
typeName = CrayonThemeEditorStrings.stockTheme;
|
||||
}
|
||||
infoHTML = '<div class="type ' + type + '">' + typeName + '</div><div class="content">' + infoHTML + '</div>';
|
||||
theme_info.html(infoHTML);
|
||||
// Disable for stock themes
|
||||
var disabled = !adminSettings.currThemeIsUser && !settings.debug;
|
||||
theme_editor_edit_button.attr('disabled', disabled);
|
||||
theme_editor_delete_button.attr('disabled', disabled);
|
||||
theme_editor_submit_button.attr('disabled', disabled);
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
base.show_theme_editor = function (button, editing) {
|
||||
if (theme_editor_edit_button.attr('disabled')) {
|
||||
return false;
|
||||
}
|
||||
base.refresh_theme_info();
|
||||
button.html(button.attr('loading'));
|
||||
adminSettings.editing_theme = editing;
|
||||
theme_editor_loading = true;
|
||||
// Load theme editor
|
||||
CrayonUtil.getAJAX({
|
||||
action: 'crayon-theme-editor',
|
||||
currTheme: adminSettings.currTheme,
|
||||
editing: editing
|
||||
}, function (data) {
|
||||
theme_editor_wrap.html(data);
|
||||
// Load preview into editor
|
||||
if (theme_editor_loading) {
|
||||
CrayonSyntaxThemeEditor.init();
|
||||
}
|
||||
CrayonSyntaxThemeEditor.show(function () {
|
||||
base.show_theme_editor_now(button);
|
||||
}, previewInner);
|
||||
});
|
||||
return false;
|
||||
};
|
||||
|
||||
base.resetPreview = function () {
|
||||
previewWrapper.append(previewInner);
|
||||
CrayonSyntaxThemeEditor.removeStyle();
|
||||
};
|
||||
|
||||
base.show_theme_editor_now = function (button) {
|
||||
main_wrap.hide();
|
||||
theme_editor_wrap.show();
|
||||
theme_editor_loading = false;
|
||||
button.html(button.attr('loaded'));
|
||||
};
|
||||
|
||||
// JQUERY UI DIALOGS
|
||||
|
||||
base.createAlert = function (args) {
|
||||
args = $.extend({
|
||||
title: strings.alert,
|
||||
options: {
|
||||
buttons: {
|
||||
"OK": function () {
|
||||
$(this).crayonDialog('close');
|
||||
}
|
||||
}
|
||||
}
|
||||
}, args);
|
||||
base.createDialog(args);
|
||||
};
|
||||
|
||||
base.createDialog = function (args, options) {
|
||||
var defaultArgs = {
|
||||
yesLabel: strings.yes,
|
||||
noLabel: strings.no,
|
||||
title: strings.confirm
|
||||
};
|
||||
args = $.extend(defaultArgs, args);
|
||||
var options = $.extend({
|
||||
modal: true, title: args.title, zIndex: 10000, autoOpen: true,
|
||||
width: 'auto', resizable: false,
|
||||
buttons: {
|
||||
},
|
||||
dialogClass: 'wp-dialog',
|
||||
selectedButtonIndex: 1, // starts from 1
|
||||
close: function (event, ui) {
|
||||
$(this).remove();
|
||||
}
|
||||
}, options);
|
||||
options.buttons[args.yesLabel] = function () {
|
||||
if (args.yes) {
|
||||
args.yes();
|
||||
}
|
||||
$(this).crayonDialog('close');
|
||||
};
|
||||
options.buttons[args.noLabel] = function () {
|
||||
if (args.no) {
|
||||
args.no();
|
||||
}
|
||||
$(this).crayonDialog('close');
|
||||
};
|
||||
options = $.extend(options, args.options);
|
||||
options.open = function () {
|
||||
$('.ui-button').addClass('button-primary');
|
||||
$(this).parent().find('button:nth-child(' + options.selectedButtonIndex + ')').focus();
|
||||
if (args.options.open) {
|
||||
args.options.open();
|
||||
}
|
||||
};
|
||||
$('<div></div>').appendTo('body').html(args.html).crayonDialog(options);
|
||||
// Can be modified afterwards
|
||||
return args;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
})(jQueryCrayon);
|
||||
190
js/src/cssjson.js
Normal file
190
js/src/cssjson.js
Normal file
@@ -0,0 +1,190 @@
|
||||
/**
|
||||
* CSS-JSON Converter for JavaScript, v.2.0 By Aram Kocharyan, http://aramk.com/
|
||||
* Converts CSS to JSON and back.
|
||||
*/
|
||||
|
||||
var CSSJSON = new function() {
|
||||
|
||||
var base = this;
|
||||
|
||||
base.init = function() {
|
||||
// String functions
|
||||
String.prototype.trim = function() {
|
||||
return this.replace(/^\s+|\s+$/g, '');
|
||||
};
|
||||
|
||||
String.prototype.repeat = function(n) {
|
||||
return new Array(1 + n).join(this);
|
||||
};
|
||||
};
|
||||
base.init();
|
||||
|
||||
var selX = /([^\s\;\{\}][^\;\{\}]*)\{/g;
|
||||
var endX = /\}/g;
|
||||
var lineX = /([^\;\{\}]*)\;/g;
|
||||
var commentX = /\/\*[\s\S]*?\*\//g;
|
||||
var lineAttrX = /([^\:]+):([^\;]*);/;
|
||||
|
||||
// This is used, a concatenation of all above. We use alternation to
|
||||
// capture.
|
||||
var altX = /(\/\*[\s\S]*?\*\/)|([^\s\;\{\}][^\;\{\}]*(?=\{))|(\})|([^\;\{\}]+\;(?!\s*\*\/))/gmi;
|
||||
|
||||
// Capture groups
|
||||
var capComment = 1;
|
||||
var capSelector = 2;
|
||||
var capEnd = 3;
|
||||
var capAttr = 4;
|
||||
|
||||
var isEmpty = function(x) {
|
||||
return typeof x == 'undefined' || x.length == 0 || x == null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Input is css string and current pos, returns JSON object
|
||||
*
|
||||
* @param cssString
|
||||
* The CSS string.
|
||||
* @param args
|
||||
* An optional argument object. ordered: Whether order of
|
||||
* comments and other nodes should be kept in the output. This
|
||||
* will return an object where all the keys are numbers and the
|
||||
* values are objects containing "name" and "value" keys for each
|
||||
* node. comments: Whether to capture comments. split: Whether to
|
||||
* split each comma separated list of selectors.
|
||||
*/
|
||||
base.toJSON = function(cssString, args) {
|
||||
var node = {
|
||||
children: {},
|
||||
attributes: {}
|
||||
};
|
||||
var match = null;
|
||||
var count = 0;
|
||||
|
||||
if (typeof args == 'undefined') {
|
||||
var args = {
|
||||
ordered : false,
|
||||
comments : false,
|
||||
stripComments : false,
|
||||
split : false
|
||||
};
|
||||
}
|
||||
if (args.stripComments) {
|
||||
args.comments = false;
|
||||
cssString = cssString.replace(commentX, '');
|
||||
}
|
||||
|
||||
while ((match = altX.exec(cssString)) != null) {
|
||||
if (!isEmpty(match[capComment]) && args.comments) {
|
||||
// Comment
|
||||
var add = match[capComment].trim();
|
||||
node[count++] = add;
|
||||
} else if (!isEmpty(match[capSelector])) {
|
||||
// New node, we recurse
|
||||
var name = match[capSelector].trim();
|
||||
// This will return when we encounter a closing brace
|
||||
var newNode = base.toJSON(cssString, args);
|
||||
if (args.ordered) {
|
||||
var obj = {};
|
||||
obj['name'] = name;
|
||||
obj['value'] = newNode;
|
||||
// Since we must use key as index to keep order and not
|
||||
// name, this will differentiate between a Rule Node and an
|
||||
// Attribute, since both contain a name and value pair.
|
||||
obj['type'] = 'rule';
|
||||
node[count++] = obj;
|
||||
} else {
|
||||
if (args.split) {
|
||||
var bits = name.split(',');
|
||||
} else {
|
||||
var bits = [name];
|
||||
}
|
||||
for (i in bits) {
|
||||
var sel = bits[i].trim();
|
||||
if (sel in node.children) {
|
||||
for (var att in newNode.attributes) {
|
||||
node.children[sel].attributes[att] = newNode.attributes[att];
|
||||
}
|
||||
} else {
|
||||
node.children[sel] = newNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (!isEmpty(match[capEnd])) {
|
||||
// Node has finished
|
||||
return node;
|
||||
} else if (!isEmpty(match[capAttr])) {
|
||||
var line = match[capAttr].trim();
|
||||
var attr = lineAttrX.exec(line);
|
||||
if (attr) {
|
||||
// Attribute
|
||||
var name = attr[1].trim();
|
||||
var value = attr[2].trim();
|
||||
if (args.ordered) {
|
||||
var obj = {};
|
||||
obj['name'] = name;
|
||||
obj['value'] = value;
|
||||
obj['type'] = 'attr';
|
||||
node[count++] = obj;
|
||||
} else {
|
||||
node.attributes[name] = value;
|
||||
}
|
||||
} else {
|
||||
// Semicolon terminated line
|
||||
node[count++] = line;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param node
|
||||
* A JSON node.
|
||||
* @param depth
|
||||
* The depth of the current node; used for indentation and
|
||||
* optional.
|
||||
* @param breaks
|
||||
* Whether to add line breaks in the output.
|
||||
*/
|
||||
base.toCSS = function(node, depth, breaks) {
|
||||
var cssString = '';
|
||||
if (typeof depth == 'undefined') {
|
||||
depth = 0;
|
||||
}
|
||||
if (typeof breaks == 'undefined') {
|
||||
breaks = false;
|
||||
}
|
||||
if (node.attributes) {
|
||||
for (i in node.attributes) {
|
||||
cssString += strAttr(i, node.attributes[i], depth);
|
||||
}
|
||||
}
|
||||
if (node.children) {
|
||||
var first = true;
|
||||
for (i in node.children) {
|
||||
if (breaks && !first) {
|
||||
cssString += '\n';
|
||||
} else {
|
||||
first = false;
|
||||
}
|
||||
cssString += strNode(i, node.children[i], depth);
|
||||
}
|
||||
}
|
||||
return cssString;
|
||||
};
|
||||
|
||||
// Helpers
|
||||
|
||||
var strAttr = function(name, value, depth) {
|
||||
return '\t'.repeat(depth) + name + ': ' + value + ';\n';
|
||||
};
|
||||
|
||||
var strNode = function(name, value, depth) {
|
||||
var cssString = '\t'.repeat(depth) + name + ' {\n';
|
||||
cssString += base.toCSS(value, depth + 1);
|
||||
cssString += '\t'.repeat(depth) + '}\n';
|
||||
return cssString;
|
||||
};
|
||||
|
||||
};
|
||||
101
js/src/jquery.popup.js
Normal file
101
js/src/jquery.popup.js
Normal file
@@ -0,0 +1,101 @@
|
||||
// Default Settings
|
||||
jqueryPopup = Object();
|
||||
jqueryPopup.defaultSettings = {
|
||||
centerBrowser:0, // center window over browser window? {1 (YES) or 0 (NO)}. overrides top and left
|
||||
centerScreen:0, // center window over entire screen? {1 (YES) or 0 (NO)}. overrides top and left
|
||||
height:500, // sets the height in pixels of the window.
|
||||
left:0, // left position when the window appears.
|
||||
location:0, // determines whether the address bar is displayed {1 (YES) or 0 (NO)}.
|
||||
menubar:0, // determines whether the menu bar is displayed {1 (YES) or 0 (NO)}.
|
||||
resizable:0, // whether the window can be resized {1 (YES) or 0 (NO)}. Can also be overloaded using resizable.
|
||||
scrollbars:0, // determines whether scrollbars appear on the window {1 (YES) or 0 (NO)}.
|
||||
status:0, // whether a status line appears at the bottom of the window {1 (YES) or 0 (NO)}.
|
||||
width:500, // sets the width in pixels of the window.
|
||||
windowName:null, // name of window set from the name attribute of the element that invokes the click
|
||||
windowURL:null, // url used for the popup
|
||||
top:0, // top position when the window appears.
|
||||
toolbar:0, // determines whether a toolbar (includes the forward and back buttons) is displayed {1 (YES) or 0 (NO)}.
|
||||
data:null,
|
||||
event:'click'
|
||||
};
|
||||
|
||||
(function ($) {
|
||||
|
||||
popupWindow = function (object, instanceSettings, beforeCallback, afterCallback) {
|
||||
beforeCallback = typeof beforeCallback !== 'undefined' ? beforeCallback : null;
|
||||
afterCallback = typeof afterCallback !== 'undefined' ? afterCallback : null;
|
||||
|
||||
if (typeof object == 'string') {
|
||||
object = jQuery(object);
|
||||
}
|
||||
if (!(object instanceof jQuery)) {
|
||||
return false;
|
||||
}
|
||||
var settings = jQuery.extend({}, jqueryPopup.defaultSettings, instanceSettings || {});
|
||||
object.handler = jQuery(object).bind(settings.event, function() {
|
||||
|
||||
if (beforeCallback) {
|
||||
beforeCallback();
|
||||
}
|
||||
|
||||
var windowFeatures = 'height=' + settings.height +
|
||||
',width=' + settings.width +
|
||||
',toolbar=' + settings.toolbar +
|
||||
',scrollbars=' + settings.scrollbars +
|
||||
',status=' + settings.status +
|
||||
',resizable=' + settings.resizable +
|
||||
',location=' + settings.location +
|
||||
',menuBar=' + settings.menubar;
|
||||
|
||||
settings.windowName = settings.windowName || jQuery(this).attr('name');
|
||||
var href = jQuery(this).attr('href');
|
||||
if (!settings.windowURL && !(href == '#') && !(href == '')) {
|
||||
settings.windowURL = jQuery(this).attr('href');
|
||||
}
|
||||
|
||||
var centeredY,centeredX;
|
||||
|
||||
var win = null;
|
||||
if (settings.centerBrowser) {
|
||||
if (typeof window.screenY == 'undefined') {// not defined for old IE versions
|
||||
centeredY = (window.screenTop - 120) + ((((document.documentElement.clientHeight + 120)/2) - (settings.height/2)));
|
||||
centeredX = window.screenLeft + ((((document.body.offsetWidth + 20)/2) - (settings.width/2)));
|
||||
} else {
|
||||
centeredY = window.screenY + (((window.outerHeight/2) - (settings.height/2)));
|
||||
centeredX = window.screenX + (((window.outerWidth/2) - (settings.width/2)));
|
||||
}
|
||||
win = window.open(settings.windowURL, settings.windowName, windowFeatures+',left=' + centeredX +',top=' + centeredY);
|
||||
} else if (settings.centerScreen) {
|
||||
centeredY = (screen.height - settings.height)/2;
|
||||
centeredX = (screen.width - settings.width)/2;
|
||||
win = window.open(settings.windowURL, settings.windowName, windowFeatures+',left=' + centeredX +',top=' + centeredY);
|
||||
} else {
|
||||
win = window.open(settings.windowURL, settings.windowName, windowFeatures+',left=' + settings.left +',top=' + settings.top);
|
||||
}
|
||||
if (win != null) {
|
||||
win.focus();
|
||||
if (settings.data) {
|
||||
win.document.write(settings.data);
|
||||
}
|
||||
}
|
||||
|
||||
if (afterCallback) {
|
||||
afterCallback();
|
||||
}
|
||||
});
|
||||
return settings;
|
||||
};
|
||||
|
||||
popdownWindow = function(object, event) {
|
||||
if (typeof event == 'undefined') {
|
||||
event = 'click';
|
||||
}
|
||||
object = jQuery(object);
|
||||
if (!(object instanceof jQuery)) {
|
||||
return false;
|
||||
}
|
||||
object.unbind(event, object.handler);
|
||||
};
|
||||
|
||||
})(jQueryCrayon);
|
||||
|
||||
265
js/src/util.js
Normal file
265
js/src/util.js
Normal file
@@ -0,0 +1,265 @@
|
||||
// To avoid duplicates conflicting
|
||||
var jQueryCrayon = jQuery;
|
||||
|
||||
(function ($) {
|
||||
|
||||
CrayonUtil = new function () {
|
||||
|
||||
var base = this;
|
||||
var settings = null;
|
||||
|
||||
base.init = function () {
|
||||
settings = CrayonSyntaxSettings;
|
||||
base.initGET();
|
||||
};
|
||||
|
||||
base.addPrefixToID = function (id) {
|
||||
return id.replace(/^([#.])?(.*)$/, '$1' + settings.prefix + '$2');
|
||||
};
|
||||
|
||||
base.removePrefixFromID = function (id) {
|
||||
var re = new RegExp('^[#.]?' + settings.prefix, 'i');
|
||||
return id.replace(re, '');
|
||||
};
|
||||
|
||||
base.cssElem = function (id) {
|
||||
return $(base.addPrefixToID(id));
|
||||
};
|
||||
|
||||
base.setDefault = function (v, d) {
|
||||
return (typeof v == 'undefined') ? d : v;
|
||||
};
|
||||
|
||||
base.setMax = function (v, max) {
|
||||
return v <= max ? v : max;
|
||||
};
|
||||
|
||||
base.setMin = function (v, min) {
|
||||
return v >= min ? v : min;
|
||||
};
|
||||
|
||||
base.setRange = function (v, min, max) {
|
||||
return base.setMax(base.setMin(v, min), max);
|
||||
};
|
||||
|
||||
base.getExt = function (str) {
|
||||
if (str.indexOf('.') == -1) {
|
||||
return undefined;
|
||||
}
|
||||
var ext = str.split('.');
|
||||
if (ext.length) {
|
||||
ext = ext[ext.length - 1];
|
||||
} else {
|
||||
ext = '';
|
||||
}
|
||||
return ext;
|
||||
};
|
||||
|
||||
base.initGET = function () {
|
||||
// URLs
|
||||
window.currentURL = window.location.protocol + '//' + window.location.host + window.location.pathname;
|
||||
window.currentDir = window.currentURL.substring(0, window.currentURL.lastIndexOf('/'));
|
||||
|
||||
// http://stackoverflow.com/questions/439463
|
||||
function getQueryParams(qs) {
|
||||
qs = qs.split("+").join(" ");
|
||||
var params = {}, tokens, re = /[?&]?([^=]+)=([^&]*)/g;
|
||||
while (tokens = re.exec(qs)) {
|
||||
params[decodeURIComponent(tokens[1])] = decodeURIComponent(tokens[2]);
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
window.GET = getQueryParams(document.location.search);
|
||||
};
|
||||
|
||||
base.getAJAX = function (args, callback) {
|
||||
args.version = settings.version;
|
||||
$.get(settings.ajaxurl, args, callback);
|
||||
};
|
||||
|
||||
base.postAJAX = function (args, callback) {
|
||||
args.version = settings.version;
|
||||
$.post(settings.ajaxurl, args, callback);
|
||||
};
|
||||
|
||||
base.reload = function () {
|
||||
var get = '?';
|
||||
for (var i in window.GET) {
|
||||
get += i + '=' + window.GET[i] + '&';
|
||||
}
|
||||
window.location = window.currentURL + get;
|
||||
};
|
||||
|
||||
base.escape = function (string) {
|
||||
if (typeof encodeURIComponent == 'function') {
|
||||
return encodeURIComponent(string);
|
||||
} else if (typeof escape != 'function') {
|
||||
return escape(string);
|
||||
} else {
|
||||
return string;
|
||||
}
|
||||
};
|
||||
|
||||
base.log = function (string) {
|
||||
if (typeof console != 'undefined' && settings.debug) {
|
||||
console.log(string);
|
||||
}
|
||||
};
|
||||
|
||||
base.decode_html = function (str) {
|
||||
return String(str).replace(/&/g, '&').replace(/</g, '<').replace(
|
||||
/>/g, '>');
|
||||
};
|
||||
|
||||
base.encode_html = function (str) {
|
||||
return String(str).replace(/&/g, '&').replace(/</g, '<').replace(
|
||||
/>/g, '>');
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns either black or white to ensure this color is distinguishable with the given RGB hex.
|
||||
* This function can be used to create a readable foreground color given a background color, or vice versa.
|
||||
* It forms a radius around white where black is returned. Outside this radius, white is returned.
|
||||
*
|
||||
* @param hex An RGB hex (e.g. "#FFFFFF")
|
||||
* @requires jQuery and TinyColor
|
||||
* @param args The argument object. Properties:
|
||||
* amount: a value in the range [0,1]. If the distance of the given hex from white exceeds this value,
|
||||
* white is returned. Otherwise, black is returned.
|
||||
* xMulti: a multiplier to the distance in the x-axis.
|
||||
* yMulti: a multiplier to the distance in the y-axis.
|
||||
* normalizeHue: either falsey or an [x,y] array range. If hex is a colour with hue in this range,
|
||||
* then normalizeHueXMulti and normalizeHueYMulti are applied.
|
||||
* normalizeHueXMulti: a multiplier to the distance in the x-axis if hue is normalized.
|
||||
* normalizeHueYMulti: a multiplier to the distance in the y-axis if hue is normalized.
|
||||
* @return the RGB hex string of black or white.
|
||||
*/
|
||||
base.getReadableColor = function (hex, args) {
|
||||
args = $.extend({
|
||||
amount: 0.5,
|
||||
xMulti: 1,
|
||||
// We want to achieve white a bit sooner in the y axis
|
||||
yMulti: 1.5,
|
||||
normalizeHue: [20, 180],
|
||||
// For colors that appear lighter (yellow, green, light blue) we reduce the distance in the x direction,
|
||||
// stretching the radius in the x axis allowing more black than before.
|
||||
normalizeHueXMulti: 1 / 2.5,
|
||||
normalizeHueYMulti: 1
|
||||
}, args);
|
||||
var color = tinycolor(hex);
|
||||
var hsv = color.toHsv();
|
||||
// Origin is white
|
||||
var coord = {x: hsv.s, y: 1 - hsv.v};
|
||||
// Multipliers
|
||||
coord.x *= args.xMulti;
|
||||
coord.y *= args.yMulti;
|
||||
if (args.normalizeHue && hsv.h > args.normalizeHue[0] && hsv.h < args.normalizeHue[1]) {
|
||||
coord.x *= args.normalizeHueXMulti;
|
||||
coord.y *= args.normalizeHueYMulti;
|
||||
}
|
||||
var dist = Math.sqrt(Math.pow(coord.x, 2) + Math.pow(coord.y, 2));
|
||||
if (dist < args.amount) {
|
||||
hsv.v = 0; // black
|
||||
} else {
|
||||
hsv.v = 1; // white
|
||||
}
|
||||
hsv.s = 0;
|
||||
return tinycolor(hsv).toHexString();
|
||||
};
|
||||
|
||||
base.removeChars = function (chars, str) {
|
||||
var re = new RegExp('[' + chars + ']', 'gmi');
|
||||
return str.replace(re, '');
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
$(document).ready(function () {
|
||||
CrayonUtil.init();
|
||||
});
|
||||
|
||||
// http://stackoverflow.com/questions/2360655/jquery-event-handlers-always-execute-in-order-they-were-bound-any-way-around-t
|
||||
|
||||
// [name] is the name of the event "click", "mouseover", ..
|
||||
// same as you'd pass it to bind()
|
||||
// [fn] is the handler function
|
||||
$.fn.bindFirst = function (name, fn) {
|
||||
// bind as you normally would
|
||||
// don't want to miss out on any jQuery magic
|
||||
this.bind(name, fn);
|
||||
// Thanks to a comment by @Martin, adding support for
|
||||
// namespaced events too.
|
||||
var handlers = this.data('events')[name.split('.')[0]];
|
||||
// take out the handler we just inserted from the end
|
||||
var handler = handlers.pop();
|
||||
// move it at the beginning
|
||||
handlers.splice(0, 0, handler);
|
||||
};
|
||||
|
||||
// http://stackoverflow.com/questions/4079274/how-to-get-an-objects-properties-in-javascript-jquery
|
||||
$.keys = function (obj) {
|
||||
var keys = [];
|
||||
for (var key in obj) {
|
||||
keys.push(key);
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
|
||||
// Prototype modifications
|
||||
|
||||
RegExp.prototype.execAll = function (string) {
|
||||
var matches = [];
|
||||
var match = null;
|
||||
while ((match = this.exec(string)) != null) {
|
||||
var matchArray = [];
|
||||
for (var i in match) {
|
||||
if (parseInt(i) == i) {
|
||||
matchArray.push(match[i]);
|
||||
}
|
||||
}
|
||||
matches.push(matchArray);
|
||||
}
|
||||
return matches;
|
||||
};
|
||||
|
||||
// Escape regex chars with \
|
||||
RegExp.prototype.escape = function (text) {
|
||||
return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
|
||||
};
|
||||
|
||||
String.prototype.sliceReplace = function (start, end, repl) {
|
||||
return this.substring(0, start) + repl + this.substring(end);
|
||||
};
|
||||
|
||||
String.prototype.escape = function () {
|
||||
var tagsToReplace = {
|
||||
'&': '&',
|
||||
'<': '<',
|
||||
'>': '>'
|
||||
};
|
||||
return this.replace(/[&<>]/g, function (tag) {
|
||||
return tagsToReplace[tag] || tag;
|
||||
});
|
||||
};
|
||||
|
||||
String.prototype.linkify = function (target) {
|
||||
target = typeof target != 'undefined' ? target : '';
|
||||
return this.replace(/(http(s)?:\/\/(\S)+)/gmi, '<a href="$1" target="' + target + '">$1</a>');
|
||||
};
|
||||
|
||||
String.prototype.toTitleCase = function () {
|
||||
var parts = this.split(/\s+/);
|
||||
var title = '';
|
||||
$.each(parts, function (i, part) {
|
||||
if (part != '') {
|
||||
title += part.slice(0, 1).toUpperCase() + part.slice(1, part.length);
|
||||
if (i != parts.length - 1 && parts[i + 1] != '') {
|
||||
title += ' ';
|
||||
}
|
||||
}
|
||||
});
|
||||
return title;
|
||||
};
|
||||
|
||||
})(jQueryCrayon);
|
||||
Reference in New Issue
Block a user