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
  • некоторые компании проводят двухэтапное ревью: первый этап - зачистка, поиск и исправление проблем форматирования/читаемости, второй этап - собственно глубокое ревью
  • можно выделить наиболее критические участки кода или изменения и проводить их ревью более тщательно