26 нояб. 2014 г.

HTML5 draggable and contenteditable

Handle for draggable element


var target, allowedHandleSelector = '.drag-handle';
var onmousedown = function(e) {
    target = e.target;
};
var ondragstart = function(e) {
    if (!target.matches(allowedHandleSelector) {
        // prevent drag when target does not match handle selector
        e.preventDefault();
        return;
    }
    ...
};

Make draggable element and its flying ghost look differently

http://farhadi.ir/posts/the-story-behind-html5-sortable/

var ondragstart = function(e) {
    var $element = $(e.target).closest('.draggable');
    $element.toggleClass('drag-ghost', true);
    // modify element after creation of flying ghost
    setTimeout(function() {
        $element.toggleClass('drag-ghost', false);
        $element.toggleClass('dragging', true);
    }, 0);
    ...
};

Disable spell checking for contenteditable element


<div spellcheck="false" contenteditable="true">Editable content</div>
<div spellcheck="false" contenteditable="false">This content could be made editable</div>

300px limit

At least on Windows browser clips width of ghost (drag image) to 300x and applies radial opacity gradient: opacity of the image drops from 1 directly under the mouse cursor to zero at 300px distance.

Avoid nesting draggable and contenteditable attributes

Here be dragons!

Upgrade React to 0.12


  1. Rename React.renderComponent to React.render and use React.createFactory:
    was in 0.11:
    React.renderComponent(ReactClass(props), container)
    should be in 0.12:
    React.render(React.createFactory(ReactClass)(props), container)
  2. Use displayName where possible - it will be used in console messages
  3. Use either JSX or React.createFactory to render children components:
    JSX:
    var Child = React.createClass(...);
    render: function() {
        return <Child name={this.props.name} />;
    }

    JS:
    var Child = React.createClass(...);
    var factory = React.createFactory(Child);
    render: function() {
        return factory({name: this.props.name});
    }
  4. Do not use transferPropsTo. Use explicit props object in JS code or spread operator in JSX:
    JS:
    render: function() {
        return childFactory(_.extend({}, this.props,
            {className: 'name ' + this.props.className});
    }

    or:
    render: function() {
        return React.createElement(Child, props);
    }

    JSX:
    render: function() {
        return <Child {...this.props} className={'name ' + this.props.className} />;
    }
  5. Do not use this.props.key in React class - it is removed from props.
    was in 0.11:
    var Child = React.createClass({
        render: function() {
            return <div data-uid={this.props.key} />;
        }
    });
    ...
    var children = items.map(item => <Child key={item.uid} />);

    should be in 0.12:
    var Child = React.createClass({
        render: function() {
            return <div data-uid={this.props.uid} />;
        }
    });
    ...
    var children = items.map(item => <Child key={item.uid} uid={item.uid} />);

5 нояб. 2014 г.

Повторное использование кода в React

В React отсутствует какое-либо наследование компонентов, так что если необходимо реализовать несколько компонентов с похожим функционалом (и одинаковым кодом), и избежать копирования общего кода, то для этого существует только два способа повторного использования кода:
  1. Mixin (docs)
  2. Компонент-обёртка

13 окт. 2014 г.

JavaScript RegExp simplification


  • [0-9] could be replaced with \d
  • ($|&|\s) could be simplified to [$&\s] or to ([$&\s]) if you need capturing
  • a*.* could be simplified to just .*
  • similarly, a+.* could be simplified to .*
  • non-capturing group (?:foo) has slightly better performance than capturing (foo)
  • {0,1} could be replaced with ?
  • {1} could be omitted
Link to dead simple RegExp validator/optimizer

3 сент. 2014 г.

Code review: мысли и факты


Code review
  • регулярный code review делают меньше 50% команд shepard/492/ppt/ppt18.ppt
  • 96% дефектов выявляется при просмотре кода в одиночку (не на формальном митинге) http://dl.acm.org/citation.cfm?id=167070
  • количество ревьюеров не должно быть большим http://blog.smartbear.com/code-review/who-should-review-my-code/
  • одиночный ревьюер находит примерно 50% дефектов, два ревьюера - примерно 75% http://www.leshatton.org/Documents/checklists_in_inspections.pdf
  • разработчик, который перепроверяет свой же код, также находит примерно 50% дефектов http://smartbear.com/resources/whitepapers/best-kept-secrets-of-peer-code-review/
  • количество проблем, обнаруженных во втором code review, составляет примерно 50% от количества найденных в первом, команды из 3-4-5 ревьюеров практически не дают преимущества перед двумя ревьюерами http://dl.acm.org/citation.cfm?id=331521
  • code review проводится не новичками, но для новичков
  • эффективность ревью сильно зависит от уровня ревьюера и его знания просматриваемого кода http://dl.acm.org/citation.cfm?id=331521
  • лучшие разработчики, тим-лиды и архитекторы могут и должны тратить время на code review
  • соответствие кода стандартам кодирования/форматирования должно проверяться автоматически до ревью
  • наибольшее время в ходе ревью уделяется проблемам сопровождаемости и читаемости кода: поиск ошибок в чужом коде намного сложнее, чем поиск ошибок в своём, сначала его надо прочитать и понять http://dl.acm.org/citation.cfm?id=1592371 http://www.st.ewi.tudelft.nl/~mbeller/publications/2014_beller_bacchelli_zaidman_juergens_modern_code_reviews_in_open-source_projects_which_problems_do_they_fix.pdf
  • некоторые компании проводят двухэтапное ревью: первый этап - зачистка, поиск и исправление проблем форматирования/читаемости, второй этап - собственно глубокое ревью
  • можно выделить наиболее критические участки кода или изменения и проводить их ревью более тщательно

26 авг. 2014 г.

Глубина стека JavaScript (дубль 2)

Продолжение (первая часть здесь).

На http://www.2ality.com/2014/04/call-stack-size.html натолкнулся на мысль, что измеряемая глубина стека зависит от размера фрейма (который может зависеть от локальных переменных и аргументов функции). Дополнил скрипт, заодно для наглядности вставил рисование графика глубины стека в зависимости от количества аргументов/локальных переменных. Результат:

Кол-во
аргументов/     0/0    1/0    1/1    1/2    1/3
переменных

Chrome 39:      41962  31472  27975  25178  22889  ±50
Chrome 36:      20986  15740  13991  12592  11447  ±50
Safari 5.1.7:   65532  58250  52425  47659  43688
Opera 12.17:    32624  31505  32691  31478  31419
Opera 17:       21002  15752  14002  12602  11456  ±50
IE9 (IETester): 24789  20657  20657  20657  20657
IE11:           32000..62000 не зависит от кол-ва переменных
Firefox 20:     27000..52000 не зависит от кол-ва переменных
Firefox 31:      6600..21000 не зависит от кол-ва переменных

Результаты для IE11 и Firefox не зависят от количества локальных переменных/аргументов, и сильно изменяются от запуска к запуску.

Результаты для Chrome и новой Opera незначительно изменяются после первого запуска, далее остаются постоянными.


6 июн. 2014 г.

Social software: A Group Is Its Own Worst Enemy

A Group Is Its Own Worst Enemy

Learning from experience is the worst possible way to learn something. Learning from experience is one up from remembering. That's not great. The best way to learn something is when someone else figures it out and tells you: "Don't go in that swamp. There are alligators in there."
  • Groups of people are aggregations of individuals or a cohesive group? Hopelessly committed to both.
  • Uncontrolled groups tend to defeat their goals via sex talks, identification and vilification of external enemies, religious veneration etc.
  • Constitutions are a necessary component of large, long-lived, heterogeneous groups.
  • You cannot completely separate technical and social issues.
  • Members are different than users.
  • The core group has rights that trump individual rights in some situations.
  • Social software should have the handles the user can invest in ("identity").
  • Social software should have some way in which good works get recognized.
  • Social software should have to have some cost to either join or participate, if not at the lowest level, then at higher levels.
  • Social software should have a way to spare the group from scale.

30 мая 2014 г.

Как MSBuild.Exec определяет ошибки при запуске third-party tools

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

Как это реализовано в MSBuild: Exec Task - Runs the specified program or command by using the specified arguments.

У Exec есть одна особенность, о которой в документации прямо не упомянуто: "умное" определение ошибок выполнения. Если выполненная программа завершилась с ненулевым кодом, то Exec считает это ошибкой, но если программа завершилась с нулевым кодом, то Exec дополнительно сканирует её вывод (stdout, stderr) на наличие ключевых слов.

12 мая 2014 г.

Generics in JSDoc

/**
 * @interface
 * @template T
 */
MyEnumerable = function () { };

/**
 * @param {T} item
 */
MyEnumerable.prototype.add = function (item) { };

/**
 * @constructor
 * @template TItemType
 * @extends {MyEnumerable.<TItemType>}
 */
MyList = function () { };

/**
 * @param {TItemType} item the item
 */
MyList.prototype.addItem = function (item) { };

/** @type {MyEnumerable.<string>}*/
var enumerable = new MyList();
enumerable.add("Bob"); // correct
enumerable.add(123); // correct warning: number is not assignable to type string 

/** @type {MyList.<string>}*/
var list = new MyList();
list.add("Bob"); // incorrect warning: number is not assignable to type TITemType 
list.addItem("Bob"); // correct

Now works in WebStorm

25 мар. 2014 г.

Chrome 33: null !== null (sometimes)

Если в Chrome 33 посмотреть в консоль на страничках http://jsfiddle.net/u42Xm/1/ и http://jsfiddle.net/u42Xm/2/ то увидим интересную картину: условие null === null не выполняется 26440 раз из 50000 проходов цикла. Баг оптимизатора?

5 мар. 2014 г.

Эффективность реализации алгоритма reflow (layout) в браузерах

Реализация shadow DOM была удалена из кода WebKit, чтобы переписать её заново в отдельной ветке. По замыслу авторов это должно позволить

  1. избавиться от устаревшего кода, который много раз менялся вместе с изменениями спеки
  2. контролировать влияние на производительность (постепенные изменения кода в течение нескольких лет дали в итоге замедление времени загрузки страницы на 5%, но измерить результат было сложно, теперь сравнивать производительность разных веток кода будет проще)
> The old implementation on trunk resulted in 5% overall slowdown in the page load time but we didn't quantify that until we removed the feature entirely last year.  That's probably because the feature was added over years as a pile of small changesets each of which introduced immeasurably small performance regressions.  Development in a branch allows a faithful performance comparison between the two.
> JSC team has been utilizing SVN branches to work on Concurrent JIT, Generational GC, FTL, etc... to quantity the total performance cost and benefit of each feature, and it has been working very well as far as I could tell.

4 мар. 2014 г.

Порядок перечисления в for-in и Object.keys()

ECMAScript Language Specification Edition 3 (ECMA-262-3):

  • 4.3.3 Object
    An object is a member of the type Object. It is an unordered collection of properties each of which contains a primitive value, object, or function.
  • 12.6.4 The for-in Statement
    The mechanics of enumerating the properties (get the name of the next property ... that doesn't have the DontEnum attribute) is implementation dependent.
ECMAScript Language Specification Edition 5.1 (ECMA-262-5.1):
  • 8.6 The Object Type
    An Object is a collection of properties.
  • 12.6.4 The for-in Statement
    The mechanics and order of enumerating the properties (let P be the name of the next property of obj whose [[Enumerable]] attribute is true) is not specified.
  • 15.2.3.14 Object.keys ( O )
    If an implementation defines a specific order of enumeration for the for-in statement, that same enumeration order must be used in step 5 of this algorithm.

17 янв. 2014 г.

Java GC log analysis tools


  1. GCViewer
    Free open source tool to visualize data produced by the Java VM options -verbose:gc and -Xloggc:<file>. It also calculates garbage collection related performance metrics (throughput, accumulated pauses, longest pause, etc.).
    Development stopped in 2008.
  2. Fork of original GCViewer
    Supports Java 1.7. Github, 'nuff said.
  3. Garbage Cat
    Garbage Cat parses Java garbage collection logging and provides analysis to support JVM tuning and troubleshooting for OpenJDK and Sun JDK. It differs from other tools in that it goes beyond the simple math of calculating statistics such as maximum pause time and throughput. It adds context to these numbers by identifying the associated collector or collector phase, which allows for much deeper insight and analysis. This is especially relevant to collectors such as the Concurrent Mark Sweep collector that have multiple concurrent and stop-the-world phases.
  4. IBM GCMV
    IBM Monitoring and Diagnostic Tools for Java - Garbage Collection and Memory Visualizer (GCMV) provides analysis and views of your applications verbose gc output. GCMV displays the data in both graphical and tabulated form. It provides a clear summary and interprets the information to produce a series of tuning recommendations.
    Installed within the IBM Support Assistant Workbench.
  5. jClarity Censum
    Censum is an intelligent tool that takes log files from the complex Java™ (JVM) garbage collection sub-system and gives you meaningful answers. 14-day free trial.

13 янв. 2014 г.

IE document/browser modes

http://jsfiddle.net/7ZE7M/

IE9:
http://i.stack.imgur.com/yzXVq.png

IE10:
  • navigator.appName: Microsoft Internet Explorer
  • navigator.userAgent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)
  • document.compatMode: CSS1Compat
  • document.documentMode: 10

IE11:
  • navigator.appName: Netscape
  • navigator.userAgent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; rv:11.0) like Gecko
  • document.compatMode: CSS1Compat
  • document.documentMode: 11

3 янв. 2014 г.

Interesting thoughts


  • Amusingly, the history of the evolution of C++ over time can be described as a history of trying to plug the leaks in the string abstraction. Why they couldn't just add a native string class to the language itself eludes me at the moment.
    Joel Spolsky, http://www.joelonsoftware.com/articles/LeakyAbstractions.html
  • Organizations are constrained to produce designs which are copies of the communication structures of these organizations. If you have four groups working on a compiler, you'll get a 4-pass compiler.
    Melvin Conway, http://en.wikipedia.org/wiki/Conway's_law
  • When I wrote this, only God and I understood what I was doing. Now, God only knows.
    Karl Weierstrass, http://stackoverflow.com/a/316233/1235394
  • The big ground shaker is Version 11 of Microsoft Explorer. And it has an amazing string including the words "like Gecko" in it. Apparently, MS ran into problems of page rendering when they tried to use version 11 (think of all those browser detection scripts return version 1 by jove).
    http://www.zytrax.com/tech/web/browser_ids.htm
  • One fun thing about concurrency is that the more you increase a concurrent process’s efficiency, the more likely you are to discover its buried race conditions and deadlocks. 5 Another fun thing is that eliminating one race condition will make smaller, more obscure race conditions more likely to bite you.
    http://blog.npmjs.org/post/98131109725/npm-2-0-0