<commit_before>var DOMReady = require('document-ready-promise')();
var defaults = require('object.defaults/immutable');
var mix = require('mixwith-es5').mix;
var Sig = require('./sig');
var EventEmitterMixin = require('./event-emitter-mixin');
var isApplicationOf = require('mixwith-es5').isApplicationOf;
var Component = require('./component');

Sig.addTypeAlias('CSSString', 'String');

var defaultOpts = {
    renderInterval: 41.6667,
    markupRenderFormat: null,
    stylesRenderFormat: 'CSSString',
    markupTransforms: [],
    pipelineInitMethods: {},
    stylesTransforms: [],
    childStylesFirst: true
};

var App = class extends mix(App).with(EventEmitterMixin) {
    constructor(opts) {
        opts = defaults(opts, defaultOpts);
        super(opts);
        this.styles = opts.styles;
        this.el = opts.el;
        this.renderOrder = ['markup', 'styles'];
        this.pipelineInitMethods = opts.pipelineInitMethods;
        this.styleEl = opts.styleEl;
        this.componentInitOpts = Array.isArray(opts.Component) ? opts.Component[1] : {};
        this.Component = this.makeComponentClass(Array.isArray(opts.Component) ? opts.Component[0] : opts.Component);
        this.component = null;
        this.shouldRender = {};
        this.renderInterval = opts.renderInterval;
        this.renderPromise = null;
        this.stylesRenderFormat = opts.stylesRenderFormat;
        this.markupRenderFormat = opts.markupRenderFormat;
        this.markupTransforms = opts.markupTransforms;
        this.stylesTransforms = opts.stylesTransforms;
        this.childStylesFirst = opts.childStylesFirst;
        this.renderers = {};
        var Sig = this.constructor.Weddell.classes.Sig;

        var consts = this.constructor.Weddell.consts;

        if (!this.Component) {
            throw "There is no base component set for this app. Can't mount.";
        }
        if (consts.VAR_NAME in window) {
            throw "Namespace collision for", consts.VAR_NAME, "on window object. Aborting.";
        }

        Object.defineProperty(window, consts.VAR_NAME, {
            value: {app: this, components: {} }
        });
        
        this.pipelines = {
            styles: {
                init: 'initStylesPipeline',
                render: 'renderStyles',
                componentEvent: 'renderstyles'
            },
            markup: {
                render: 'renderMarkup',
                componentEvent: 'rendermarkup'
            }            
        };
    }

    renderCSS(CSSString) {
        this.styleEl.textContent = CSSString;
    }

    initStylesPipeline() {
        if (typeof this.styleEl == 'string') {
            this.styleEl = document.querySelector(this.styleEl);
        } else if (!this.styleEl) {
            this.styleEl = document.createElement('style');
            this.styleEl.setAttribute('type', 'text/css');
            document.head.appendChild(this.styleEl);
        }
        var appStyles = this.styles;
        if (appStyles) {
            this.renderCSS(appStyles);
        }
    }

    renderMarkup(evt) {
        if (!(evt.renderFormat in this.renderers)) {
            throw "No appropriate markup renderer found for format: " + evt.renderFormat;
        }
        this.renderers[evt.renderFormat].call(this, evt.output);
        this.component.trigger('renderdommarkup', Object.assign({}, evt));
    }

    renderStyles(evt) {
        var staticStyles = [];
        
        var flattenStyles = (obj) => {
            var childStyles = (obj.components ? obj.components.map(flattenStyles).join('\r\n') : '');
            var styles = Array.isArray(obj) ? obj.map(flattenStyles).join('\r\n') : (obj.output ? obj.output : '');

            if (obj.staticStyles) {
                var staticObj = {
                    class: obj.component.constructor,
                    styles: obj.staticStyles
                };
                if (this.childStylesFirst) {
                    staticStyles.unshift(staticObj)
                } else {
                    staticStyles.push(staticObj)
                }
            }

            return (this.childStylesFirst ? childStyles + styles : styles + childStyles).trim();
        };
        var instanceStyles = flattenStyles(evt);

        staticStyles = staticStyles.reduce((finalArr, styleObj) => {
            if (!styleObj.class._BaseClass || !finalArr.some(otherStyleObj => otherStyleObj.class._BaseClass === styleObj.class._BaseClass || otherStyleObj.class._BaseClass instanceof styleObj.class._BaseClass)) {
                return finalArr.concat(styleObj)
            }
            return finalArr;
        }, []).map(styleObj => typeof styleObj.styles === 'string' ? styleObj.styles : '').join('\n\r');

        var styles = [this.styles || '', staticStyles, instanceStyles].join('\r\n').trim();
        this.renderCSS(styles);

        this.component.trigger('renderdomstyles', Object.assign({}, evt));
    }

    makeComponentClass(ComponentClass) {
        if (ComponentClass.prototype && (ComponentClass.prototype instanceof Component || ComponentClass.prototype.constructor === Component)) {
            if (ComponentClass.prototype instanceof this.constructor.Weddell.classes.Component || ComponentClass.prototype.constructor === this.constructor.Weddell.classes.Component) {
                return ComponentClass;<commit_msg>Render styles into separate style elements<commit_after>var DOMReady = require('document-ready-promise')();
var defaults = require('object.defaults/immutable');
var mix = require('mixwith-es5').mix;
var Sig = require('./sig');
var EventEmitterMixin = require('./event-emitter-mixin');
var isApplicationOf = require('mixwith-es5').isApplicationOf;
var Component = require('./component');

Sig.addTypeAlias('CSSString', 'String');

var defaultOpts = {
    renderInterval: 41.6667,
    markupRenderFormat: null,
    stylesRenderFormat: 'CSSString',
    markupTransforms: [],
    pipelineInitMethods: {},
    stylesTransforms: [],
    childStylesFirst: true
};

function createStyleEl() {
    var styleEl = document.createElement('style');
    styleEl.setAttribute('type', 'text/css');
    document.head.appendChild(styleEl);
    return styleEl;
}

var App = class extends mix(App).with(EventEmitterMixin) {
    constructor(opts) {
        opts = defaults(opts, defaultOpts);
        super(opts);
        this.styles = opts.styles;
        this.el = opts.el;
        this.renderOrder = ['markup', 'styles'];
        this.pipelineInitMethods = opts.pipelineInitMethods;
        this.styleEl = opts.styleEl;
        this.componentInitOpts = Array.isArray(opts.Component) ? opts.Component[1] : {};
        this.Component = this.makeComponentClass(Array.isArray(opts.Component) ? opts.Component[0] : opts.Component);
        this.component = null;
        this.shouldRender = {};
        this.renderInterval = opts.renderInterval;
        this.renderPromise = null;
        this.stylesRenderFormat = opts.stylesRenderFormat;
        this.markupRenderFormat = opts.markupRenderFormat;
        this.markupTransforms = opts.markupTransforms;
        this.stylesTransforms = opts.stylesTransforms;
        this.childStylesFirst = opts.childStylesFirst;
        this.renderers = {};
        var Sig = this.constructor.Weddell.classes.Sig;

        var consts = this.constructor.Weddell.consts;

        if (!this.Component) {
            throw "There is no base component set for this app. Can't mount.";
        }
        if (consts.VAR_NAME in window) {
            throw "Namespace collision for", consts.VAR_NAME, "on window object. Aborting.";
        }

        Object.defineProperty(window, consts.VAR_NAME, {
            value: {app: this, components: {} }
        });
        
        this.pipelines = {
            styles: {
                init: 'initStylesPipeline',
                render: 'renderStyles',
                componentEvent: 'renderstyles'
            },
            markup: {
                render: 'renderMarkup',
                componentEvent: 'rendermarkup'
            }            
        };
    }

    renderCSS(staticStyles=[], instanceStyles=[]) {
        if (this.styles && !this.styleEl.textContent) {
            this.styleEl.textContent = this.styles;
        }
        var prevEl;
        var leftovers = staticStyles.concat(instanceStyles).reduce((final, obj) => {
            var styleIndex = final.findIndex(styleEl => styleEl.id === 'weddell-style-' + obj.id);
            var styleEl;

            if (styleIndex === -1) {
                styleEl = createStyleEl();
                styleEl.id = 'weddell-style-' + obj.id;
                styleEl.classList.add('weddell-style');
            } else {
                styleEl = final.splice(styleIndex, 1)[0];
            }

            if (!(styleEl.textContent === obj.styles)) {
                styleEl.textContent = obj.styles;
            }

            if (prevEl) {
                var comparison = prevEl.compareDocumentPosition(styleEl);
                if (comparison !== Node.DOCUMENT_POSITION_FOLLOWING) {
                    prevEl.parentNode.insertBefore(styleEl, prevEl.nextSibling);
                }
            }

            prevEl = styleEl;

            return final;
        }, Array.from(document.querySelectorAll('head style.weddell-style')));

        leftovers.forEach(el => {
            document.head.removeChild(el);
        });
    }

    initStylesPipeline() {
        if (typeof this.styleEl == 'string') {
            this.styleEl = document.querySelector(this.styleEl);
        } else if (!this.styleEl) {
            this.styleEl = createStyleEl();
        }
        var appStyles = this.styles;
        if (appStyles) {
            this.renderCSS();
        }
    }

    renderMarkup(evt) {
        if (!(evt.renderFormat in this.renderers)) {
            throw "No appropriate markup renderer found for format: " + evt.renderFormat;
        }
        this.renderers[evt.renderFormat].call(this, evt.output);
        this.component.trigger('renderdommarkup', Object.assign({}, evt));
    }

    renderStyles(evt) {
        var staticStyles = [];
        
        var flattenStyles = (obj) => {
            var childStyles = (obj.components ? obj.components.map(flattenStyles) : []).reduce((final, item) => final.concat(item), []);
            var styles = Array.isArray(obj) ? obj.map(flattenStyles) : ({ styles: obj.output ? obj.output.trim() : '', id: obj.component._id });

            if (obj.staticStyles) {
                var staticObj = {
                    class: obj.component.constructor,
                    styles: obj.staticStyles.trim()
                };
                if (this.childStylesFirst) {
                    staticStyles.unshift(staticObj)
                } else {
                    staticStyles.push(staticObj)
                }
            }
            return (this.childStylesFirst ? childStyles.concat(styles) : [styles].concat(childStyles));
        };
        var instanceStyles = flattenStyles(evt)
            .filter(item => item.styles);

        staticStyles = staticStyles.reduce((finalArr, styleObj) => {
            if (!styleObj.class._BaseClass || !finalArr.some(otherStyleObj => otherStyleObj.class._BaseClass === styleObj.class._BaseClass || otherStyleObj.class._BaseClass instanceof styleObj.class._BaseClass)) {
                return finalArr.concat(styleObj)
            }
            return finalArr;
        }, [])
        .map(item => ({ id: item.class._id || 'root', styles: item.styles }))

        this.renderCSS(staticStyles, instanceStyles);

        this.component.trigger('renderdomstyles', Object.assign({}, evt));
    }

    makeComponentClass(ComponentClass) {
        if (ComponentClass.prototype && (ComponentClass.prototype instanceof Component || ComponentClass.prototype.constructor === Component)) {
            if (ComponentClass.prototype instanceof this.constructor.Weddell.classes.Component || ComponentClass.prototype.constructor === this.constructor.Weddell.classes.Component) {
                return ComponentClass;
{'fraction_non_alphanumeric': 0.12331151073174774, 'fraction_numerical': 0.001906024695450402, 'mean_word_length': 2.2388620504562535, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 16, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1597273', 'n_tokens_mistral': 3275, 'n_tokens_neox': 3278, 'n_words': 589}