Исправления Drupal 6 для совместимости с jQuery 1.7.2 и более старших версий.
Работают все функции в том числе ajax, ahah, загрузка файлов, autocomplite, batch и tabledrag.
update: j 1.7.2 & j.forms 3.09
в 6.26 пофиксили tabledrag. Правка мелкая, но все же ( сабж в атаче + немного почиканый drupal.js );
новый jquery.forms.js ( v 3.09 )
cdn: http://malsup.github.com/jquery.form.js
или
git: https://github.com/malsup/form
В common.includes нужно заменить функции для преобразования в формат json:
* Converts a PHP variable into its Javascript equivalent.
*
* We use HTML-safe strings, i.e. with <, > and & escaped.
*/
function drupal_to_js($var) {
switch (gettype($var)) {
case 'boolean':
return $var ? 'true' : 'false'; // Lowercase necessary!
case 'integer':
case 'double':
return $var;
case 'resource':
case 'string':
// Always use Unicode escape sequences (\u0022) over JSON escape
// sequences (\") to prevent browsers interpreting these as
// special characters.
// Pattern :
// array(
// [UTF8 (hex)] => [C/C++/Java Source code]
// );
// [updated] 10.06.2012
$replace_pairs = array(
// ", \ and U+0000 - U+001F must be escaped according to RFC 4627.
"\x5c" => '\u005c',
"\x22" => '\u0022',
"\x00" => '\u0000',
"\x01" => '\u0001',
"\x02" => '\u0002',
"\x03" => '\u0003',
"\x04" => '\u0004',
"\x05" => '\u0005',
"\x06" => '\u0006',
"\x07" => '\u0007',
"\x08" => '\u0008',
"\x09" => '\u0009', //TAB
"\x0a" => '\u000a', //LF : Line Feed
"\x0b" => '\u000b',
"\x0c" => '\u000c',
"\x0d" => '\u000d',
"\x0e" => '\u000e',
"\x0f" => '\u000f',
"\x10" => '\u0010',
"\x11" => '\u0011',
"\x12" => '\u0012',
"\x13" => '\u0013',
"\x14" => '\u0014',
"\x15" => '\u0015',
"\x16" => '\u0016',
"\x17" => '\u0017',
"\x18" => '\u0018',
"\x19" => '\u0019',
"\x1a" => '\u001a',
"\x1b" => '\u001b',
"\x1c" => '\u001c',
"\x1d" => '\u001d',
"\x1e" => '\u001e',
"\x1f" => '\u001f',
// Prevent browsers from interpreting these as as special.
"\x27" => '\u0027',
"\x3c" => '\u003c',
"\x3e" => '\u003e',
"\x26" => '\u0026',
"\x24" => '\u0024',
"\x40" => '\u0040',
"\x21" => '\u0021',
"\x3a" => '\u003a',
"\x3b" => '\u003b',
"\x3f" => '\u003f',
"\x5e" => '\u005e',
"\x28" => '\u0028',
"\x29" => '\u0029',
"\x7c" => '\u007c',
"\x60" => '\u0060',
"\x7e" => '\u007e',
// Prevent browsers from interpreting the solidus as special and
// non-compliant JSON parsers from interpreting // as a comment.
"\x2f" => '\u002f', // slash
// While these are allowed unescaped according to ECMA-262, section
// 15.12.2, they cause problems in some JSON parser.
"\xe2\x80\xa8" => '\u2028', // U+2028, Line Separator.
"\xe2\x80\xa9" => '\u2029', // U+2029, Paragraph Separator.
);
//return '"'. strtr($var, $replace_pairs) .'"';
return '"' . unicode_replacer ( $var, $replace_pairs ) . '"';
case 'array':
// Arrays in JSON can't be associative. If the array is empty or if it
// has sequential whole number keys starting with 0, it's not associative
// so we can go ahead and convert it as an array.
if (empty ($var) || array_keys($var) === range(0, sizeof($var) - 1)) {
$output = array();
foreach ($var as $v) {
$output[] = drupal_to_js($v);
}
return '[ '. implode(', ', $output) .' ]';
}
// Otherwise, fall through to convert the array as an object.
case 'object':
$output = array();
foreach ($var as $k => $v) {
$output[] = drupal_to_js(strval($k)) .': '. drupal_to_js($v);
}
return '{ '. implode(', ', $output) .' }';
default:
return 'null';
}
}
/*
Alternate for strtr( ) looks like more speedy
*/
function unicode_replacer ( $text, $replace ) {
$keys = array_keys($replace);
$length = array_combine($keys, array_map('strlen', $keys));
arsort($length);
$array[] = $text;
$count = 1;
reset($length);
while ($key = key($length)) {
if (strpos($text, $key) !== false) {
for ($i = 0; $i < $count; $i += 2) {
if (($pos = strpos($array[$i], $key)) === false) continue;
array_splice($array, $i, 1, array(substr($array[$i], 0, $pos), $replace[$key], substr($array[$i], $pos + strlen($key))));
$count += 2;
}
}
next($length);
}
return implode( $array );
}
/**
* Return data in JSON format.
*
* This function should be used for JavaScript callback functions returning
* data in JSON format. It sets the header for JavaScript output.
*
* param $var
* (optional) If set, the variable will be converted to JSON and output.
*/
function drupal_json($var = NULL) {
// We are returning JavaScript, so tell the browser.
drupal_set_header('Content-Type: application/json; charset=utf-8');
if (isset($var)) {
echo drupal_to_js($var);
}
}
В атаче исправленные JS файлы из папки misc.
Что может произойти: некоторые написанные старым языком модули могут перестать работать. По своему опыту могу сказать, что все исправляется достаточно просто и все модули в основном написаны совместимо.
p.s.: если активно перебираете DOM, то вместо указателя на селектор $('selector') в скриптах можно использовать $.shell.find('selector'), который работает в области видимости только document без учета window, что несколько быстрее.( зачем так? затем что всякие дополнительные скрипты типа гуглпоиска, метрики, других решений, которые бомбят в документ фрейемы и прочие посторонние объекты могут реально раздувать поле выборки )
Вложение | Размер |
---|---|
drupal_javascripts_08_05_2012.zip | 31.5 КБ |
Комментарии
Нужны, выкладывайте, хорошее дело.
А можете подробнее написать по поводу фикса? Как я понял это патч json для работы jqery 1.6 -1.7. На сколько корректно работает, не наблюдаются ли проблемы с ajax во views?
На вьюхе не проверял, но c новыми form.js работает на ура. Батч, загрузка файлов и т.д. Могут быть проблемы со старыми модулями, но там все просто фиксится.
Я хотел сделать сборку, но один, наверное, не смогу оказать ей должной поддержки, поэтому готов отдать все фиксы нуждающимся.
могу. это в jquery изменилось представление кодировки json некоторых спецсимволов и, в виду, особенностей парсинга json, то, что было в Drupal стало непригодным.
приатачил. у меня инклуд форм хакнут, чтобы можно было на CDN положить(позже может быть скину)
ещё отваливается tabledrag
а его в фиксах нет
добавил
Спасибо очень помогло.
А у меня во views перестали раскрываться настройки. Плюс imce перестал загружать картинки. Никто не подскажет что поправить?
надо обновить jquery.form который в imce на совместимый
есть небольшая поправка, позже выложу
Спасибо за ваш труд!
У меня после замены js поля imagefield ведут себя неправильно.
После начала загрузки файла в любой из них все поля imagefield становятся disabled.
После окончания загрузки атрибут disabled у полей не снимается.
July 7, 2006 at 5:41am
Хм ... В модуле JS нет. Попробуйте поискать проблему в JS:
ImageField 6.x depends on the CCK and FileField modules
Возможно, где-то код устарел морально. Посмотреть в ближайшее время не могу, к сожалению.
Времени не хватает. Сегодня понадобилась jquery.form отдельно. Выяснилась инетерсная деталь( дело толи в моих кривых руках и невнимательности, толи в библиотеке ).
Такая же реализация в друпал почему-то работает весьма адекватно:
<!--
Shift (c) 2012 for ...
-->
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="core.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script src="http://malsup.github.com/jquery.form.js"></script>
<title>____</title>
</head>
<body>
<div id="shell">
<!-- mail send form -->
<form id="send" action="sender.php" enctype="multipart/form-data" method="post">
<fieldset>
<legend>Отправка сообщения c вложением:
<!-- messages -->
<span id="messages">
</span>
<!-- #messages -->
</legend>
<label for="recepient">Получатель:
<input name="email" id="recepient" type="text" placeholder="введите email получателя">
</label>
<!-- #recepient -->
<label for="subject">Тема:
<input name="subject" id="subject" type="text" placeholder="введите тему письма">
</label>
<!-- #subject -->
<br />
<label for="include" title="выбранный файл должен быть изображением">Вложение:
<input name="image" id="include" type="file">
</label>
<!-- #include -->
<br />
<br style="clear: both" />
<label for="message">Текст сообщения:
<textarea name="message" id="message"></textarea>
</label>
<!-- #message -->
<br />
<br style="clear: both" />
<!-- #SEND# -->
<input type="submit" value="Отправить Почту">
<!-- #SEND# -->
<p style="clear: both" id="res">
</p>
</fieldset>
</form>
<!-- mail send form -->
</div>
<script>
$(function() {
// request options
var options = {
beforeSubmit: check_form,
success: success_form,
dataType: 'json'
};
// targets
var form = $( '#send' , '#shell' );
var msg = $( '#messages' , form );
// sending form
form.submit( function( e ) {
$(this).ajaxSubmit(options);
e.preventDefault();
});
// helpers
function check_form() {
}
function success_form( responseText, statusText ) {
$( 'input', form ).removeClass('error');
var status = ( responseText[0].txt );
var field = ( responseText[0].field_id ) ? responseText[0].field_id : false;
if( field ) {
$( field ).addClass('error');
$( msg ).addClass('error');
//$( '#send ' + tgt ).clearFields();
} else {
$( msg ).removeClass('error').addClass('success');
$( 'input[type=submit]', form ).remove();
}
msg.text( status );
}
});
</script>
<?php //header( 'Content-Type: application/json; charset=utf-8' );
$status[] = array(
$subject = text_check( $_POST['subject'] );
$subject = false;
$message = text_check( $_POST['message'] );
$message = false;
send_mail( $email, $subject, $message, $status );
// RETURN STATUS IN JSON FOR AJAX
$status[] = array(
$status[] = array(
// RETURN STATUS IN JSON FOR AJAX
$status = array(); //email check
$email = ( !empty( $_POST['email'] ) && preg_match('/[^@]+\@[^\.]+\.[a-z]{2,4}/i', $_POST['email']) ) ? text_check( $_POST['email'] ) : false;
if( !
$email ) {'txt' => 'проверьте поле email',
'field_id' => '#recepient',
);
}
// subject checkif( !empty( $_POST['subject'] ) ) {
} else {
$status[] = array(
'txt' => 'проверьте поле "тема"',
'field_id' => '#subject',
);
}
//message checkif( !empty( $_POST['message'] ) ) {
} else {
$status[] = array(
'txt' => 'проверьте поле текста сообщения',
'field_id' => '#message',
);
}
/*(*)разобраться почему с помощью AJAX
в $_POST не приходит содержимое файла;
image check
if( !empty( $_POST['image'] && ) ) {
//$_POST['image'] :: До сабмита переменная есть => после нету ):
} else {
$image = false;
$status = array_merge(
$status,
array(
'txt' => 'выбранный файл не является изображением',
'field_id' => '#message',
)
);
}
*/
/**
if( $email && $subject && $message ) {* Prepare male to send
*/
} else {
$output = json_encode( $status );
print $output;
}
// :: DEBUG ::
//print '<pre>';
//print_r( $status );
//print_r( $_POST );
//print '</pre>';
/**
function text_check( $text ) {* helper functions for trim text
*/
return strip_tags( htmlspecialchars( stripslashes( $text ) ) );
} /**
* helper function for send mail
*/ function send_mail( $recepient, $subject, $message, $status ) {
if( mail( $recepient , $subject , $message ) ) {
'txt' => 'письмо для ' . $recepient . " отправлено",
);
}
else {
'txt' => "ошибка: письмо не отправлено",
);
}
$output = json_encode( $status );
print $output;
}
?>Возможно затык где-то в этом, но не уверен. Я так понимаю там множественные поля с файлами ???
В пределах одной формы или в разных?
Отдельно файл, если нет тругих инпут отправляется -- вместе нет.
p.s.: кому надо - ковыряйте сами. у меня вроде работает. времени тупо не хватает
мало, что из написанного понял ))
какая такая "интересная деталь" была выявлена?
да, дизаблятся разные поля одной формы.
разбирайся сам; нет времени
Эти файлы затрутся при обновлении Drupal?
да. к счастью последние обновления не слишком масштабные. можно чэнджлог посмотреть и обновить только нужное.
переделал hex'ы( http://www.fileformat.info/info/unicode/char/search.htm?q=%D1%91&preview... );Буду признателен, если кто даст толковую ссылку на RFC, где описано, что именно должно маскироваться и в каком порядке( чет не могу найти; все кодировать смысла нет: сильно раздувает выхлоп ).p.s.: надо будет по другому сделать; чем больше символов перекодируется, тем больше памяти жрёт.можно юзать
По поводу нативного и ненативного преобразования hex в unicode mask:
<?phpstrtr($var, $replace_pairs);?>
<?phpunicode_replacer ( $var, $replace_pairs );?>
Первая работает на порядок быстрее второй, но только на чистом сервере localhost. Разница достаточно ощутимая( где-то 500-800 ms на пробной замене );
На настроенном продакшн сервере вторая функция показывает лучшие результаты( чуть медленнее первой, скорость работы всегда стабильная -- нет разброса ). Если на Drupal включен кэш, то вторая функция выглядит гораздо эффективнее первой.
Видимо дело в opcode кэшере или чем-то еще( как вариант нативный вариант не может быть закешен и каждый раз отрабатывает с нуля, что дает свои корреляции на время обработки строк в зависимости от самочувствия сервера ... как-то так ). Таким образом я остановился на выборе самописной.
Внимание после обновления ломается VIEWS
http://drupal.org/files/ctools-dependent-js-broken-with-jquery-1.7-14948...
Советую никому не пользоваться рекомендациями в этой теме, какие они есть на данный момент. Я поймал ошибку, которую искал примерно 4 часа, я даже не мог понять в чём дело, что не так, никаких идей не было, а потом вспомнил, что воспользовался этими рекомендациям.
Вот здесь подробней - http://www.drupal.ru/node/94978
просто за совместимостью библиотек надо следить, а не бездумно обновлять всё подряд
Спасибо за проделанную работу.
Добавь в свой массив несколько элементов (с https://api.drupal.org/api/drupal/includes!json-encode.inc/function/drup...)
« // Prevent browsers from interpreting these as as special.
"'" => '\u0027',
'<' => '\u003C',
'>' => '\u003E',
'&' => '\u0026',
// Prevent browsers from interpreting the solidus as special and
// non-compliant JSON parsers from interpreting // as a comment.
'/' => '\u002F',
»
У меня без этих строк не получалось распарсить json-массив.