jQuery UI - неработоспособность минифицированной версии в Firefox

База знаний
  1. 10 г. назад

    при использовании минифицированной версии jQuery UI свежих версий 1.10, скачанной с офсайта, сталкиваемся с её неработоспособностью в браузере Mozilla Firefox (в остальных браузерах работает, по крайней мере, в хроме и престо работает, в остальных не проверял)

    при этом в консоли наблюдаем следующее сообщение об ошибке:

    SyntaxError: invalid increment operand

    не-минифицированная версия работает нормально

    проблема заключена в данном участке кода:
    в мин.версии

    (this.id="ui-id-"+ ++s)
    

    в полной версии он выглядит так:

    this.id = "ui-id-" + (++uuid);
    

    решение проблемы:
    заключаем в скобки

    (this.id="ui-id-"+ (++s))

    источник проблемы - не jQuery UI, а Minify, с помощью которого происходит минификация кода.
    пишут, что в версии 2.1.5 Minify проблема исправлена (лично не проверял)

    тикет на офсайте: http://bugs.jqueryui.com/ticket/8666
    помечен как закрытый, но по состоянию на сейчас скачанный с офсайта минифицированный файл до сих пор подвержен данной проблеме. видимо, до сих пор на офсайте используется старая версия Minify

    потратил много времени на поиск этих граблей, так что делюсь знаниями

  2. 18.01.2014 22:39:12 отредактировано andrewks

    code.google.com/p/minify/source/browse/HISTORY.txt

    Version 2.1.4
    * Option to minify JS with Closure Compiler API w/ JSMin failover
    * Cookie/bookmarklet-based debug mode. No HTML editing!
    * Allows 1 file to be missing w/o complete failure
    * Combine multiple groups and files in single URI
    * More useful HTML helpers for writing versioned URIs
    * More detailed error logging, including minifier exceptions
    * Builder offers more helpful messages/PHP environment warnings
    * Bypass minification based on filename pattern. e.g. foo.min.js / foo-min.css
    * JSMin won't choke on common Closure compiler syntaxes (i+ ++j)
    * Better caching in IE6
    * Cache ids are influenced by group/file names
    * Debug mode for Javascript doesn't break on common XPath strings (Prototype 1.6)
    * Removed annoying maxFiles limit
    * mbstring.func_overload usage is safer

  3. Интересная информация. То есть, 2.1.4 - не качать.
    Кстати, вопрос. У меня насчёт jQueryUI сложилось нехорошее впечатление. То есть, декларируемые возможности - агромадные. Но и весит до фига (впрочем, сейчас это не столь существенно). А вот то, что проблемы с одной из фич (которая даже не используются) могут положить весь проект - как-то настораживает.
    Поэтому jQueryUI (в отличие от самого jQuery, без которого ужк не могу) - стараюсь не использовать. Тем паче, что нужные вещи реализуются и другими средствами. Вопрос: я излишне перестраховываюсь, или это всё же оправданно?

  4. 19.01.2014 13:10:42 отредактировано andrewks

    Rie То есть, 2.1.4 - не качать.

    наоборот, в Minify версии 2.1.4 глюк был исправлен, а так на сайте Minify уже версия 2.1.7, только в чём беда - гораздо удобнее скачать с офсайта jQuery UI уже минифицированную и кастомизированную версию, а у них там, видимо, используется старая версия Minify.
    поэтому быстрее в текстовом редакторе пририсовать две скобки (надо только знать, где - вот я и дал рецепт, где надо подправить)

    Rie То есть, декларируемые возможности - агромадные. Но и весит до фига

    ну, не знаю, например, минифицированная версия 1.10 с набором Core/Widget/Mouse/Sortable/Draggable весит всего 55 кило, и это почти в два раза меньше, чем минифицрованная версия 1.10 jQuery

    Rie Вопрос: я излишне перестраховываюсь, или это всё же оправданно?

    думаю, всё же зря отказываешься, библиотечка хорошая. а какие такие проблемы ты наблюдал, которые ложат целиком проект?

  5. Не наблюдал, поскольку её избегаю. Но - это ж Javascript. То, что ты привёл - чисто синтаксическая ошибка где-то там. Но беда Javascript в том, что локализовать подобное - крайне сложно. Он - целен и целеустремлён. :-) Поэтому и опасаюсь - запиндюришь, польстившись на новую фичу, непроверенную новую версию. И огребёшь потом.

  6. да, забыл интересную деталь: Firefox, почему-то, не всегда ошибочно парсит данную конструкцию.
    например, создал чистую страничку с только лишь jQuery и jQuery UI - и проблема не воспроизводится! работает!
    поэтому был сбит с толку, и очень долго искал причину.

    а, будучи загруженным с кучей других js - Firefox выдаёт обозначенную ошибку при парсинге (в это же самое время остальные браузеры парсят нормально)

  7. Rie То, что ты привёл - чисто синтаксическая ошибка где-то там.

    фишка в том, что синтакс.ошибки нет, просто js-движок огнелиса, видимо, излишне страдает удалением пробелов даже в тех местах, где их удалять нельзя.
    он конструкцию "ui-id-"+ ++s превращает в "ui-id-"+++s и потом вопит, что операнд "+++" инвалид

    причём, как я уже говорил, это, почему-то, зависит от контекста (т.е. воспроизводится не при любом наборе js-файлов)

    Ответы: (8)
  8. Вот как раз блин на фиг. Это и напрягает несколько. IE славился "своеобразнейшим" обращениям с javascript. Ну, к этому все уже привыкли и соответствующие проверки писали на автомате. А тут ещё и Огнелис отметился....

    Ответы: (9)
  9. (6) Так это и есть ошибка синтаксического анализа. Минимизатор - убирает лишние пробелы. А синтанализатор - потом не может понять, как этот "+++" разделить на запчасти. В "плюсах", к слову, эта тема включена в описание языка. От художеств минимизатора - понятно дело, не спасёт. Но будет ясно, кто виноват (впрочем, как будто от этого легче :-) )

    Ответы: (10)
  10. (7) любой интерпретируемый язык с кол-вом движков-парсеров больше одного потенциально обладает данными проблемами

    например, как-то задумался, попутал, где php, а где js, и зафигачил в объявлении js-функции значение параметра по-умолчанию (т.е. param="default" - в php это можно)

    так обнаружил, что одни движки эту конструкцию просто игнорировали, и функция осталась работоспособной, другие вообще отказывались обрабатывать такую функцию, т.е. она не работала

    а уж про css - вообще отдельная тема, каждый движок может интерпретировать по-разному

  11. (8) да не, ты не понял. минимизатор Minify не убирал пробел, он убирал лишние, по его мнению, скобки, при этом конструкция должна оставаться работоспособной, исходя из синтаксиса js.
    но такую конструкцию начал неправильно парсить движок Firefox (наличие скобок не даёт ему проглючить)

    короче, тут идёт наложение Minify + Firefox + контекст (т.е. не всегда проблема воспроизводится)

    вот такая гремучая смесь

    просто Minify исправил не свою ошибку, а, по сути, подстроился под Firefox

    Ответы: (12)
  12. Rie IE славился "своеобразнейшим" обращениям с javascript

    IE никто не переплюнет.

    IE6, IE7, IE8, IE9, IE10 - суть не разные версии одного браузера, а суть разные браузеры :)

    Ответы: (12)
  13. (10) Ой, а это - принципиальная разница - скобки или пробел? Меня куда более беспокоит то, что "по его мнению" сотворённая конструкция - не работает. (К слову, по моему непросвещённому мнению, данная конструкция, полученнная после действий минимизатора - и не должна работать; это я, как человек, некоторое время получавший з/п именно за разработку компиляторов, говорю).

    (11) Тут - спору нет. "Мелкософт" доблестно потрудился, и теперь в результате хрен проссышь, что будет работать, а что - нет. Правда, последние браузеры вроде как стараются следовать... Но - тут лучше проверить, нежели поверить.

  14. Тут в чём на самом деле проблема и почему я на чисто информационное сообщение отреагировал... За долгие годы сложилась привычка: если IE - отлавливай и обрабатывай особо; ежели прочие браузеры - ну, присматривай помалу, но особых подвохов не жди. Однако тут ведь не в браузерах проблема. Это - проблема разработчика. Огнелис просто её корректно вычислил.
    И заставил призадуматься - вот те инструменты, которыми мы все на самом деле пользуемся...

  15. 19.01.2014 13:56:16 отредактировано andrewks

    Rie К слову, по моему непросвещённому мнению, данная конструкция, полученнная после действий минимизатора - и не должна работать

    почему? на C++ есть же баянистый пример неопределённости i = i++ + ++i; - синтаксис позволяет

    lurk:++i_+_++i :)

    Ответы: (15)
  16. (14) Синтаксис - позволяет. А стандарт - даёт этой неопределённости некую расшифровку (даже лень комментировать, ибо на всех форумах по "плюсам" этот пример уже обсуждался уже туеву хучу раз).

    Ответы: (16) (17)
  17. (15) да это я так, для примера привёл, в сабже фишка-то не в неопределённости, там синтаксически правильная конструкция

    Ответы: (18)
  18. +(15) Не, я согласен - синтаксис тут далеко не очевиден. Но от что касается "плюсов" - стандарт там довольно жёсткий.

  19. (16) А вот насчёт синтаксической правильности - будь бобёр. Ссылочку на синтаксис ECMAScript (ну, или другого Javascript - по твоему выбору). Доказательство правильности сией конструкции. И её семантическую расшифровку - в студию. :-)
    Я не из вредности - просто JS тут малость того-с...

    Ответы: (19)
  20. (18) от ты хитёр бобёр! :) ты же прекрасно понимаешь, что нет единой спецификации под названием JavaScript

    Ответы: (21)
  21. Firefox имеет движок SpiderMonkey, который заявлет о поддержке стандарта ECMAScript для XML (E4X)

    щас посмотрим, что в нём

    Ответы: (21)
  22. (20) Вот ни фига не читал данный стандарт. И читать не буду (по крайней мере, сейчас; потом, возможно, придётся; или не придётся). Но рискну предсказать: стандарт эту конструкцию либо обходит молчанием (и тогда - в топку такой стандарт), либо объявляет её неоднозначной и предлагает разработчикам трансляторов не парить моск, а выдать соответствующее сообщение. Что, как я понял, и было сделано. Соответственно, претензии - к криворуким авторам минимизатора.

    (19) Конечно, понимаю. Поэтому и не требовал спецификации Javascript :-)

    Ответы: (22)
  23. +(21) А что касается сообщений - тут надо учесть некую специфику интерпретируемых языков.

  24. итак, имеем спецификацию: http://www.ecma-international.org/ecma-262/5.1/

    11.1 Primary Expressions
    Syntax
    PrimaryExpression :
    this
    Identifier
    Literal
    ArrayLiteral
    ObjectLiteral
    ( Expression )

    11.2 Left-Hand-Side Expressions
    Syntax
    MemberExpression :
    PrimaryExpression
    FunctionExpression
    MemberExpression [ Expression ]
    MemberExpression . IdentifierName
    new MemberExpression Arguments
    NewExpression :
    MemberExpression
    new NewExpression
    CallExpression :
    MemberExpression Arguments
    CallExpression Arguments
    CallExpression [ Expression ]
    CallExpression . IdentifierName
    Arguments :
    ( )
    ( ArgumentList )
    ArgumentList :
    AssignmentExpression
    ArgumentList , AssignmentExpression
    LeftHandSideExpression :
    NewExpression
    CallExpression

    11.3 Postfix Expressions
    Syntax
    PostfixExpression :
    LeftHandSideExpression
    LeftHandSideExpression [no LineTerminator here] ++
    LeftHandSideExpression [no LineTerminator here] --

    11.4 Unary Operators
    Syntax
    UnaryExpression :
    PostfixExpression
    delete UnaryExpression
    void UnaryExpression
    typeof UnaryExpression
    ++ UnaryExpression
    -- UnaryExpression
    + UnaryExpression
    - UnaryExpression
    ~ UnaryExpression
    ! UnaryExpression

    11.5 Multiplicative Operators
    Syntax
    MultiplicativeExpression :
    UnaryExpression
    MultiplicativeExpression * UnaryExpression
    MultiplicativeExpression / UnaryExpression
    MultiplicativeExpression % UnaryExpression

    11.6 Additive Operators
    Syntax
    AdditiveExpression :
    MultiplicativeExpression
    AdditiveExpression + MultiplicativeExpression
    AdditiveExpression - MultiplicativeExpression

    получается, что даже без пробела и без скобок должно работать

  25. 19.01.2014 15:05:35 отредактировано andrewks

    что и подтверждается экспериментом:

    	var i=5;
    	alert(i+++i);
    

    срабатывает без ошибок во всех браузерах включая Firefox!!!11 (только в осле не проверял) и выдаёт 11

  26. 19.01.2014 15:10:01 отредактировано andrewks

    т.е. Firefox, в принципе, считает данную конструкцию синтаксически правильной, вот только при каких-то обстоятельствах (контексте) происходит сбой

    конструкцию

    	var i=5;
    	alert(i+ ++i);
    

    Firefox также глотает без ошибок

  27. дальше-больше
    конструкцию

    	var i=5;
    	alert(i+++ ++i);
    

    правильно интерпретируют и Firefox, и Chrome

    а вот если убрать необязательный пробел - перестают понимать оба

  28. 19.01.2014 15:24:13 отредактировано andrewks
    i+++i++

    понимают, а вот красивую

    ++i+++i++

    уже не хотят

  29. Говорят, что нынче модно ReactScript и ClojureScript, а jQuery закопать надо.

  30. bvn13 нынче модно ReactScript и ClojureScript

    кто все эти люди? :)

  31. ReactScript это от создателей фейсбука. Очень скоростной. А Кложур - это... ну... Яваскрипт с синтаксисом лиспа :)

    Ответы: (31)
  32. (30) а там есть аналог jQuery UI?

    (хотя, если честно, jQuery меня вполне устраивает, а какие там есть плюшки по сравнению?)

  33. andrewks (30) а там есть аналог jQuery UI?

    (хотя, если честно, jQuery меня вполне устраивает, а какие там есть плюшки по сравнению?)

    http://habrahabr.ru/post/189230/
    http://facebook.github.io/react/

    Ответы: (33)
  34. (32) и как он - насколько быстрее jQuery? что-то не вижу каких-либо сравнительных тестов по производительности

    пока, чисто субъективно, те же яйца, но вид сбоку.
    надо будет попробовать на досуге (вот только когда он будет - этот досуг? :( )

  35. К нам приезжал Александр Соловьев с докладом Реактивное программирование.

    вот этот. Они тестировали точно. :)

    Ответы: (35)
  36. (34) спасибо, посмотрю вечерком

или зарегистрируйтесь чтобы ответить!