fork
94
util/crayon_log.class.php
Normal file
@ -0,0 +1,94 @@
|
||||
<?php
|
||||
require_once (CRAYON_ROOT_PATH . 'crayon_settings.class.php');
|
||||
|
||||
/* Manages logging variable values to the log file. */
|
||||
class CrayonLog {
|
||||
private static $file = NULL;
|
||||
|
||||
// Logs a variable value to a log file
|
||||
|
||||
public static function log($var = NULL, $title = '', $trim_url = TRUE) {
|
||||
if ($var === NULL) {
|
||||
// Return log
|
||||
|
||||
if (($log = CrayonUtil::file(CRAYON_LOG_FILE)) !== FALSE) {
|
||||
return $log;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
if (self::$file == NULL) {
|
||||
self::$file = @fopen(CRAYON_LOG_FILE, 'a+');
|
||||
|
||||
if (self::$file) {
|
||||
$header = /*CRAYON_DASH .*/ CRAYON_NL . '[Crayon Syntax Highlighter Log Entry - ' . date('g:i:s A - d M Y') . ']' . CRAYON_NL .
|
||||
/*CRAYON_DASH .*/ CRAYON_NL;
|
||||
fwrite(self::$file, $header);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Capture variable dump
|
||||
$buffer = trim(strip_tags(var_export($var, true)));
|
||||
$title = (!empty($title) ? " [$title]" : '');
|
||||
|
||||
// Remove absolute path to plugin directory from buffer
|
||||
if ($trim_url) {
|
||||
$buffer = CrayonUtil::path_rel($buffer);
|
||||
}
|
||||
$write = $title . ' ' . $buffer . CRAYON_NL /* . CRAYON_LINE . CRAYON_NL*/;
|
||||
|
||||
// If we exceed max file size, truncate file first
|
||||
if (filesize(CRAYON_LOG_FILE) + strlen($write) > CRAYON_LOG_MAX_SIZE) {
|
||||
ftruncate(self::$file, 0);
|
||||
fwrite(self::$file, 'The log has been truncated since it exceeded ' . CRAYON_LOG_MAX_SIZE .
|
||||
' bytes.' . CRAYON_NL . /*CRAYON_LINE .*/ CRAYON_NL);
|
||||
}
|
||||
clearstatcache();
|
||||
fwrite(self::$file, $write, CRAYON_LOG_MAX_SIZE);
|
||||
} catch (Exception $e) {
|
||||
// Ignore fatal errors during logging
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Logs system-wide only if global settings permit
|
||||
|
||||
public static function syslog($var = NULL, $title = '', $trim_url = TRUE) {
|
||||
if (CrayonGlobalSettings::val(CrayonSettings::ERROR_LOG_SYS)) {
|
||||
$title = (empty($title)) ? 'SYSTEM LOG' : $title;
|
||||
self::log($var, $title, $trim_url);
|
||||
}
|
||||
}
|
||||
|
||||
public static function debug($var = NULL, $title = '', $trim_url = TRUE) {
|
||||
if (CRAYON_DEBUG) {
|
||||
$title = (empty($title)) ? 'DEBUG' : $title;
|
||||
self::log($var, $title, $trim_url);
|
||||
}
|
||||
}
|
||||
|
||||
public static function clear() {
|
||||
if (!@unlink(CRAYON_LOG_FILE)) {
|
||||
// Will result in nothing if we can't log
|
||||
|
||||
self::log('The log could not be cleared', 'Log Clear');
|
||||
}
|
||||
self::$file = NULL; // Remove file handle
|
||||
|
||||
}
|
||||
|
||||
public static function email($to, $from = NULL) {
|
||||
if (($log_contents = CrayonUtil::file(CRAYON_LOG_FILE)) !== FALSE) {
|
||||
$headers = $from ? 'From: ' . $from : '';
|
||||
$result = @mail($to, 'Crayon Syntax Highlighter Log', $log_contents, $headers);
|
||||
self::log('The log was emailed to the admin.', 'Log Email');
|
||||
} else {
|
||||
// Will result in nothing if we can't email
|
||||
|
||||
self::log("The log could not be emailed to $to.", 'Log Email');
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
24
util/crayon_timer.class.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
/* Used to measure execution time */
|
||||
class CrayonTimer {
|
||||
const NO_SET = -1;
|
||||
private $start_time = self::NO_SET;
|
||||
|
||||
function __construct() {}
|
||||
|
||||
public function start() {
|
||||
$this->start_time = microtime(true);
|
||||
}
|
||||
|
||||
public function stop() {
|
||||
if ($this->start_time != self::NO_SET) {
|
||||
$end_time = microtime(true) - $this->start_time;
|
||||
$this->start_time = self::NO_SET;
|
||||
return $end_time;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
858
util/crayon_util.class.php
Normal file
@ -0,0 +1,858 @@
|
||||
<?php
|
||||
|
||||
/* Common utility functions mainly for formatting, parsing etc. */
|
||||
class CrayonUtil {
|
||||
|
||||
// Used to detect touchscreen devices
|
||||
private static $touchscreen = NULL;
|
||||
|
||||
/* Return the lines inside a file as an array, options:
|
||||
l - lowercase
|
||||
w - remove whitespace
|
||||
r - escape regex chars
|
||||
c - remove comments
|
||||
s - return as string */
|
||||
public static function lines($path, $opts = NULL) {
|
||||
$path = self::pathf($path);
|
||||
if (($str = self::file($path)) === FALSE) {
|
||||
// Log failure, n = no log
|
||||
if (strpos($opts, 'n') === FALSE) {
|
||||
CrayonLog::syslog("Cannot read lines at '$path'.", "CrayonUtil::lines()");
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
// Read the options
|
||||
if (is_string($opts)) {
|
||||
$lowercase = strpos($opts, 'l') !== FALSE;
|
||||
$whitespace = strpos($opts, 'w') !== FALSE;
|
||||
$escape_regex = strpos($opts, 'r') !== FALSE;
|
||||
$clean_commments = strpos($opts, 'c') !== FALSE;
|
||||
$return_string = strpos($opts, 's') !== FALSE;
|
||||
// $escape_hash = strpos($opts, 'h') !== FALSE;
|
||||
} else {
|
||||
$lowercase = $whitespace = $escape_regex = $clean_commments = $return_string = /*$escape_hash =*/
|
||||
FALSE;
|
||||
}
|
||||
// Remove comments
|
||||
if ($clean_commments) {
|
||||
$str = self::clean_comments($str);
|
||||
}
|
||||
|
||||
// Convert to lowercase if needed
|
||||
if ($lowercase) {
|
||||
$str = strtolower($str);
|
||||
}
|
||||
/* Match all the content on non-empty lines, also remove any whitespace to the left and
|
||||
right if needed */
|
||||
if ($whitespace) {
|
||||
$pattern = '[^\s]+(?:.*[^\s])?';
|
||||
} else {
|
||||
$pattern = '^(?:.*)?';
|
||||
}
|
||||
|
||||
preg_match_all('|' . $pattern . '|m', $str, $matches);
|
||||
$lines = $matches[0];
|
||||
// Remove regex syntax and assume all characters are literal
|
||||
if ($escape_regex) {
|
||||
for ($i = 0; $i < count($lines); $i++) {
|
||||
$lines[$i] = self::esc_regex($lines[$i]);
|
||||
// if ($escape_hash || true) {
|
||||
// If we have used \#, then we don't want it to become \\#
|
||||
$lines[$i] = preg_replace('|\\\\\\\\#|', '\#', $lines[$i]);
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
// Return as string if needed
|
||||
if ($return_string) {
|
||||
// Add line breaks if they were stripped
|
||||
$delimiter = '';
|
||||
if ($whitespace) {
|
||||
$delimiter = CRAYON_NL;
|
||||
}
|
||||
$lines = implode($lines, $delimiter);
|
||||
}
|
||||
|
||||
return $lines;
|
||||
}
|
||||
|
||||
// Returns the contents of a file
|
||||
public static function file($path) {
|
||||
if (($str = @file_get_contents($path)) === FALSE) {
|
||||
return FALSE;
|
||||
} else {
|
||||
return $str;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Zips a source file or directory.
|
||||
*
|
||||
* @param $src A directory or file
|
||||
* @param $dest A directory or zip file. If a zip file is provided it must exist beforehand.
|
||||
*/
|
||||
public static function createZip($src, $dest, $removeExistingZip = FALSE) {
|
||||
if ($src == $dest) {
|
||||
throw new InvalidArgumentException("Source '$src' and '$dest' cannot be the same");
|
||||
}
|
||||
|
||||
if (is_dir($src)) {
|
||||
$src = CrayonUtil::path_slash($src);
|
||||
$base = $src;
|
||||
// Make sure the destination isn't in the files
|
||||
$files = self::getFiles($src, array('recursive' => TRUE, 'ignore' => array($dest)));
|
||||
} else if (is_file($src)) {
|
||||
$files = array($src);
|
||||
$base = dirname($src);
|
||||
} else {
|
||||
throw new InvalidArgumentException("Source '$src' is not a directory or file");
|
||||
}
|
||||
|
||||
if (is_dir($dest)) {
|
||||
$dest = CrayonUtil::path_slash($dest);
|
||||
$zipFile = $dest . basename($src) . '.zip';
|
||||
} else if (is_file($dest)) {
|
||||
$zipFile = $dest;
|
||||
} else {
|
||||
throw new InvalidArgumentException("Destination '$dest' is not a directory or file");
|
||||
}
|
||||
|
||||
if ($removeExistingZip) {
|
||||
@unlink($zipFile);
|
||||
}
|
||||
|
||||
$zip = new ZipArchive;
|
||||
|
||||
if ($zip->open($zipFile, ZIPARCHIVE::CREATE) === TRUE) {
|
||||
foreach ($files as $file) {
|
||||
$relFile = str_replace($base, '', $file);
|
||||
$zip->addFile($file, $relFile);
|
||||
}
|
||||
$zip->close();
|
||||
} else {
|
||||
throw new Exception("Could not create zip file at '$zipFile'");
|
||||
}
|
||||
|
||||
return $zipFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends an email in html and plain encodings with a file attachment.
|
||||
*
|
||||
* @param array $args Arguments associative array
|
||||
* 'to' (string)
|
||||
* 'from' (string)
|
||||
* 'subject' (optional string)
|
||||
* 'message' (HTML string)
|
||||
* 'plain' (optional plain string)
|
||||
* 'file' (optional file path of the attachment)
|
||||
* @see http://webcheatsheet.com/php/send_email_text_html_attachment.php
|
||||
*/
|
||||
public static function emailFile($args) {
|
||||
$to = self::set_default($args['to']);
|
||||
$from = self::set_default($args['from']);
|
||||
$subject = self::set_default($args['subject'], '');
|
||||
$message = self::set_default($args['message'], '');
|
||||
$plain = self::set_default($args['plain'], '');
|
||||
$file = self::set_default($args['file']);
|
||||
|
||||
// MIME
|
||||
$random_hash = md5(date('r', time()));
|
||||
$boundaryMixed = 'PHP-mixed-' . $random_hash;
|
||||
$boundaryAlt = 'PHP-alt-' . $random_hash;
|
||||
$charset = 'UTF-8';
|
||||
$bits = '8bit';
|
||||
|
||||
// Headers
|
||||
$headers = "MIME-Version: 1.0";
|
||||
$headers .= "Reply-To: $to\r\n";
|
||||
if ($from !== NULL) {
|
||||
$headers .= "From: $from\r\n";
|
||||
}
|
||||
$headers .= "Content-Type: multipart/mixed; boundary=$boundaryMixed";
|
||||
if ($file !== NULL) {
|
||||
$info = pathinfo($file);
|
||||
$filename = $info['filename'];
|
||||
$extension = $info['extension'];
|
||||
$contents = @file_get_contents($file);
|
||||
if ($contents === FALSE) {
|
||||
throw new Exception("File contents of '$file' could not be read");
|
||||
}
|
||||
$chunks = chunk_split(base64_encode($contents));
|
||||
$attachment = <<<EOT
|
||||
--$boundaryMixed
|
||||
Content-Type: application/$extension; name=$filename.$extension
|
||||
Content-Transfer-Encoding: base64
|
||||
Content-Disposition: attachment
|
||||
|
||||
$chunks
|
||||
EOT;
|
||||
} else {
|
||||
$attachment = '';
|
||||
}
|
||||
|
||||
$body = <<<EOT
|
||||
--$boundaryMixed
|
||||
Content-Type: multipart/alternative; boundary=$boundaryAlt
|
||||
|
||||
--$boundaryAlt
|
||||
Content-Type: text/plain; charset="$charset"
|
||||
Content-Transfer-Encoding: $bits
|
||||
|
||||
$plain
|
||||
|
||||
--$boundaryAlt
|
||||
Content-Type: text/html; charset="$charset"
|
||||
Content-Transfer-Encoding: $bits
|
||||
|
||||
$message
|
||||
--$boundaryAlt--
|
||||
|
||||
$attachment
|
||||
|
||||
--$boundaryMixed--
|
||||
EOT;
|
||||
|
||||
$result = @mail($to, $subject, $body, $headers);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $path A directory
|
||||
* @param array $args Argument array:
|
||||
* hidden: If true, hidden files beginning with a dot will be included
|
||||
* ignoreRef: If true, . and .. are ignored
|
||||
* recursive: If true, this function is recursive
|
||||
* ignore: An array of paths to ignore
|
||||
* @return array Files in the directory
|
||||
*/
|
||||
public static function getFiles($path, $args = array()) {
|
||||
$hidden = self::set_default($args['hidden'], TRUE);
|
||||
$ignoreRef = self::set_default($args['ignoreRef'], TRUE);
|
||||
$recursive = self::set_default($args['recursive'], FALSE);
|
||||
$ignore = self::set_default($args['ignore'], NULL);
|
||||
|
||||
$ignore_map = array();
|
||||
if ($ignore) {
|
||||
foreach ($ignore as $i) {
|
||||
if (is_dir($i)) {
|
||||
$i = CrayonUtil::path_slash($i);
|
||||
}
|
||||
$ignore_map[$i] = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
$files = glob($path . '*', GLOB_MARK);
|
||||
if ($hidden) {
|
||||
$files = array_merge($files, glob($path . '.*', GLOB_MARK));
|
||||
}
|
||||
if ($ignoreRef || $ignore) {
|
||||
$result = array();
|
||||
for ($i = 0; $i < count($files); $i++) {
|
||||
$file = $files[$i];
|
||||
if (!isset($ignore_map[$file]) && (!$ignoreRef || (basename($file) != '.' && basename($file) != '..'))) {
|
||||
$result[] = $file;
|
||||
if ($recursive && is_dir($file)) {
|
||||
$result = array_merge($result, self::getFiles($file, $args));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$result = $files;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public static function deleteDir($path) {
|
||||
if (!is_dir($path)) {
|
||||
throw new InvalidArgumentException("deleteDir: $path is not a directory");
|
||||
}
|
||||
if (substr($path, strlen($path) - 1, 1) != '/') {
|
||||
$path .= '/';
|
||||
}
|
||||
$files = self::getFiles($path);
|
||||
foreach ($files as $file) {
|
||||
if (is_dir($file)) {
|
||||
self::deleteDir($file);
|
||||
} else {
|
||||
unlink($file);
|
||||
}
|
||||
}
|
||||
rmdir($path);
|
||||
}
|
||||
|
||||
public static function copyDir($src, $dst, $mkdir = NULL) {
|
||||
// http://stackoverflow.com/questions/2050859
|
||||
if (!is_dir($src)) {
|
||||
throw new InvalidArgumentException("copyDir: $src is not a directory");
|
||||
}
|
||||
$dir = opendir($src);
|
||||
if ($mkdir !== NULL) {
|
||||
call_user_func($mkdir, $dst);
|
||||
} else {
|
||||
@mkdir($dst, 0777, TRUE);
|
||||
}
|
||||
while (false !== ($file = readdir($dir))) {
|
||||
if (($file != '.') && ($file != '..')) {
|
||||
if (is_dir($src . '/' . $file)) {
|
||||
self::copyDir($src . '/' . $file, $dst . '/' . $file);
|
||||
} else {
|
||||
copy($src . '/' . $file, $dst . '/' . $file);
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir($dir);
|
||||
}
|
||||
|
||||
// Supports arrays in the values
|
||||
public static function array_flip($array) {
|
||||
$result = array();
|
||||
foreach ($array as $k => $v) {
|
||||
if (is_array($v)) {
|
||||
foreach ($v as $u) {
|
||||
self::_array_flip($result, $k, $u);
|
||||
}
|
||||
} else {
|
||||
self::_array_flip($result, $k, $v);
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
private static function _array_flip(&$array, $k, $v) {
|
||||
if (is_string($v) || is_int($v)) {
|
||||
$array[$v] = $k;
|
||||
} else {
|
||||
trigger_error("Values must be STRING or INTEGER", E_USER_WARNING);
|
||||
}
|
||||
}
|
||||
|
||||
// Detects if device is touchscreen or mobile
|
||||
public static function is_touch() {
|
||||
// Only detect once
|
||||
if (self::$touchscreen !== NULL) {
|
||||
return self::$touchscreen;
|
||||
}
|
||||
if (($devices = self::lines(CRAYON_TOUCH_FILE, 'lw')) !== FALSE) {
|
||||
if (!isset($_SERVER['HTTP_USER_AGENT'])) {
|
||||
return false;
|
||||
}
|
||||
// Create array of device strings from file
|
||||
$user_agent = strtolower($_SERVER['HTTP_USER_AGENT']);
|
||||
self::$touchscreen = (self::strposa($user_agent, $devices) !== FALSE);
|
||||
return self::$touchscreen;
|
||||
} else {
|
||||
CrayonLog::syslog('Error occurred when trying to identify touchscreen devices');
|
||||
}
|
||||
}
|
||||
|
||||
// Removes duplicates in array, ensures they are all strings
|
||||
public static function array_unique_str($array) {
|
||||
if (!is_array($array) || empty($array)) {
|
||||
return array();
|
||||
}
|
||||
for ($i = 0; $i < count($array); $i++) {
|
||||
$array[$i] = strval($array[$i]);
|
||||
}
|
||||
return array_unique($array);
|
||||
}
|
||||
|
||||
// Same as array_key_exists, but returns the key when exists, else FALSE;
|
||||
public static function array_key_exists($key, $array) {
|
||||
if (!is_array($array) || empty($array) || !is_string($key) || empty($key)) {
|
||||
FALSE;
|
||||
}
|
||||
if (array_key_exists($key, $array)) {
|
||||
return $array[$key];
|
||||
}
|
||||
}
|
||||
|
||||
// Performs explode() on a string with the given delimiter and trims all whitespace
|
||||
public static function trim_e($str, $delimiter = ',') {
|
||||
if (is_string($delimiter)) {
|
||||
$str = trim(preg_replace('|\s*(?:' . preg_quote($delimiter) . ')\s*|', $delimiter, $str));
|
||||
return explode($delimiter, $str);
|
||||
}
|
||||
return $str;
|
||||
}
|
||||
|
||||
/* Creates an array of integers based on a given range string of format "int - int"
|
||||
Eg. range_str('2 - 5'); */
|
||||
public static function range_str($str) {
|
||||
preg_match('#(\d+)\s*-\s*(\d+)#', $str, $matches);
|
||||
if (count($matches) == 3) {
|
||||
return range($matches[1], $matches[2]);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Creates an array out of a single range string (e.i "x-y")
|
||||
public static function range_str_single($str) {
|
||||
$match = preg_match('#(\d+)(?:\s*-\s*(\d+))?#', $str, $matches);
|
||||
if ($match > 0) {
|
||||
if (empty($matches[2])) {
|
||||
$matches[2] = $matches[1];
|
||||
}
|
||||
if ($matches[1] <= $matches[2]) {
|
||||
return array($matches[1], $matches[2]);
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Sets a variable to a string if valid
|
||||
public static function str(&$var, $str, $escape = TRUE) {
|
||||
if (is_string($str)) {
|
||||
$var = ($escape == TRUE ? self::htmlentities($str) : $str);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Converts all special characters to entities
|
||||
public static function htmlentities($str) {
|
||||
return htmlentities($str, ENT_COMPAT, 'UTF-8');
|
||||
}
|
||||
|
||||
public static function html_entity_decode($str) {
|
||||
return html_entity_decode($str, ENT_QUOTES, 'UTF-8');
|
||||
}
|
||||
|
||||
// Converts <, >, & into entities
|
||||
public static function htmlspecialchars($str) {
|
||||
return htmlspecialchars($str, ENT_NOQUOTES, 'UTF-8');
|
||||
}
|
||||
|
||||
// Sets a variable to an int if valid
|
||||
public static function num(&$var, $num) {
|
||||
if (is_numeric($num)) {
|
||||
$var = intval($num);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Sets a variable to an array if valid
|
||||
public static function arr(&$var, $array) {
|
||||
if (is_array($array)) {
|
||||
$var = $array;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Sets a variable to an array if valid
|
||||
public static function set_array($var, $array, $false = FALSE) {
|
||||
return isset($array[$var]) ? $array[$var] : $false;
|
||||
}
|
||||
|
||||
// Sets a variable to null if not set
|
||||
public static function set_var(&$var, $false = NULL) {
|
||||
$var = isset($var) ? $var : $false;
|
||||
}
|
||||
|
||||
// Sets a variable to null if not set
|
||||
public static function set_default(&$var, $default = NULL) {
|
||||
return isset($var) ? $var : $default;
|
||||
}
|
||||
|
||||
public static function set_default_null($var, $default = NULL) {
|
||||
return $var !== NULL ? $var : $default;
|
||||
}
|
||||
|
||||
// Thanks, http://www.php.net/manual/en/function.str-replace.php#102186
|
||||
function str_replace_once($str_pattern, $str_replacement, $string) {
|
||||
if (strpos($string, $str_pattern) !== FALSE) {
|
||||
$occurrence = strpos($string, $str_pattern);
|
||||
return substr_replace($string, $str_replacement, strpos($string, $str_pattern), strlen($str_pattern));
|
||||
}
|
||||
return $string;
|
||||
}
|
||||
|
||||
// Removes non-numeric chars in string
|
||||
public static function clean_int($str, $return_zero = TRUE) {
|
||||
$str = preg_replace('#[^\d]#', '', $str);
|
||||
if ($return_zero) {
|
||||
// If '', then returns 0
|
||||
return strval(intval($str));
|
||||
} else {
|
||||
// Might be ''
|
||||
return $str;
|
||||
}
|
||||
}
|
||||
|
||||
// Replaces whitespace with hypthens
|
||||
public static function space_to_hyphen($str) {
|
||||
return preg_replace('#\s+#', '-', $str);
|
||||
}
|
||||
|
||||
// Replaces hypthens with spaces
|
||||
public static function hyphen_to_space($str) {
|
||||
return preg_replace('#-#', ' ', $str);
|
||||
}
|
||||
|
||||
// Remove comments with /* */, // or #, if they occur before any other char on a line
|
||||
public static function clean_comments($str) {
|
||||
$comment_pattern = '#(?:^\s*/\*.*?^\s*\*/)|(?:^(?!\s*$)[\s]*(?://|\#)[^\r\n]*)#ms';
|
||||
$str = preg_replace($comment_pattern, '', $str);
|
||||
return $str;
|
||||
}
|
||||
|
||||
// Convert to title case and replace underscores with spaces
|
||||
public static function ucwords($str) {
|
||||
$str = strval($str);
|
||||
$str = str_replace('_', ' ', $str);
|
||||
return ucwords($str);
|
||||
}
|
||||
|
||||
// Escapes regex characters as literals
|
||||
public static function esc_regex($regex) {
|
||||
return /*htmlspecialchars(*/
|
||||
preg_quote($regex) /* , ENT_NOQUOTES)*/
|
||||
;
|
||||
}
|
||||
|
||||
// Escapes hash character as literals
|
||||
public static function esc_hash($regex) {
|
||||
if (is_string($regex)) {
|
||||
return preg_replace('|(?<!\\\\)#|', '\#', $regex);
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure all parenthesis are atomic to avoid conflicting with element matches
|
||||
public static function esc_atomic($regex) {
|
||||
return preg_replace('#(?<!\\\\)\((?!\?)#', '(?:', $regex);
|
||||
}
|
||||
|
||||
// Returns the current HTTP URL
|
||||
public static function current_url() {
|
||||
$p = self::isSecure() ? "https://" : "http://";
|
||||
return $p . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
|
||||
}
|
||||
|
||||
// Removes crayon plugin path from absolute path
|
||||
public static function path_rel($url) {
|
||||
if (is_string($url)) {
|
||||
return str_replace(CRAYON_ROOT_PATH, '/', $url);
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
|
||||
// Returns path according to detected use of forwardslash/backslash
|
||||
// Deprecated from regular use after v.1.1.1
|
||||
public static function path($path, $detect) {
|
||||
$slash = self::detect_slash($detect);
|
||||
return str_replace(array('\\', '/'), $slash, $path);
|
||||
}
|
||||
|
||||
// Detect which kind of slash is being used in a path
|
||||
public static function detect_slash($path) {
|
||||
if (strpos($path, '\\')) {
|
||||
// Windows
|
||||
return $slash = '\\';
|
||||
} else {
|
||||
// UNIX
|
||||
return $slash = '/';
|
||||
}
|
||||
}
|
||||
|
||||
// Returns path using forward slashes
|
||||
public static function pathf($url) {
|
||||
return str_replace('\\', '/', trim(strval($url)));
|
||||
}
|
||||
|
||||
// Returns path using back slashes
|
||||
public static function pathb($url) {
|
||||
return str_replace('/', '\\', trim(strval($url)));
|
||||
}
|
||||
|
||||
// returns 'true' or 'false' depending on whether this PHP file was served over HTTPS
|
||||
public static function isSecure() {
|
||||
// From https://core.trac.wordpress.org/browser/tags/4.0.1/src/wp-includes/functions.php
|
||||
if ( isset($_SERVER['HTTPS']) ) {
|
||||
if ( 'on' == strtolower($_SERVER['HTTPS']) )
|
||||
return true;
|
||||
if ( '1' == $_SERVER['HTTPS'] )
|
||||
return true;
|
||||
} elseif ( isset($_SERVER['SERVER_PORT']) && ( '443' == $_SERVER['SERVER_PORT'] ) ) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function startsWith($haystack, $needle) {
|
||||
return substr($haystack, 0, strlen($needle)) === $needle;
|
||||
}
|
||||
|
||||
// Append either forward slash or backslash based on environment to paths
|
||||
public static function path_slash($path) {
|
||||
$path = self::pathf($path);
|
||||
if (!empty($path) && !preg_match('#\/$#', $path)) {
|
||||
$path .= '/';
|
||||
}
|
||||
if (self::startsWith($path, 'http://') && self::isSecure()) {
|
||||
$path = str_replace('http://', 'https://', $path);
|
||||
}
|
||||
return $path;
|
||||
}
|
||||
|
||||
public static function path_slash_remove($path) {
|
||||
return preg_replace('#\/+$#', '', $path);
|
||||
}
|
||||
|
||||
// Append a forward slash to a path if needed
|
||||
public static function url_slash($url) {
|
||||
$url = self::pathf($url);
|
||||
if (!empty($url) && !preg_match('#\/$#', $url)) {
|
||||
$url .= '/';
|
||||
}
|
||||
if (self::startsWith($url, 'http://') && self::isSecure()) {
|
||||
$url = str_replace('http://', 'https://', $url);
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
|
||||
// Removes extension from file path
|
||||
public static function path_rem_ext($path) {
|
||||
$path = self::pathf($path);
|
||||
return preg_replace('#\.\w+$#m', '', $path);
|
||||
}
|
||||
|
||||
// Shorten a URL into a string of given length, used to identify a URL uniquely
|
||||
public static function shorten_url_to_length($url, $length) {
|
||||
if ($length < 1) {
|
||||
return '';
|
||||
}
|
||||
$url = preg_replace('#(^\w+://)|([/\.])#si', '', $url);
|
||||
if (strlen($url) > $length) {
|
||||
$diff = strlen($url) - $length;
|
||||
$rem = floor(strlen($url) / $diff);
|
||||
$rem_count = 0;
|
||||
for ($i = $rem - 1; $i < strlen($url) && $rem_count < $diff; $i = $i + $rem) {
|
||||
$url[$i] = '.';
|
||||
$rem_count++;
|
||||
}
|
||||
$url = preg_replace('#\.#s', '', $url);
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
|
||||
// Creates a unique ID from a string
|
||||
public static function get_var_str() {
|
||||
$get_vars = array();
|
||||
foreach ($_GET as $get => $val) {
|
||||
$get_vars[] = $get . '=' . $val;
|
||||
}
|
||||
return implode($get_vars, '&');
|
||||
}
|
||||
|
||||
// Creates a unique ID from a string
|
||||
public static function str_uid($str) {
|
||||
$uid = 0;
|
||||
for ($i = 1; $i < strlen($str); $i++) {
|
||||
$uid += round(ord($str[$i]) * ($i / strlen($str)), 2) * 100;
|
||||
}
|
||||
return strval(dechex(strlen($str))) . strval(dechex($uid));
|
||||
}
|
||||
|
||||
// Breaks up a version string into parts
|
||||
public static function version_parts($version) {
|
||||
preg_match('#[\d+\.]+#msi', $version, $match);
|
||||
if (count($match[0])) {
|
||||
return explode('.', $match[0]);
|
||||
} else {
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
// Compares two version strings lexicographically
|
||||
public static function version_compare($a, $b) {
|
||||
$a_parts = self::version_parts($a);
|
||||
$b_parts = self::version_parts($b);
|
||||
return self::array_compare_lexi($a_parts, $b_parts);
|
||||
}
|
||||
|
||||
// Compares two arrays lexicographically
|
||||
// This could be extended with a compare function argument
|
||||
public static function array_compare_lexi($a, $b) {
|
||||
$short = count($a) < count($b) ? $a : $b;
|
||||
for ($i = 0; $i < count($short); $i++) {
|
||||
if ($a[$i] > $b[$i]) {
|
||||
return 1;
|
||||
} else if ($a[$i] < $b[$i]) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// strpos with an array of $needles
|
||||
public static function strposa($haystack, $needles, $insensitive = FALSE) {
|
||||
if (is_array($needles)) {
|
||||
foreach ($needles as $str) {
|
||||
if (is_array($str)) {
|
||||
$pos = self::strposa($haystack, $str, $insensitive);
|
||||
} else {
|
||||
$pos = $insensitive ? stripos($haystack, $str) : strpos($haystack, $str);
|
||||
}
|
||||
if ($pos !== FALSE) {
|
||||
return $pos;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
} else {
|
||||
return strpos($haystack, $needles);
|
||||
}
|
||||
}
|
||||
|
||||
// tests if $needle is equal to any strings in $haystack
|
||||
public static function str_equal_array($needle, $haystack, $case_insensitive = TRUE) {
|
||||
if (!is_string($needle) || !is_array($haystack)) {
|
||||
return FALSE;
|
||||
}
|
||||
if ($case_insensitive) {
|
||||
$needle = strtolower($needle);
|
||||
}
|
||||
foreach ($haystack as $hay) {
|
||||
if (!is_string($hay)) {
|
||||
continue;
|
||||
}
|
||||
if ($case_insensitive) {
|
||||
$hay = strtolower($hay);
|
||||
}
|
||||
if ($needle == $hay) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Support for singular and plural string variations
|
||||
public static function spnum($int, $singular, $plural = NULL) {
|
||||
if (!is_int($int) || !is_string($singular)) {
|
||||
$int = intval($int);
|
||||
$singular = strval($singular);
|
||||
}
|
||||
if ($plural == NULL || !is_string($plural)) {
|
||||
$plural = $singular . 's';
|
||||
}
|
||||
return $int . ' ' . (($int == 1) ? $singular : $plural);
|
||||
}
|
||||
|
||||
// Turn boolean into Yes/No
|
||||
public static function bool_yn($bool) {
|
||||
return $bool ? 'Yes' : 'No';
|
||||
}
|
||||
|
||||
// String to boolean, default decides what boolean value to return when not found
|
||||
public static function str_to_bool($str, $default = TRUE) {
|
||||
$str = self::tlower($str);
|
||||
if ($default === FALSE) {
|
||||
if ($str == 'true' || $str == 'yes' || $str == '1') {
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
} else {
|
||||
if ($str == 'false' || $str == 'no' || $str == '0') {
|
||||
return FALSE;
|
||||
} else {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function bool_to_str($bool, $strict = FALSE) {
|
||||
if ($strict) {
|
||||
return $bool === TRUE ? 'true' : 'false';
|
||||
} else {
|
||||
return $bool ? 'true' : 'false';
|
||||
}
|
||||
}
|
||||
|
||||
public static function tlower($str) {
|
||||
return trim(strtolower($str));
|
||||
}
|
||||
|
||||
// Escapes $ and \ from the replacement to avoid becoming a backreference
|
||||
public static function preg_replace_escape_back($pattern, $replacement, $subject, $limit = -1, &$count = 0) {
|
||||
return preg_replace($pattern, self::preg_escape_back($replacement), $subject, $limit, $count);
|
||||
}
|
||||
|
||||
// Escape backreferences from string for use with regex
|
||||
public static function preg_escape_back($string) {
|
||||
// Replace $ with \$ and \ with \\
|
||||
$string = preg_replace('#(\\$|\\\\)#', '\\\\$1', $string);
|
||||
return $string;
|
||||
}
|
||||
|
||||
// Detect if on a Mac or PC
|
||||
public static function is_mac($default = FALSE) {
|
||||
$user = $_SERVER['HTTP_USER_AGENT'];
|
||||
if (stripos($user, 'macintosh') !== FALSE) {
|
||||
return TRUE;
|
||||
} else if (stripos($user, 'windows') !== FALSE || stripos($user, 'linux') !== FALSE) {
|
||||
return FALSE;
|
||||
} else {
|
||||
return $default === TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
// Decodes WP html entities
|
||||
public static function html_entity_decode_wp($str) {
|
||||
if (!is_string($str) || empty($str)) {
|
||||
return $str;
|
||||
}
|
||||
// http://www.ascii.cl/htmlcodes.htm
|
||||
$wp_entities = array('‘', '’', '‚', '“', '”');
|
||||
$wp_replace = array('\'', '\'', ',', '"', '"');
|
||||
$str = str_replace($wp_entities, $wp_replace, $str);
|
||||
return $str;
|
||||
}
|
||||
|
||||
// Constructs an html element
|
||||
// If $content = FALSE, then element is closed
|
||||
public static function html_element($name, $content = NULL, $attributes = array()) {
|
||||
$atts = self::html_attributes($attributes);
|
||||
$tag = "<$name $atts";
|
||||
$tag .= $content === FALSE ? '/>' : ">$content</$name>";
|
||||
return $tag;
|
||||
}
|
||||
|
||||
public static function html_attributes($attributes, $assign = '=', $quote = '"', $glue = ' ') {
|
||||
$atts = '';
|
||||
foreach ($attributes as $k => $v) {
|
||||
$atts .= $k . $assign . $quote . $v . $quote . $glue;
|
||||
}
|
||||
return $atts;
|
||||
}
|
||||
|
||||
// Strips only the given tags in the given HTML string.
|
||||
public static function strip_tags_blacklist($html, $tags) {
|
||||
foreach ($tags as $tag) {
|
||||
$regex = '#<\s*\b' . $tag . '\b[^>]*>.*?<\s*/\s*'. $tag . '\b[^>]*>?#msi';
|
||||
$html = preg_replace($regex, '', $html);
|
||||
}
|
||||
return $html;
|
||||
}
|
||||
|
||||
// Strips the given attributes found in the given HTML string.
|
||||
public static function strip_attributes($html, $atts) {
|
||||
foreach ($atts as $att) {
|
||||
$regex = '#\b' . $att . '\b(\s*=\s*[\'"][^\'"]*[\'"])?(?=[^<]*>)#msi';
|
||||
$html = preg_replace($regex, '', $html);
|
||||
}
|
||||
return $html;
|
||||
}
|
||||
|
||||
// Strips all event attributes on DOM elements (prefixe with "on").
|
||||
public static function strip_event_attributes($html) {
|
||||
$regex = '#\bon\w+\b(\s*=\s*[\'"][^\'"]*[\'"])?(?=[^<]*>)#msi';
|
||||
return preg_replace($regex, '', $html);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
57
util/external_use.php
Normal file
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
require_once ('../global.php');
|
||||
require_once (CRAYON_HIGHLIGHTER_PHP);
|
||||
|
||||
// These will depend on your framework
|
||||
CrayonGlobalSettings::site_url('http://localhost/crayon/wp-content/plugins/crayon-syntax-highlighter/');
|
||||
CrayonGlobalSettings::site_path(dirname(__FILE__));
|
||||
CrayonGlobalSettings::plugin_path('http://localhost/crayon/wp-content/plugins/crayon-syntax-highlighter/');
|
||||
|
||||
// Should be in the header
|
||||
crayon_resources();
|
||||
|
||||
$crayon = new CrayonHighlighter();
|
||||
$crayon->code('some code');
|
||||
$crayon->language('php');
|
||||
$crayon->title('the title');
|
||||
$crayon->marked('1-2');
|
||||
$crayon->is_inline(FALSE);
|
||||
|
||||
// Settings
|
||||
$settings = array(
|
||||
// Just regular settings
|
||||
CrayonSettings::NUMS => FALSE,
|
||||
CrayonSettings::TOOLBAR => TRUE,
|
||||
// Enqueue supported only for WP
|
||||
CrayonSettings::ENQUEUE_THEMES => FALSE,
|
||||
CrayonSettings::ENQUEUE_FONTS => FALSE);
|
||||
$settings = CrayonSettings::smart_settings($settings);
|
||||
$crayon->settings($settings);
|
||||
|
||||
// Print the Crayon
|
||||
$crayon_formatted = $crayon->output(TRUE, FALSE);
|
||||
echo $crayon_formatted;
|
||||
|
||||
// Utility Functions
|
||||
|
||||
function crayon_print_style($id, $url, $version) {
|
||||
echo '<link id="',$id,'" href="',$url,'?v=',$version,'" type="text/css" rel="stylesheet" />',"\n";
|
||||
}
|
||||
|
||||
function crayon_print_script($id, $url, $version) {
|
||||
echo '<script id="',$id,'" src="',$url,'?v=',$version,'" type="text/javascript"></script>',"\n";
|
||||
}
|
||||
|
||||
function crayon_resources() {
|
||||
global $CRAYON_VERSION;
|
||||
$plugin_url = CrayonGlobalSettings::plugin_path();
|
||||
// jQuery only needed once! Don't have two jQuerys, so remove if you've already got one in your header :)
|
||||
crayon_print_script('jquery', 'https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js', $CRAYON_VERSION);
|
||||
crayon_print_style('crayon-style', $plugin_url.CRAYON_STYLE, $CRAYON_VERSION);
|
||||
crayon_print_script('crayon_util_js', $plugin_url.CRAYON_JS_UTIL, $CRAYON_VERSION);
|
||||
crayon_print_script('crayon-js', $plugin_url.CRAYON_JS, $CRAYON_VERSION);
|
||||
crayon_print_script('crayon-jquery-popup', $plugin_url.CRAYON_JQUERY_POPUP, $CRAYON_VERSION);
|
||||
}
|
||||
|
||||
?>
|
11
util/lines_to_array.rb
Normal file
@ -0,0 +1,11 @@
|
||||
#!/usr/bin/env ruby
|
||||
# Converts lines from a file into an array of strings.
|
||||
if ARGV.size == 0
|
||||
puts "lines_to_array.rb <file>"
|
||||
else
|
||||
lines = File.readlines(ARGV[0])
|
||||
lines = lines.map do |line|
|
||||
"'" + line.strip + "'"
|
||||
end
|
||||
puts '[' + lines.join(',') + ']'
|
||||
end
|
11
util/lines_to_regex.rb
Normal file
@ -0,0 +1,11 @@
|
||||
#!/usr/bin/env ruby
|
||||
# Converts lines from a file into an alternation of regex.
|
||||
if ARGV.size == 0
|
||||
puts "lines_to_array.rb <file>"
|
||||
else
|
||||
lines = File.readlines(ARGV[0])
|
||||
lines = lines.map do |line|
|
||||
line.strip
|
||||
end
|
||||
puts '/\\b(' + lines.join('|') + ')\\b/'
|
||||
end
|
17
util/minify.sh
Normal file
@ -0,0 +1,17 @@
|
||||
#!/bin/bash
|
||||
BASEDIR=$(dirname $0)
|
||||
cd $BASEDIR
|
||||
|
||||
MINIFIER='/Users/Aram/Development/Tools/yuicompressor-2.4.7.jar'
|
||||
INPUT_PATH='src'
|
||||
OUTPUT_PATH='min'
|
||||
TE_PATH='../util/tag-editor'
|
||||
COLORBOX_PATH='../util/tag-editor/colorbox'
|
||||
JS_PATH='../js'
|
||||
|
||||
function minify {
|
||||
inputs=${@:0:$#}
|
||||
output=${@:$#}
|
||||
cat $inputs > $output
|
||||
java -jar $MINIFIER $output -o $output
|
||||
}
|
8
util/sample/abap.txt
Normal file
@ -0,0 +1,8 @@
|
||||
* A sample function
|
||||
CALL FUNCTION 'KD_GET_FILENAME_ON_F4'
|
||||
EXPORTING
|
||||
MASK = ',*.txt,*.*'
|
||||
STATIC = 'X'
|
||||
CHANGING
|
||||
FILE_NAME = LV_FILE.
|
||||
|
3
util/sample/apache.txt
Normal file
@ -0,0 +1,3 @@
|
||||
RewriteEngine On
|
||||
RewriteCond %{DOCUMENT_ROOT}/cache%{REQUEST_URI}.html -f
|
||||
RewriteRule ^(.*)$ /cache/$1.html [QSA,L]
|
10
util/sample/applescript.txt
Normal file
@ -0,0 +1,10 @@
|
||||
-- Dialog
|
||||
set dialogReply to display dialog
|
||||
"Dialog Text" default answer
|
||||
"Text Answer" hidden answer false
|
||||
buttons {"Skip", "Okay", "Cancel"}
|
||||
default button
|
||||
"Okay" cancel button
|
||||
"Skip" with title
|
||||
"Dialog Window Title" with icon note
|
||||
giving up after 20
|
12
util/sample/arduino.txt
Normal file
@ -0,0 +1,12 @@
|
||||
#define LED_PIN 13
|
||||
|
||||
void setup () {
|
||||
pinMode (LED_PIN, OUTPUT); // enable pin 13 for digital output
|
||||
}
|
||||
|
||||
void loop () {
|
||||
digitalWrite (LED_PIN, HIGH); // turn on the LED
|
||||
delay (1000); // wait one second (1000 milliseconds)
|
||||
digitalWrite (LED_PIN, LOW); // turn off the LED
|
||||
delay (1000); // wait one second
|
||||
}
|
9
util/sample/as.txt
Normal file
@ -0,0 +1,9 @@
|
||||
class com.example.Greeter extends MovieClip
|
||||
{
|
||||
public function Greeter() {}
|
||||
public function onLoad():Void
|
||||
{
|
||||
var txtHello:TextField = this.createTextField("txtHello", 0, 0, 0, 100, 100);
|
||||
txtHello.text = "Hello, world";
|
||||
}
|
||||
}
|
5
util/sample/asm.txt
Normal file
@ -0,0 +1,5 @@
|
||||
mov eax, [ebx] ; Move the 4 bytes in memory at the address contained in EBX into EAX
|
||||
mov [var], ebx ; Move the contents of EBX into the 4 bytes at memory address var. (Note, var is a 32-bit constant).
|
||||
mov eax, [esi-4] ; Move 4 bytes at memory address ESI + (-4) into EAX
|
||||
mov [esi+eax], cl ; Move the contents of CL into the byte at address ESI+EAX
|
||||
mov edx, [esi+4*ebx] ; Move the 4 bytes of data at address ESI+4*EBX into EDX
|
7
util/sample/asp.txt
Normal file
@ -0,0 +1,7 @@
|
||||
Set FS=Server.CreateObject("Scripting.FileSystemObject")
|
||||
Set RS=FS.OpenTextFile(Server.MapPath("counter.txt"), 1, False)
|
||||
fcount=RS.ReadLine
|
||||
RS.Close
|
||||
fcount=fcount+1
|
||||
Set RS=Nothing
|
||||
Set FS=Nothing
|
11
util/sample/autoit.txt
Normal file
@ -0,0 +1,11 @@
|
||||
;Finds the average of numbers specified by a user.
|
||||
;The numbers must be delimited by commas.
|
||||
#NoTrayIcon
|
||||
#include <GUIConstantsEx.au3>
|
||||
#include <Array.au3>
|
||||
;region---------------GUI-----------------------
|
||||
$form = GUICreate("Average Finder", 300, 100)
|
||||
$label = GUICtrlCreateLabel("Enter the numbers to be averaged separated by commas", 19, 0)
|
||||
$textbox = GUICtrlCreateInput("", 20, 20, 220)
|
||||
GUISetState()
|
||||
;endregion---------------END GUI-----------------------
|
11
util/sample/batch.txt
Normal file
@ -0,0 +1,11 @@
|
||||
if [%3]==[] (
|
||||
goto :usage
|
||||
)
|
||||
if not exist %3 (
|
||||
echo Creating %3 dir...
|
||||
mkdir %3
|
||||
)
|
||||
echo Copying original files to %3 dir...
|
||||
copy %2\* %3 >nul
|
||||
echo Adding background...
|
||||
mogrify -background #%1 -flatten %3\*
|
10
util/sample/c#.txt
Normal file
@ -0,0 +1,10 @@
|
||||
using Functions;
|
||||
class FunctionClient {
|
||||
public static void Main(string[] args) {
|
||||
Console.WriteLine("Function Client");
|
||||
if ( args.Length == 0 ) {
|
||||
Console.WriteLine("Usage: FunctionTest ... ");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
16
util/sample/c++.txt
Normal file
@ -0,0 +1,16 @@
|
||||
#include <fstream.h>
|
||||
|
||||
void main () {
|
||||
ifstream f1;
|
||||
ofstream f2;
|
||||
f1.open("scores.96");
|
||||
f2.open("final.96");
|
||||
|
||||
int s1, s2, s3;
|
||||
float w1, w2, w3;
|
||||
|
||||
f1 >> s1 >> w1;
|
||||
f1 >> s2 >> w2;
|
||||
f1 >> s3 >> w3;
|
||||
f2 << (s1*w1+s2*w2+s3*w3);
|
||||
}
|
9
util/sample/c.txt
Normal file
@ -0,0 +1,9 @@
|
||||
#include <stdio.h>
|
||||
int main(void) {
|
||||
int x;
|
||||
x = 0;
|
||||
// Uses a pointer
|
||||
set(&x, 42);
|
||||
printf("%d %d", x);
|
||||
return 0;
|
||||
}
|
5
util/sample/clojure.txt
Normal file
@ -0,0 +1,5 @@
|
||||
(defn keyword-params-request
|
||||
"Converts string keys in :params map to keywords. See: wrap-keyword-params."
|
||||
{:added "1.2"}
|
||||
[request]
|
||||
(update-in request [:params] keyify-params))
|
14
util/sample/coffee.txt
Normal file
@ -0,0 +1,14 @@
|
||||
# Example Script
|
||||
|
||||
class Animal
|
||||
constructor: (@name) ->
|
||||
|
||||
move: (meters) ->
|
||||
alert @name + " moved #{meters}m."
|
||||
alert @name.foo
|
||||
alert this.name
|
||||
|
||||
class Snake extends Animal
|
||||
move: ->
|
||||
alert "Slithering..."
|
||||
super 5
|
12
util/sample/css.txt
Normal file
@ -0,0 +1,12 @@
|
||||
@import url('fonts/monaco/monaco.css');
|
||||
|
||||
/* General ========================= */
|
||||
.crayon-syntax {
|
||||
overflow: hidden !important;
|
||||
position: relative !important;
|
||||
}
|
||||
|
||||
.crayon-syntax .crayon-toolbar {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
8
util/sample/default.txt
Normal file
@ -0,0 +1,8 @@
|
||||
// A sample class
|
||||
class Human {
|
||||
private int age = 0;
|
||||
public void birthday() {
|
||||
age++;
|
||||
print('Happy Birthday!');
|
||||
}
|
||||
}
|
9
util/sample/delphi.txt
Normal file
@ -0,0 +1,9 @@
|
||||
type
|
||||
THelloWorld = class
|
||||
procedure Put;
|
||||
end;
|
||||
|
||||
procedure THelloWorld.Put;
|
||||
begin
|
||||
Writeln('Hello, World!');
|
||||
end;
|
9
util/sample/diff.txt
Normal file
@ -0,0 +1,9 @@
|
||||
*** testing ***
|
||||
It is important to spell
|
||||
--- testing ---
|
||||
-check this dokument. On
|
||||
+check this document. On
|
||||
the other hand, a
|
||||
! misspelled word isn't
|
||||
the end of the world.
|
||||
@@ -22,3 +22,7 @@
|
13
util/sample/dws.txt
Normal file
@ -0,0 +1,13 @@
|
||||
type
|
||||
THelloWorld = class
|
||||
procedure Put; // you can also implement out of line
|
||||
begin
|
||||
PrintLn('Hello, World!');
|
||||
end
|
||||
end;
|
||||
|
||||
var HelloWorld := new THelloWorld; // strong typing, inferred
|
||||
|
||||
HelloWorld.Put;
|
||||
|
||||
// no need to release objects thanks to automatic memory management
|
12
util/sample/erlang.txt
Normal file
@ -0,0 +1,12 @@
|
||||
%% qsort:qsort(List)
|
||||
%% Sort a list of items
|
||||
-module(qsort). % This is the file 'qsort.erl'
|
||||
-export([qsort/1]). % A function 'qsort' with 1 parameter is exported (no type, no name)
|
||||
|
||||
qsort([]) -> []; % If the list [] is empty, return an empty list (nothing to sort)
|
||||
qsort([Pivot|Rest]) ->
|
||||
% Compose recursively a list with 'Front' for all elements that should be before 'Pivot'
|
||||
% then 'Pivot' then 'Back' for all elements that should be after 'Pivot'
|
||||
qsort([Front || Front <- Rest, Front < Pivot])
|
||||
++ [Pivot] ++
|
||||
qsort([Back || Back <- Rest, Back >= Pivot]).
|
11
util/sample/go.txt
Normal file
@ -0,0 +1,11 @@
|
||||
package geometry
|
||||
import "math"
|
||||
// Test functions
|
||||
func add(a, b int) int { return a + b }
|
||||
func (self *Point) Scale(factor float64) {
|
||||
self.setX(self.x * factor)
|
||||
self.setY(self.y * factor)
|
||||
}
|
||||
type Writer interface {
|
||||
Write(p []byte) (n int, err os.Error)
|
||||
}
|
23
util/sample/haskell.txt
Normal file
@ -0,0 +1,23 @@
|
||||
module Interpret(interpret) where
|
||||
|
||||
import Prog
|
||||
|
||||
import System.IO.Unsafe
|
||||
import Control.Monad
|
||||
import Char
|
||||
|
||||
-- In a call to this function such as "interpret prog vars entry debug":
|
||||
-- prog is the ABCD program to be interpreted;
|
||||
-- vars represents the initial values of the four variables;
|
||||
-- entry is the name of the entry point function, "main" by default; and
|
||||
-- debug specifies whether the user wants debugging output.
|
||||
|
||||
interpret :: Prog -> Vars -> String -> MaybeDebug -> IO ()
|
||||
interpret prog vars entry debug = do
|
||||
let context = Context prog vars entry debug 0
|
||||
let newContext = runFunc entry context
|
||||
let output =
|
||||
case newContext of
|
||||
IError s -> "abcdi: " ++ s
|
||||
IOK c -> (strVal (getVar A (cVars c))) ++ "\n"
|
||||
putStrLn output
|
10
util/sample/ilogic.txt
Normal file
@ -0,0 +1,10 @@
|
||||
Dim map As Inventor.NameValueMap = ThisApplication.TransientObjects.CreateNameValueMap()
|
||||
map.Add("Arg1", "Arg1Value")
|
||||
iLogicVb.RunRule("ruleName", map)
|
||||
iLogicVb.RunRule("PartA:1", "ruleName")
|
||||
InventorVb.RunMacro("projectName", "moduleName", "macroName")
|
||||
AddVbRule "RuleName"
|
||||
AddReference "fileName.dll"
|
||||
AddVbFile "fileName.vb"
|
||||
AddResources "fileName.resources"
|
||||
arg1Value = RuleArguments("Arg1")
|
10
util/sample/ini.txt
Normal file
@ -0,0 +1,10 @@
|
||||
; last modified 1 April 2001 by John Doe
|
||||
[owner]
|
||||
name=John Doe
|
||||
organization=Acme Widgets Inc.
|
||||
|
||||
[database]
|
||||
; use IP address in case network name resolution is not working
|
||||
server=192.0.2.62
|
||||
port=143
|
||||
file="payroll.dat"
|
8
util/sample/java.txt
Normal file
@ -0,0 +1,8 @@
|
||||
// A sample class
|
||||
class Human extends Mammal implements Humanoid {
|
||||
private int age = 0;
|
||||
public void birthday() {
|
||||
age++;
|
||||
System.out.println('Happy Birthday!');
|
||||
}
|
||||
}
|
12
util/sample/js.txt
Normal file
@ -0,0 +1,12 @@
|
||||
// Convert '-10px' to -10
|
||||
function px_to_int(pixels) {
|
||||
if (typeof pixels != 'string') {
|
||||
return 0;
|
||||
}
|
||||
var result = pixels.replace(/[^-0-9]/g, '');
|
||||
if (result.length == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return parseInt(result);
|
||||
}
|
||||
}
|
18
util/sample/kl.txt
Normal file
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Swirley Movement OP KL Example
|
||||
*/
|
||||
|
||||
require Math;
|
||||
|
||||
operator swirleyMovementOp(
|
||||
Scalar seconds,
|
||||
Index id,
|
||||
Xfo baseXfo,
|
||||
io Xfo xfo
|
||||
) {
|
||||
xfo.tr = baseXfo.tr + Vec3(sin((seconds * 2.3) + (id * 3.2)) * 3.0, cos(seconds * 4.30) * 3.0, 0.0);
|
||||
|
||||
// The following line will log a message to the console...
|
||||
// report("swirleyMovementOp :" + xfo.tr);
|
||||
}
|
||||
|
13
util/sample/less.txt
Normal file
@ -0,0 +1,13 @@
|
||||
@import "lib.css";
|
||||
@the-border: 1px;
|
||||
@base-color: #111;
|
||||
@red: #842210;
|
||||
#header {
|
||||
color: (@base-color * 3);
|
||||
border-left: @the-border;
|
||||
border-right: (@the-border * 2);
|
||||
}
|
||||
#footer {
|
||||
color: (@base-color + #003300);
|
||||
border-color: desaturate(@red, 10%);
|
||||
}
|
12
util/sample/lisp.txt
Normal file
@ -0,0 +1,12 @@
|
||||
;Coding starts here
|
||||
(defun c:lg ( / x_object x_length)
|
||||
(vl-load-com)
|
||||
(setq x_object (entsel))
|
||||
(setq x_object (vlax-Ename->Vla-Object (car x_object)))
|
||||
(setq x_length (vlax-curve-getdistatparam x_object
|
||||
(vlax-curve-getendparam x_object )))
|
||||
(alert (strcat "Length = " (rtos x_length)))
|
||||
(princ)
|
||||
);defun
|
||||
(princ)
|
||||
;Coding ends here
|
7
util/sample/lua.txt
Normal file
@ -0,0 +1,7 @@
|
||||
fibs = { 1, 1 } -- Initial values for fibs[1] and fibs[2].
|
||||
setmetatable(fibs, {
|
||||
__index = function(name, n) -- Call this function if fibs[n] does not exist.
|
||||
name[n] = name[n - 1] + name[n - 2] -- Calculate and memoize fibs[n].
|
||||
return name[n]
|
||||
end
|
||||
})
|
9
util/sample/matlab.txt
Normal file
@ -0,0 +1,9 @@
|
||||
clear
|
||||
N = input('Give numerator: ');
|
||||
D = input('Give denominator: ');
|
||||
|
||||
if D==0
|
||||
'Sorry, cannot divide by zero'
|
||||
else
|
||||
ratio = N/D
|
||||
end
|
24
util/sample/mel.txt
Normal file
@ -0,0 +1,24 @@
|
||||
// Code starts here
|
||||
global proc human(int $age){
|
||||
string $ageExt;
|
||||
$age++;
|
||||
|
||||
if($age == 0){
|
||||
$ageExt = "th";
|
||||
}else if($age == 1){
|
||||
$ageExt = "st";
|
||||
}else if($age == 2){
|
||||
$ageExt = "nd";
|
||||
}else{
|
||||
$ageExt = "th";
|
||||
}
|
||||
|
||||
print("Happy " + $age + $ageExt + " Birthday!\n");
|
||||
}
|
||||
|
||||
|
||||
int $i=0;
|
||||
for($i=0;$i<=99;$i+=1){
|
||||
human($i);
|
||||
}
|
||||
|
8
util/sample/monkey.txt
Normal file
@ -0,0 +1,8 @@
|
||||
Class GameApp Extends App
|
||||
Field player:Player
|
||||
Method OnCreate:Int()
|
||||
local img:Image = LoadImage("player.png")
|
||||
player = New Player(img, 100, 100)
|
||||
SetUpdateRate 60
|
||||
End
|
||||
End
|
8
util/sample/mysql.txt
Normal file
@ -0,0 +1,8 @@
|
||||
CREATE TABLE shop (
|
||||
article INT(4) UNSIGNED ZEROFILL DEFAULT '0000' NOT NULL,
|
||||
dealer CHAR(20) DEFAULT '' NOT NULL,
|
||||
price DOUBLE(16,2) DEFAULT '0.00' NOT NULL,
|
||||
PRIMARY KEY(article, dealer));
|
||||
INSERT INTO shop VALUES
|
||||
(1,'A',3.45),(1,'B',3.99),(2,'A',10.99),(3,'B',1.45),
|
||||
(3,'C',1.69),(3,'D',1.25),(4,'D',19.95);
|
8
util/sample/objc.txt
Normal file
@ -0,0 +1,8 @@
|
||||
#import <objc/Object.h>
|
||||
@interface Forwarder : Object {
|
||||
id recipient; // The object we want to forward the message to.
|
||||
}
|
||||
// Accessor methods.
|
||||
- (id) recipient;
|
||||
- (id) setRecipient:(id)_recipient;
|
||||
@end
|
14
util/sample/perl.txt
Normal file
@ -0,0 +1,14 @@
|
||||
while (<STDIN>) {
|
||||
$oldStr = $_;
|
||||
foreach $k (keys %dic) {
|
||||
s/$k/$dic{$k}/g;
|
||||
}
|
||||
|
||||
$newStr = $_;
|
||||
if ($oldStr ne $newStr) {
|
||||
print STDERR "\n";
|
||||
print STDERR "old>>$oldStr";
|
||||
print STDERR "new>>$newStr";
|
||||
}
|
||||
print;
|
||||
}
|
8
util/sample/pgsql.txt
Normal file
@ -0,0 +1,8 @@
|
||||
CREATE TABLE arr(f1 int[], f2 int[]);
|
||||
INSERT INTO arr VALUES (ARRAY[[1,2],[3,4]], ARRAY[[5,6],[7,8]]);
|
||||
SELECT ARRAY[f1, f2, '{{9,10},{11,12}}'::int[]] FROM arr;
|
||||
array_prepend(1, ARRAY[2,3])
|
||||
SELECT ROW(table.*) IS NULL FROM table; -- detect all-null rows
|
||||
SELECT getf1(CAST(ROW(11,'this is a test',2.5) AS myrowtype));
|
||||
|
||||
CHARACTER VARYING
|
10
util/sample/php.txt
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
// A sample class
|
||||
class Human {
|
||||
$age = 0;
|
||||
function birthday() {
|
||||
$age++;
|
||||
echo 'Happy Birthday!';
|
||||
}
|
||||
}
|
||||
?>
|
11
util/sample/plsql.txt
Normal file
@ -0,0 +1,11 @@
|
||||
DECLARE
|
||||
number1 NUMBER(2);
|
||||
number2 number1%TYPE := 17; -- value default
|
||||
text1 VARCHAR2(12) := 'Hello world';
|
||||
text2 DATE := SYSDATE; -- current date and time
|
||||
BEGIN
|
||||
SELECT street_number
|
||||
INTO number1
|
||||
FROM address
|
||||
WHERE name = 'INU';
|
||||
END;
|
2
util/sample/ps.txt
Normal file
@ -0,0 +1,2 @@
|
||||
# Find the processes that use more than 1000 MB of memory and kill them
|
||||
Get-Process | Where-Object { $_.WS -gt 1000MB } | Stop-Process
|
9
util/sample/python.txt
Normal file
@ -0,0 +1,9 @@
|
||||
# Merge example
|
||||
def mergeWithoutOverlap(oneDict, otherDict):
|
||||
newDict = oneDict.copy()
|
||||
for key in otherDict.keys():
|
||||
if key in oneDict.keys():
|
||||
raise ValueError, "the two dictionaries are sharing keys!"
|
||||
newDict[key] = otherDict[key]
|
||||
return newDict
|
||||
|
14
util/sample/r.txt
Normal file
@ -0,0 +1,14 @@
|
||||
library(caTools) # external package providing write.gif function
|
||||
jet.colors <- colorRampPalette(c("#00007F", "blue", "#007FFF", "cyan", "#7FFF7F",
|
||||
"yellow", "#FF7F00", "red", "#7F0000"))
|
||||
m <- 1200 # define size
|
||||
C <- complex( real=rep(seq(-1.8,0.6, length.out=m), each=m ),
|
||||
imag=rep(seq(-1.2,1.2, length.out=m), m ) )
|
||||
C <- matrix(C,m,m) # reshape as square matrix of complex numbers
|
||||
Z <- 0 # initialize Z to zero
|
||||
X <- array(0, c(m,m,20)) # initialize output 3D array
|
||||
for (k in 1:20) { # loop with 20 iterations
|
||||
Z <- Z^2+C # the central difference equation
|
||||
X[,,k] <- exp(-abs(Z)) # capture results
|
||||
}
|
||||
write.gif(X, "Mandelbrot.gif", col=jet.colors, delay=100)
|
7
util/sample/reg.txt
Normal file
@ -0,0 +1,7 @@
|
||||
Windows Registry Editor Version 5.00
|
||||
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft]
|
||||
"Value A"="<String value data>"
|
||||
"Value B"=hex:<Binary data (as comma-delimited list of hexadecimal values)>
|
||||
"Value C"=dword:<DWORD value integer>
|
||||
"Value D"=hex(7):<Multi-string value data (as comma-delimited list of hexadecimal values)>
|
||||
"Value E"=hex(2):<Expandable string value data (as comma-delimited list of hexadecimal values)>
|
9
util/sample/ruby.txt
Normal file
@ -0,0 +1,9 @@
|
||||
# 'w' denotes "write mode".
|
||||
File.open('file.txt', 'w') do |file|
|
||||
file.puts 'Wrote some text.'
|
||||
end # File is automatically closed here
|
||||
|
||||
File.readlines('file.txt').each do |line|
|
||||
puts line
|
||||
end
|
||||
# => Wrote some text.
|
8
util/sample/rust.txt
Normal file
@ -0,0 +1,8 @@
|
||||
/* The branches in this function exhibit Rust's optional implicit return
|
||||
values, which can be utilized where a more "functional" style is preferred.
|
||||
Unlike C++ and related languages, Rust's `if` construct is an expression
|
||||
rather than a statement, and thus has a return value of its own. */
|
||||
fn recursive_factorial(n: int) -> int {
|
||||
if n <= 1 { 1 }
|
||||
else { n * recursive_factorial(n-1) }
|
||||
}
|
11
util/sample/sass.txt
Normal file
@ -0,0 +1,11 @@
|
||||
@mixin adjust-location($x, $y) {
|
||||
@if unitless($x) {
|
||||
@warn "Assuming #{$x} to be in pixels";
|
||||
$x: 1px * $x;
|
||||
}
|
||||
@if unitless($y) {
|
||||
@warn "Assuming #{$y} to be in pixels";
|
||||
$y: 1px * $y;
|
||||
}
|
||||
position: relative; left: $x; top: $y;
|
||||
}
|
15
util/sample/scala.txt
Normal file
@ -0,0 +1,15 @@
|
||||
// A sample class
|
||||
object Newton extends App {
|
||||
|
||||
def EPS = 1e-5
|
||||
|
||||
def sqrt(x: Double): Double = {
|
||||
def loop(y: Double): Double =
|
||||
if (math.abs(y * y - x) > EPS) loop(((x / y) + y) / 2.0)
|
||||
else y
|
||||
|
||||
loop(1.0)
|
||||
}
|
||||
|
||||
println(sqrt(2.0)) // 1.41
|
||||
}
|
6
util/sample/scheme.txt
Normal file
@ -0,0 +1,6 @@
|
||||
(define var "goose")
|
||||
;; Any reference to var here will be bound to "goose"
|
||||
(let* ((var1 10)
|
||||
(var2 (+ var1 12)))
|
||||
;; But the definition of var1 could not refer to var2
|
||||
)
|
12
util/sample/sh.txt
Normal file
@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
for jpg in "$@" ; do
|
||||
png="${jpg%.jpg}.png"
|
||||
echo converting "$jpg" ...
|
||||
if convert "$jpg" jpg.to.png ; then
|
||||
mv jpg.to.png "$png"
|
||||
else
|
||||
echo 'error: failed output saved in "jpg.to.png".' 1>&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
echo all conversions successful
|
7
util/sample/swift.txt
Normal file
@ -0,0 +1,7 @@
|
||||
class Human {
|
||||
var age = 0
|
||||
func birthday() {
|
||||
age++;
|
||||
println('Happy Birthday!');
|
||||
}
|
||||
}
|
5
util/sample/tex.txt
Normal file
@ -0,0 +1,5 @@
|
||||
\begin{document}
|
||||
\hello % Here a comment
|
||||
% Here a comment from line beginning
|
||||
|
||||
10\% is not a comment.
|
4
util/sample/tsql.txt
Normal file
@ -0,0 +1,4 @@
|
||||
IF DATEPART(dw, GETDATE()) = 7 OR DATEPART(dw, GETDATE()) = 1
|
||||
PRINT 'It is the weekend.'
|
||||
ELSE
|
||||
PRINT 'It is a weekday.'
|
10
util/sample/vb.txt
Normal file
@ -0,0 +1,10 @@
|
||||
Option Explicit
|
||||
Dim Count As Integer
|
||||
Private Sub Form_Load()
|
||||
Count = 0
|
||||
Timer1.Interval = 1000 ' units of milliseconds
|
||||
End Sub
|
||||
Private Sub Timer1_Timer()
|
||||
Count = Count + 1
|
||||
lblCount.Caption = Count
|
||||
End Sub
|
8
util/sample/vbnet.txt
Normal file
@ -0,0 +1,8 @@
|
||||
Imports System
|
||||
Module Module1
|
||||
'This program will display Hello World
|
||||
Sub Main()
|
||||
Console.WriteLine("Hello World")
|
||||
Console.ReadKey()
|
||||
End Sub
|
||||
End Module
|
12
util/sample/vim.txt
Normal file
@ -0,0 +1,12 @@
|
||||
"Toggle word checking on or off...
|
||||
function! WordCheck ()
|
||||
"Toggle the flag (or set it if it doesn't yet exist)...
|
||||
let w:check_words = exists('w:check_words') ? !w:check_words : 1
|
||||
|
||||
"Turn match mechanism on/off, according to new state of flag...
|
||||
if w:check_words
|
||||
exec s:words_matcher
|
||||
else
|
||||
match none
|
||||
endif
|
||||
endfunction
|
12
util/sample/xhtml.txt
Normal file
@ -0,0 +1,12 @@
|
||||
<body onload="loadpdf()">
|
||||
<p>This is an example of an
|
||||
<abbr title="Extensible HyperText Markup Language">XHTML</abbr> 1.0 Strict document.<br />
|
||||
<img id="validation-icon" src="http://www.w3.org/Icons/valid-xhtml10" alt="Valid XHTML 1.0 Strict" /><br />
|
||||
<object id="pdf-object"
|
||||
name="pdf-object"
|
||||
type="application/pdf"
|
||||
data="http://www.w3.org/TR/xhtml1/xhtml1.pdf"
|
||||
width="100%"
|
||||
height="500">
|
||||
</object>
|
||||
</p>
|
7
util/sample/yaml.txt
Normal file
@ -0,0 +1,7 @@
|
||||
---
|
||||
receipt: Oz-Ware Purchase Invoice
|
||||
date: 2007-08-06
|
||||
customer:
|
||||
given: "Dorothy"
|
||||
family: Gale
|
||||
...
|
20
util/sample/zsh.txt
Normal file
@ -0,0 +1,20 @@
|
||||
parse_options()
|
||||
{
|
||||
o_port=(-p 9999)
|
||||
o_root=(-r WWW)
|
||||
o_log=(-d ZWS.log)
|
||||
|
||||
zparseopts -K -- p:=o_port r:=o_root l:=o_log h=o_help
|
||||
if [[ $? != 0 || "$o_help" != "" ]]; then
|
||||
echo Usage: $(basename "$0") "[-p PORT] [-r DIRECTORY]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
port=$o_port[2]
|
||||
root=$o_root[2]
|
||||
log=$o_log[2]
|
||||
|
||||
if [[ $root[1] != '/' ]]; then root="$PWD/$root"; fi
|
||||
}
|
||||
# now use the function:
|
||||
parse_options $*
|
21
util/scraper/file_concat.py
Normal file
@ -0,0 +1,21 @@
|
||||
import sys
|
||||
|
||||
'''
|
||||
Concatenates all arguments together, assuming they are files, into the last argument file.
|
||||
'''
|
||||
|
||||
if len(sys.argv) < 4:
|
||||
print "Usage: file_concat.py <inputfile1>, <inputfile2>, ... <outputfile>"
|
||||
exit()
|
||||
else:
|
||||
ins = sys.argv[1:-1]
|
||||
out = sys.argv[-1]
|
||||
outfile = open(out, 'w')
|
||||
|
||||
all_lines = []
|
||||
for i in ins:
|
||||
f = open(i, 'r')
|
||||
lines = [x.strip() for x in f.readlines()]
|
||||
all_lines += lines
|
||||
|
||||
outfile.write('\n'.join(all_lines))
|
26
util/scraper/keyword_join.py
Normal file
@ -0,0 +1,26 @@
|
||||
import sys
|
||||
import keyword_scraper
|
||||
|
||||
'''
|
||||
Invokes keyword_scraper to sort a file of keywords
|
||||
|
||||
Example:
|
||||
|
||||
$ python keyword_scraper_tool.py geshi_lang_file.php somedir
|
||||
'''
|
||||
|
||||
if len(sys.argv) < 2:
|
||||
print "Usage: keyword_scraper_tool <inputfile> <outputfile>"
|
||||
exit()
|
||||
else:
|
||||
infile_ = sys.argv[1]
|
||||
outfile_ = sys.argv[2] if len(sys.argv) >= 3 else None
|
||||
|
||||
infile = open(infile_, 'r')
|
||||
keywords = [x.strip() for x in infile.readlines()]
|
||||
keywords.sort(keyword_scraper.cmp_keywords)
|
||||
|
||||
if outfile_:
|
||||
outfile = open(outfile_, 'w')
|
||||
outfile.write('\n'.join(keywords))
|
||||
|
73
util/scraper/keyword_scraper.py
Normal file
@ -0,0 +1,73 @@
|
||||
import re
|
||||
import os
|
||||
|
||||
def cmp_keywords(x,y):
|
||||
'''
|
||||
Sorts keywords by length, and then alphabetically
|
||||
'''
|
||||
if len(x) < len(y):
|
||||
return 1
|
||||
elif len(x) == len(y):
|
||||
# Sort alphabetically
|
||||
if x == y:
|
||||
return 0
|
||||
elif x < y:
|
||||
return -1
|
||||
else:
|
||||
return 1
|
||||
else:
|
||||
return -1
|
||||
|
||||
def keywords(infile, outdir):
|
||||
'''
|
||||
Scrapes comma separated keywords out of a file and sorts them in descending order of length.
|
||||
It is assumed a keyword is surrounded in quotes ('' or ""), are grouped by commas and separated by line breaks.
|
||||
The output is then printed and each group is written in text files in the given directory
|
||||
|
||||
An example use case for this is scraping keywords out of GeSHi language files:
|
||||
|
||||
>>> keywords('geshi_lang_file.php', 'somedir')
|
||||
|
||||
'''
|
||||
if outdir and not os.path.exists(outdir):
|
||||
os.makedirs(outdir)
|
||||
|
||||
f = open(infile, 'r')
|
||||
fs = f.read()
|
||||
fs = re.sub(r"(//.*?[\r\n])|(/\*.*?\*/)", '', fs)
|
||||
|
||||
matches = re.findall(r"(?:(?:'[^']+'|\"[^\"]+\")(?:[ \t]*[\r\n]?[ \t]*,[ \t]*[\r\n]?[ \t]*)?(?!\s*=>)){2,}", fs, flags=re.I | re.M | re.S)
|
||||
output = ''
|
||||
group = 0
|
||||
for i in matches:
|
||||
match = re.findall(r"'([^']+)'", i, flags=re.I | re.M | re.S)
|
||||
match.sort(cmp=cmp_keywords)
|
||||
suboutput = ''
|
||||
for m in match:
|
||||
m = m.strip()
|
||||
if len(m) > 0:
|
||||
suboutput += m + '\n'
|
||||
suboutput += '\n'
|
||||
if outdir:
|
||||
w = open(outdir + '/' + str(group) + '.txt' , 'w')
|
||||
w.write(suboutput)
|
||||
output += suboutput
|
||||
group += 1;
|
||||
|
||||
print output
|
||||
|
||||
exit()
|
||||
matches = re.findall(r"(['\"])(.*?)\1", fs, re.I | re.M | re.S)
|
||||
output = ''
|
||||
if len(matches):
|
||||
for m in matches:
|
||||
s = m[1].strip()
|
||||
if len(s) > 0:
|
||||
output += s + '\n'
|
||||
f.close()
|
||||
print output
|
||||
if w:
|
||||
w.write(output)
|
||||
w.close()
|
||||
|
||||
|
18
util/scraper/keyword_scraper_tool.py
Normal file
@ -0,0 +1,18 @@
|
||||
import sys
|
||||
import keyword_scraper
|
||||
|
||||
'''
|
||||
Invokes keyword_scraper over command line
|
||||
|
||||
Example:
|
||||
|
||||
$ python keyword_scraper_tool.py geshi_lang_file.php somedir
|
||||
'''
|
||||
|
||||
if len(sys.argv) < 2:
|
||||
print "Usage: keyword_scraper_tool <inputfile> [directory]"
|
||||
exit()
|
||||
else:
|
||||
infile = sys.argv[1]
|
||||
outdir = sys.argv[2] if len(sys.argv) >= 3 else None
|
||||
keyword_scraper.keywords(infile, outdir)
|
1
util/scraper/readme.txt
Normal file
@ -0,0 +1 @@
|
||||
I created this to help scrape keywords out of text files. Mostly I use it to scrape GeSHi language files and remove the bits I need.
|
48
util/settings_list.txt
Normal file
@ -0,0 +1,48 @@
|
||||
theme
|
||||
font
|
||||
font-size-enable
|
||||
font-size
|
||||
preview
|
||||
height-set
|
||||
height-mode
|
||||
height
|
||||
height-unit
|
||||
width-set
|
||||
width-mode
|
||||
width
|
||||
width-unit
|
||||
top-set
|
||||
top-margin
|
||||
left-set
|
||||
left-margin
|
||||
bottom-set
|
||||
bottom-margin
|
||||
right-set
|
||||
right-margin
|
||||
h-align
|
||||
float-enable
|
||||
toolbar
|
||||
toolbar-overlay
|
||||
toolbar-hide
|
||||
toolbar-delay
|
||||
show-lang
|
||||
show-title
|
||||
striped
|
||||
marking
|
||||
nums
|
||||
nums-toggle
|
||||
trim-whitespace
|
||||
tab-size
|
||||
fallback-lang
|
||||
local-path
|
||||
scroll
|
||||
plain
|
||||
show-plain
|
||||
runtime
|
||||
exp-scroll
|
||||
touchscreen
|
||||
disable-anim
|
||||
error-log
|
||||
error-log-sys
|
||||
error-msg-show
|
||||
error-msg
|
145
util/tag-editor/colorbox/colorbox.css
Normal file
@ -0,0 +1,145 @@
|
||||
/*
|
||||
Colorbox Core Style:
|
||||
The following CSS is consistent between example themes and should not be altered.
|
||||
*/
|
||||
#colorbox.crayon-colorbox, #cboxOverlay.crayon-colorbox, .crayon-colorbox #cboxWrapper {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 9999;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#cboxOverlay.crayon-colorbox {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.crayon-colorbox #cboxMiddleLeft, .crayon-colorbox #cboxBottomLeft {
|
||||
clear: left;
|
||||
}
|
||||
|
||||
.crayon-colorbox #cboxContent {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.crayon-colorbox #cboxLoadedContent {
|
||||
overflow: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
.crayon-colorbox #cboxTitle {
|
||||
/* Fixes overlay issue preventing tag editor controls from being selected */
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.crayon-colorbox #cboxLoadingOverlay, .crayon-colorbox #cboxLoadingGraphic {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.crayon-colorbox #cboxPrevious, .crayon-colorbox #cboxNext, .crayon-colorbox #cboxClose, .crayon-colorbox #cboxSlideshow {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.crayon-colorbox .cboxPhoto {
|
||||
float: left;
|
||||
margin: auto;
|
||||
border: 0;
|
||||
display: block;
|
||||
max-width: none;
|
||||
-ms-interpolation-mode: bicubic;
|
||||
}
|
||||
|
||||
.crayon-colorbox .cboxIframe {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: block;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
#colorbox.crayon-colorbox, .crayon-colorbox #cboxContent, .crayon-colorbox #cboxLoadedContent {
|
||||
box-sizing: content-box;
|
||||
-moz-box-sizing: content-box;
|
||||
-webkit-box-sizing: content-box;
|
||||
}
|
||||
|
||||
/*
|
||||
User Style:
|
||||
Change the following styles to modify the appearance of Colorbox. They are
|
||||
ordered & tabbed in a way that represents the nesting of the generated HTML.
|
||||
*/
|
||||
#cboxOverlay.crayon-colorbox {
|
||||
background: #000;
|
||||
}
|
||||
|
||||
#colorbox.crayon-colorbox {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.crayon-colorbox #cboxContent {
|
||||
margin-top: 20px;
|
||||
background: #000;
|
||||
}
|
||||
|
||||
.crayon-colorbox .cboxIframe {
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.crayon-colorbox #cboxError {
|
||||
padding: 50px;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
.crayon-colorbox #cboxLoadedContent {
|
||||
border: 5px solid #000;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.crayon-colorbox #cboxTitle {
|
||||
position: absolute;
|
||||
top: -20px;
|
||||
left: 0;
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
.crayon-colorbox #cboxCurrent {
|
||||
position: absolute;
|
||||
top: -20px;
|
||||
right: 0px;
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
/* these elements are buttons, and may need to have additional styles reset to avoid unwanted base styles */
|
||||
.crayon-colorbox #cboxPrevious, .crayon-colorbox #cboxNext, .crayon-colorbox #cboxSlideshow, .crayon-colorbox #cboxClose {
|
||||
border: 0;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
overflow: visible;
|
||||
width: auto;
|
||||
background: none;
|
||||
}
|
||||
|
||||
/* avoid outlines on :active (mouseclick), but preserve outlines on :focus (tabbed navigating) */
|
||||
.crayon-colorbox #cboxPrevious:active, .crayon-colorbox #cboxNext:active, .crayon-colorbox #cboxSlideshow:active, .crayon-colorbox #cboxClose:active {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.crayon-colorbox #cboxSlideshow {
|
||||
position: absolute;
|
||||
top: -20px;
|
||||
right: 90px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.crayon-colorbox #cboxContent {
|
||||
margin-top: 0
|
||||
}
|
||||
|
||||
.crayon-colorbox #cboxLoadedContent {
|
||||
border: 0
|
||||
}
|
7
util/tag-editor/colorbox/jquery.colorbox-min.js
vendored
Normal file
51
util/tag-editor/crayon_qt.js
Normal file
@ -0,0 +1,51 @@
|
||||
(function ($) {
|
||||
|
||||
var settings = CrayonTagEditorSettings;
|
||||
|
||||
window.CrayonQuickTags = new function () {
|
||||
|
||||
var base = this;
|
||||
|
||||
base.init = function () {
|
||||
base.sel = '*[id*="crayon_quicktag"],*[class*="crayon_quicktag"]';
|
||||
var buttonText = settings.quicktag_text;
|
||||
buttonText = buttonText !== undefined ? buttonText : 'crayon';
|
||||
QTags.addButton('crayon_quicktag', buttonText, function () {
|
||||
CrayonTagEditor.showDialog({
|
||||
insert: function (shortcode) {
|
||||
QTags.insertContent(shortcode);
|
||||
},
|
||||
select: base.getSelectedText,
|
||||
editor_str: 'html',
|
||||
output: 'encode'
|
||||
});
|
||||
$(base.sel).removeClass('qt_crayon_highlight');
|
||||
});
|
||||
var qt_crayon;
|
||||
var find_qt_crayon = setInterval(function () {
|
||||
qt_crayon = $(base.sel).first();
|
||||
if (typeof qt_crayon != 'undefined') {
|
||||
CrayonTagEditor.bind(base.sel);
|
||||
clearInterval(find_qt_crayon);
|
||||
}
|
||||
}, 100);
|
||||
};
|
||||
|
||||
base.getSelectedText = function () {
|
||||
if (QTags.instances.length == 0) {
|
||||
return null;
|
||||
} else {
|
||||
var qt = QTags.instances[0];
|
||||
var startPos = qt.canvas.selectionStart;
|
||||
var endPos = qt.canvas.selectionEnd;
|
||||
return qt.canvas.value.substring(startPos, endPos);
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
$(document).ready(function () {
|
||||
CrayonQuickTags.init();
|
||||
});
|
||||
|
||||
})(jQueryCrayon);
|
631
util/tag-editor/crayon_tag_editor.js
Normal file
@ -0,0 +1,631 @@
|
||||
(function ($) {
|
||||
|
||||
window.CrayonTagEditor = new function () {
|
||||
var base = this;
|
||||
|
||||
var isInit = false;
|
||||
var loaded = false;
|
||||
var editing = false;
|
||||
var insertCallback, editCallback, showCallback, hideCallback, selectCallback;
|
||||
// Used for encoding, decoding
|
||||
var inputHTML, outputHTML, editor_name, ajax_class_timer;
|
||||
var ajax_class_timer_count = 0;
|
||||
|
||||
var code_refresh, url_refresh;
|
||||
|
||||
// Current $ obj of pre node
|
||||
var currCrayon = null;
|
||||
// Classes from pre node, excl. settings
|
||||
var currClasses = '';
|
||||
// Whether to make span or pre
|
||||
var is_inline = false;
|
||||
|
||||
// Generated in WP and contains the settings
|
||||
var s, gs, util;
|
||||
|
||||
// CSS
|
||||
var dialog, code, clear, submit, cancel;
|
||||
|
||||
var colorboxSettings = {
|
||||
inline: true,
|
||||
width: 690,
|
||||
height: '90%',
|
||||
closeButton: false,
|
||||
fixed: true,
|
||||
transition: 'none',
|
||||
className: 'crayon-colorbox',
|
||||
onOpen: function () {
|
||||
$(this.outer).prepend($(s.bar_content));
|
||||
},
|
||||
onComplete: function () {
|
||||
$(s.code_css).focus();
|
||||
},
|
||||
onCleanup: function () {
|
||||
$(s.bar).prepend($(s.bar_content));
|
||||
}
|
||||
};
|
||||
|
||||
base.init = function () {
|
||||
s = CrayonTagEditorSettings;
|
||||
gs = CrayonSyntaxSettings;
|
||||
util = CrayonUtil;
|
||||
// This allows us to call $.colorbox and reload without needing a button click.
|
||||
colorboxSettings.href = s.content_css;
|
||||
};
|
||||
|
||||
base.bind = function (buttonCls) {
|
||||
if (!isInit) {
|
||||
isInit = true;
|
||||
base.init();
|
||||
}
|
||||
var $buttons = $(buttonCls);
|
||||
$buttons.each(function (i, button) {
|
||||
var $button = $(button);
|
||||
var $wrapper = $('<a class="crayon-tag-editor-button-wrapper"></a>').attr('href', s.content_css);
|
||||
$button.after($wrapper);
|
||||
$wrapper.append($button);
|
||||
$wrapper.colorbox(colorboxSettings);
|
||||
});
|
||||
};
|
||||
|
||||
base.hide = function () {
|
||||
$.colorbox.close();
|
||||
return false;
|
||||
};
|
||||
|
||||
// XXX Loads dialog contents
|
||||
base.loadDialog = function (callback) {
|
||||
// Loaded once url is given
|
||||
if (!loaded) {
|
||||
loaded = true;
|
||||
} else {
|
||||
callback && callback();
|
||||
return;
|
||||
}
|
||||
// Load the editor content
|
||||
CrayonUtil.getAJAX({action: 'crayon-tag-editor', is_admin: gs.is_admin}, function (data) {
|
||||
dialog = $('<div id="' + s.css + '"></div>');
|
||||
dialog.appendTo('body').hide();
|
||||
dialog.html(data);
|
||||
|
||||
base.setOrigValues();
|
||||
|
||||
submit = dialog.find(s.submit_css);
|
||||
cancel = dialog.find(s.cancel_css);
|
||||
|
||||
code = $(s.code_css);
|
||||
clear = $('#crayon-te-clear');
|
||||
code_refresh = function () {
|
||||
var clear_visible = clear.is(":visible");
|
||||
if (code.val().length > 0 && !clear_visible) {
|
||||
clear.show();
|
||||
code.removeClass(gs.selected);
|
||||
} else if (code.val().length <= 0) {
|
||||
clear.hide();
|
||||
}
|
||||
};
|
||||
|
||||
code.keyup(code_refresh);
|
||||
code.change(code_refresh);
|
||||
clear.click(function () {
|
||||
code.val('');
|
||||
code.removeClass(gs.selected);
|
||||
code.focus();
|
||||
});
|
||||
|
||||
var url = $(s.url_css);
|
||||
var url_info = $(s.url_info_css);
|
||||
var exts = CrayonTagEditorSettings.extensions;
|
||||
url_refresh = function () {
|
||||
if (url.val().length > 0 && !url_info.is(":visible")) {
|
||||
url_info.show();
|
||||
url.removeClass(gs.selected);
|
||||
} else if (url.val().length <= 0) {
|
||||
url_info.hide();
|
||||
}
|
||||
|
||||
// Check for extensions and select language automatically
|
||||
var ext = CrayonUtil.getExt(url.val());
|
||||
if (ext) {
|
||||
var lang = exts[ext];
|
||||
// Otherwise use the extention as the lang
|
||||
var lang_id = lang ? lang : ext;
|
||||
var final_lang = CrayonTagEditorSettings.fallback_lang;
|
||||
$(s.lang_css + ' option').each(function () {
|
||||
if ($(this).val() == lang_id) {
|
||||
final_lang = lang_id;
|
||||
}
|
||||
});
|
||||
$(s.lang_css).val(final_lang);
|
||||
}
|
||||
};
|
||||
url.keyup(url_refresh);
|
||||
url.change(url_refresh);
|
||||
|
||||
var setting_change = function () {
|
||||
var setting = $(this);
|
||||
var orig_value = $(this).attr(gs.orig_value);
|
||||
if (typeof orig_value == 'undefined') {
|
||||
orig_value = '';
|
||||
}
|
||||
// Depends on type
|
||||
var value = base.settingValue(setting);
|
||||
CrayonUtil.log(setting.attr('id') + ' value: ' + value);
|
||||
var highlight = null;
|
||||
if (setting.is('input[type=checkbox]')) {
|
||||
highlight = setting.next('span');
|
||||
}
|
||||
|
||||
CrayonUtil.log(' >>> ' + setting.attr('id') + ' is ' + orig_value + ' = ' + value);
|
||||
if (orig_value == value) {
|
||||
// No change
|
||||
setting.removeClass(gs.changed);
|
||||
if (highlight) {
|
||||
highlight.removeClass(gs.changed);
|
||||
}
|
||||
} else {
|
||||
// Changed
|
||||
setting.addClass(gs.changed);
|
||||
if (highlight) {
|
||||
highlight.addClass(gs.changed);
|
||||
}
|
||||
}
|
||||
// Save standardized value for later
|
||||
base.settingValue(setting, value);
|
||||
};
|
||||
$('.' + gs.setting + '[id]:not(.' + gs.special + ')').each(function () {
|
||||
$(this).change(setting_change);
|
||||
$(this).keyup(setting_change);
|
||||
});
|
||||
callback && callback();
|
||||
});
|
||||
};
|
||||
|
||||
// XXX Displays the dialog.
|
||||
base.showDialog = function (args) {
|
||||
var wasLoaded = loaded;
|
||||
base.loadDialog(function () {
|
||||
if (!wasLoaded) {
|
||||
// Forcefully load the colorbox. Otherwise it populates the content after opening the window and
|
||||
// never renders.
|
||||
$.colorbox(colorboxSettings);
|
||||
}
|
||||
base._showDialog(args);
|
||||
});
|
||||
};
|
||||
|
||||
base._showDialog = function (args) {
|
||||
args = $.extend({
|
||||
insert: null,
|
||||
edit: null,
|
||||
show: null,
|
||||
hide: base.hide,
|
||||
select: null,
|
||||
editor_str: null,
|
||||
ed: null,
|
||||
node: null,
|
||||
input: null,
|
||||
output: null
|
||||
}, args);
|
||||
|
||||
// Need to reset all settings back to original, clear yellow highlighting
|
||||
base.resetSettings();
|
||||
// Save these for when we add a Crayon
|
||||
insertCallback = args.insert;
|
||||
editCallback = args.edit;
|
||||
showCallback = args.show;
|
||||
hideCallback = args.hide;
|
||||
selectCallback = args.select;
|
||||
inputHTML = args.input;
|
||||
outputHTML = args.output;
|
||||
editor_name = args.editor_str;
|
||||
var currNode = args.node;
|
||||
var currNode = args.node;
|
||||
is_inline = false;
|
||||
|
||||
// Unbind submit
|
||||
submit.unbind();
|
||||
submit.click(function (e) {
|
||||
base.submitButton();
|
||||
e.preventDefault();
|
||||
});
|
||||
base.setSubmitText(s.submit_add);
|
||||
|
||||
cancel.unbind();
|
||||
cancel.click(function (e) {
|
||||
base.hide();
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
if (base.isCrayon(currNode)) {
|
||||
currCrayon = $(currNode);
|
||||
if (currCrayon.length != 0) {
|
||||
// Read back settings for editing
|
||||
currClasses = currCrayon.attr('class');
|
||||
var re = new RegExp('\\b([A-Za-z-]+)' + s.attr_sep + '(\\S+)', 'gim');
|
||||
var matches = re.execAll(currClasses);
|
||||
// Retain all other classes, remove settings
|
||||
currClasses = $.trim(currClasses.replace(re, ''));
|
||||
var atts = {};
|
||||
for (var i in matches) {
|
||||
var id = matches[i][1];
|
||||
var value = matches[i][2];
|
||||
atts[id] = value;
|
||||
}
|
||||
|
||||
// Title
|
||||
var title = currCrayon.attr('title');
|
||||
if (title) {
|
||||
atts['title'] = title;
|
||||
}
|
||||
|
||||
// URL
|
||||
var url = currCrayon.attr('data-url');
|
||||
if (url) {
|
||||
atts['url'] = url;
|
||||
}
|
||||
|
||||
// Inverted settings
|
||||
if (typeof atts['highlight'] != 'undefined') {
|
||||
atts['highlight'] = '0' ? '1' : '0';
|
||||
}
|
||||
|
||||
// Inline
|
||||
is_inline = currCrayon.hasClass(s.inline_css);
|
||||
atts['inline'] = is_inline ? '1' : '0';
|
||||
|
||||
// Ensure language goes to fallback if invalid
|
||||
var avail_langs = [];
|
||||
$(s.lang_css + ' option').each(function () {
|
||||
var value = $(this).val();
|
||||
if (value) {
|
||||
avail_langs.push(value);
|
||||
}
|
||||
});
|
||||
if ($.inArray(atts['lang'], avail_langs) == -1) {
|
||||
atts['lang'] = s.fallback_lang;
|
||||
}
|
||||
|
||||
// Validate the attributes
|
||||
atts = base.validate(atts);
|
||||
|
||||
// Load in attributes, add prefix
|
||||
for (var att in atts) {
|
||||
var setting = $('#' + gs.prefix + att + '.' + gs.setting);
|
||||
var value = atts[att];
|
||||
base.settingValue(setting, value);
|
||||
// Update highlights
|
||||
setting.change();
|
||||
// If global setting changes and we access settings, it should declare loaded settings as changed even if they equal the global value, just so they aren't lost on save
|
||||
if (!setting.hasClass(gs.special)) {
|
||||
setting.addClass(gs.changed);
|
||||
if (setting.is('input[type=checkbox]')) {
|
||||
highlight = setting.next('span');
|
||||
highlight.addClass(gs.changed);
|
||||
}
|
||||
}
|
||||
CrayonUtil.log('loaded: ' + att + ':' + value);
|
||||
}
|
||||
|
||||
editing = true;
|
||||
base.setSubmitText(s.submit_edit);
|
||||
|
||||
// Code
|
||||
var content = currCrayon.html();
|
||||
if (inputHTML == 'encode') {
|
||||
content = CrayonUtil.encode_html(content);
|
||||
} else if (inputHTML == 'decode') {
|
||||
content = CrayonUtil.decode_html(content);
|
||||
}
|
||||
code.val(content);
|
||||
|
||||
} else {
|
||||
CrayonUtil.log('cannot load currNode of type pre');
|
||||
}
|
||||
} else {
|
||||
if (selectCallback) {
|
||||
// Add selected content as code
|
||||
code.val(selectCallback);
|
||||
}
|
||||
// We are creating a new Crayon, not editing
|
||||
editing = false;
|
||||
base.setSubmitText(s.submit_add);
|
||||
currCrayon = null;
|
||||
currClasses = '';
|
||||
}
|
||||
|
||||
// Inline
|
||||
var inline = $('#' + s.inline_css);
|
||||
inline.change(function () {
|
||||
is_inline = $(this).is(':checked');
|
||||
var inline_hide = $('.' + s.inline_hide_css);
|
||||
var inline_single = $('.' + s.inline_hide_only_css);
|
||||
var disabled = [s.mark_css, s.range_css, s.title_css, s.url_css];
|
||||
|
||||
for (var i in disabled) {
|
||||
var obj = $(disabled[i]);
|
||||
obj.attr('disabled', is_inline);
|
||||
}
|
||||
|
||||
if (is_inline) {
|
||||
inline_hide.hide();
|
||||
inline_single.hide();
|
||||
inline_hide.closest('tr').hide();
|
||||
for (var i in disabled) {
|
||||
var obj = $(disabled[i]);
|
||||
obj.addClass('crayon-disabled');
|
||||
}
|
||||
} else {
|
||||
inline_hide.show();
|
||||
inline_single.show();
|
||||
inline_hide.closest('tr').show();
|
||||
for (var i in disabled) {
|
||||
var obj = $(disabled[i]);
|
||||
obj.removeClass('crayon-disabled');
|
||||
}
|
||||
}
|
||||
});
|
||||
inline.change();
|
||||
|
||||
// Show the dialog
|
||||
var dialog_title = editing ? s.edit_text : s.add_text;
|
||||
$(s.dialog_title_css).html(dialog_title);
|
||||
if (showCallback) {
|
||||
showCallback();
|
||||
}
|
||||
|
||||
code.focus();
|
||||
code_refresh();
|
||||
url_refresh();
|
||||
if (ajax_class_timer) {
|
||||
clearInterval(ajax_class_timer);
|
||||
ajax_class_timer_count = 0;
|
||||
}
|
||||
|
||||
var ajax_window = $('#TB_window');
|
||||
ajax_window.hide();
|
||||
var fallback = function () {
|
||||
ajax_window.show();
|
||||
// Prevent draw artifacts
|
||||
var oldScroll = $(window).scrollTop();
|
||||
$(window).scrollTop(oldScroll + 10);
|
||||
$(window).scrollTop(oldScroll - 10);
|
||||
};
|
||||
|
||||
ajax_class_timer = setInterval(function () {
|
||||
if (typeof ajax_window != 'undefined' && !ajax_window.hasClass('crayon-te-ajax')) {
|
||||
ajax_window.addClass('crayon-te-ajax');
|
||||
clearInterval(ajax_class_timer);
|
||||
fallback();
|
||||
}
|
||||
if (ajax_class_timer_count >= 100) {
|
||||
// In case it never loads, terminate
|
||||
clearInterval(ajax_class_timer);
|
||||
fallback();
|
||||
}
|
||||
ajax_class_timer_count++;
|
||||
}, 40);
|
||||
};
|
||||
|
||||
// XXX Add Crayon to editor
|
||||
base.addCrayon = function () {
|
||||
var url = $(s.url_css);
|
||||
if (url.val().length == 0 && code.val().length == 0) {
|
||||
code.addClass(gs.selected);
|
||||
code.focus();
|
||||
return false;
|
||||
}
|
||||
code.removeClass(gs.selected);
|
||||
|
||||
// Add inline for matching with CSS
|
||||
var inline = $('#' + s.inline_css);
|
||||
is_inline = inline.length != 0 && inline.is(':checked');
|
||||
|
||||
// Spacing only for <pre>
|
||||
var br_before = br_after = '';
|
||||
if (!editing) {
|
||||
// Don't add spaces if editing
|
||||
if (!is_inline) {
|
||||
if (editor_name == 'html') {
|
||||
br_after = br_before = ' \n';
|
||||
} else {
|
||||
br_after = '<p> </p>';
|
||||
}
|
||||
} else {
|
||||
// Add a space after
|
||||
if (editor_name == 'html') {
|
||||
br_after = br_before = ' ';
|
||||
} else {
|
||||
br_after = ' ';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var tag = (is_inline ? 'span' : 'pre');
|
||||
var shortcode = br_before + '<' + tag + ' ';
|
||||
|
||||
var atts = {};
|
||||
shortcode += 'class="';
|
||||
|
||||
var inline_re = new RegExp('\\b' + s.inline_css + '\\b', 'gim');
|
||||
if (is_inline) {
|
||||
// If don't have inline class, add it
|
||||
if (inline_re.exec(currClasses) == null) {
|
||||
currClasses += ' ' + s.inline_css + ' ';
|
||||
}
|
||||
} else {
|
||||
// Remove inline css if it exists
|
||||
currClasses = currClasses.replace(inline_re, '');
|
||||
}
|
||||
|
||||
// Grab settings as attributes
|
||||
$('.' + gs.changed + '[id],.' + gs.changed + '[' + s.data_value + ']').each(function () {
|
||||
var id = $(this).attr('id');
|
||||
var value = $(this).attr(s.data_value);
|
||||
// Remove prefix
|
||||
id = util.removePrefixFromID(id);
|
||||
atts[id] = value;
|
||||
});
|
||||
|
||||
// Settings
|
||||
atts['lang'] = $(s.lang_css).val();
|
||||
var mark = $(s.mark_css).val();
|
||||
if (mark.length != 0 && !is_inline) {
|
||||
atts['mark'] = mark;
|
||||
}
|
||||
var range = $(s.range_css).val();
|
||||
if (range.length != 0 && !is_inline) {
|
||||
atts['range'] = range;
|
||||
}
|
||||
|
||||
// XXX Code highlighting, checked means 0!
|
||||
if ($(s.hl_css).is(':checked')) {
|
||||
atts['highlight'] = '0';
|
||||
}
|
||||
|
||||
// XXX Very important when working with editor
|
||||
atts['decode'] = 'true';
|
||||
|
||||
// Validate the attributes
|
||||
atts = base.validate(atts);
|
||||
|
||||
for (var id in atts) {
|
||||
// Remove prefix, if exists
|
||||
var value = atts[id];
|
||||
CrayonUtil.log('add ' + id + ':' + value);
|
||||
shortcode += id + s.attr_sep + value + ' ';
|
||||
}
|
||||
|
||||
// Add classes
|
||||
shortcode += currClasses;
|
||||
// Don't forget to close quote for class
|
||||
shortcode += '" ';
|
||||
|
||||
if (!is_inline) {
|
||||
// Title
|
||||
var title = $(s.title_css).val();
|
||||
if (title.length != 0) {
|
||||
shortcode += 'title="' + title + '" ';
|
||||
}
|
||||
// URL
|
||||
var url = $(s.url_css).val();
|
||||
if (url.length != 0) {
|
||||
shortcode += 'data-url="' + url + '" ';
|
||||
}
|
||||
}
|
||||
|
||||
var content = $(s.code_css).val();
|
||||
if (outputHTML == 'encode') {
|
||||
content = CrayonUtil.encode_html(content);
|
||||
} else if (outputHTML == 'decode') {
|
||||
content = CrayonUtil.decode_html(content);
|
||||
}
|
||||
content = typeof content != 'undefined' ? content : '';
|
||||
shortcode += '>' + content + '</' + tag + '>' + br_after;
|
||||
|
||||
if (editing && editCallback) {
|
||||
// Edit the current selected node
|
||||
editCallback(shortcode);
|
||||
} else if (insertCallback) {
|
||||
// Insert the tag and hide dialog
|
||||
insertCallback(shortcode);
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
base.submitButton = function () {
|
||||
CrayonUtil.log('submit');
|
||||
if (base.addCrayon() != false) {
|
||||
base.hideDialog();
|
||||
}
|
||||
};
|
||||
|
||||
base.hideDialog = function () {
|
||||
CrayonUtil.log('hide');
|
||||
if (hideCallback) {
|
||||
hideCallback();
|
||||
}
|
||||
};
|
||||
|
||||
// XXX Auxiliary methods
|
||||
|
||||
base.setOrigValues = function () {
|
||||
$('.' + gs.setting + '[id]').each(function () {
|
||||
var setting = $(this);
|
||||
setting.attr(gs.orig_value, base.settingValue(setting));
|
||||
});
|
||||
};
|
||||
|
||||
base.resetSettings = function () {
|
||||
CrayonUtil.log('reset');
|
||||
$('.' + gs.setting).each(function () {
|
||||
var setting = $(this);
|
||||
base.settingValue(setting, setting.attr(gs.orig_value));
|
||||
// Update highlights
|
||||
setting.change();
|
||||
});
|
||||
code.val('');
|
||||
};
|
||||
|
||||
base.settingValue = function (setting, value) {
|
||||
if (typeof value == 'undefined') {
|
||||
// getter
|
||||
value = '';
|
||||
if (setting.is('input[type=checkbox]')) {
|
||||
// Boolean is stored as string
|
||||
value = setting.is(':checked') ? 'true' : 'false';
|
||||
} else {
|
||||
value = setting.val();
|
||||
}
|
||||
return value;
|
||||
} else {
|
||||
// setter
|
||||
if (setting.is('input[type=checkbox]')) {
|
||||
if (typeof value == 'string') {
|
||||
if (value == 'true' || value == '1') {
|
||||
value = true;
|
||||
} else if (value == 'false' || value == '0') {
|
||||
value = false;
|
||||
}
|
||||
}
|
||||
setting.prop('checked', value);
|
||||
} else {
|
||||
setting.val(value);
|
||||
}
|
||||
setting.attr(s.data_value, value);
|
||||
}
|
||||
};
|
||||
|
||||
base.validate = function (atts) {
|
||||
var fields = ['range', 'mark'];
|
||||
for (var i in fields) {
|
||||
var field = fields[i];
|
||||
if (typeof atts[field] != 'undefined') {
|
||||
atts[field] = atts[field].replace(/\s/g, '');
|
||||
}
|
||||
}
|
||||
return atts;
|
||||
};
|
||||
|
||||
base.isCrayon = function (node) {
|
||||
return node != null &&
|
||||
(node.nodeName == 'PRE' || (node.nodeName == 'SPAN' && $(node).hasClass(s.inline_css)));
|
||||
};
|
||||
|
||||
base.elemValue = function (obj) {
|
||||
var value = null;
|
||||
if (obj.is('input[type=checkbox]')) {
|
||||
value = obj.is(':checked');
|
||||
} else {
|
||||
value = obj.val();
|
||||
}
|
||||
return value;
|
||||
};
|
||||
|
||||
base.setSubmitText = function (text) {
|
||||
submit.html(text);
|
||||
};
|
||||
|
||||
};
|
||||
})(jQueryCrayon);
|
292
util/tag-editor/crayon_tag_editor_wp.class.php
Normal file
@ -0,0 +1,292 @@
|
||||
<?php
|
||||
|
||||
require_once(CRAYON_ROOT_PATH . 'crayon_settings_wp.class.php');
|
||||
|
||||
class CrayonTagEditorWP {
|
||||
|
||||
public static $settings = null;
|
||||
|
||||
public static function init() {
|
||||
// Hooks
|
||||
if (CRAYON_TAG_EDITOR) {
|
||||
CrayonSettingsWP::load_settings(TRUE);
|
||||
if (is_admin()) {
|
||||
// XXX Only runs in wp-admin
|
||||
add_action('admin_print_scripts-post-new.php', 'CrayonTagEditorWP::enqueue_resources');
|
||||
add_action('admin_print_scripts-post.php', 'CrayonTagEditorWP::enqueue_resources');
|
||||
add_filter('tiny_mce_before_init', 'CrayonTagEditorWP::init_tinymce');
|
||||
// Must come after
|
||||
add_action("admin_print_scripts-post-new.php", 'CrayonSettingsWP::init_js_settings');
|
||||
add_action("admin_print_scripts-post.php", 'CrayonSettingsWP::init_js_settings');
|
||||
self::addbuttons();
|
||||
} else if (CrayonGlobalSettings::val(CrayonSettings::TAG_EDITOR_FRONT)) {
|
||||
// XXX This will always need to enqueue, but only runs on front end
|
||||
add_action('wp', 'CrayonTagEditorWP::enqueue_resources');
|
||||
add_filter('tiny_mce_before_init', 'CrayonTagEditorWP::init_tinymce');
|
||||
self::addbuttons();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function init_settings() {
|
||||
|
||||
if (!self::$settings) {
|
||||
// Add settings
|
||||
self::$settings = array(
|
||||
'home_url' => home_url(),
|
||||
'css' => 'crayon-te',
|
||||
'css_selected' => 'crayon-selected',
|
||||
'code_css' => '#crayon-code',
|
||||
'url_css' => '#crayon-url',
|
||||
'url_info_css' => '#crayon-te-url-info',
|
||||
'lang_css' => '#crayon-lang',
|
||||
'title_css' => '#crayon-title',
|
||||
'mark_css' => '#crayon-mark',
|
||||
'range_css' => '#crayon-range',
|
||||
'inline_css' => 'crayon-inline',
|
||||
'inline_hide_css' => 'crayon-hide-inline',
|
||||
'inline_hide_only_css' => 'crayon-hide-inline-only',
|
||||
'hl_css' => '#crayon-highlight',
|
||||
'switch_html' => '#content-html',
|
||||
'switch_tmce' => '#content-tmce',
|
||||
'tinymce_button_generic' => '.mce-btn',
|
||||
'tinymce_button' => 'a.mce_crayon_tinymce,.mce-i-crayon_tinymce',
|
||||
'tinymce_button_unique' => 'mce_crayon_tinymce',
|
||||
'tinymce_highlight' => 'mce-active',
|
||||
'submit_css' => '#crayon-te-ok',
|
||||
'cancel_css' => '#crayon-te-cancel',
|
||||
'content_css' => '#crayon-te-content',
|
||||
'dialog_title_css' => '#crayon-te-title',
|
||||
'submit_wrapper_css' => '#crayon-te-submit-wrapper',
|
||||
'data_value' => 'data-value',
|
||||
'attr_sep' => CrayonGlobalSettings::val_str(CrayonSettings::ATTR_SEP),
|
||||
'css_sep' => '_',
|
||||
'fallback_lang' => CrayonGlobalSettings::val(CrayonSettings::FALLBACK_LANG),
|
||||
'add_text' => CrayonGlobalSettings::val(CrayonSettings::TAG_EDITOR_ADD_BUTTON_TEXT),
|
||||
'edit_text' => CrayonGlobalSettings::val(CrayonSettings::TAG_EDITOR_EDIT_BUTTON_TEXT),
|
||||
'quicktag_text' => CrayonGlobalSettings::val(CrayonSettings::TAG_EDITOR_QUICKTAG_BUTTON_TEXT),
|
||||
'submit_add' => crayon__('Add'),
|
||||
'submit_edit' => crayon__('Save'),
|
||||
'bar' => '#crayon-te-bar',
|
||||
'bar_content' => '#crayon-te-bar-content',
|
||||
'extensions' => CrayonResources::langs()->extensions_inverted()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public static function enqueue_resources() {
|
||||
global $CRAYON_VERSION;
|
||||
self::init_settings();
|
||||
|
||||
if (CRAYON_MINIFY) {
|
||||
wp_deregister_script('crayon_js');
|
||||
wp_enqueue_script('crayon_js', plugins_url(CRAYON_JS_TE_MIN, dirname(dirname(__FILE__))), array('jquery', 'quicktags'), $CRAYON_VERSION);
|
||||
CrayonSettingsWP::init_js_settings();
|
||||
wp_localize_script('crayon_js', 'CrayonTagEditorSettings', self::$settings);
|
||||
} else {
|
||||
wp_enqueue_script('crayon_colorbox_js', plugins_url(CRAYON_COLORBOX_JS, __FILE__), array('jquery'), $CRAYON_VERSION);
|
||||
wp_enqueue_style('crayon_colorbox_css', plugins_url(CRAYON_COLORBOX_CSS, __FILE__), array(), $CRAYON_VERSION);
|
||||
wp_enqueue_script('crayon_te_js', plugins_url(CRAYON_TAG_EDITOR_JS, __FILE__), array('crayon_util_js', 'crayon_colorbox_js'), $CRAYON_VERSION);
|
||||
wp_enqueue_script('crayon_qt_js', plugins_url(CRAYON_QUICKTAGS_JS, __FILE__), array('quicktags', 'crayon_te_js'), $CRAYON_VERSION, TRUE);
|
||||
wp_localize_script('crayon_te_js', 'CrayonTagEditorSettings', self::$settings);
|
||||
CrayonSettingsWP::other_scripts();
|
||||
}
|
||||
}
|
||||
|
||||
public static function init_tinymce($init) {
|
||||
if (!array_key_exists('extended_valid_elements', $init)) {
|
||||
$init['extended_valid_elements'] = '';
|
||||
}
|
||||
$init['extended_valid_elements'] .= ',pre[*],code[*],iframe[*]';
|
||||
return $init;
|
||||
}
|
||||
|
||||
public static function addbuttons() {
|
||||
// Add only in Rich Editor mode
|
||||
add_filter('mce_external_plugins', 'CrayonTagEditorWP::add_plugin');
|
||||
add_filter('mce_buttons', 'CrayonTagEditorWP::register_buttons');
|
||||
add_filter('bbp_before_get_the_content_parse_args', 'CrayonTagEditorWP::bbp_get_the_content_args');
|
||||
}
|
||||
|
||||
public static function bbp_get_the_content_args($args) {
|
||||
// Turn off "teeny" to allow the bbPress TinyMCE to display external plugins
|
||||
return array_merge($args, array('teeny' => false));
|
||||
}
|
||||
|
||||
public static function register_buttons($buttons) {
|
||||
array_push($buttons, 'separator', 'crayon_tinymce');
|
||||
return $buttons;
|
||||
}
|
||||
|
||||
public static function add_plugin($plugin_array) {
|
||||
$plugin_array['crayon_tinymce'] = plugins_url(CRAYON_TINYMCE_JS, __FILE__);
|
||||
return $plugin_array;
|
||||
}
|
||||
|
||||
// The remaining functions are for displayed output.
|
||||
|
||||
public static function select_resource($id, $resources, $current, $set_class = TRUE) {
|
||||
$id = CrayonSettings::PREFIX . $id;
|
||||
if (count($resources) > 0) {
|
||||
$class = $set_class ? 'class="' . CrayonSettings::SETTING . ' ' . CrayonSettings::SETTING_SPECIAL . '"' : '';
|
||||
echo '<select id="' . $id . '" name="' . $id . '" ' . $class . ' ' . CrayonSettings::SETTING_ORIG_VALUE . '="' . $current . '">';
|
||||
foreach ($resources as $resource) {
|
||||
$asterisk = $current == $resource->id() ? ' *' : '';
|
||||
echo '<option value="' . $resource->id() . '" ' . selected($current, $resource->id()) . ' >' . $resource->name() . $asterisk . '</option>';
|
||||
}
|
||||
echo '</select>';
|
||||
} else {
|
||||
// None found, default to text box
|
||||
echo '<input type="text" id="' . $id . '" name="' . $id . '" class="' . CrayonSettings::SETTING . ' ' . CrayonSettings::SETTING_SPECIAL . '" />';
|
||||
}
|
||||
}
|
||||
|
||||
public static function checkbox($id) {
|
||||
$id = CrayonSettings::PREFIX . $id;
|
||||
echo '<input type="checkbox" id="' . $id . '" name="' . $id . '" class="' . CrayonSettings::SETTING . ' ' . CrayonSettings::SETTING_SPECIAL . '" />';
|
||||
}
|
||||
|
||||
public static function textbox($id, $atts = array(), $set_class = TRUE) {
|
||||
$id = CrayonSettings::PREFIX . $id;
|
||||
$atts_str = '';
|
||||
$class = $set_class ? 'class="' . CrayonSettings::SETTING . ' ' . CrayonSettings::SETTING_SPECIAL . '"' : '';
|
||||
foreach ($atts as $k => $v) {
|
||||
$atts_str = $k . '="' . $v . '" ';
|
||||
}
|
||||
echo '<input type="text" id="' . $id . '" name="' . $id . '" ' . $class . ' ' . $atts_str . ' />';
|
||||
}
|
||||
|
||||
public static function submit() {
|
||||
?>
|
||||
<input type="button"
|
||||
class="button-primary <?php echo CrayonTagEditorWP::$settings['submit_css']; ?>"
|
||||
value="<?php echo CrayonTagEditorWP::$settings['submit_add']; ?>"
|
||||
name="submit"/>
|
||||
<?php
|
||||
}
|
||||
|
||||
public static function content() {
|
||||
CrayonSettingsWP::load_settings();
|
||||
$langs = CrayonLangs::sort_by_name(CrayonParser::parse_all());
|
||||
$curr_lang = CrayonGlobalSettings::val(CrayonSettings::FALLBACK_LANG);
|
||||
$themes = CrayonResources::themes()->get();
|
||||
$curr_theme = CrayonGlobalSettings::val(CrayonSettings::THEME);
|
||||
$fonts = CrayonResources::fonts()->get();
|
||||
$curr_font = CrayonGlobalSettings::val(CrayonSettings::FONT);
|
||||
CrayonTagEditorWP::init_settings();
|
||||
|
||||
?>
|
||||
|
||||
<div id="crayon-te-content" class="crayon-te">
|
||||
<div id="crayon-te-bar">
|
||||
<div id="crayon-te-bar-content">
|
||||
<div id="crayon-te-title">Title</div>
|
||||
<div id="crayon-te-controls">
|
||||
<a id="crayon-te-ok" href="#"><?php crayon_e('OK'); ?></a> <span
|
||||
class="crayon-te-seperator">|</span> <a id="crayon-te-cancel"
|
||||
href="#"><?php crayon_e('Cancel'); ?></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table id="crayon-te-table" class="describe">
|
||||
<tr class="crayon-tr-center">
|
||||
<th><?php crayon_e('Title'); ?>
|
||||
</th>
|
||||
<td class="crayon-nowrap"><?php self::textbox('title', array('placeholder' => crayon__('A short description'))); ?>
|
||||
<span id="crayon-te-sub-section"> <?php self::checkbox('inline'); ?>
|
||||
<span class="crayon-te-section"><?php crayon_e('Inline'); ?> </span>
|
||||
</span> <span id="crayon-te-sub-section"> <?php self::checkbox('highlight'); ?>
|
||||
<span class="crayon-te-section"><?php crayon_e("Don't Highlight"); ?>
|
||||
</span>
|
||||
</span></td>
|
||||
</tr>
|
||||
<tr class="crayon-tr-center">
|
||||
<th><?php crayon_e('Language'); ?>
|
||||
</th>
|
||||
<td class="crayon-nowrap"><?php self::select_resource('lang', $langs, $curr_lang); ?>
|
||||
<span class="crayon-te-section"><?php crayon_e('Line Range'); ?> </span>
|
||||
<?php self::textbox('range', array('placeholder' => crayon__('(e.g. 3-5 or 3)'))); ?>
|
||||
<span class="crayon-te-section"><?php crayon_e('Marked Lines'); ?> </span>
|
||||
<?php self::textbox('mark', array('placeholder' => crayon__('(e.g. 1,2,3-5)'))); ?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="crayon-tr-center" style="text-align: center;">
|
||||
<th>
|
||||
<div>
|
||||
<?php crayon_e('Code'); ?>
|
||||
</div>
|
||||
<input type="button" id="crayon-te-clear"
|
||||
class="secondary-primary" value="<?php crayon_e('Clear'); ?>"
|
||||
name="clear"/>
|
||||
</th>
|
||||
<td><textarea id="crayon-code" name="code"
|
||||
placeholder="<?php crayon_e('Paste your code here, or type it in manually.'); ?>"></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="crayon-tr-center">
|
||||
<th id="crayon-url-th"><?php crayon_e('URL'); ?>
|
||||
</th>
|
||||
<td><?php self::textbox('url', array('placeholder' => crayon__('Relative local path or absolute URL'))); ?>
|
||||
<div id="crayon-te-url-info" class="crayon-te-info">
|
||||
<?php
|
||||
crayon_e("If the URL fails to load, the code above will be shown instead. If no code exists, an error is shown.");
|
||||
echo ' ';
|
||||
printf(crayon__('If a relative local path is given it will be appended to %s - which is defined in %sCrayon > Settings > Files%s.'), '<span class="crayon-te-quote">' . get_home_url() . '/' . CrayonGlobalSettings::val(CrayonSettings::LOCAL_PATH) . '</span>', '<a href="options-general.php?page=crayon_settings" target="_blank">', '</a>');
|
||||
?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id="crayon-te-submit-wrapper" colspan="2"
|
||||
style="text-align: center;"><?php self::submit(); ?></td>
|
||||
</tr>
|
||||
<!-- <tr>-->
|
||||
<!-- <td colspan="2"><div id="crayon-te-warning" class="updated crayon-te-info"></div></td>-->
|
||||
<!-- </tr>-->
|
||||
<tr>
|
||||
<td colspan="2"><?php
|
||||
$admin = isset($_GET['is_admin']) ? intval($_GET['is_admin']) : is_admin();
|
||||
if (!$admin && !CrayonGlobalSettings::val(CrayonSettings::TAG_EDITOR_SETTINGS)) {
|
||||
exit();
|
||||
}
|
||||
?>
|
||||
<hr/>
|
||||
<div>
|
||||
<h2 class="crayon-te-heading">
|
||||
<?php crayon_e('Settings'); ?>
|
||||
</h2>
|
||||
</div>
|
||||
<div id="crayon-te-settings-info" class="crayon-te-info">
|
||||
<?php
|
||||
crayon_e('Change the following settings to override their global values.');
|
||||
echo ' <span class="', CrayonSettings::SETTING_CHANGED, '">';
|
||||
crayon_e('Only changes (shown yellow) are applied.');
|
||||
echo '</span><br/>';
|
||||
echo sprintf(crayon__('Future changes to the global settings under %sCrayon > Settings%s won\'t affect overridden settings.'), '<a href="options-general.php?page=crayon_settings" target="_blank">', '</a>');
|
||||
?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
$sections = array('Theme', 'Font', 'Metrics', 'Toolbar', 'Lines', 'Code');
|
||||
foreach ($sections as $section) {
|
||||
echo '<tr><th>', crayon__($section), '</th><td>';
|
||||
call_user_func('CrayonSettingsWP::' . strtolower($section), TRUE);
|
||||
echo '</td></tr>';
|
||||
}
|
||||
?>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
exit();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (defined('ABSPATH')) {
|
||||
add_action('init', 'CrayonTagEditorWP::init');
|
||||
}
|
||||
|
||||
?>
|
32
util/tag-editor/crayon_te.css
Normal file
@ -0,0 +1,32 @@
|
||||
pre {
|
||||
background: #F4F4F4 !important;
|
||||
border: 1px solid #CCC !important;
|
||||
margin-bottom: 1.5em !important;
|
||||
padding: 0.3em 0.5em !important;
|
||||
min-height: 1.5em;
|
||||
}
|
||||
|
||||
pre.crayon-selected {
|
||||
background: #cce4f5 !important;
|
||||
border: 1px solid #9dc8e6 !important;
|
||||
}
|
||||
|
||||
pre, span.crayon-inline {
|
||||
font-family: "Courier 10 Pitch", Courier, monospace !important;
|
||||
font-size: 80% !important;
|
||||
}
|
||||
|
||||
span.crayon-inline {
|
||||
background: #F4F4F4 !important;
|
||||
border: 1px solid #CCC !important;
|
||||
padding: 2px 3px;
|
||||
|
||||
/* font: 80% !important; */
|
||||
/* margin-bottom: 1.5em !important; */
|
||||
/* padding: 0.3em 0.5em !important; */
|
||||
}
|
||||
|
||||
span.crayon-inline.crayon-selected {
|
||||
background: #d2eeca !important;
|
||||
border: 1px solid #b8dc9b !important;
|
||||
}
|
270
util/tag-editor/crayon_tinymce.js
Normal file
@ -0,0 +1,270 @@
|
||||
(function ($) {
|
||||
|
||||
window.CrayonTinyMCE = new function () {
|
||||
|
||||
// TinyMCE specific
|
||||
var name = 'crayon_tinymce';
|
||||
var s, te = null;
|
||||
var isHighlighted = false;
|
||||
var currPre = null;
|
||||
var isInit = false;
|
||||
// Switch events
|
||||
var switch_html_click = switch_tmce_click = null;
|
||||
|
||||
var base = this;
|
||||
// var wasHighlighted = false;
|
||||
|
||||
base.setHighlight = function (highlight) {
|
||||
$(s.tinymce_button).closest(s.tinymce_button_generic).toggleClass(s.tinymce_highlight, highlight);
|
||||
isHighlighted = highlight;
|
||||
};
|
||||
|
||||
base.selectPreCSS = function (selected) {
|
||||
if (currPre) {
|
||||
if (selected) {
|
||||
$(currPre).addClass(s.css_selected);
|
||||
} else {
|
||||
$(currPre).removeClass(s.css_selected);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
base.isPreSelectedCSS = function () {
|
||||
if (currPre) {
|
||||
return $(currPre).hasClass(s.css_selected);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
base.loadTinyMCE = function () {
|
||||
var version = parseInt(tinymce.majorVersion);
|
||||
if (!isNaN(version) && version <= 3) {
|
||||
return this._loadTinyMCEv3();
|
||||
}
|
||||
|
||||
s = CrayonTagEditorSettings;
|
||||
te = CrayonTagEditor;
|
||||
|
||||
// TODO(aramk) find the TinyMCE version 4 compliant command for this.
|
||||
//tinymce.PluginManager.requireLangPack(name);
|
||||
|
||||
tinymce.PluginManager.add(name, function (ed, url) {
|
||||
// TODO(aramk) This is called twice for some reason.
|
||||
ed.on('init', function () {
|
||||
ed.dom.loadCSS(url + '/crayon_te.css');
|
||||
if (isInit) {
|
||||
return;
|
||||
}
|
||||
$(s.tinymce_button).parent().addClass(s.tinymce_button_unique);
|
||||
CrayonTagEditor.bind('.' + s.tinymce_button_unique);
|
||||
// Remove all selected pre tags
|
||||
$('.' + s.css_selected, ed.getContent()).removeClass(s.css_selected);
|
||||
isInit = true;
|
||||
});
|
||||
|
||||
// Prevent <p> on enter, turn into \n
|
||||
ed.on('keyDown', function (e) {
|
||||
var selection = ed.selection;
|
||||
if (e.keyCode == 13) {
|
||||
var node = selection.getNode();
|
||||
if (node.nodeName == 'PRE') {
|
||||
selection.setContent('\n', {format: 'raw'});
|
||||
return tinymce.dom.Event.cancel(e);
|
||||
} else if (te.isCrayon(node)) {
|
||||
// Only triggers for inline <span>, ignore enter in inline
|
||||
return tinymce.dom.Event.cancel(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Remove onclick and call ourselves
|
||||
var switch_html = $(s.switch_html);
|
||||
switch_html.prop('onclick', null);
|
||||
switch_html.click(function () {
|
||||
// Remove selected pre class when switching to HTML editor
|
||||
base.selectPreCSS(false);
|
||||
switchEditors.go('content', 'html');
|
||||
});
|
||||
|
||||
// Highlight selected
|
||||
ed.on('nodeChange', function (event) {
|
||||
var n = event.element;
|
||||
if (n != currPre) {
|
||||
// We only care if we select another same object
|
||||
if (currPre) {
|
||||
// If we have a previous pre, remove it
|
||||
base.selectPreCSS(false);
|
||||
currPre = null;
|
||||
}
|
||||
if (te.isCrayon(n)) {
|
||||
// Add new pre
|
||||
currPre = n;
|
||||
base.selectPreCSS(true);
|
||||
base.setHighlight(true);
|
||||
} else {
|
||||
// No pre selected
|
||||
base.setHighlight(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ed.addButton(name, {
|
||||
// TODO add translation
|
||||
title: s.dialog_title_add,
|
||||
onclick: function () {
|
||||
te.showDialog({
|
||||
insert: function (shortcode) {
|
||||
ed.execCommand('mceInsertContent', 0, shortcode);
|
||||
},
|
||||
edit: function (shortcode) {
|
||||
// This will change the currPre object
|
||||
var newPre = $(shortcode);
|
||||
$(currPre).replaceWith(newPre);
|
||||
// XXX DOM element not jQuery
|
||||
currPre = newPre[0];
|
||||
},
|
||||
select: function () {
|
||||
return ed.selection.getContent({format: 'text'});
|
||||
},
|
||||
editor_str: 'tinymce',
|
||||
ed: ed,
|
||||
node: currPre,
|
||||
input: 'decode',
|
||||
output: 'encode'
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
// TinyMCE v3 - deprecated.
|
||||
base._loadTinyMCEv3 = function () {
|
||||
s = CrayonTagEditorSettings;
|
||||
te = CrayonTagEditor;
|
||||
|
||||
tinymce.PluginManager.requireLangPack(name);
|
||||
|
||||
tinymce.create('tinymce.plugins.Crayon', {
|
||||
init: function (ed, url) {
|
||||
|
||||
ed.onInit.add(function (ed) {
|
||||
ed.dom.loadCSS(url + '/crayon_te.css');
|
||||
});
|
||||
|
||||
// Prevent <p> on enter, turn into \n
|
||||
ed.onKeyDown.add(function (ed, e) {
|
||||
var selection = ed.selection;
|
||||
if (e.keyCode == 13) {
|
||||
var node = selection.getNode();
|
||||
if (node.nodeName == 'PRE') {
|
||||
selection.setContent('\n', {format: 'raw'});
|
||||
return tinymce.dom.Event.cancel(e);
|
||||
} else if (te.isCrayon(node)) {
|
||||
// Only triggers for inline <span>, ignore enter in inline
|
||||
return tinymce.dom.Event.cancel(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ed.onInit.add(function (ed) {
|
||||
CrayonTagEditor.bind(s.tinymce_button);
|
||||
});
|
||||
|
||||
ed.addCommand('showCrayon', function () {
|
||||
te.showDialog({
|
||||
insert: function (shortcode) {
|
||||
ed.execCommand('mceInsertContent', 0, shortcode);
|
||||
},
|
||||
edit: function (shortcode) {
|
||||
// This will change the currPre object
|
||||
var newPre = $(shortcode);
|
||||
$(currPre).replaceWith(newPre);
|
||||
// XXX DOM element not jQuery
|
||||
currPre = newPre[0];
|
||||
},
|
||||
select: function () {
|
||||
return ed.selection.getContent({format: 'text'});
|
||||
},
|
||||
editor_str: 'tinymce',
|
||||
ed: ed,
|
||||
node: currPre,
|
||||
input: 'decode',
|
||||
output: 'encode'
|
||||
});
|
||||
});
|
||||
|
||||
// Remove onclick and call ourselves
|
||||
var switch_html = $(s.switch_html);
|
||||
switch_html.prop('onclick', null);
|
||||
switch_html.click(function () {
|
||||
// Remove selected pre class when switching to HTML editor
|
||||
base.selectPreCSS(false);
|
||||
switchEditors.go('content', 'html');
|
||||
});
|
||||
|
||||
// Highlight selected
|
||||
ed.onNodeChange.add(function (ed, cm, n, co) {
|
||||
if (n != currPre) {
|
||||
// We only care if we select another same object
|
||||
if (currPre) {
|
||||
// If we have a previous pre, remove it
|
||||
base.selectPreCSS(false);
|
||||
currPre = null;
|
||||
}
|
||||
if (te.isCrayon(n)) {
|
||||
// Add new pre
|
||||
currPre = n;
|
||||
base.selectPreCSS(true);
|
||||
base.setHighlight(true);
|
||||
} else {
|
||||
// No pre selected
|
||||
base.setHighlight(false);
|
||||
}
|
||||
// var tooltip = currPre ? s.dialog_title_edit : s.dialog_title_add;
|
||||
// $(s.tinymce_button).attr('title', tooltip);
|
||||
}
|
||||
});
|
||||
|
||||
ed.onBeforeSetContent.add(function (ed, o) {
|
||||
// Remove all selected pre tags
|
||||
var content = $(o.content);
|
||||
var wrapper = $('<div>');
|
||||
content.each(function () {
|
||||
$(this).removeClass(s.css_selected);
|
||||
wrapper.append($(this).clone());
|
||||
});
|
||||
o.content = wrapper.html();
|
||||
});
|
||||
|
||||
ed.addButton(name, {
|
||||
// TODO add translation
|
||||
title: s.dialog_title,
|
||||
cmd: 'showCrayon'
|
||||
});
|
||||
},
|
||||
createControl: function (n, cm) {
|
||||
return null;
|
||||
},
|
||||
getInfo: function () {
|
||||
return {
|
||||
longname: 'Crayon Syntax Highlighter',
|
||||
author: 'Aram Kocharyan',
|
||||
authorurl: 'http://aramk.com/',
|
||||
infourl: 'https://github.com/aramk/crayon-syntax-highlighter',
|
||||
version: "1.0"
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
tinymce.PluginManager.add(name, tinymce.plugins.Crayon);
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
$(document).ready(function () {
|
||||
// Load TinyMCE
|
||||
CrayonTinyMCE.loadTinyMCE();
|
||||
});
|
||||
|
||||
})(jQueryCrayon);
|
BIN
util/theme-editor/images/button-pressed.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
util/theme-editor/images/button.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
util/theme-editor/images/frame.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
util/theme-editor/images/highlighting.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
util/theme-editor/images/information.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
util/theme-editor/images/lines.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
util/theme-editor/images/numbers.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
util/theme-editor/images/title.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
BIN
util/theme-editor/images/toolbar.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
317
util/theme-editor/theme_editor.css
Normal file
@ -0,0 +1,317 @@
|
||||
#crayon-theme-editor-button {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
#crayon-editor-controls {
|
||||
|
||||
}
|
||||
|
||||
#crayon-editor-preview .crayon-syntax {
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
#crayon-editor-control-wrapper {
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
#crayon-editor-control-wrapper,
|
||||
#crayon-editor-controls {
|
||||
width: 422px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#crayon-editor-save {
|
||||
margin: 0 5px;
|
||||
}
|
||||
|
||||
#crayon-editor-controls label {
|
||||
margin-right: 10px;
|
||||
width: 70px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
#crayon-editor-controls .crayon-theme-editor-form .separator .content {
|
||||
font-weight: bold;
|
||||
color: #999;
|
||||
padding-top: 8px;
|
||||
border-bottom: 1px solid #ccc;
|
||||
text-shadow: 0 1px 0px #fff;
|
||||
text-align: center;
|
||||
padding-bottom: 2px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
#crayon-editor-controls .crayon-theme-editor-form .separator.first .content {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
#crayon-editor-controls .crayon-theme-editor-form .separator.title .content {
|
||||
line-height: 24px;
|
||||
height: 22px;
|
||||
padding-top: 0;
|
||||
background: #dedede url(images/title.png) center bottom repeat-x;
|
||||
border-color: #999;
|
||||
}
|
||||
|
||||
#crayon-editor-controls .crayon-theme-editor-form .separator.title .content {
|
||||
color: #333;
|
||||
text-shadow: 0 1px 2px #eee;
|
||||
}
|
||||
|
||||
#crayon-editor-controls .crayon-theme-editor-form .separator.title td {
|
||||
color: #333;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#crayon-editor-controls .crayon-theme-editor-form .field {
|
||||
border: 0px;
|
||||
padding-right: 5px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
#crayon-editor-controls .crayon-theme-editor-form .split-field td {
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
#crayon-editor-controls .crayon-theme-editor-form .split-field td.last {
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
#crayon-editor-controls .split-field input,
|
||||
#crayon-editor-controls .split-field select {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#crayon-editor-controls .crayon-theme-editor-form table td.value.split {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
#crayon-editor-controls .crayon-theme-editor-form table td.field.split {
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
#crayon-editor-controls input {
|
||||
line-height: 23px;
|
||||
height: 23px;
|
||||
border: 1px solid #ccc;
|
||||
padding: 0 5px;
|
||||
margin: 2px 0;
|
||||
}
|
||||
|
||||
#crayon-editor-controls input:focus {
|
||||
border: 1px solid #999;
|
||||
}
|
||||
|
||||
#crayon-editor-controls .ui-tabs-panel {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.crayon-theme-editor-form table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#crayon-editor-controls .crayon-theme-editor-form table,
|
||||
#crayon-editor-controls .crayon-theme-editor-form tr,
|
||||
#crayon-editor-controls .crayon-theme-editor-form td {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border-spacing: 0 !important;
|
||||
}
|
||||
|
||||
#crayon-editor-controls .crayon-theme-editor-form table tr:first-child td,
|
||||
#crayon-editor-controls .crayon-theme-editor-form table tr:last-child td {
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
#crayon-editor-controls .crayon-theme-editor-form table td {
|
||||
padding: 1px 4px;
|
||||
}
|
||||
|
||||
.crayon-theme-editor-form table .value input {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#crayon-editor-controls .ui-tabs-nav li {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border-top: 0;
|
||||
border-left: 0;
|
||||
}
|
||||
|
||||
#crayon-editor-controls .ui-tabs-nav * {
|
||||
border-radius: 0px;
|
||||
}
|
||||
|
||||
#crayon-editor-controls .ui-tabs-nav {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#crayon-editor-controls .ui-tabs-nav,
|
||||
#crayon-editor-controls .ui-tabs-nav li,
|
||||
#crayon-editor-controls .ui-tabs-nav li a {
|
||||
height: 33px;
|
||||
line-height: 33px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#crayon-editor-controls .ui-tabs-nav li a,
|
||||
#crayon-editor-controls .ui-tabs-nav li {
|
||||
float: left;
|
||||
width: 70px;
|
||||
}
|
||||
|
||||
#crayon-editor-controls.ui-tabs {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#crayon-editor-controls .ui-widget-header {
|
||||
width: 1000px;
|
||||
overflow: hidden;
|
||||
border-bottom-left-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
|
||||
#crayon-editor-controls .ui-widget-header li:last-child {
|
||||
border-right: none !important;
|
||||
}
|
||||
|
||||
#crayon-editor-control-wrapper .ui-widget-content {
|
||||
border: 0;
|
||||
background: none;
|
||||
}
|
||||
|
||||
#crayon-editor-controls .ui-widget-content {
|
||||
border: 1px solid #bbb;
|
||||
border-top-style: none;
|
||||
background: #f5f5f5 50% top repeat-x;
|
||||
color: #333333;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.ui-colorpicker-preview-container .ui-colorpicker-border,
|
||||
.ui-colorpicker-preview-initial,
|
||||
.ui-colorpicker-preview-current {
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.ui-colorpicker .ui-colorpicker-mode {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.ui-colorpicker-swatches {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.ui-colorpicker {
|
||||
z-index: 100 !important;
|
||||
}
|
||||
|
||||
.crayon-tab-information {
|
||||
background: url(images/information.png) no-repeat top center;
|
||||
}
|
||||
|
||||
.crayon-tab-highlighting {
|
||||
background: url(images/highlighting.png) no-repeat top center;
|
||||
}
|
||||
|
||||
.crayon-tab-frame {
|
||||
background: url(images/frame.png) no-repeat top center;
|
||||
}
|
||||
|
||||
.crayon-tab-lines {
|
||||
background: url(images/lines.png) no-repeat top center;
|
||||
}
|
||||
|
||||
.crayon-tab-numbers {
|
||||
background: url(images/numbers.png) no-repeat top center;
|
||||
}
|
||||
|
||||
.crayon-tab-toolbar {
|
||||
background: url(images/toolbar.png) no-repeat top center;
|
||||
}
|
||||
|
||||
#crayon-editor-controls .ui-widget-header {
|
||||
border: 1px solid #b3b3b3;
|
||||
border-bottom: 1px solid #666;
|
||||
background: #929292 url(images/button.png) center bottom repeat-x;
|
||||
color: #474747;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#crayon-editor-controls .ui-state-default,
|
||||
#crayon-editor-controls .ui-widget-content .ui-state-default,
|
||||
#crayon-editor-controls .ui-widget-header .ui-state-default {
|
||||
border: none;
|
||||
background: #929292 url(images/button.png) center bottom repeat-x;
|
||||
font-weight: bold;
|
||||
color: #545454;
|
||||
border-top: 1px solid #ccc !important;
|
||||
}
|
||||
|
||||
#crayon-editor-controls .ui-state-hover,
|
||||
#crayon-editor-controls .ui-widget-content .ui-state-hover,
|
||||
#crayon-editor-controls .ui-widget-header .ui-state-hover,
|
||||
#crayon-editor-controls .ui-state-focus,
|
||||
#crayon-editor-controls .ui-widget-content .ui-state-focus,
|
||||
#crayon-editor-controls .ui-widget-header .ui-state-focus {
|
||||
border: none;
|
||||
background: #b3b3b3 url(images/button-pressed.png) center bottom repeat-x;
|
||||
border-top: 1px solid #eee !important;
|
||||
font-weight: bold;
|
||||
color: #00467a;
|
||||
}
|
||||
|
||||
#crayon-editor-controls .ui-state-active,
|
||||
#crayon-editor-controls .ui-widget-content .ui-state-active,
|
||||
#crayon-editor-controls .ui-widget-header .ui-state-active {
|
||||
border: none;
|
||||
background: #b3b3b3 url(images/button-pressed.png) center bottom repeat-x;
|
||||
font-weight: bold;
|
||||
color: #4f4f4f;
|
||||
border-top: 1px solid #eee !important;
|
||||
}
|
||||
|
||||
.wp-dialog {
|
||||
min-width: 300px;
|
||||
}
|
||||
|
||||
.wp-dialog .ui-dialog-content {
|
||||
padding: 10px;
|
||||
min-height: 10px !important;
|
||||
}
|
||||
|
||||
.wp-dialog .ui-dialog-content td {
|
||||
padding: 5px 0;
|
||||
}
|
||||
|
||||
.wp-dialog .ui-dialog-content .field-table td input,
|
||||
.wp-dialog .ui-dialog-content .field-table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.ui-colorpicker-dialog {
|
||||
width: 575px !important;
|
||||
height: 350px !important;
|
||||
/*position: fixed;*/
|
||||
/*left: auto;*/
|
||||
/*right: 450px;*/
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.ui-colorpicker-dialog .ui-colorpicker-bar-container {
|
||||
padding-right: 5px !important;
|
||||
}
|
||||
.ui-colorpicker-dialog .ui-dialog-buttonpane {
|
||||
margin-top: 0;
|
||||
padding-top: 0;
|
||||
}
|
||||
.ui-colorpicker-dialog .ui-dialog-content {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
/* {*/
|
||||
/*height: auto !important;*/
|
||||
/*}*/
|
655
util/theme-editor/theme_editor.js
Normal file
@ -0,0 +1,655 @@
|
||||
// Crayon Syntax Highlighter Theme Editor JavaScript
|
||||
|
||||
(function ($) {
|
||||
|
||||
CrayonSyntaxThemeEditor = new function () {
|
||||
|
||||
var base = this;
|
||||
|
||||
var crayonSettings = CrayonSyntaxSettings;
|
||||
var adminSettings = CrayonAdminSettings;
|
||||
var settings = CrayonThemeEditorSettings;
|
||||
var strings = CrayonThemeEditorStrings;
|
||||
var adminStrings = CrayonAdminStrings;
|
||||
var admin = CrayonSyntaxAdmin;
|
||||
|
||||
var preview, previewCrayon, previewCSS, status, title, info;
|
||||
var colorPickerPos;
|
||||
var changed, loaded;
|
||||
var themeID, themeJSON, themeCSS, themeStr, themeInfo;
|
||||
var reImportant = /\s+!important$/gmi;
|
||||
var reSize = /^[0-9-]+px$/;
|
||||
var reCopy = /-copy(-\d+)?$/;
|
||||
var changedAttr = 'data-value';
|
||||
var borderCSS = {'border': true, 'border-left': true, 'border-right': true, 'border-top': true, 'border-bottom': true};
|
||||
|
||||
base.init = function (callback) {
|
||||
// Called only once
|
||||
CrayonUtil.log('editor init');
|
||||
base.initUI();
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
base.show = function (callback, crayon) {
|
||||
// Called each time editor is shown
|
||||
previewCrayon = crayon.find('.crayon-syntax');
|
||||
preview.append(crayon)
|
||||
base.load();
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
base.load = function () {
|
||||
loaded = false;
|
||||
themeStr = adminSettings.currThemeCSS;
|
||||
themeID = adminSettings.currTheme;
|
||||
changed = false;
|
||||
themeJSON = CSSJSON.toJSON(themeStr, {
|
||||
stripComments: true,
|
||||
split: true
|
||||
});
|
||||
themeJSON = base.filterCSS(themeJSON);
|
||||
CrayonUtil.log(themeJSON);
|
||||
themeInfo = base.readCSSInfo(themeStr);
|
||||
base.removeExistingCSS();
|
||||
base.initInfoUI();
|
||||
base.updateTitle();
|
||||
base.updateInfo();
|
||||
base.setFieldValues(themeInfo);
|
||||
base.populateAttributes();
|
||||
base.updateLiveCSS();
|
||||
base.updateUI();
|
||||
loaded = true;
|
||||
};
|
||||
|
||||
base.save = function () {
|
||||
// Update info from form fields
|
||||
themeInfo = base.getFieldValues($.keys(themeInfo));
|
||||
// Get the names of the fields and map them to their values
|
||||
var names = base.getFieldNames(themeInfo);
|
||||
var info = {};
|
||||
for (var id in themeInfo) {
|
||||
info[names[id]] = themeInfo[id];
|
||||
}
|
||||
// Update attributes
|
||||
base.persistAttributes();
|
||||
// Save
|
||||
themeCSS = CSSJSON.toCSS(themeJSON);
|
||||
var newThemeStr = base.writeCSSInfo(info) + themeCSS;
|
||||
CrayonUtil.postAJAX({
|
||||
action: 'crayon-theme-editor-save',
|
||||
id: themeID,
|
||||
name: base.getName(),
|
||||
css: newThemeStr
|
||||
}, function (result) {
|
||||
status.show();
|
||||
result = parseInt(result);
|
||||
if (result > 0) {
|
||||
status.html(strings.success);
|
||||
if (result === 2) {
|
||||
window.GET['theme-editor'] = 1;
|
||||
CrayonUtil.reload();
|
||||
}
|
||||
} else {
|
||||
status.html(strings.fail);
|
||||
}
|
||||
changed = false;
|
||||
setTimeout(function () {
|
||||
status.fadeOut();
|
||||
}, 1000);
|
||||
});
|
||||
};
|
||||
|
||||
base.del = function (id, name) {
|
||||
admin.createDialog({
|
||||
title: strings.del,
|
||||
html: strings.deleteThemeConfirm.replace('%s', name),
|
||||
yes: function () {
|
||||
CrayonUtil.postAJAX({
|
||||
action: 'crayon-theme-editor-delete',
|
||||
id: id
|
||||
}, function (result) {
|
||||
if (result > 0) {
|
||||
CrayonUtil.reload();
|
||||
} else {
|
||||
admin.createAlert({
|
||||
html: strings.deleteFail + ' ' + strings.checkLog
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
options: {
|
||||
selectedButtonIndex: 2
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
base.duplicate = function (id, name) {
|
||||
base.createPrompt({
|
||||
//html: "Are you sure you want to duplicate the '" + name + "' theme?",
|
||||
title: strings.duplicate,
|
||||
text: strings.newName,
|
||||
value: base.getNextAvailableName(id),
|
||||
ok: function (val) {
|
||||
CrayonUtil.postAJAX({
|
||||
action: 'crayon-theme-editor-duplicate',
|
||||
id: id,
|
||||
name: val
|
||||
}, function (result) {
|
||||
if (result > 0) {
|
||||
CrayonUtil.reload();
|
||||
} else {
|
||||
admin.createAlert({
|
||||
html: strings.duplicateFail + ' ' + strings.checkLog
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
base.submit = function (id, name) {
|
||||
base.createPrompt({
|
||||
title: strings.submit,
|
||||
desc: strings.submitText,
|
||||
text: strings.message,
|
||||
value: strings.submitMessage,
|
||||
ok: function (val) {
|
||||
CrayonUtil.postAJAX({
|
||||
action: 'crayon-theme-editor-submit',
|
||||
id: id,
|
||||
message: val
|
||||
}, function (result) {
|
||||
var msg = result > 0 ? strings.submitSucceed : strings.submitFail + ' ' + strings.checkLog;
|
||||
admin.createAlert({
|
||||
html: msg
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
base.getNextAvailableName = function (id) {
|
||||
var next = base.getNextAvailableID(id);
|
||||
return base.idToName(next[1]);
|
||||
};
|
||||
|
||||
base.getNextAvailableID = function (id) {
|
||||
var themes = adminSettings.themes;
|
||||
var count = 0;
|
||||
if (reCopy.test(id)) {
|
||||
// Remove the "copy" if it already exists
|
||||
var newID = id.replace(reCopy, '');
|
||||
if (newID.length > 0) {
|
||||
id = newID;
|
||||
}
|
||||
}
|
||||
var nextID = id;
|
||||
while (nextID in themes) {
|
||||
count++;
|
||||
if (count == 1) {
|
||||
nextID = id + '-copy';
|
||||
} else {
|
||||
nextID = id + '-copy-' + count.toString();
|
||||
}
|
||||
}
|
||||
return [count, nextID];
|
||||
};
|
||||
|
||||
base.readCSSInfo = function (cssStr) {
|
||||
var infoStr = /^\s*\/\*[\s\S]*?\*\//gmi.exec(cssStr);
|
||||
var themeInfo = {};
|
||||
var match = null;
|
||||
var infoRegex = /([^\r\n:]*[^\r\n\s:])\s*:\s*([^\r\n]+)/gmi;
|
||||
while ((match = infoRegex.exec(infoStr)) != null) {
|
||||
themeInfo[base.nameToID(match[1])] = CrayonUtil.encode_html(match[2]);
|
||||
}
|
||||
// Force title case on the name
|
||||
if (themeInfo.name) {
|
||||
themeInfo.name = base.idToName(themeInfo.name);
|
||||
}
|
||||
return themeInfo;
|
||||
};
|
||||
|
||||
base.getFieldName = function (id) {
|
||||
var name = '';
|
||||
if (id in settings.fields) {
|
||||
name = settings.fields[id];
|
||||
} else {
|
||||
name = base.idToName(id);
|
||||
}
|
||||
return name;
|
||||
};
|
||||
|
||||
base.getFieldNames = function (fields) {
|
||||
var names = {};
|
||||
for (var id in fields) {
|
||||
names[id] = base.getFieldName(id);
|
||||
}
|
||||
return names;
|
||||
};
|
||||
|
||||
base.removeExistingCSS = function () {
|
||||
// Remove the old <style> tag to prevent clashes
|
||||
preview.find('link[rel="stylesheet"][href*="' + adminSettings.currThemeURL + '"]').remove()
|
||||
};
|
||||
|
||||
base.initInfoUI = function () {
|
||||
CrayonUtil.log(themeInfo);
|
||||
// TODO abstract
|
||||
var names = base.getFieldNames(themeInfo);
|
||||
var fields = {};
|
||||
for (var id in names) {
|
||||
var name = names[id];
|
||||
var value = themeInfo[id];
|
||||
fields[name] = base.createInput(id, value);
|
||||
}
|
||||
$('#tabs-1-contents').html(base.createForm(fields));
|
||||
base.getField('name').bind('change keydown keyup', function () {
|
||||
themeInfo.name = base.getFieldValue('name');
|
||||
base.updateTitle();
|
||||
});
|
||||
};
|
||||
|
||||
base.nameToID = function (name) {
|
||||
return name.toLowerCase().replace(/\s+/gmi, '-');
|
||||
};
|
||||
|
||||
base.idToName = function (id) {
|
||||
id = id.replace(/-/gmi, ' ');
|
||||
return id.toTitleCase();
|
||||
};
|
||||
|
||||
base.getName = function () {
|
||||
var name = themeInfo.name;
|
||||
if (!name) {
|
||||
name = base.idToName(themeID);
|
||||
}
|
||||
return name;
|
||||
};
|
||||
|
||||
base.getField = function (id) {
|
||||
return $('#' + settings.cssInputPrefix + id);
|
||||
};
|
||||
|
||||
base.getFieldValue = function (id) {
|
||||
return base.getElemValue(base.getField(id));
|
||||
};
|
||||
|
||||
base.getElemValue = function (elem) {
|
||||
if (elem) {
|
||||
// TODO add support for checkboxes etc.
|
||||
return elem.val();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
base.getFieldValues = function (fields) {
|
||||
var info = {};
|
||||
$(fields).each(function (i, id) {
|
||||
info[id] = base.getFieldValue(id);
|
||||
});
|
||||
return info;
|
||||
};
|
||||
|
||||
base.setFieldValue = function (id, value) {
|
||||
base.setElemValue(base.getField(id), value);
|
||||
};
|
||||
|
||||
base.setFieldValues = function (obj) {
|
||||
for (var i in obj) {
|
||||
base.setFieldValue(i, obj[i]);
|
||||
}
|
||||
};
|
||||
|
||||
base.setElemValue = function (elem, val) {
|
||||
if (elem) {
|
||||
// TODO add support for checkboxes etc.
|
||||
return elem.val(val);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
base.getAttribute = function (element, attribute) {
|
||||
return base.getField(element + '_' + attribute);
|
||||
};
|
||||
|
||||
base.getAttributes = function () {
|
||||
return $('.' + settings.cssInputPrefix + settings.attribute);
|
||||
};
|
||||
|
||||
base.visitAttribute = function (attr, callback) {
|
||||
var elems = themeJSON.children;
|
||||
var root = settings.cssThemePrefix + base.nameToID(themeInfo.name);
|
||||
var dataElem = attr.attr('data-element');
|
||||
var dataAttr = attr.attr('data-attribute');
|
||||
var elem = elems[root + dataElem];
|
||||
callback(attr, elem, dataElem, dataAttr, root, elems);
|
||||
};
|
||||
|
||||
base.persistAttributes = function (remove_default) {
|
||||
remove_default = CrayonUtil.setDefault(remove_default, true);
|
||||
base.getAttributes().each(function () {
|
||||
base.persistAttribute($(this), remove_default);
|
||||
});
|
||||
};
|
||||
|
||||
base.persistAttribute = function (attr, remove_default) {
|
||||
remove_default = CrayonUtil.setDefault(remove_default, true);
|
||||
base.visitAttribute(attr, function (attr, elem, dataElem, dataAttr, root, elems) {
|
||||
if (remove_default && attr.prop('tagName') == 'SELECT' && attr.val() == attr.attr('data-default')) {
|
||||
if (elem) {
|
||||
// If default is selected in a dropdown, then remove
|
||||
delete elem.attributes[dataAttr];
|
||||
}
|
||||
return;
|
||||
}
|
||||
var val = base.getElemValue(attr);
|
||||
if ((val == null || val == '')) {
|
||||
// No value given
|
||||
if (remove_default && elem) {
|
||||
delete elem.attributes[dataAttr];
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
val = base.addImportant(val);
|
||||
if (!elem) {
|
||||
elem = elems[root + dataElem] = {
|
||||
attributes: {},
|
||||
children: {}
|
||||
};
|
||||
}
|
||||
elem.attributes[dataAttr] = val;
|
||||
}
|
||||
CrayonUtil.log(dataElem + ' ' + dataAttr);
|
||||
});
|
||||
};
|
||||
|
||||
base.populateAttributes = function ($change) {
|
||||
var elems = themeJSON.children;
|
||||
var root = settings.cssThemePrefix + base.nameToID(themeInfo.name);
|
||||
CrayonUtil.log(elems, root);
|
||||
base.getAttributes().each(function () {
|
||||
base.visitAttribute($(this), function (attr, elem, dataElem, dataAttr, root, elems) {
|
||||
if (elem) {
|
||||
if (dataAttr in elem.attributes) {
|
||||
var val = base.removeImportant(elem.attributes[dataAttr]);
|
||||
base.setElemValue(attr, val);
|
||||
attr.trigger('change');
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
base.addImportant = function (attr) {
|
||||
if (!reImportant.test(attr)) {
|
||||
attr = attr + ' !important';
|
||||
}
|
||||
return attr;
|
||||
};
|
||||
|
||||
base.removeImportant = function (attr) {
|
||||
return attr.replace(reImportant, '');
|
||||
};
|
||||
|
||||
base.isImportant = function (attr) {
|
||||
return reImportant.exec(attr) != null;
|
||||
};
|
||||
|
||||
base.appendStyle = function (css) {
|
||||
previewCSS.html('<style>' + css + '</style>');
|
||||
};
|
||||
|
||||
base.removeStyle = function () {
|
||||
previewCSS.html('');
|
||||
};
|
||||
|
||||
base.writeCSSInfo = function (info) {
|
||||
var infoStr = '/*\n';
|
||||
for (var field in info) {
|
||||
infoStr += field + ': ' + info[field] + '\n';
|
||||
}
|
||||
return infoStr + '*/\n';
|
||||
};
|
||||
|
||||
base.filterCSS = function (css) {
|
||||
// Split all border CSS attributes into individual attributes
|
||||
for (var child in css.children) {
|
||||
var atts = css.children[child].attributes;
|
||||
for (var att in atts) {
|
||||
if (att in borderCSS) {
|
||||
var rules = base.getBorderCSS(atts[att]);
|
||||
for (var rule in rules) {
|
||||
atts[att + '-' + rule] = rules[rule];
|
||||
}
|
||||
delete atts[att];
|
||||
}
|
||||
}
|
||||
}
|
||||
return css;
|
||||
},
|
||||
|
||||
base.getBorderCSS = function (css) {
|
||||
var result = {};
|
||||
var important = base.isImportant(css);
|
||||
$.each(strings.borderStyles, function (i, style) {
|
||||
if (css.indexOf(style) >= 0) {
|
||||
result.style = style;
|
||||
}
|
||||
});
|
||||
var width = /\d+\s*(px|%|em|rem)/gi.exec(css);
|
||||
if (width) {
|
||||
result.width = width[0];
|
||||
}
|
||||
var color = /#\w+/gi.exec(css);
|
||||
if (color) {
|
||||
result.color = color[0];
|
||||
}
|
||||
if (important) {
|
||||
for (var rule in result) {
|
||||
result[rule] = base.addImportant(result[rule]);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
base.createPrompt = function (args) {
|
||||
args = $.extend({
|
||||
title: adminStrings.prompt,
|
||||
text: adminStrings.value,
|
||||
desc: null,
|
||||
value: '',
|
||||
options: {
|
||||
buttons: {
|
||||
"OK": function () {
|
||||
if (args.ok) {
|
||||
args.ok(base.getFieldValue('prompt-text'));
|
||||
}
|
||||
$(this).crayonDialog('close');
|
||||
},
|
||||
"Cancel": function () {
|
||||
$(this).crayonDialog('close');
|
||||
}
|
||||
},
|
||||
open: function () {
|
||||
base.getField('prompt-text').val(args.value).focus();
|
||||
}
|
||||
}
|
||||
}, args);
|
||||
args.html = '<table class="field-table crayon-prompt-' + base.nameToID(args.title) + '">';
|
||||
if (args.desc) {
|
||||
args.html += '<tr><td colspan="2">' + args.desc + '</td></tr>';
|
||||
}
|
||||
args.html += '<tr><td>' + args.text + ':</td><td>' + base.createInput('prompt-text') + '</td></tr>';
|
||||
args.html += '</table>';
|
||||
var options = {width: '400px'};
|
||||
admin.createDialog(args, options);
|
||||
};
|
||||
|
||||
base.initUI = function () {
|
||||
// Bind events
|
||||
preview = $('#crayon-editor-preview');
|
||||
previewCSS = $('#crayon-editor-preview-css');
|
||||
status = $('#crayon-editor-status');
|
||||
title = $('#crayon-theme-editor-name');
|
||||
info = $('#crayon-theme-editor-info');
|
||||
$('#crayon-editor-controls').tabs();
|
||||
$('#crayon-editor-back').click(function () {
|
||||
if (changed) {
|
||||
admin.createDialog({
|
||||
html: strings.discardConfirm,
|
||||
title: adminStrings.confirm,
|
||||
yes: function () {
|
||||
showMain();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
showMain();
|
||||
}
|
||||
});
|
||||
$('#crayon-editor-save').click(base.save);
|
||||
|
||||
// Set up jQuery UI
|
||||
base.getAttributes().each(function () {
|
||||
var attr = $(this);
|
||||
var type = attr.attr('data-group');
|
||||
if (type == 'color') {
|
||||
var args = {
|
||||
parts: 'full',
|
||||
showNoneButton: true,
|
||||
colorFormat: '#HEX'
|
||||
};
|
||||
args.open = function (e, color) {
|
||||
$('.ui-colorpicker-dialog .ui-button').addClass('button-primary');
|
||||
if (colorPickerPos) {
|
||||
var picker = $('.ui-colorpicker-dialog:visible');
|
||||
picker.css('left', colorPickerPos.left);
|
||||
// picker.css('top', colorPickerPos.top);
|
||||
}
|
||||
};
|
||||
args.select = function (e, color) {
|
||||
attr.trigger('change');
|
||||
};
|
||||
args.close = function (e, color) {
|
||||
attr.trigger('change');
|
||||
};
|
||||
attr.colorpicker(args);
|
||||
attr.bind('change', function () {
|
||||
var hex = attr.val();
|
||||
attr.css('background-color', hex);
|
||||
attr.css('color', CrayonUtil.getReadableColor(hex));
|
||||
});
|
||||
} else if (type == 'size') {
|
||||
attr.bind('change', function () {
|
||||
var val = attr.val();
|
||||
if (!reSize.test(val)) {
|
||||
val = CrayonUtil.removeChars('^0-9-', val);
|
||||
if (val != '') {
|
||||
attr.val(val + 'px');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
if (type != 'color') {
|
||||
// For regular text boxes, capture changes on keys
|
||||
attr.bind('keydown keyup', function () {
|
||||
if (attr.attr(changedAttr) != attr.val()) {
|
||||
CrayonUtil.log('triggering', attr.attr(changedAttr), attr.val());
|
||||
attr.trigger('change');
|
||||
}
|
||||
});
|
||||
}
|
||||
// Update CSS changes to the live instance
|
||||
attr.bind('change', function () {
|
||||
if (attr.attr(changedAttr) == attr.val()) {
|
||||
return;
|
||||
} else {
|
||||
attr.attr(changedAttr, attr.val());
|
||||
}
|
||||
if (loaded) {
|
||||
base.persistAttribute(attr);
|
||||
base.updateLiveCSS();
|
||||
}
|
||||
});
|
||||
});
|
||||
$('.ui-colorpicker-dialog').addClass('wp-dialog');
|
||||
$('.ui-colorpicker-dialog').mouseup(function () {
|
||||
base.colorPickerMove($(this));
|
||||
});
|
||||
};
|
||||
|
||||
base.colorPickerMove = function (picker) {
|
||||
if (picker) {
|
||||
colorPickerPos = {left: picker.css('left'), top: picker.css('top')};
|
||||
}
|
||||
};
|
||||
|
||||
base.updateLiveCSS = function (clone) {
|
||||
clone = CrayonUtil.setDefault(clone, false);
|
||||
if (previewCrayon) {
|
||||
var json;
|
||||
if (clone) {
|
||||
var id = previewCrayon.attr('id');
|
||||
json = $.extend(true, {}, themeJSON);
|
||||
$.each(json.children, function (child) {
|
||||
json.children['#' + id + child] = json.children[child];
|
||||
delete json.children[child];
|
||||
});
|
||||
} else {
|
||||
json = themeJSON;
|
||||
}
|
||||
base.appendStyle(CSSJSON.toCSS(json));
|
||||
}
|
||||
};
|
||||
|
||||
base.updateUI = function () {
|
||||
$('#crayon-editor-controls input, #crayon-editor-controls select').bind('change', function () {
|
||||
changed = true;
|
||||
});
|
||||
};
|
||||
|
||||
base.createInput = function (id, value, type) {
|
||||
value = CrayonUtil.setDefault(value, '');
|
||||
type = CrayonUtil.setDefault(type, 'text');
|
||||
return '<input id="' + settings.cssInputPrefix + id + '" class="' + settings.cssInputPrefix + type + '" type="' + type + '" value="' + value + '" />';
|
||||
};
|
||||
|
||||
base.createForm = function (inputs) {
|
||||
var str = '<form class="' + settings.prefix + '-form"><table>';
|
||||
$.each(inputs, function (input) {
|
||||
str += '<tr><td class="field">' + input + '</td><td class="value">' + inputs[input] + '</td></tr>';
|
||||
});
|
||||
str += '</table></form>';
|
||||
return str;
|
||||
};
|
||||
|
||||
var showMain = function () {
|
||||
admin.resetPreview();
|
||||
admin.preview_update();
|
||||
admin.show_theme_info();
|
||||
admin.show_main();
|
||||
//preview.html('');
|
||||
};
|
||||
|
||||
base.updateTitle = function () {
|
||||
var name = base.getName();
|
||||
if (adminSettings.editing_theme) {
|
||||
title.html(strings.editingTheme.replace('%s', name));
|
||||
} else {
|
||||
title.html(strings.creatingTheme.replace('%s', name));
|
||||
}
|
||||
};
|
||||
|
||||
base.updateInfo = function () {
|
||||
info.html('<a target="_blank" href="' + adminSettings.currThemeURL + '">' + adminSettings.currThemeURL + '</a>');
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
})(jQueryCrayon);
|
879
util/theme-editor/theme_editor.php
Normal file
@ -0,0 +1,879 @@
|
||||
<?php
|
||||
|
||||
class CrayonHTMLElement {
|
||||
public $id;
|
||||
public $class = '';
|
||||
public $tag = 'div';
|
||||
public $closed = FALSE;
|
||||
public $contents = '';
|
||||
public $attributes = array();
|
||||
const CSS_INPUT_PREFIX = "crayon-theme-input-";
|
||||
|
||||
public static $borderStyles = array(
|
||||
'none',
|
||||
'hidden',
|
||||
'dotted',
|
||||
'dashed',
|
||||
'solid',
|
||||
'double',
|
||||
'groove',
|
||||
'ridge',
|
||||
'inset',
|
||||
'outset',
|
||||
'inherit'
|
||||
);
|
||||
|
||||
public function __construct($id) {
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
public function addClass($class) {
|
||||
$this->class .= ' ' . self::CSS_INPUT_PREFIX . $class;
|
||||
}
|
||||
|
||||
public function addAttributes($atts) {
|
||||
$this->attributes = array_merge($this->attributes, $atts);
|
||||
}
|
||||
|
||||
public function attributeString() {
|
||||
$str = '';
|
||||
foreach ($this->attributes as $k => $v) {
|
||||
$str .= "$k=\"$v\" ";
|
||||
}
|
||||
return $str;
|
||||
}
|
||||
|
||||
public function __toString() {
|
||||
return '<' . $this->tag . ' id="' . self::CSS_INPUT_PREFIX . $this->id . '" class="' . self::CSS_INPUT_PREFIX . $this->class . '" ' . $this->attributeString() . ($this->closed ? ' />' : ' >' . $this->contents . "</$this->tag>");
|
||||
}
|
||||
}
|
||||
|
||||
class CrayonHTMLInput extends CrayonHTMLElement {
|
||||
public $name;
|
||||
public $type;
|
||||
|
||||
public function __construct($id, $name = NULL, $value = '', $type = 'text') {
|
||||
parent::__construct($id);
|
||||
$this->tag = 'input';
|
||||
$this->closed = TRUE;
|
||||
if ($name === NULL) {
|
||||
$name = CrayonUserResource::clean_name($id);
|
||||
}
|
||||
$this->name = $name;
|
||||
$this->class .= $type;
|
||||
$this->addAttributes(array(
|
||||
'type' => $type,
|
||||
'value' => $value
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
class CrayonHTMLSelect extends CrayonHTMLInput {
|
||||
public $options;
|
||||
public $selected = NULL;
|
||||
|
||||
public function __construct($id, $name = NULL, $value = '', $options = array()) {
|
||||
parent::__construct($id, $name, 'select');
|
||||
$this->tag = 'select';
|
||||
$this->closed = FALSE;
|
||||
$this->addOptions($options);
|
||||
}
|
||||
|
||||
public function addOptions($options, $default = NULL) {
|
||||
for ($i = 0; $i < count($options); $i++) {
|
||||
$key = $options[$i];
|
||||
$value = isset($options[$key]) ? $options[$key] : $key;
|
||||
$this->options[$key] = $value;
|
||||
}
|
||||
if ($default === NULL && count($options) > 1) {
|
||||
$this->attributes['data-default'] = $options[0];
|
||||
} else {
|
||||
$this->attributes['data-default'] = $default;
|
||||
}
|
||||
}
|
||||
|
||||
public function getOptionsString() {
|
||||
$str = '';
|
||||
foreach ($this->options as $k => $v) {
|
||||
$selected = $this->selected == $k ? 'selected="selected"' : '';
|
||||
$str .= "<option value=\"$k\" $selected>$v</option>";
|
||||
}
|
||||
return $str;
|
||||
}
|
||||
|
||||
public function __toString() {
|
||||
$this->contents = $this->getOptionsString();
|
||||
return parent::__toString();
|
||||
}
|
||||
}
|
||||
|
||||
class CrayonHTMLSeparator extends CrayonHTMLElement {
|
||||
public $name = '';
|
||||
|
||||
public function __construct($name) {
|
||||
parent::__construct($name);
|
||||
$this->name = $name;
|
||||
}
|
||||
}
|
||||
|
||||
class CrayonHTMLTitle extends CrayonHTMLSeparator {
|
||||
|
||||
}
|
||||
|
||||
class CrayonThemeEditorWP {
|
||||
|
||||
public static $attributes = NULL;
|
||||
public static $attributeGroups = NULL;
|
||||
public static $attributeGroupsInverse = NULL;
|
||||
public static $attributeTypes = NULL;
|
||||
public static $attributeTypesInverse = NULL;
|
||||
public static $infoFields = NULL;
|
||||
public static $infoFieldsInverse = NULL;
|
||||
public static $settings = NULL;
|
||||
public static $strings = NULL;
|
||||
|
||||
const ATTRIBUTE = 'attribute';
|
||||
|
||||
const RE_COMMENT = '#^\s*\/\*[\s\S]*?\*\/#msi';
|
||||
|
||||
public static function initFields() {
|
||||
if (self::$infoFields === NULL) {
|
||||
self::$infoFields = array(
|
||||
// These are canonical and can't be translated, since they appear in the comments of the CSS
|
||||
'name' => 'Name',
|
||||
'description' => 'Description',
|
||||
'version' => 'Version',
|
||||
'author' => 'Author',
|
||||
'url' => 'URL',
|
||||
'original-author' => 'Original Author',
|
||||
'notes' => 'Notes',
|
||||
'maintainer' => 'Maintainer',
|
||||
'maintainer-url' => 'Maintainer URL'
|
||||
);
|
||||
self::$infoFieldsInverse = CrayonUtil::array_flip(self::$infoFields);
|
||||
// A map of CSS element name and property to name
|
||||
self::$attributes = array();
|
||||
// A map of CSS attribute to input type
|
||||
self::$attributeGroups = array(
|
||||
'color' => array('background', 'background-color', 'border-color', 'color', 'border-top-color', 'border-bottom-color', 'border-left-color', 'border-right-color'),
|
||||
'size' => array('border-width'),
|
||||
'border-style' => array('border-style', 'border-bottom-style', 'border-top-style', 'border-left-style', 'border-right-style')
|
||||
);
|
||||
self::$attributeGroupsInverse = CrayonUtil::array_flip(self::$attributeGroups);
|
||||
// Mapping of input type to attribute group
|
||||
self::$attributeTypes = array(
|
||||
'select' => array('border-style', 'font-style', 'font-weight', 'text-decoration')
|
||||
);
|
||||
self::$attributeTypesInverse = CrayonUtil::array_flip(self::$attributeTypes);
|
||||
}
|
||||
}
|
||||
|
||||
public static function initSettings() {
|
||||
CrayonSettingsWP::load_settings();
|
||||
self::initFields();
|
||||
self::initStrings();
|
||||
if (self::$settings === NULL) {
|
||||
self::$settings = array(
|
||||
// Only things the theme editor needs
|
||||
'cssThemePrefix' => CrayonThemes::CSS_PREFIX,
|
||||
'cssInputPrefix' => CrayonHTMLElement::CSS_INPUT_PREFIX,
|
||||
'attribute' => self::ATTRIBUTE,
|
||||
'fields' => self::$infoFields,
|
||||
'fieldsInverse' => self::$infoFieldsInverse,
|
||||
'prefix' => 'crayon-theme-editor'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public static function initStrings() {
|
||||
if (self::$strings === NULL) {
|
||||
self::$strings = array(
|
||||
// These appear only in the UI and can be translated
|
||||
'userTheme' => crayon__("User-Defined Theme"),
|
||||
'stockTheme' => crayon__("Stock Theme"),
|
||||
'success' => crayon__("Success!"),
|
||||
'fail' => crayon__("Failed!"),
|
||||
'delete' => crayon__("Delete"),
|
||||
'deleteThemeConfirm' => crayon__("Are you sure you want to delete the \"%s\" theme?"),
|
||||
'deleteFail' => crayon__("Delete failed!"),
|
||||
'duplicate' => crayon__("Duplicate"),
|
||||
'newName' => crayon__("New Name"),
|
||||
'duplicateFail' => crayon__("Duplicate failed!"),
|
||||
'checkLog' => crayon__("Please check the log for details."),
|
||||
'discardConfirm' => crayon__("Are you sure you want to discard all changes?"),
|
||||
'editingTheme' => crayon__("Editing Theme: %s"),
|
||||
'creatingTheme' => crayon__("Creating Theme: %s"),
|
||||
'submit' => crayon__("Submit Your Theme"),
|
||||
'submitText' => crayon__("Submit your User Theme for inclusion as a Stock Theme in Crayon! This will email me your theme - make sure it's considerably different from the stock themes :)"),
|
||||
'message' => crayon__("Message"),
|
||||
'submitMessage' => crayon__("Please include this theme in Crayon!"),
|
||||
'submitSucceed' => crayon__("Submit was successful."),
|
||||
'submitFail' => crayon__("Submit failed!"),
|
||||
'borderStyles' => CrayonHTMLElement::$borderStyles
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public static function admin_resources() {
|
||||
global $CRAYON_VERSION;
|
||||
self::initSettings();
|
||||
$path = dirname(dirname(__FILE__));
|
||||
|
||||
wp_enqueue_script('cssjson_js', plugins_url(CRAYON_CSSJSON_JS, $path), $CRAYON_VERSION);
|
||||
wp_enqueue_script('jquery_colorpicker_js', plugins_url(CRAYON_JS_JQUERY_COLORPICKER, $path), array('jquery', 'jquery-ui-core', 'jquery-ui-widget', 'jquery-ui-tabs', 'jquery-ui-draggable', 'jquery-ui-dialog', 'jquery-ui-position', 'jquery-ui-mouse', 'jquery-ui-slider', 'jquery-ui-droppable', 'jquery-ui-selectable', 'jquery-ui-resizable'), $CRAYON_VERSION);
|
||||
wp_enqueue_script('jquery_tinycolor_js', plugins_url(CRAYON_JS_TINYCOLOR, $path), array(), $CRAYON_VERSION);
|
||||
|
||||
if (CRAYON_MINIFY) {
|
||||
wp_enqueue_script('crayon_theme_editor', plugins_url(CRAYON_THEME_EDITOR_JS, $path), array('jquery', 'crayon_js', 'crayon_admin_js', 'cssjson_js', 'jquery_colorpicker_js', 'jquery_tinycolor_js'), $CRAYON_VERSION);
|
||||
} else {
|
||||
wp_enqueue_script('crayon_theme_editor', plugins_url(CRAYON_THEME_EDITOR_JS, $path), array('jquery', 'crayon_util_js', 'crayon_admin_js', 'cssjson_js', 'jquery_colorpicker_js', 'jquery_tinycolor_js'), $CRAYON_VERSION);
|
||||
}
|
||||
|
||||
wp_localize_script('crayon_theme_editor', 'CrayonThemeEditorSettings', self::$settings);
|
||||
wp_localize_script('crayon_theme_editor', 'CrayonThemeEditorStrings', self::$strings);
|
||||
|
||||
wp_enqueue_style('crayon_theme_editor', plugins_url(CRAYON_THEME_EDITOR_STYLE, $path), array('wp-jquery-ui-dialog'), $CRAYON_VERSION);
|
||||
wp_enqueue_style('jquery_colorpicker', plugins_url(CRAYON_CSS_JQUERY_COLORPICKER, $path), array(), $CRAYON_VERSION);
|
||||
}
|
||||
|
||||
public static function form($inputs) {
|
||||
$str = '<form class="' . self::$settings['prefix'] . '-form"><table>';
|
||||
$sepCount = 0;
|
||||
foreach ($inputs as $input) {
|
||||
if ($input instanceof CrayonHTMLInput) {
|
||||
$str .= self::formField($input->name, $input);
|
||||
} else if ($input instanceof CrayonHTMLSeparator) {
|
||||
$sepClass = '';
|
||||
if ($input instanceof CrayonHTMLTitle) {
|
||||
$sepClass .= ' title';
|
||||
}
|
||||
if ($sepCount == 0) {
|
||||
$sepClass .= ' first';
|
||||
}
|
||||
$str .= '<tr class="separator' . $sepClass . '"><td colspan="2"><div class="content">' . $input->name . '</div></td></tr>';
|
||||
$sepCount++;
|
||||
} else if (is_array($input) && count($input) > 1) {
|
||||
$name = $input[0];
|
||||
$fields = '<table class="split-field"><tr>';
|
||||
$percent = 100 / count($input);
|
||||
for ($i = 1; $i < count($input); $i++) {
|
||||
$class = $i == count($input) - 1 ? 'class="last"' : '';
|
||||
$fields .= '<td ' . $class . ' style="width: ' . $percent . '%">' . $input[$i] . '</td>';
|
||||
}
|
||||
$fields .= '</tr></table>';
|
||||
$str .= self::formField($name, $fields, 'split');
|
||||
}
|
||||
}
|
||||
$str .= '</table></form>';
|
||||
return $str;
|
||||
}
|
||||
|
||||
public static function formField($name, $field, $class = '') {
|
||||
return '<tr><td class="field ' . $class . '">' . $name . '</td><td class="value ' . $class . '">' . $field . '</td></tr>';
|
||||
}
|
||||
|
||||
public static function content() {
|
||||
self::initSettings();
|
||||
$theme = CrayonResources::themes()->get_default();
|
||||
$editing = false;
|
||||
|
||||
if (isset($_GET['curr_theme'])) {
|
||||
$currTheme = CrayonResources::themes()->get($_GET['curr_theme']);
|
||||
if ($currTheme) {
|
||||
$theme = $currTheme;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($_GET['editing'])) {
|
||||
$editing = CrayonUtil::str_to_bool($_GET['editing'], FALSE);
|
||||
}
|
||||
|
||||
$tInformation = crayon__("Information");
|
||||
$tHighlighting = crayon__("Highlighting");
|
||||
$tFrame = crayon__("Frame");
|
||||
$tLines = crayon__("Lines");
|
||||
$tNumbers = crayon__("Line Numbers");
|
||||
$tToolbar = crayon__("Toolbar");
|
||||
|
||||
$tBackground = crayon__("Background");
|
||||
$tText = crayon__("Text");
|
||||
$tBorder = crayon__("Border");
|
||||
$tTopBorder = crayon__("Top Border");
|
||||
$tBottomBorder = crayon__("Bottom Border");
|
||||
$tBorderRight = crayon__("Right Border");
|
||||
|
||||
$tHover = crayon__("Hover");
|
||||
$tActive = crayon__("Active");
|
||||
$tPressed = crayon__("Pressed");
|
||||
$tHoverPressed = crayon__("Pressed & Hover");
|
||||
$tActivePressed = crayon__("Pressed & Active");
|
||||
|
||||
$tTitle = crayon__("Title");
|
||||
$tButtons = crayon__("Buttons");
|
||||
|
||||
$tNormal = crayon__("Normal");
|
||||
$tInline = crayon__("Inline");
|
||||
$tStriped = crayon__("Striped");
|
||||
$tMarked = crayon__("Marked");
|
||||
$tStripedMarked = crayon__("Striped & Marked");
|
||||
$tLanguage = crayon__("Language");
|
||||
|
||||
$top = '.crayon-top';
|
||||
$bottom = '.crayon-bottom';
|
||||
$hover = ':hover';
|
||||
$active = ':active';
|
||||
$pressed = '.crayon-pressed';
|
||||
|
||||
?>
|
||||
|
||||
<div
|
||||
id="icon-options-general" class="icon32"></div>
|
||||
<h2>
|
||||
Crayon Syntax Highlighter
|
||||
<?php crayon_e('Theme Editor'); ?>
|
||||
</h2>
|
||||
|
||||
<h3 id="<?php echo self::$settings['prefix'] ?>-name">
|
||||
<?php
|
||||
// if ($editing) {
|
||||
// echo sprintf(crayon__('Editing "%s" Theme'), $theme->name());
|
||||
// } else {
|
||||
// echo sprintf(crayon__('Creating Theme From "%s"'), $theme->name());
|
||||
// }
|
||||
?>
|
||||
</h3>
|
||||
<div id="<?php echo self::$settings['prefix'] ?>-info"></div>
|
||||
|
||||
<p>
|
||||
<a id="crayon-editor-back" class="button-primary"><?php crayon_e("Back To Settings"); ?></a>
|
||||
<a id="crayon-editor-save" class="button-primary"><?php crayon_e("Save"); ?></a>
|
||||
<span id="crayon-editor-status"></span>
|
||||
</p>
|
||||
|
||||
<?php //crayon_e('Use the Sidebar on the right to change the Theme of the Preview window.') ?>
|
||||
|
||||
<div id="crayon-editor-top-controls"></div>
|
||||
|
||||
<table id="crayon-editor-table" style="width: 100%;" cellspacing="5"
|
||||
cellpadding="0">
|
||||
<tr>
|
||||
<td id="crayon-editor-preview-wrapper">
|
||||
<div id="crayon-editor-preview"></div>
|
||||
</td>
|
||||
<div id="crayon-editor-preview-css"></div>
|
||||
<td id="crayon-editor-control-wrapper">
|
||||
<div id="crayon-editor-controls">
|
||||
<ul>
|
||||
<li title="<?php echo $tInformation ?>"><a class="crayon-tab-information" href="#tabs-1"></a></li>
|
||||
<li title="<?php echo $tHighlighting ?>"><a class="crayon-tab-highlighting" href="#tabs-2"></a></li>
|
||||
<li title="<?php echo $tFrame ?>"><a class="crayon-tab-frame" href="#tabs-3"></a></li>
|
||||
<li title="<?php echo $tLines ?>"><a class="crayon-tab-lines" href="#tabs-4"></a></li>
|
||||
<li title="<?php echo $tNumbers ?>"><a class="crayon-tab-numbers" href="#tabs-5"></a></li>
|
||||
<li title="<?php echo $tToolbar ?>"><a class="crayon-tab-toolbar" href="#tabs-6"></a></li>
|
||||
</ul>
|
||||
<div id="tabs-1">
|
||||
<?php
|
||||
self::createAttributesForm(array(
|
||||
new CrayonHTMLTitle($tInformation)
|
||||
));
|
||||
?>
|
||||
<div id="tabs-1-contents"></div>
|
||||
<!-- Auto-filled by theme_editor.js -->
|
||||
</div>
|
||||
<div id="tabs-2">
|
||||
<?php
|
||||
$highlight = ' .crayon-pre';
|
||||
$elems = array(
|
||||
'c' => crayon__("Comment"),
|
||||
's' => crayon__("String"),
|
||||
'p' => crayon__("Preprocessor"),
|
||||
'ta' => crayon__("Tag"),
|
||||
'k' => crayon__("Keyword"),
|
||||
'st' => crayon__("Statement"),
|
||||
'r' => crayon__("Reserved"),
|
||||
't' => crayon__("Type"),
|
||||
'm' => crayon__("Modifier"),
|
||||
'i' => crayon__("Identifier"),
|
||||
'e' => crayon__("Entity"),
|
||||
'v' => crayon__("Variable"),
|
||||
'cn' => crayon__("Constant"),
|
||||
'o' => crayon__("Operator"),
|
||||
'sy' => crayon__("Symbol"),
|
||||
'n' => crayon__("Notation"),
|
||||
'f' => crayon__("Faded"),
|
||||
'h' => crayon__("HTML"),
|
||||
'' => crayon__("Unhighlighted")
|
||||
);
|
||||
$atts = array(new CrayonHTMLTitle($tHighlighting));
|
||||
foreach ($elems as $class => $name) {
|
||||
$fullClass = $class != '' ? $highlight . ' .crayon-' . $class : $highlight;
|
||||
$atts[] = array(
|
||||
$name,
|
||||
self::createAttribute($fullClass, 'color'),
|
||||
self::createAttribute($fullClass, 'font-weight'),
|
||||
self::createAttribute($fullClass, 'font-style'),
|
||||
self::createAttribute($fullClass, 'text-decoration')
|
||||
);
|
||||
}
|
||||
self::createAttributesForm($atts);
|
||||
?>
|
||||
</div>
|
||||
<div id="tabs-3">
|
||||
<?php
|
||||
$inline = '-inline';
|
||||
self::createAttributesForm(array(
|
||||
new CrayonHTMLTitle($tFrame),
|
||||
new CrayonHTMLSeparator($tNormal),
|
||||
// self::createAttribute('', 'background', $tBackground),
|
||||
array(
|
||||
$tBorder,
|
||||
self::createAttribute('', 'border-width'),
|
||||
self::createAttribute('', 'border-color'),
|
||||
self::createAttribute('', 'border-style')
|
||||
),
|
||||
new CrayonHTMLSeparator($tInline),
|
||||
self::createAttribute($inline, 'background', $tBackground),
|
||||
array(
|
||||
$tBorder,
|
||||
self::createAttribute($inline, 'border-width'),
|
||||
self::createAttribute($inline, 'border-color'),
|
||||
self::createAttribute($inline, 'border-style')
|
||||
),
|
||||
));
|
||||
?>
|
||||
</div>
|
||||
<div id="tabs-4">
|
||||
<?php
|
||||
$stripedLine = ' .crayon-striped-line';
|
||||
$markedLine = ' .crayon-marked-line';
|
||||
$stripedMarkedLine = ' .crayon-marked-line.crayon-striped-line';
|
||||
self::createAttributesForm(array(
|
||||
new CrayonHTMLTitle($tLines),
|
||||
new CrayonHTMLSeparator($tNormal),
|
||||
self::createAttribute('', 'background', $tBackground),
|
||||
new CrayonHTMLSeparator($tStriped),
|
||||
self::createAttribute($stripedLine, 'background', $tBackground),
|
||||
new CrayonHTMLSeparator($tMarked),
|
||||
self::createAttribute($markedLine, 'background', $tBackground),
|
||||
array(
|
||||
$tBorder,
|
||||
self::createAttribute($markedLine, 'border-width'),
|
||||
self::createAttribute($markedLine, 'border-color'),
|
||||
self::createAttribute($markedLine, 'border-style'),
|
||||
),
|
||||
self::createAttribute($markedLine . $top, 'border-top-style', $tTopBorder),
|
||||
self::createAttribute($markedLine . $bottom, 'border-bottom-style', $tBottomBorder),
|
||||
new CrayonHTMLSeparator($tStripedMarked),
|
||||
self::createAttribute($stripedMarkedLine, 'background', $tBackground),
|
||||
));
|
||||
?>
|
||||
</div>
|
||||
<div id="tabs-5">
|
||||
<?php
|
||||
$nums = ' .crayon-table .crayon-nums';
|
||||
$stripedNum = ' .crayon-striped-num';
|
||||
$markedNum = ' .crayon-marked-num';
|
||||
$stripedMarkedNum = ' .crayon-marked-num.crayon-striped-num';
|
||||
self::createAttributesForm(array(
|
||||
new CrayonHTMLTitle($tNumbers),
|
||||
array(
|
||||
$tBorderRight,
|
||||
self::createAttribute($nums, 'border-right-width'),
|
||||
self::createAttribute($nums, 'border-right-color'),
|
||||
self::createAttribute($nums, 'border-right-style'),
|
||||
),
|
||||
new CrayonHTMLSeparator($tNormal),
|
||||
self::createAttribute($nums, 'background', $tBackground),
|
||||
self::createAttribute($nums, 'color', $tText),
|
||||
new CrayonHTMLSeparator($tStriped),
|
||||
self::createAttribute($stripedNum, 'background', $tBackground),
|
||||
self::createAttribute($stripedNum, 'color', $tText),
|
||||
new CrayonHTMLSeparator($tMarked),
|
||||
self::createAttribute($markedNum, 'background', $tBackground),
|
||||
self::createAttribute($markedNum, 'color', $tText),
|
||||
array(
|
||||
$tBorder,
|
||||
self::createAttribute($markedNum, 'border-width'),
|
||||
self::createAttribute($markedNum, 'border-color'),
|
||||
self::createAttribute($markedNum, 'border-style'),
|
||||
),
|
||||
self::createAttribute($markedNum.$top, 'border-top-style', $tTopBorder),
|
||||
self::createAttribute($markedNum.$bottom, 'border-bottom-style', $tBottomBorder),
|
||||
new CrayonHTMLSeparator($tStripedMarked),
|
||||
self::createAttribute($stripedMarkedNum, 'background', $tBackground),
|
||||
self::createAttribute($stripedMarkedNum, 'color', $tText),
|
||||
));
|
||||
?>
|
||||
</div>
|
||||
<div id="tabs-6">
|
||||
<?php
|
||||
$toolbar = ' .crayon-toolbar';
|
||||
$title = ' .crayon-title';
|
||||
$button = ' .crayon-button';
|
||||
$info = ' .crayon-info';
|
||||
$language = ' .crayon-language';
|
||||
self::createAttributesForm(array(
|
||||
new CrayonHTMLTitle($tToolbar),
|
||||
new CrayonHTMLSeparator($tFrame),
|
||||
self::createAttribute($toolbar, 'background', $tBackground),
|
||||
array(
|
||||
$tBottomBorder,
|
||||
self::createAttribute($toolbar, 'border-bottom-width'),
|
||||
self::createAttribute($toolbar, 'border-bottom-color'),
|
||||
self::createAttribute($toolbar, 'border-bottom-style'),
|
||||
),
|
||||
array(
|
||||
$tTitle,
|
||||
self::createAttribute($title, 'color'),
|
||||
self::createAttribute($title, 'font-weight'),
|
||||
self::createAttribute($title, 'font-style'),
|
||||
self::createAttribute($title, 'text-decoration')
|
||||
),
|
||||
new CrayonHTMLSeparator($tButtons),
|
||||
self::createAttribute($button, 'background-color', $tBackground),
|
||||
self::createAttribute($button.$hover, 'background-color', $tHover),
|
||||
self::createAttribute($button.$active, 'background-color', $tActive),
|
||||
self::createAttribute($button.$pressed, 'background-color', $tPressed),
|
||||
self::createAttribute($button.$pressed.$hover, 'background-color', $tHoverPressed),
|
||||
self::createAttribute($button.$pressed.$active, 'background-color', $tActivePressed),
|
||||
new CrayonHTMLSeparator($tInformation . ' ' . crayon__("(Used for Copy/Paste)")),
|
||||
self::createAttribute($info, 'background', $tBackground),
|
||||
array(
|
||||
$tText,
|
||||
self::createAttribute($info, 'color'),
|
||||
self::createAttribute($info, 'font-weight'),
|
||||
self::createAttribute($info, 'font-style'),
|
||||
self::createAttribute($info, 'text-decoration')
|
||||
),
|
||||
array(
|
||||
$tBottomBorder,
|
||||
self::createAttribute($info, 'border-bottom-width'),
|
||||
self::createAttribute($info, 'border-bottom-color'),
|
||||
self::createAttribute($info, 'border-bottom-style'),
|
||||
),
|
||||
new CrayonHTMLSeparator($tLanguage),
|
||||
array(
|
||||
$tText,
|
||||
self::createAttribute($language, 'color'),
|
||||
self::createAttribute($language, 'font-weight'),
|
||||
self::createAttribute($language, 'font-style'),
|
||||
self::createAttribute($language, 'text-decoration')
|
||||
),
|
||||
self::createAttribute($language, 'background-color', $tBackground)
|
||||
));
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
<?php
|
||||
exit();
|
||||
}
|
||||
|
||||
public static function createAttribute($element, $attribute, $name = NULL) {
|
||||
$group = self::getAttributeGroup($attribute);
|
||||
$type = self::getAttributeType($group);
|
||||
if ($type == 'select') {
|
||||
$input = new CrayonHTMLSelect($element . '_' . $attribute, $name);
|
||||
if ($group == 'border-style') {
|
||||
$input->addOptions(CrayonHTMLElement::$borderStyles);
|
||||
} else if ($group == 'float') {
|
||||
$input->addOptions(array(
|
||||
'left',
|
||||
'right',
|
||||
'both',
|
||||
'none',
|
||||
'inherit'
|
||||
));
|
||||
} else if ($group == 'font-style') {
|
||||
$input->addOptions(array(
|
||||
'normal',
|
||||
'italic',
|
||||
'oblique',
|
||||
'inherit'
|
||||
));
|
||||
} else if ($group == 'font-weight') {
|
||||
$input->addOptions(array(
|
||||
'normal',
|
||||
'bold',
|
||||
'bolder',
|
||||
'lighter',
|
||||
'100',
|
||||
'200',
|
||||
'300',
|
||||
'400',
|
||||
'500',
|
||||
'600',
|
||||
'700',
|
||||
'800',
|
||||
'900',
|
||||
'inherit'
|
||||
));
|
||||
} else if ($group == 'text-decoration') {
|
||||
$input->addOptions(array(
|
||||
'none',
|
||||
'underline',
|
||||
'overline',
|
||||
'line-through',
|
||||
'blink',
|
||||
'inherit'
|
||||
));
|
||||
}
|
||||
} else {
|
||||
$input = new CrayonHTMLInput($element . '_' . $attribute, $name);
|
||||
}
|
||||
$input->addClass(self::ATTRIBUTE);
|
||||
$input->addAttributes(array(
|
||||
'data-element' => $element,
|
||||
'data-attribute' => $attribute,
|
||||
'data-group' => $group
|
||||
));
|
||||
return $input;
|
||||
}
|
||||
|
||||
public static function createAttributesForm($atts) {
|
||||
echo self::form($atts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the given theme id and css, making any necessary path and id changes to ensure the new theme is valid.
|
||||
* Echos 0 on failure, 1 on success and 2 on success and if paths have changed.
|
||||
*/
|
||||
public static function save() {
|
||||
CrayonSettingsWP::load_settings();
|
||||
$oldID = stripslashes($_POST['id']);
|
||||
$name = stripslashes($_POST['name']);
|
||||
$css = stripslashes($_POST['css']);
|
||||
$change_settings = CrayonUtil::set_default($_POST['change_settings'], TRUE);
|
||||
$allow_edit = CrayonUtil::set_default($_POST['allow_edit'], TRUE);
|
||||
$allow_edit_stock_theme = CrayonUtil::set_default($_POST['allow_edit_stock_theme'], CRAYON_DEBUG);
|
||||
$delete = CrayonUtil::set_default($_POST['delete'], TRUE);
|
||||
$oldTheme = CrayonResources::themes()->get($oldID);
|
||||
|
||||
if (!empty($oldID) && !empty($css) && !empty($name)) {
|
||||
// By default, expect a user theme to be saved - prevents editing stock themes
|
||||
// If in DEBUG mode, then allow editing stock themes.
|
||||
$user = $oldTheme !== NULL && $allow_edit_stock_theme ? $oldTheme->user() : TRUE;
|
||||
$oldPath = CrayonResources::themes()->path($oldID);
|
||||
$oldDir = CrayonResources::themes()->dirpath_for_id($oldID);
|
||||
// Create an instance to use functions, since late static binding is only available in 5.3 (PHP kinda sucks)
|
||||
$theme = CrayonResources::themes()->resource_instance('');
|
||||
$newID = $theme->clean_id($name);
|
||||
$name = CrayonResource::clean_name($newID);
|
||||
$newPath = CrayonResources::themes()->path($newID, $user);
|
||||
$newDir = CrayonResources::themes()->dirpath_for_id($newID, $user);
|
||||
|
||||
$exists = CrayonResources::themes()->is_loaded($newID) || (is_file($newPath) && is_file($oldPath));
|
||||
if ($exists && $oldPath != $newPath) {
|
||||
// Never allow overwriting a theme with a different id!
|
||||
echo -3;
|
||||
exit();
|
||||
}
|
||||
|
||||
if ($oldPath == $newPath && $allow_edit === FALSE) {
|
||||
// Don't allow editing
|
||||
echo -4;
|
||||
exit();
|
||||
}
|
||||
|
||||
// Create the new path if needed
|
||||
if (!is_dir($newDir)) {
|
||||
wp_mkdir_p($newDir);
|
||||
$imageSrc = $oldDir . 'images';
|
||||
if (is_dir($imageSrc)) {
|
||||
try {
|
||||
// Copy image folder
|
||||
CrayonUtil::copyDir($imageSrc, $newDir . 'images', 'wp_mkdir_p');
|
||||
} catch (Exception $e) {
|
||||
CrayonLog::syslog($e->getMessage(), "THEME SAVE");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$refresh = FALSE;
|
||||
$replaceID = $oldID;
|
||||
// Replace ids in the CSS
|
||||
if (!is_file($oldPath) || strpos($css, CrayonThemes::CSS_PREFIX . $oldID) === FALSE) {
|
||||
// The old path/id is no longer valid - something has gone wrong - we should refresh afterwards
|
||||
$refresh = TRUE;
|
||||
}
|
||||
// XXX This is case sensitive to avoid modifying text, but it means that CSS must be in lowercase
|
||||
$css = preg_replace('#(?<=' . CrayonThemes::CSS_PREFIX . ')' . $replaceID . '\b#ms', $newID, $css);
|
||||
|
||||
// Replace the name with the new one
|
||||
$info = self::getCSSInfo($css);
|
||||
$info['name'] = $name;
|
||||
$css = self::setCSSInfo($css, $info);
|
||||
|
||||
$result = @file_put_contents($newPath, $css);
|
||||
$success = $result !== FALSE;
|
||||
if ($success && $oldPath !== $newPath) {
|
||||
if ($oldID !== CrayonThemes::DEFAULT_THEME && $delete) {
|
||||
// Only delete the old path if it isn't the default theme
|
||||
try {
|
||||
// Delete the old path
|
||||
CrayonUtil::deleteDir($oldDir);
|
||||
} catch (Exception $e) {
|
||||
CrayonLog::syslog($e->getMessage(), "THEME SAVE");
|
||||
}
|
||||
}
|
||||
// Refresh
|
||||
echo 2;
|
||||
} else {
|
||||
if ($refresh) {
|
||||
echo 2;
|
||||
} else {
|
||||
if ($success) {
|
||||
echo 1;
|
||||
} else {
|
||||
echo -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Set the new theme in settings
|
||||
if ($change_settings) {
|
||||
CrayonGlobalSettings::set(CrayonSettings::THEME, $newID);
|
||||
CrayonSettingsWP::save_settings();
|
||||
}
|
||||
} else {
|
||||
CrayonLog::syslog("$oldID=$oldID\n\n$name=$name", "THEME SAVE");
|
||||
echo -1;
|
||||
}
|
||||
exit();
|
||||
}
|
||||
|
||||
public static function duplicate() {
|
||||
CrayonSettingsWP::load_settings();
|
||||
$oldID = $_POST['id'];
|
||||
$oldPath = CrayonResources::themes()->path($oldID);
|
||||
$_POST['css'] = file_get_contents($oldPath);
|
||||
$_POST['delete'] = FALSE;
|
||||
$_POST['allow_edit'] = FALSE;
|
||||
$_POST['allow_edit_stock_theme'] = FALSE;
|
||||
self::save();
|
||||
}
|
||||
|
||||
public static function delete() {
|
||||
CrayonSettingsWP::load_settings();
|
||||
$id = $_POST['id'];
|
||||
$dir = CrayonResources::themes()->dirpath_for_id($id);
|
||||
if (is_dir($dir) && CrayonResources::themes()->exists($id)) {
|
||||
try {
|
||||
CrayonUtil::deleteDir($dir);
|
||||
CrayonGlobalSettings::set(CrayonSettings::THEME, CrayonThemes::DEFAULT_THEME);
|
||||
CrayonSettingsWP::save_settings();
|
||||
echo 1;
|
||||
} catch (Exception $e) {
|
||||
CrayonLog::syslog($e->getMessage(), "THEME SAVE");
|
||||
echo -2;
|
||||
}
|
||||
} else {
|
||||
echo -1;
|
||||
}
|
||||
exit();
|
||||
}
|
||||
|
||||
public static function submit() {
|
||||
global $CRAYON_EMAIL;
|
||||
CrayonSettingsWP::load_settings();
|
||||
$id = $_POST['id'];
|
||||
$message = $_POST['message'];
|
||||
$dir = CrayonResources::themes()->dirpath_for_id($id);
|
||||
$dest = $dir . 'tmp';
|
||||
wp_mkdir_p($dest);
|
||||
|
||||
if (is_dir($dir) && CrayonResources::themes()->exists($id)) {
|
||||
try {
|
||||
$zipFile = CrayonUtil::createZip($dir, $dest, TRUE);
|
||||
$result = CrayonUtil::emailFile(array(
|
||||
'to' => $CRAYON_EMAIL,
|
||||
'from' => get_bloginfo('admin_email'),
|
||||
'subject' => 'Theme Editor Submission',
|
||||
'message' => $message,
|
||||
'file' => $zipFile
|
||||
));
|
||||
CrayonUtil::deleteDir($dest);
|
||||
if ($result) {
|
||||
echo 1;
|
||||
} else {
|
||||
echo -3;
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
CrayonLog::syslog($e->getMessage(), "THEME SUBMIT");
|
||||
echo -2;
|
||||
}
|
||||
} else {
|
||||
echo -1;
|
||||
}
|
||||
exit();
|
||||
}
|
||||
|
||||
public static function getCSSInfo($css) {
|
||||
$info = array();
|
||||
preg_match(self::RE_COMMENT, $css, $matches);
|
||||
if (count($matches)) {
|
||||
$comment = $matches[0];
|
||||
preg_match_all('#([^\r\n:]*[^\r\n\s:])\s*:\s*([^\r\n]+)#msi', $comment, $matches);
|
||||
if (count($matches)) {
|
||||
for ($i = 0; $i < count($matches[1]); $i++) {
|
||||
$name = $matches[1][$i];
|
||||
$value = $matches[2][$i];
|
||||
$info[self::getFieldID($name)] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $info;
|
||||
}
|
||||
|
||||
public static function cssInfoToString($info) {
|
||||
$str = "/*\n";
|
||||
foreach ($info as $id => $value) {
|
||||
$str .= self::getFieldName($id) . ': ' . $value . "\n";
|
||||
}
|
||||
$str .= "*/";
|
||||
return $str;
|
||||
}
|
||||
|
||||
public static function setCSSInfo($css, $info) {
|
||||
return preg_replace(self::RE_COMMENT, self::cssInfoToString($info), $css);
|
||||
}
|
||||
|
||||
public static function getFieldID($name) {
|
||||
if (isset(self::$infoFieldsInverse[$name])) {
|
||||
return self::$infoFieldsInverse[$name];
|
||||
} else {
|
||||
return CrayonUserResource::clean_id($name);
|
||||
}
|
||||
}
|
||||
|
||||
public static function getFieldName($id) {
|
||||
self::initFields();
|
||||
if (isset(self::$infoFields[$id])) {
|
||||
return self::$infoFields[$id];
|
||||
} else {
|
||||
return CrayonUserResource::clean_name($id);
|
||||
}
|
||||
}
|
||||
|
||||
public static function getAttributeGroup($attribute) {
|
||||
if (isset(self::$attributeGroupsInverse[$attribute])) {
|
||||
return self::$attributeGroupsInverse[$attribute];
|
||||
} else {
|
||||
return $attribute;
|
||||
}
|
||||
}
|
||||
|
||||
public static function getAttributeType($group) {
|
||||
if (isset(self::$attributeTypesInverse[$group])) {
|
||||
return self::$attributeTypesInverse[$group];
|
||||
} else {
|
||||
return 'text';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
18
util/touch.txt
Normal file
@ -0,0 +1,18 @@
|
||||
// List of mobile device strings to look for inside the user agent of browsers.
|
||||
// This is used to disable mouseover triggered events and just show the content if possible.
|
||||
Android
|
||||
Mobile
|
||||
Touch
|
||||
Phone
|
||||
Nokia
|
||||
Motorola
|
||||
HTC
|
||||
Blackberry
|
||||
Samsung
|
||||
Ericsson
|
||||
LGE
|
||||
Palm
|
||||
Kindle
|
||||
iPhone
|
||||
iPad
|
||||
iPod
|