<commit_before>export default class DropZone {
    /**
     * DropZone
     * @param {Element} node
     * @param {Object} options
     * @param {DropZoneValidatorDispatcher} validator
     * @param {DropZoneEventManager} eventManager
     * @param {DropZoneIdleTimer} idleTimer
     * @param {DropZoneFileManager} fileManager
     * @param {DropZoneCallbackManager} callbackManager
     */
    constructor (node, options, validator, eventManager, idleTimer, fileManager, callbackManager) {
        this.validator = validator;
        this.eventManager = eventManager;
        this.idleTimer = idleTimer;
        this.fileManager = fileManager;
        this.callbackManager = callbackManager;
        this.node = window.$ && node instanceof window.$ ? node[0] : node;
        this.options = options;
        this.id = this.options.dropZoneId;
        // cache methods with context
        this.handleDropWithContext = this.handleDrop.bind(this);
        this.handleWindowEnterWithContext = this.handleWindowEnter.bind(this);
        this.handleWindowLeaveWithContext = this.handleWindowLeave.bind(this);
        // a flag for determining support
        this.supportsDataTransfer = true;
        // setup files and size storage
        this.files = [];
        this.size = 0;
    }

    /**
     * Initialise plugin
     */
    init () {
        if (!this.node) {
            throw new Error('DropZone requires a DOM node');
        }

        // add events for environments that support data transfer items
        if (this.options.supported) {
            this.windowActive = false;
            this.dropZoneActive = false;
            // prevent
            this.eventManager.add(window, 'drag', this.eventManager.preventer);
            this.eventManager.add(window, 'dragstart', this.eventManager.preventer);
            this.eventManager.add(window, 'dragend', this.eventManager.preventer);
            this.eventManager.add(window, 'dragover', this.eventManager.preventer);
            this.eventManager.add(window, 'dragenter', this.eventManager.preventer);
            this.eventManager.add(window, 'dragleave', this.eventManager.preventer);
            this.eventManager.add(window, 'drop', this.eventManager.preventer);
            // interactions
            this.eventManager.add(window, 'dragenter', this.handleWindowEnterWithContext);
            this.eventManager.add(window, 'dragleave', this.handleWindowLeaveWithContext);
            this.eventManager.add(window, 'drop', this.handleDropWithContext);

            // attempt to handle missed callbacks
            // mouseout has proven to be more reliable than dragleave
            this.eventManager.add(document, 'mouseout', this.idleTimer.start(event => {
                if (this.windowActive || this.dropZoneActive) {
                    this.handleWindowLeave(event, true);
                }
            }));
        }
    }

    /**
     * Handle drop event
     * @param  {Event} event
     */
    handleDrop (event) {
        const files = event.dataTransfer.items || event.dataTransfer.files;

        // determine where the drop has taken place
        // dropped on the DropZone
        if (this.windowActive && this.dropZoneActive) {
            this.addFiles(files);
            // dropped on the window
        } else if (this.windowActive && !this.dropZoneActive) {
            this.callbackManager.create(
                this.options.windowDrop,
                this,
                { files: this.files, node: this.node }
            );
        }

        // reset DropZone state
        this.windowActive = false;
        this.dropZoneActive = false;
    }

    /**
     * Validate and add files to the DropZone
     * @param {Array} files
     * @param {Object} meta
     */
    addFiles (files, meta = {}) {
        const { valid, text } = this.validator.validate(files, this.files.length, this.size);
        let processedFiles = [];

        for (let i = 0; i < files.length; i++) {
            const file = files[i].getAsFile ? files[i].getAsFile() : files[i];

            // increment size store
            this.size += file.size;
            // process file
            processedFiles.push(
                this.fileManager.createFileObject(file, this.files.length, meta)
            );
        }

        if (valid) {
            // add processed files to file store
            this.files = [...this.files, ...processedFiles];
        }

        // fire dropped callback
        this.callbackManager.create(
            this.options.dropZoneDrop,
            this,
            { files: processedFiles, node: this.node, valid, text }
        );
    }

    /**
     * Determine if file is on window
     * @param {number} x
     * @param {number} y
     * @returns {boolean|Element}
     */
    fileOnWindow (x, y) {
        const offWindow = x === 0 && y === 0;
        return !offWindow && document.elementFromPoint(x, y);
    }

    /**
     * Handle a file dragged into the window
     * @param {Event} event
     */
    handleWindowEnter (event) {
        const onWindow = this.fileOnWindow(event.clientX, event.clientY);
        const onDropZone = this.node.contains(onWindow);
        const files = event.dataTransfer.items || event.dataTransfer.files;

        // clear idle timer
        this.idleTimer.clear();

        // if we are unable to get a length from the files we know data transfer
        // isn't supported, so we'll set this flag to use later
        if (!files.length) {
            this.supportsDataTransfer = false;
        }

        if (onWindow && !this.windowActive) {
            // handle files on window
            const {valid, text} = this.validator.validate(files, this.files.length, this.size);

            this.windowActive = true;
            this.callbackManager.create(
                this.options.windowEnter,
                this,
                {valid, text}
            );
        }

        if (onDropZone && !this.dropZoneActive) {
            // handle files on DropZone
            this.handleDropZoneEnter(files);
        }
    }

    /**
     * Handle a file being dragged off of the window
     * @param {Event} event
     * @param {Boolean} force
     */
    handleWindowLeave (event, force = false) {
        const onDropZone = this.node.contains(document.elementFromPoint(event.clientX, event.clientY));
        const onWindow = this.fileOnWindow(event.clientX, event.clientY);
        const files = event.dataTransfer.items || event.dataTransfer.files;

        if (force || !onWindow) {
            this.windowActive = false;
            this.dropZoneActive = false;
            this.idleTimer.clear();
            this.callbackManager.create(this.options.windowLeave, this);
        } else if (!onDropZone && this.dropZoneActive) {
            this.handleDropZoneLeave(files);
        }
    }

    /**
     * Handle drag entering the DropZone
     * @param {Array} files
     */
    handleDropZoneEnter (files) {
        const { valid, text } = this.validator.validate(files, this.getFiles().length, this.getSize());

        this.idleTimer.clear();
        this.dropZoneActive = true;
        this.callbackManager.create(
            this.options.dropZoneEnter,
            this,
            { valid, text }
        );
    }

    /**
     * Handle drag leaving the DropZone
     * @param {Array} files
     */
    handleDropZoneLeave (files) {
        const { valid, text } = this.validator.validate(files, this.getFiles().length, this.getSize());

        this.idleTimer.clear();
        this.dropZoneActive = false;
        this.callbackManager.create(
            this.options.dropZoneLeave,
            this,
            { valid, text }
        );
    }

    /**
     * Return all files in the store or a file at a specified index
     * @param {Number} index
     * @return {Array|Object}
     */
    getFiles (index = -1) {
        return index < 0 ? this.files : this.files[index];
    }

    /**
     * Return total size of files on the DropZone
     * @return {Number}
     */
    getSize () {
        return this.size;
    }

    /**
     * Remove a file from the store using it's ID
     * @param {number} id
     */
    removeFile (id) {
        this.files = this.files.filter(file => {
            if (file.id === id) {
                this.size -= file.raw.size;
            } else {
                return file;
            }
        });

        this.callbackManager.create(this.options.fileRemoved, this);
    }

    /**
     * Reset
     * - Remove any events attached by DropZone
     * - re-initialise default values, and event handlers
     */
    reset () {
        this.files = [];
        this.size = 0;
        this.eventManager.removeAll();
        this.init();
    }

    /**
     * Get DropZone ID
     * @returns {number}
     */
    getDropZoneId () {
        return this.id;
    }

    /**
     * Get dataTransfer support
     * @returns {boolean}
     */
    getSupportsDataTransfer () {
        return this.supportsDataTransfer;
    }
}
<commit_msg>linting<commit_after>export default class DropZone {
    /**
     * DropZone
     * @param {Element} node
     * @param {Object} options
     * @param {DropZoneValidatorDispatcher} validator
     * @param {DropZoneEventManager} eventManager
     * @param {DropZoneIdleTimer} idleTimer
     * @param {DropZoneFileManager} fileManager
     * @param {DropZoneCallbackManager} callbackManager
     */
    constructor (node, options, validator, eventManager, idleTimer, fileManager, callbackManager) {
        this.validator = validator;
        this.eventManager = eventManager;
        this.idleTimer = idleTimer;
        this.fileManager = fileManager;
        this.callbackManager = callbackManager;
        this.node = window.$ && node instanceof window.$ ? node[0] : node;
        this.options = options;
        this.id = this.options.dropZoneId;
        // cache methods with context
        this.handleDropWithContext = this.handleDrop.bind(this);
        this.handleWindowEnterWithContext = this.handleWindowEnter.bind(this);
        this.handleWindowLeaveWithContext = this.handleWindowLeave.bind(this);
        // a flag for determining support
        this.supportsDataTransfer = true;
        // setup files and size storage
        this.files = [];
        this.size = 0;
    }

    /**
     * Initialise plugin
     */
    init () {
        if (!this.node) {
            throw new Error('DropZone requires a DOM node');
        }

        // add events for environments that support data transfer items
        if (this.options.supported) {
            this.windowActive = false;
            this.dropZoneActive = false;
            // prevent
            this.eventManager.add(window, 'drag', this.eventManager.preventer);
            this.eventManager.add(window, 'dragstart', this.eventManager.preventer);
            this.eventManager.add(window, 'dragend', this.eventManager.preventer);
            this.eventManager.add(window, 'dragover', this.eventManager.preventer);
            this.eventManager.add(window, 'dragenter', this.eventManager.preventer);
            this.eventManager.add(window, 'dragleave', this.eventManager.preventer);
            this.eventManager.add(window, 'drop', this.eventManager.preventer);
            // interactions
            this.eventManager.add(window, 'dragenter', this.handleWindowEnterWithContext);
            this.eventManager.add(window, 'dragleave', this.handleWindowLeaveWithContext);
            this.eventManager.add(window, 'drop', this.handleDropWithContext);

            // attempt to handle missed callbacks
            // mouseout has proven to be more reliable than dragleave
            this.eventManager.add(document, 'mouseout', this.idleTimer.start(event => {
                if (this.windowActive || this.dropZoneActive) {
                    this.handleWindowLeave(event, true);
                }
            }));
        }
    }

    /**
     * Handle drop event
     * @param  {Event} event
     */
    handleDrop (event) {
        const files = event.dataTransfer.items || event.dataTransfer.files;

        // determine where the drop has taken place
        // dropped on the DropZone
        if (this.windowActive && this.dropZoneActive) {
            this.addFiles(files);
        // dropped on the window
        } else if (this.windowActive && !this.dropZoneActive) {
            this.callbackManager.create(
                this.options.windowDrop,
                this,
                { files: this.files, node: this.node }
            );
        }

        // reset DropZone state
        this.windowActive = false;
        this.dropZoneActive = false;
    }

    /**
     * Validate and add files to the DropZone
     * @param {Array} files
     * @param {Object} meta
     */
    addFiles (files, meta = {}) {
        const { valid, text } = this.validator.validate(files, this.files.length, this.size);
        let processedFiles = [];

        for (let i = 0; i < files.length; i++) {
            const file = files[i].getAsFile ? files[i].getAsFile() : files[i];

            // increment size store
            this.size += file.size;
            // process file
            processedFiles.push(
                this.fileManager.createFileObject(file, this.files.length, meta)
            );
        }

        if (valid) {
            // add processed files to file store
            this.files = [...this.files, ...processedFiles];
        }

        // fire dropped callback
        this.callbackManager.create(
            this.options.dropZoneDrop,
            this,
            { files: processedFiles, node: this.node, valid, text }
        );
    }

    /**
     * Determine if file is on window
     * @param {number} x
     * @param {number} y
     * @returns {boolean|Element}
     */
    fileOnWindow (x, y) {
        const offWindow = x === 0 && y === 0;
        return !offWindow && document.elementFromPoint(x, y);
    }

    /**
     * Handle a file dragged into the window
     * @param {Event} event
     */
    handleWindowEnter (event) {
        const onWindow = this.fileOnWindow(event.clientX, event.clientY);
        const onDropZone = this.node.contains(onWindow);
        const files = event.dataTransfer.items || event.dataTransfer.files;

        // clear idle timer
        this.idleTimer.clear();

        // if we are unable to get a length from the files we know data transfer
        // isn't supported, so we'll set this flag to use later
        if (!files.length) {
            this.supportsDataTransfer = false;
        }

        if (onWindow && !this.windowActive) {
            // handle files on window
            const {valid, text} = this.validator.validate(files, this.files.length, this.size);

            this.windowActive = true;
            this.callbackManager.create(
                this.options.windowEnter,
                this,
                {valid, text}
            );
        }

        if (onDropZone && !this.dropZoneActive) {
            // handle files on DropZone
            this.handleDropZoneEnter(files);
        }
    }

    /**
     * Handle a file being dragged off of the window
     * @param {Event} event
     * @param {Boolean} force
     */
    handleWindowLeave (event, force = false) {
        const onDropZone = this.node.contains(document.elementFromPoint(event.clientX, event.clientY));
        const onWindow = this.fileOnWindow(event.clientX, event.clientY);
        const files = event.dataTransfer.items || event.dataTransfer.files;

        if (force || !onWindow) {
            this.windowActive = false;
            this.dropZoneActive = false;
            this.idleTimer.clear();
            this.callbackManager.create(this.options.windowLeave, this);
        } else if (!onDropZone && this.dropZoneActive) {
            this.handleDropZoneLeave(files);
        }
    }

    /**
     * Handle drag entering the DropZone
     * @param {Array} files
     */
    handleDropZoneEnter (files) {
        const { valid, text } = this.validator.validate(files, this.getFiles().length, this.getSize());

        this.idleTimer.clear();
        this.dropZoneActive = true;
        this.callbackManager.create(
            this.options.dropZoneEnter,
            this,
            { valid, text }
        );
    }

    /**
     * Handle drag leaving the DropZone
     * @param {Array} files
     */
    handleDropZoneLeave (files) {
        const { valid, text } = this.validator.validate(files, this.getFiles().length, this.getSize());

        this.idleTimer.clear();
        this.dropZoneActive = false;
        this.callbackManager.create(
            this.options.dropZoneLeave,
            this,
            { valid, text }
        );
    }

    /**
     * Return all files in the store or a file at a specified index
     * @param {Number} index
     * @return {Array|Object}
     */
    getFiles (index = -1) {
        return index < 0 ? this.files : this.files[index];
    }

    /**
     * Return total size of files on the DropZone
     * @return {Number}
     */
    getSize () {
        return this.size;
    }

    /**
     * Remove a file from the store using it's ID
     * @param {number} id
     */
    removeFile (id) {
        this.files = this.files.filter(file => {
            if (file.id === id) {
                this.size -= file.raw.size;
            } else {
                return file;
            }
        });

        this.callbackManager.create(this.options.fileRemoved, this);
    }

    /**
     * Reset
     * - Remove any events attached by DropZone
     * - re-initialise default values, and event handlers
     */
    reset () {
        this.files = [];
        this.size = 0;
        this.eventManager.removeAll();
        this.init();
    }

    /**
     * Get DropZone ID
     * @returns {number}
     */
    getDropZoneId () {
        return this.id;
    }

    /**
     * Get dataTransfer support
     * @returns {boolean}
     */
    getSupportsDataTransfer () {
        return this.supportsDataTransfer;
    }
}
<|endoftext|>


<commit_before>var objectCounter = 0;
var payload = "";
var objects = {};
var emptyObject = function(){
    return { _id:"obj"+objectCounter,
        attributes:{"name":"ojj"+objectCounter++,"payload":payload, "isPort":true},
        registry:{  "position" : { "x" : Math.round(Math.random() * 1000), "y":  Math.round(Math.random() * 1000)},
                    "isConnection" : false,
                    "isPort" : true},
        relations:{parentId:null,
            childrenIds:[],
            baseId:null,
            inheritorIds:[]
        },
        pointers:{}
    }
};
var generatePayload = function(size){
    var i,
        j;
    payload="";
    for(i=0;i<size;i++){
        for(j=0;j<1024;j++){
            payload+="a";
        }
    }
};
var easyBase = function(){
    var object, connection;
    object = emptyObject();
    object._id = "object";
    object.relations.inheritorIds.push("connection");
    objects["object"] = object;
    connection = emptyObject();
    connection._id = "connection";
    connection.relations.baseId = "object";
    connection.registry.isConnection = true;
    objects["connection"] = connection;
    return object;
};
var generateBase = function(length){
    var i,
        previousobject=null,
        currentobject;
    for(i=0;i<length;i++){
        currentobject = emptyObject();
        currentobject.attributes.bazis = "turoburo";
        if(previousobject){
            currentobject.relations.baseId = previousobject._id;
            previousobject.relations.inheritorIds.push = currentobject._id;
        }
        objects[currentobject._id] = currentobject;
        previousobject = currentobject;
    }
    return currentobject;
};

var rGenerateTree = function(level,maxlevel,maxchildren){
    var i,
        root,
        children;
    root = emptyObject();
    if(level === 0){
        root._id = "root";
    }
    root.relations.baseId = commonbase._id;
    commonbase.relations.inheritorIds.push(root._id);
    if(level<maxlevel){
        for(i=0;i<maxchildren;i++){
            children = rGenerateTree(level+1,maxlevel,maxchildren);
            children.relations.parentId = root._id;
            root.relations.childrenIds.push(children._id);
        }
    }
    objects[root._id] = root;
    return root;
};

/*main*/
var i,
    fs = require('fs'),
    arguments = process.argv.splice(" "),
    commonbase,
    root;
if(arguments.length !== 6){
    console.log("usage: gensimpl3 filename numoflevels numofchildren sizeofpayload");
    process.exit(0);
}
generatePayload(Number(arguments[5]));
commonbase = /*generateBase(Number(arguments[6]))*/ easyBase();
root = rGenerateTree(0,Number(arguments[3]),Number(arguments[4]));
fs.writeFileSync(arguments[2]+".tpf", JSON.stringify(objects));
console.log(objectCounter+" object have been created!");
process.exit(0);
<commit_msg>creating connections under "root"<commit_after>var objectCounter = 0;
var payload = "";
var objects = {};
var emptyObject = function(){
    return { _id:"obj"+objectCounter,
        attributes:{"name":"obj"+objectCounter++,"payload":payload, "isPort":true},
        registry:{  "position" : { "x" : Math.round(Math.random() * 1000), "y":  Math.round(Math.random() * 1000)},
                    "isConnection" : false},
        relations:{parentId:null,
            childrenIds:[],
            baseId:null,
            inheritorIds:[]
        },
        pointers:{}
    }
};
var generatePayload = function(size){
    var i,
        j;
    payload="";
    for(i=0;i<size;i++){
        for(j=0;j<1024;j++){
            payload+="a";
        }
    }
};
var easyBase = function(){
    var object, connection;
    object = emptyObject();
    object._id = "object";
    object.relations.inheritorIds.push("connection");
    objects["object"] = object;
    connection = emptyObject();
    connection._id = "connection";
    connection.relations.baseId = "object";
    connection.registry.isConnection = true;
    objects["connection"] = connection;
    return object;
};
var generateBase = function(length){
    var i,
        previousobject=null,
        currentobject;
    for(i=0;i<length;i++){
        currentobject = emptyObject();
        currentobject.attributes.bazis = "turoburo";
        if(previousobject){
            currentobject.relations.baseId = previousobject._id;
            previousobject.relations.inheritorIds.push = currentobject._id;
        }
        objects[currentobject._id] = currentobject;
        previousobject = currentobject;
    }
    return currentobject;
};

var rGenerateTree = function(level,maxlevel,maxchildren){
    var i,
        root,
        children;
    root = emptyObject();
    if(level === 0){
        root._id = "root";
    }
    root.relations.baseId = commonbase._id;
    commonbase.relations.inheritorIds.push(root._id);
    if(level<maxlevel){
        for(i=0;i<maxchildren;i++){
            children = rGenerateTree(level+1,maxlevel,maxchildren);
            children.relations.parentId = root._id;
            root.relations.childrenIds.push(children._id);
        }
    }
    objects[root._id] = root;
    return root;
};

/*main*/
var i,
    fs = require('fs'),
    arguments = process.argv.splice(" "),
    commonbase,
    root;
if(arguments.length !== 6){
    console.log("usage: gensimpl3 filename numoflevels numofchildren sizeofpayload");
    process.exit(0);
}
generatePayload(Number(arguments[5]));
commonbase = /*generateBase(Number(arguments[6]))*/ easyBase();
root = rGenerateTree(0,Number(arguments[3]),Number(arguments[4]));
//all the objects are generated, create connection
console.log("root.relations.childrenIds.length: " + root.relations.childrenIds.length);
var rootChildren = root.relations.childrenIds.length;
for (i = 0; i < rootChildren; i++) {
    //console.log("i: " + i);
    var connId = "conn_" + root.relations.childrenIds[0] + "_" + root.relations.childrenIds[i];
    var connObject = emptyObject();
    connObject._id = connId;
    connObject.attributes.name = connId;
    connObject.relations.baseId = "connection";
    connObject.relations.inheritorIds.push(connId);

    //set parent
    connObject.relations.parentId = root._id;
    root.relations.childrenIds.push(connId);

    //set source and target
    connObject.pointers.source = { "to": root.relations.childrenIds[0], "from": [] };
    connObject.pointers.target = { "to": root.relations.childrenIds[i], "from": [] };

    var sourceFrom = objects[root.relations.childrenIds[0]].pointers.source || { "to" : null, "from" : [] };
    sourceFrom.from.push(connId);
    objects[root.relations.childrenIds[0]].pointers.source = sourceFrom;

    var targetFrom = objects[root.relations.childrenIds[i]].pointers.target || { "to" : null, "from" : [] };
    targetFrom.from.push(connId);
    objects[root.relations.childrenIds[i]].pointers.target = targetFrom;

    objects[connId] = connObject;
}

fs.writeFileSync(arguments[2]+".tpf", JSON.stringify(objects));
console.log(objectCounter+" object have been created!");
process.exit(0);
<|endoftext|>


<commit_before>const GObject = imports.gi.GObject;
const Lang = imports.lang;

const Compat = imports.app.compat.compat;
const Engine = imports.search.engine;
const EosKnowledgePrivate = imports.gi.EosKnowledgePrivate;
const Knowledge = imports.app.knowledge;
const Warehouse = imports.app.warehouse;

const ROOT_NAME = 'root';

/**
 * Class: ModuleFactory
 */
const ModuleFactory = new Knowledge.Class({
    Name: 'ModuleFactory',
    Extends: GObject.Object,
    Properties: {
        /**
         * Property: warehouse
         *
         * The warehouse that holds the paths for creating modules.
         */
        'warehouse': GObject.ParamSpec.object('warehouse', 'Warehouse', 'Warehouse',
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
            GObject.Object.$gtype),
        /**
         * Property: version
         * Version of the app.json that powers this factory
         */
        'version': GObject.ParamSpec.uint('version', 'Version',
            'Version of the app.json that powers this factory',
            GObject.ParamFlags.READABLE, 0, 999, 2),
    },

    _init: function (props={}) {
        /**
         * Property: app-json
         *
         * The json object parsed from app.json that contains the app's
         * description.
         */
        Object.defineProperties(this, {
            'app_json': {
                value: props['app_json'] || props['app-json'] || props['appJson'],
                writable: true,
            },
        });
        delete props['app_json'];
        delete props['app-json'];
        delete props['appJson'];

        props.warehouse = props.warehouse || new Warehouse.Warehouse();

        this.parent(props);

        if (!this.app_json.hasOwnProperty('version') || this.app_json.version < 2) {
            this.app_json = Compat.transform_v1_description(this.app_json);
            this._version = 1;
        } else {
            this._version = this.app_json.version;
        }
        // After this point, the app.json must be the current version!

        this._ids = new Set();
        this._id_to_module = new Map();
        this._id_to_pending_callbacks = new Map();
        this._path_to_description = new Map();
        this._extract_ids(this.app_json[ROOT_NAME], false);
        this._unique_count = 0;
    },

    get version() {
        return this._version;
    },

    _parse_json_property: function (module_class, property_name, json_value) {
        let param_spec = GObject.Object.find_property.call(module_class, property_name);
        if (param_spec === null) {
            logError(new Error('Could not find property for ' + module_class + ' named ' + property_name));
            return [false, null];
        }
        if (!EosKnowledgePrivate.param_spec_is_enum(param_spec))
            return [true, json_value];
        let [success, enum_value] = EosKnowledgePrivate.param_spec_enum_value_from_string(param_spec, json_value);
        if (!success) {
            logError(new Error('Could not find enum for ' + property_name + ' named ' + json_value));
            return [false, null];
        }
        return [true, enum_value];
    },

    _create_module: function (path, description, extra_props={}) {
        this._path_to_description.set(path, description);

        let id = ('id' in description) ? description['id'] : null;
        let styles = ('styles' in description) ? description['styles'] : null;

        let module_class = this.warehouse.type_to_class(description['type']);
        let module_props = {
            factory: this,
            factory_path: path,
        };
        if (id)
            module_props['factory_id'] = id;

        if (description.hasOwnProperty('properties')) {
            let properties = description['properties'];
            for (let property_name in properties) {
                let [success, value] = this._parse_json_property(module_class, property_name, properties[property_name]);
                if (!success)
                    continue;
                module_props[property_name] = value;
            }
        }
        Lang.copyProperties(extra_props, module_props);

        let module = new module_class(module_props);

        if (styles) {
            let context = module.get_style_context();
            styles.forEach(context.add_class, context);
        }
        if (id) {
            this._id_to_module.set(id, module);
            this._deliver_module_reference(module);
        }

        return module;
    },

    /**
     * Method: create_module_tree
     * Creates the root of the module tree
     *
     * Creates the root module of the module tree described in app.json.
     * This module is usually the interaction that drives the app.
     *
     * Parameters:
     *   extra_props - Extra construct properties for the module.
     */
    create_module_tree: function (extra_props={}) {
        return this._create_module(ROOT_NAME, this.app_json[ROOT_NAME],
            extra_props);
    },

    /**
     * Method: create_module_for_slot
     * Returns module specified in app.json for a slot
     *
     * Searches the app.json for the module meant to fill the slot
     * {slot} of module {parent_module}. Creates and returns this module, or null
     * if the slot was not filled.
     *
     * Parameters:
     *   parent_module - Module for which to create submodule
     *   slot - Slot for which to create module
     *   extra_props - dictionary of construct properties for the submodule
     */
    create_module_for_slot: function (parent_module, slot, extra_props={}) {
        let slots_info = parent_module.constructor.__slots__;
        if (!(slot in slots_info))
            throw new Error('No slot named ' + slot +
                '; did you define it in Slots in your Module.Class definition?');

        let empty_return = slots_info[slot].array ? [] : null;
        let slots = this._path_to_description.get(parent_module.factory_path)['slots'];
        if (!slots)
            return empty_return;
        let slot_value = slots[slot];
        if (slot_value === null || slot_value === undefined)
            return empty_return;

        // The "unique count" makes sure that each instance of a module created
        // from a multi slot, as well as each instance's submodules, have a
        // unique path. For example, root -> multi-slot would get a path of
        // root.multi-slot.0, root.multi-slot.1, etc. If the module in that
        // multi-slot had a non-multi slot, then you would have
        // root.multi-slot.0.slot, root.multi-slot.1.slot, etc.
        let path = parent_module.factory_path + '.' + slot;
        if (slots_info[slot].multi)
            path += '.' + this._unique_count++;

        if (this._path_to_description.has(path))
            throw new Error('You are creating more than one instance of a ' +
                'submodule that is not in a multi slot: ' + path);

        // The module is not an array, we treat it as a single module
        if (!slots_info[slot].array)
            return this._create_module(path, slot_value, extra_props);

        if (!Array.isArray(slot_value))
            throw new Error('Slot ' + slot + ' is expected to be an array of submodules!');

        let module_array = slot_value.map((submodule, ix) => {
            let subpath = path + '.' + ix;
            return this._create_module(subpath, submodule, extra_props);
        });
        return module_array;
    },

    /**
     * Method: request_module_reference
     * Passes an existing module instance through the callback
     *
     * Passes an existing module instance through the callback if the module
     * instance is available, if is not available, just keeps the callback so
     * it can be called later when the module is created.
     *
     * Parameters:
     *   module - module asking for another module instance
     *   reference_slot - reference slot which contains the id of module instance
     *   callback - function to be called whenever the instance is available
     */
    request_module_reference: function (module, reference_slot, callback) {
        let id = this._get_id_for_reference(module, reference_slot);
        if (id === null) {
            callback(null);
            return;
        }
        if (this._id_to_module.has(id)) {
            callback(this._id_to_module.get(id));
            return;
        }
        if (!this._id_to_pending_callbacks.has(id)) {
            this._id_to_pending_callbacks.set(id, []);
        }
        this._id_to_pending_callbacks.get(id).push(callback);
    },

    _deliver_module_reference: function (module) {
        let id = module.factory_id;
        if (!this._id_to_pending_callbacks.has(id))
            return;
        this._id_to_pending_callbacks.get(id).forEach((callback) => {
            callback(module);
        });
        this._id_to_pending_callbacks.delete(id);
    },

    _get_id_for_reference: function (parent_module, reference_slot) {
        if (!(reference_slot in parent_module.constructor.__references__))
            throw new Error('No referenced slot named ' + reference_slot);
        let description = this._path_to_description.get(parent_module.factory_path);
        if (!(reference_slot in description['references']))
            return null;
        return description['references'][reference_slot];
    },

    _extract_ids: function (parent_description, parent_is_multi) {
        this._check_id(parent_description, parent_is_multi);
        if (parent_description['styles'])
            this._check_styles_support(parent_description);
        if (!('slots' in parent_description))
            return;

        Object.keys(parent_description['slots']).forEach((slot_name) => {
            let slot_value = parent_description['slots'][slot_name];
            /* keep track of whether is inside or below a multi slot */
            let is_multi = this._is_multi_slot(parent_description, slot_name, parent_is_multi);
            if(!slot_value)
                return;
            if (typeof slot_value === 'string')
                slot_value = this._path_to_description.get(slot_value);

            this._extract_ids(slot_value, is_multi);
        });
    },

    _check_id: function (description, parent_is_multi) {
        if (!('id' in description))
            return;
        let id = description['id'];
        if (parent_is_multi)
            throw new Error('id ' + id + ' defined in a multi slot');
        if (this._ids.has(id))
            throw new Error('id ' + id + ' is not unique');

        this._ids.add(id);
    },

    _is_multi_slot: function (description, slot_name, parent_is_multi) {
        let module_class = this.warehouse.type_to_class(description['type']);
        let slot_props = module_class.__slots__[slot_name];
        if (typeof slot_props === 'undefined')
            throw new Error("No slot " + slot_name + " found in module: " + module_class);
        return (parent_is_multi || ('multi' in slot_props && slot_props['multi']));
    },

    _check_styles_support: function (description) {
        let module_type = description['type'];
        let module_class = this.warehouse.type_to_class(module_type);
        if (typeof module_class.prototype.get_style_context === 'undefined')
            throw new Error('No styles support in ' + module_type);
    },
});
<commit_msg>Remove dead code<commit_after>const GObject = imports.gi.GObject;
const Lang = imports.lang;

const Compat = imports.app.compat.compat;
const Engine = imports.search.engine;
const EosKnowledgePrivate = imports.gi.EosKnowledgePrivate;
const Knowledge = imports.app.knowledge;
const Warehouse = imports.app.warehouse;

const ROOT_NAME = 'root';

/**
 * Class: ModuleFactory
 */
const ModuleFactory = new Knowledge.Class({
    Name: 'ModuleFactory',
    Extends: GObject.Object,
    Properties: {
        /**
         * Property: warehouse
         *
         * The warehouse that holds the paths for creating modules.
         */
        'warehouse': GObject.ParamSpec.object('warehouse', 'Warehouse', 'Warehouse',
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
            GObject.Object.$gtype),
        /**
         * Property: version
         * Version of the app.json that powers this factory
         */
        'version': GObject.ParamSpec.uint('version', 'Version',
            'Version of the app.json that powers this factory',
            GObject.ParamFlags.READABLE, 0, 999, 2),
    },

    _init: function (props={}) {
        /**
         * Property: app-json
         *
         * The json object parsed from app.json that contains the app's
         * description.
         */
        Object.defineProperties(this, {
            'app_json': {
                value: props['app_json'] || props['app-json'] || props['appJson'],
                writable: true,
            },
        });
        delete props['app_json'];
        delete props['app-json'];
        delete props['appJson'];

        props.warehouse = props.warehouse || new Warehouse.Warehouse();

        this.parent(props);

        if (!this.app_json.hasOwnProperty('version') || this.app_json.version < 2) {
            this.app_json = Compat.transform_v1_description(this.app_json);
            this._version = 1;
        } else {
            this._version = this.app_json.version;
        }
        // After this point, the app.json must be the current version!

        this._ids = new Set();
        this._id_to_module = new Map();
        this._id_to_pending_callbacks = new Map();
        this._path_to_description = new Map();
        this._extract_ids(this.app_json[ROOT_NAME], false);
        this._unique_count = 0;
    },

    get version() {
        return this._version;
    },

    _parse_json_property: function (module_class, property_name, json_value) {
        let param_spec = GObject.Object.find_property.call(module_class, property_name);
        if (param_spec === null) {
            logError(new Error('Could not find property for ' + module_class + ' named ' + property_name));
            return [false, null];
        }
        if (!EosKnowledgePrivate.param_spec_is_enum(param_spec))
            return [true, json_value];
        let [success, enum_value] = EosKnowledgePrivate.param_spec_enum_value_from_string(param_spec, json_value);
        if (!success) {
            logError(new Error('Could not find enum for ' + property_name + ' named ' + json_value));
            return [false, null];
        }
        return [true, enum_value];
    },

    _create_module: function (path, description, extra_props={}) {
        this._path_to_description.set(path, description);

        let id = ('id' in description) ? description['id'] : null;
        let styles = ('styles' in description) ? description['styles'] : null;

        let module_class = this.warehouse.type_to_class(description['type']);
        let module_props = {
            factory: this,
            factory_path: path,
        };
        if (id)
            module_props['factory_id'] = id;

        if (description.hasOwnProperty('properties')) {
            let properties = description['properties'];
            for (let property_name in properties) {
                let [success, value] = this._parse_json_property(module_class, property_name, properties[property_name]);
                if (!success)
                    continue;
                module_props[property_name] = value;
            }
        }
        Lang.copyProperties(extra_props, module_props);

        let module = new module_class(module_props);

        if (styles) {
            let context = module.get_style_context();
            styles.forEach(context.add_class, context);
        }
        if (id) {
            this._id_to_module.set(id, module);
            this._deliver_module_reference(module);
        }

        return module;
    },

    /**
     * Method: create_module_tree
     * Creates the root of the module tree
     *
     * Creates the root module of the module tree described in app.json.
     * This module is usually the interaction that drives the app.
     *
     * Parameters:
     *   extra_props - Extra construct properties for the module.
     */
    create_module_tree: function (extra_props={}) {
        return this._create_module(ROOT_NAME, this.app_json[ROOT_NAME],
            extra_props);
    },

    /**
     * Method: create_module_for_slot
     * Returns module specified in app.json for a slot
     *
     * Searches the app.json for the module meant to fill the slot
     * {slot} of module {parent_module}. Creates and returns this module, or null
     * if the slot was not filled.
     *
     * Parameters:
     *   parent_module - Module for which to create submodule
     *   slot - Slot for which to create module
     *   extra_props - dictionary of construct properties for the submodule
     */
    create_module_for_slot: function (parent_module, slot, extra_props={}) {
        let slots_info = parent_module.constructor.__slots__;
        if (!(slot in slots_info))
            throw new Error('No slot named ' + slot +
                '; did you define it in Slots in your Module.Class definition?');

        let empty_return = slots_info[slot].array ? [] : null;
        let slots = this._path_to_description.get(parent_module.factory_path)['slots'];
        if (!slots)
            return empty_return;
        let slot_value = slots[slot];
        if (slot_value === null || slot_value === undefined)
            return empty_return;

        // The "unique count" makes sure that each instance of a module created
        // from a multi slot, as well as each instance's submodules, have a
        // unique path. For example, root -> multi-slot would get a path of
        // root.multi-slot.0, root.multi-slot.1, etc. If the module in that
        // multi-slot had a non-multi slot, then you would have
        // root.multi-slot.0.slot, root.multi-slot.1.slot, etc.
        let path = parent_module.factory_path + '.' + slot;
        if (slots_info[slot].multi)
            path += '.' + this._unique_count++;

        if (this._path_to_description.has(path))
            throw new Error('You are creating more than one instance of a ' +
                'submodule that is not in a multi slot: ' + path);

        // The module is not an array, we treat it as a single module
        if (!slots_info[slot].array)
            return this._create_module(path, slot_value, extra_props);

        if (!Array.isArray(slot_value))
            throw new Error('Slot ' + slot + ' is expected to be an array of submodules!');

        let module_array = slot_value.map((submodule, ix) => {
            let subpath = path + '.' + ix;
            return this._create_module(subpath, submodule, extra_props);
        });
        return module_array;
    },

    /**
     * Method: request_module_reference
     * Passes an existing module instance through the callback
     *
     * Passes an existing module instance through the callback if the module
     * instance is available, if is not available, just keeps the callback so
     * it can be called later when the module is created.
     *
     * Parameters:
     *   module - module asking for another module instance
     *   reference_slot - reference slot which contains the id of module instance
     *   callback - function to be called whenever the instance is available
     */
    request_module_reference: function (module, reference_slot, callback) {
        let id = this._get_id_for_reference(module, reference_slot);
        if (id === null) {
            callback(null);
            return;
        }
        if (this._id_to_module.has(id)) {
            callback(this._id_to_module.get(id));
            return;
        }
        if (!this._id_to_pending_callbacks.has(id)) {
            this._id_to_pending_callbacks.set(id, []);
        }
        this._id_to_pending_callbacks.get(id).push(callback);
    },

    _deliver_module_reference: function (module) {
        let id = module.factory_id;
        if (!this._id_to_pending_callbacks.has(id))
            return;
        this._id_to_pending_callbacks.get(id).forEach((callback) => {
            callback(module);
        });
        this._id_to_pending_callbacks.delete(id);
    },

    _get_id_for_reference: function (parent_module, reference_slot) {
        if (!(reference_slot in parent_module.constructor.__references__))
            throw new Error('No referenced slot named ' + reference_slot);
        let description = this._path_to_description.get(parent_module.factory_path);
        if (!(reference_slot in description['references']))
            return null;
        return description['references'][reference_slot];
    },

    _extract_ids: function (parent_description, parent_is_multi) {
        this._check_id(parent_description, parent_is_multi);
        if (parent_description['styles'])
            this._check_styles_support(parent_description);
        if (!('slots' in parent_description))
            return;

        Object.keys(parent_description['slots']).forEach((slot_name) => {
            let slot_value = parent_description['slots'][slot_name];
            /* keep track of whether is inside or below a multi slot */
            let is_multi = this._is_multi_slot(parent_description, slot_name, parent_is_multi);
            if(!slot_value)
                return;
            this._extract_ids(slot_value, is_multi);
        });
    },

    _check_id: function (description, parent_is_multi) {
        if (!('id' in description))
            return;
        let id = description['id'];
        if (parent_is_multi)
            throw new Error('id ' + id + ' defined in a multi slot');
        if (this._ids.has(id))
            throw new Error('id ' + id + ' is not unique');

        this._ids.add(id);
    },

    _is_multi_slot: function (description, slot_name, parent_is_multi) {
        let module_class = this.warehouse.type_to_class(description['type']);
        let slot_props = module_class.__slots__[slot_name];
        if (typeof slot_props === 'undefined')
            throw new Error("No slot " + slot_name + " found in module: " + module_class);
        return (parent_is_multi || ('multi' in slot_props && slot_props['multi']));
    },

    _check_styles_support: function (description) {
        let module_type = description['type'];
        let module_class = this.warehouse.type_to_class(module_type);
        if (typeof module_class.prototype.get_style_context === 'undefined')
            throw new Error('No styles support in ' + module_type);
    },
});
<|endoftext|>


<commit_before>/*
  @FONT-FACE MAKER

  README:
    Generates a @font-face rule for a font. You need to call this mixin as many
    times as you have fonts.

  USAGE:
    @mixin font-face <family>, <name>, <style>, <weight>, [<directory>];
*/

const path = require('path');

module.exports = (mixin, fontFamily, fontName, fontStyle, fontWeight, fontDir) => {
  /**
   * XXX: This path may not be ideal for all build tools, especially when using
   * symlinks, it's better to specify fontDir.
   */
  const dir = fontDir || path.join(__dirname, '../../fonts');

  return {
    '@font-face': {
      'font-family': fontFamily,
      src: `local("${fontName}"),
        url("${dir}/${fontName}.woff2") format("woff2"),
        url("${dir}/${fontName}.woff") format("woff")`,
      'font-style': fontStyle,
      'font-weight': fontWeight,
    },
  };
};
<commit_msg>Small enhancement to font face mixin<commit_after>/*
  @FONT-FACE MAKER

  README:
    Generates a @font-face rule for a font. You need to call this mixin as many
    times as you have fonts. This uses the `font-display: optional` property
    which means unless the font is already downloaded and loads instantly, it
    will not flash from unstyled to styled (no FOUT).

  USAGE:
    @mixin font-face <family>, <name>, <style>, <weight>, [<directory>];
*/

const path = require('path');

module.exports = (mixin, fontFamily, fontName, fontStyle, fontWeight, fontDir) => {
  /**
   * XXX: This path may not be ideal for all build tools, especially when using
   * symlinks, it's better to specify fontDir.
   */
  const dir = fontDir || path.join(__dirname, '../../fonts');

  return {
    '@font-face': {
      'font-family': fontFamily,
      src: `local("${fontName}"),
        url("${dir}/${fontName}.woff2") format("woff2"),
        url("${dir}/${fontName}.woff") format("woff")`,
      'font-style': fontStyle,
      'font-weight': fontWeight,
      'font-display': 'optional',
    },
  };
};
<|endoftext|>


<commit_before>import Component from '@ember/component';
import layout from '../templates/components/native-simple-select';

export default Component.extend({
  layout,
  classNames: ['native-simple-select'],
  classNameBindings: ['isFocused'],

  didRender() {
    this._super(...arguments);

    const label = this.get('element')
      .querySelector('option:selected')
      .textContent
      .trim();

    this.set('displayLabel', label);
  },

  actions: {
    focusIn() {
      this.set('isFocused', true);
    },

    focusOut() {
      this.set('isFocused', false);
    }
  }
});
<commit_msg>fix demo<commit_after>import Component from '@ember/component';
import layout from '../templates/components/native-simple-select';

export default Component.extend({
  layout,
  classNames: ['native-simple-select'],
  classNameBindings: ['isFocused'],

  didRender() {
    this._super(...arguments);

    const label = this.get('element')
      .querySelector('option:checked')
      .textContent
      .trim();

    this.set('displayLabel', label);
  },

  actions: {
    focusIn() {
      this.set('isFocused', true);
    },

    focusOut() {
      this.set('isFocused', false);
    }
  }
});
<|endoftext|>


<commit_before>(function () {
    "use strict";

    var ABOUTME = "aboutMe.txt";

    // loads webpage controls
    window.onload = function () {
        // load controls
        var terminalText = document.querySelector("terminal-text");

        // openFile();
        $(document).ready(function(){
            // $("#terminal-text").load("aboutMe.txt");
            // $("#terminal-text").text("loaded");
            $.get("aboutMe.txt", null, function(data, status) {
                // $("#terminal-text").text(data);
                var lines = data.split('\n');
                var aboutMeText = "";

                for (var i = 0; i < lines.length; i++) {
                    aboutMeText += "
" + lines[i] + "
";
                }

                $("#terminal-text").html(aboutMeText);
            }, "text");
        });
    };

    /*
    Ajax helper function.
    Parameters:
    functionName - function to call when response loads
    request - XMLHttpRequest being made
    */
    function ajaxRequest(functionName, request) {
        var ajax = new XMLHttpRequest();
        ajax.onload = functionName;
        ajax.open("GET", request, true);
        ajax.send();
    }

    function openFile() {
        ajaxRequest(processFile, ABOUTME);
    }

    function processFile() {
        debugEvent("processFile()", this);

        if (this.status === 200) {
            document.querySelector(terminalText).innerHTML = this.responseText;
        }
    }

})();<commit_msg>trying cleaner jquery dom appending<commit_after>(function () {
    "use strict";

    var ABOUTME = "aboutMe.txt";

    // loads webpage controls
    window.onload = function () {
        // load controls
        var terminalText = document.querySelector("terminal-text");

        // openFile();
        $(document).ready(function(){
            // $("#terminal-text").load("aboutMe.txt");
            // $("#terminal-text").text("loaded");
            $.get("aboutMe.txt", null, function(data, status) {
                // $("#terminal-text").text(data);
                $("#terminal-text").empty();

                var lines = data.split('\n');
                // var aboutMeText = "";

                for (var i = 0; i < lines.length; i++) {
                    // aboutMeText += "
" + lines[i] + "
";
                    $("#terminal-text").append("
" + lines[i] + "
");
                }

                // $("#terminal-text").html(aboutMeText);
            }, "text");
        });
    };

    /*
    Ajax helper function.
    Parameters:
    functionName - function to call when response loads
    request - XMLHttpRequest being made
    */
    function ajaxRequest(functionName, request) {
        var ajax = new XMLHttpRequest();
        ajax.onload = functionName;
        ajax.open("GET", request, true);
        ajax.send();
    }

    function openFile() {
        ajaxRequest(processFile, ABOUTME);
    }

    function processFile() {
        debugEvent("processFile()", this);

        if (this.status === 200) {
            document.querySelector(terminalText).innerHTML = this.responseText;
        }
    }

})();<|endoftext|>


<commit_before>/* ===========================================================
 * bootstrap-tooltip.js v2.0.0
 * http://twitter.github.com/bootstrap/javascript.html#tooltip
 * Inspired by the original jQuery.tipsy by Jason Frame
 * ===========================================================
 * Copyright 2011 Twitter, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ========================================================== */

!function( $ ) {

  "use strict"

 /* TOOLTIP PUBLIC CLASS DEFINITION
  * =============================== */

  var Tooltip = function ( element, options ) {
    this.init('tooltip', element, options)
  }

  Tooltip.prototype = {

    constructor: Tooltip

  , init: function ( type, element, options ) {
      var eventIn
        , eventOut

      this.type = type
      this.$element = $(element)
      this.options = this.getOptions(options)
      this.enabled = true

      if (this.options.trigger != 'manual') {
        eventIn  = this.options.trigger == 'hover' ? 'mouseenter' : 'focus'
        eventOut = this.options.trigger == 'hover' ? 'mouseleave' : 'blur'
        this.$element.on(eventIn, this.options.selector, $.proxy(this.enter, this))
        this.$element.on(eventOut, this.options.selector, $.proxy(this.leave, this))
      }

      this.options.selector ?
        (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
        this.fixTitle()
    }

  , getOptions: function ( options ) {
      options = $.extend({}, $.fn[this.type].defaults, options, this.$element.data())

      if (options.delay && typeof options.delay == 'number') {
        options.delay = {
          show: options.delay
        , hide: options.delay
        }
      }

      return options
    }

  , enter: function ( e ) {
      var self = $(e.currentTarget)[this.type](this._options).data(this.type)

      if (!self.options.delay || !self.options.delay.show) {
        self.show()
      } else {
        self.hoverState = 'in'
        setTimeout(function() {
          if (self.hoverState == 'in') {
            self.show()
          }
        }, self.options.delay.show)
      }
    }

  , leave: function ( e ) {
      var self = $(e.currentTarget)[this.type](this._options).data(this.type)

      if (!self.options.delay || !self.options.delay.hide) {
        self.hide()
      } else {
        self.hoverState = 'out'
        setTimeout(function() {
          if (self.hoverState == 'out') {
            self.hide()
          }
        }, self.options.delay.hide)
      }
    }

  , show: function () {
      var $tip
        , inside
        , pos
        , actualWidth
        , actualHeight
        , placement
        , tp

      if (this.hasContent() && this.enabled) {
        $tip = this.tip()
        this.setContent()

        if (this.options.animation) {
          $tip.addClass('fade')
        }

        placement = typeof this.options.placement == 'function' ?
          thing.call(this, $tip[0], this.$element[0]) :
          this.options.placement

        inside = /in/.test(placement)

        $tip
          .remove()
          .css({ top: 0, left: 0, display: 'block' })
          .appendTo(inside ? this.$element : document.body)

        pos = this.getPosition(inside)

        actualWidth = $tip[0].offsetWidth
        actualHeight = $tip[0].offsetHeight

        switch (inside ? placement.split(' ')[1] : placement) {
          case 'bottom':
            tp = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2}
            break
          case 'top':
            tp = {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2}
            break
          case 'left':
            tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth}
            break
          case 'right':
            tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width}
            break
        }

        $tip
          .css(tp)
          .addClass(placement)
          .addClass('in')
      }
    }

  , setContent: function () {
      var $tip = this.tip()
      $tip.find('.tooltip-inner').html(this.getTitle())
      $tip.removeClass('fade in top bottom left right')
    }

  , hide: function () {
      var that = this
        , $tip = this.tip()

      $tip.removeClass('in')

      function removeWithAnimation() {
        var timeout = setTimeout(function () {
          $tip.off($.support.transition.end).remove()
        }, 500)

        $tip.one($.support.transition.end, function () {
          clearTimeout(timeout)
          $tip.remove()
        })
      }

      $.support.transition && this.$tip.hasClass('fade') ?
        removeWithAnimation() :
        $tip.remove()
    }

  , fixTitle: function () {
      var $e = this.$element
      if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') {
        $e.attr('data-original-title', $e.attr('title') || '').removeAttr('title')
      }
    }

  , hasContent: function () {
      return this.getTitle()
    }

  , getPosition: function (inside) {
      return $.extend({}, (inside ? {top: 0, left: 0} : this.$element.offset()), {
        width: this.$element[0].offsetWidth
      , height: this.$element[0].offsetHeight
      })
    }

  , getTitle: function () {
      var title
        , $e = this.$element
        , o = this.options

      title = $e.attr('data-original-title')
        || (typeof o.title == 'function' ? o.title.call($e[0]) :  o.title)

      title = title.toString().replace(/(^\s*|\s*$)/, "")

      return title
    }

  , tip: function () {
      return this.$tip = this.$tip || $(this.options.template)
    }

  , validate: function () {
      if (!this.$element[0].parentNode) {
        this.hide()
        this.$element = null
        this.options = null
      }
    }

  , enable: function () {
      this.enabled = true
    }

  , disable: function () {
      this.enabled = false
    }

  , toggleEnabled: function () {
      this.enabled = !this.enabled
    }

  , toggle: function () {
      this[this.tip().hasClass('in') ? 'hide' : 'show']()
    }

  }

 /* TOOLTIP PLUGIN DEFINITION
  * ========================= */

  $.fn.tooltip = function ( option ) {
    return this.each(function () {
      var $this = $(this)
        , data = $this.data('tooltip')
        , options = typeof option == 'object' && option
      if (!data) $this.data('tooltip', (data = new Tooltip(this, options)))
      if (typeof option == 'string') data[option]()
    })
  }

  $.fn.tooltip.Constructor = Tooltip

  $.fn.tooltip.defaults = {
    animation: true
  , delay: 0
  , selector: false
  , placement: 'top'
  , trigger: 'hover'
  , title: ''
  , template: '

'
  }

}( window.jQuery )<commit_msg>Fixed when placement is a function<commit_after>/* ===========================================================
 * bootstrap-tooltip.js v2.0.0
 * http://twitter.github.com/bootstrap/javascript.html#tooltip
 * Inspired by the original jQuery.tipsy by Jason Frame
 * ===========================================================
 * Copyright 2011 Twitter, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ========================================================== */

!function( $ ) {

  "use strict"

 /* TOOLTIP PUBLIC CLASS DEFINITION
  * =============================== */

  var Tooltip = function ( element, options ) {
    this.init('tooltip', element, options)
  }

  Tooltip.prototype = {

    constructor: Tooltip

  , init: function ( type, element, options ) {
      var eventIn
        , eventOut

      this.type = type
      this.$element = $(element)
      this.options = this.getOptions(options)
      this.enabled = true

      if (this.options.trigger != 'manual') {
        eventIn  = this.options.trigger == 'hover' ? 'mouseenter' : 'focus'
        eventOut = this.options.trigger == 'hover' ? 'mouseleave' : 'blur'
        this.$element.on(eventIn, this.options.selector, $.proxy(this.enter, this))
        this.$element.on(eventOut, this.options.selector, $.proxy(this.leave, this))
      }

      this.options.selector ?
        (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
        this.fixTitle()
    }

  , getOptions: function ( options ) {
      options = $.extend({}, $.fn[this.type].defaults, options, this.$element.data())

      if (options.delay && typeof options.delay == 'number') {
        options.delay = {
          show: options.delay
        , hide: options.delay
        }
      }

      return options
    }

  , enter: function ( e ) {
      var self = $(e.currentTarget)[this.type](this._options).data(this.type)

      if (!self.options.delay || !self.options.delay.show) {
        self.show()
      } else {
        self.hoverState = 'in'
        setTimeout(function() {
          if (self.hoverState == 'in') {
            self.show()
          }
        }, self.options.delay.show)
      }
    }

  , leave: function ( e ) {
      var self = $(e.currentTarget)[this.type](this._options).data(this.type)

      if (!self.options.delay || !self.options.delay.hide) {
        self.hide()
      } else {
        self.hoverState = 'out'
        setTimeout(function() {
          if (self.hoverState == 'out') {
            self.hide()
          }
        }, self.options.delay.hide)
      }
    }

  , show: function () {
      var $tip
        , inside
        , pos
        , actualWidth
        , actualHeight
        , placement
        , tp

      if (this.hasContent() && this.enabled) {
        $tip = this.tip()
        this.setContent()

        if (this.options.animation) {
          $tip.addClass('fade')
        }

        placement = typeof this.options.placement == 'function' ?
          this.options.placement.call(this, $tip[0], this.$element[0]) :
          this.options.placement

        inside = /in/.test(placement)

        $tip
          .remove()
          .css({ top: 0, left: 0, display: 'block' })
          .appendTo(inside ? this.$element : document.body)

        pos = this.getPosition(inside)

        actualWidth = $tip[0].offsetWidth
        actualHeight = $tip[0].offsetHeight

        switch (inside ? placement.split(' ')[1] : placement) {
          case 'bottom':
            tp = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2}
            break
          case 'top':
            tp = {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2}
            break
          case 'left':
            tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth}
            break
          case 'right':
            tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width}
            break
        }

        $tip
          .css(tp)
          .addClass(placement)
          .addClass('in')
      }
    }

  , setContent: function () {
      var $tip = this.tip()
      $tip.find('.tooltip-inner').html(this.getTitle())
      $tip.removeClass('fade in top bottom left right')
    }

  , hide: function () {
      var that = this
        , $tip = this.tip()

      $tip.removeClass('in')

      function removeWithAnimation() {
        var timeout = setTimeout(function () {
          $tip.off($.support.transition.end).remove()
        }, 500)

        $tip.one($.support.transition.end, function () {
          clearTimeout(timeout)
          $tip.remove()
        })
      }

      $.support.transition && this.$tip.hasClass('fade') ?
        removeWithAnimation() :
        $tip.remove()
    }

  , fixTitle: function () {
      var $e = this.$element
      if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') {
        $e.attr('data-original-title', $e.attr('title') || '').removeAttr('title')
      }
    }

  , hasContent: function () {
      return this.getTitle()
    }

  , getPosition: function (inside) {
      return $.extend({}, (inside ? {top: 0, left: 0} : this.$element.offset()), {
        width: this.$element[0].offsetWidth
      , height: this.$element[0].offsetHeight
      })
    }

  , getTitle: function () {
      var title
        , $e = this.$element
        , o = this.options

      title = $e.attr('data-original-title')
        || (typeof o.title == 'function' ? o.title.call($e[0]) :  o.title)

      title = title.toString().replace(/(^\s*|\s*$)/, "")

      return title
    }

  , tip: function () {
      return this.$tip = this.$tip || $(this.options.template)
    }

  , validate: function () {
      if (!this.$element[0].parentNode) {
        this.hide()
        this.$element = null
        this.options = null
      }
    }

  , enable: function () {
      this.enabled = true
    }

  , disable: function () {
      this.enabled = false
    }

  , toggleEnabled: function () {
      this.enabled = !this.enabled
    }

  , toggle: function () {
      this[this.tip().hasClass('in') ? 'hide' : 'show']()
    }

  }

 /* TOOLTIP PLUGIN DEFINITION
  * ========================= */

  $.fn.tooltip = function ( option ) {
    return this.each(function () {
      var $this = $(this)
        , data = $this.data('tooltip')
        , options = typeof option == 'object' && option
      if (!data) $this.data('tooltip', (data = new Tooltip(this, options)))
      if (typeof option == 'string') data[option]()
    })
  }

  $.fn.tooltip.Constructor = Tooltip

  $.fn.tooltip.defaults = {
    animation: true
  , delay: 0
  , selector: false
  , placement: 'top'
  , trigger: 'hover'
  , title: ''
  , template: '

'
  }

}( window.jQuery )
<|endoftext|>


<commit_before>/**
 * @jsx React.DOM
 */

var React = require('react');
var path = require('path');
var play = require('play-audio');

var bus = require('../bus');

var Player = React.createClass({
	getInitialState: function(){
		var playerWidget = play([],document.body).autoplay();
		playerWidget.volume(0.8);

		playerWidget.on('play', this.togglePlayState);
		playerWidget.on('ended', this.advance);

		return {
			widget: playerWidget,
			playing: false,
			position: 0,
			playlist: [],
			release: false
		};
	},
	componentDidMount: function(){
		bus.on('queue', this.queue);
	},
	componentWillUnmount: function(){
		bus.off('queue', this.queue);
	},
	doControl: function(evt){
		if (this.state.release === false) {
			return;
		}
		var ctrl = evt.target.getAttribute('data-ctrl');

		switch (ctrl) {
			case 'stop':
				this.state.widget.pause().currentTime(0);
				this.togglePlayState(false);
				break;
			case 'play':
				if (this.state.playing) this.state.widget.pause() && this.togglePlayState(false);
				else this.state.widget.play();
				break;
			case 'forward':
				this.advance(true);
				break;
			case 'back':
				this.advance(false);
				break;
		}
	},
	queue: function(release){
		// release is a backbone model
		// the only place we're publishing these events for now
		// is on the detail page, but could also make a new model
		// which has a shuffled track selection based on a tag,
		// for example
		var tracks = release.get('tracks');

		this.state.release = release;
		this.state.playlist = tracks;
		this.state.position = 0;
		this.play();
	},
	play: function(){
		var trackNumber = this.state.position;
		this.state.widget.src(this.state.playlist[trackNumber]);

	},
	togglePlayState: function(playing){

		if (playing) {
			this.state.currentTrack = path.basename(this.state.widget.src());
			this.state.playing = true;
		} else {
			this.state.playing = false;
		}
		this.forceUpdate();
	},
	advance: function(fwd){
		var mod = fwd ? 1 : -1;
		this.state.position = this.state.position + mod;
		if (this.state.position > this.state.playlist.length - 1) {
			this.state.position = 0;
		}
		else if (this.state.position < 0){
			this.state.position = this.state.playlist.length - 1;
		}
		this.play();
	},
	render: function(){
		var trackName = this.state.playing ? this.state.currentTrack : 'nothing playing';

		return (

		        {trackName}

		);
	}
});

module.exports = Player;<commit_msg>use setState instead of directly touching state<commit_after>/**
 * @jsx React.DOM
 */

var React = require('react');
var path = require('path');
var play = require('play-audio');

var bus = require('../bus');

var Player = React.createClass({
	getInitialState: function(){
		var playerWidget = play([],document.body).autoplay();
		playerWidget.volume(0.8);

		playerWidget.on('play', this.togglePlayState);
		playerWidget.on('ended', this.advance);

		return {
			widget: playerWidget,
			playing: false,
			position: 0,
			playlist: [],
			release: false
		};
	},
	componentDidMount: function(){
		bus.on('queue', this.queue);
	},
	componentWillUnmount: function(){
		bus.off('queue', this.queue);
	},
	doControl: function(evt){
		if (this.state.release === false) {
			return;
		}
		var ctrl = evt.target.getAttribute('data-ctrl');

		switch (ctrl) {
			case 'stop':
				this.state.widget.pause().currentTime(0);
				this.togglePlayState(false);
				break;
			case 'play':
				if (this.state.playing) this.state.widget.pause() && this.togglePlayState(false);
				else this.state.widget.play();
				break;
			case 'forward':
				this.advance(true);
				break;
			case 'back':
				this.advance(false);
				break;
		}
	},
	queue: function(release){
		// release is a backbone model
		// the only place we're publishing these events for now
		// is on the detail page, but could also make a new model
		// which has a shuffled track selection based on a tag,
		// for example
		var tracks = release.get('tracks');
		this.setState({
			release: release,
			playlist: tracks,
			position: 0,
			playing: false
		});
		this.play();
	},
	play: function(){
		var trackNumber = this.state.position;
		this.state.widget.src(this.state.playlist[trackNumber]);

	},
	togglePlayState: function(playing){

		if (playing) {
			this.setState({
				currentTrack: path.basename(this.state.widget.src()),
				playing: true
			});

		} else {
			this.setState({
				currentTrack: false,
				playing: false
			});
		}
	},
	advance: function(fwd){
		var mod = fwd ? 1 : -1;
		var next = this.state.position + mod;
		if (next > this.state.playlist.length - 1) {
			this.setState({
				position: 0
			});
		}
		else if (next < 0){
			this.setState({
				position: this.state.playlist.length - 1
			});
		}
		this.play();
	},
	render: function(){
		var trackName = this.state.playing ? this.state.currentTrack : 'nothing playing';

		return (

		        {trackName}

		);
	}
});

module.exports = Player;<|endoftext|>


<commit_before>var HTMLCS_WCAG2AAA_Sniffs_Principle4_Guideline4_1_4_1_2 = {
    /**
     * Determines the elements to register for processing.
     *
     * Each element of the returned array can either be an element name, or "_top"
     * which is the top element of the tested code.
     *
     * @returns {Array} The list of elements.
     */
    register: function()
    {
        return [
            'a',
            'button',
            'fieldset',
            'input',
            'select',
            'textarea'
        ];

    },

    /**
     * Process the registered element.
     *
     * @param {DOMNode} element The element registered.
     * @param {DOMNode} top     The top element of the tested code.
     */
    process: function(element, top)
    {
        if (element.nodeName.toLowerCase() === 'a') {
            this._processLinks(element);
        } else {
            this._processFormControls(element, top);
        }
    },

    _processLinks: function(element)
    {
        // Name is title attr or content
        // Value is href

        var nameFound = false;
        var hrefFound = false;
        var content   = HTMLCS.util.getElementTextContent(element);

        if ((element.hasAttribute('title') === true) && (/^\s*$/.test(element.getAttribute('title')) === false)) {
            nameFound = true;
        } else if (/^\s*$/.test(content) === false) {
            nameFound = true;
        }

        if ((element.hasAttribute('href') === true) && (/^\s*$/.test(element.getAttribute('href')) === false)) {
            hrefFound = true;
        }

        if (hrefFound === false) {
            // No href. We don't want these because, although they are commonly used
            // to create targets, they can be picked up by screen readers and
            // displayed to the user as empty links. A elements are defined by H91 as
            // having an (ARIA) role of "link", and using them as targets are
            // essentially misusing them. Place an ID on a parent element instead.
            if (/^\s*$/.test(content) === true) {
                // Also no content. (eg.  or )
                if ((element.hasAttribute('id') === true) || (element.hasAttribute('name') === true)) {
                    HTMLCS.addMessage(HTMLCS.ERROR, element, 'Empty anchor elements should not be used for defining a in-page link target. Consider moving its ID to a parent or nearby element.', 'H91.A.Empty');
                } else {
                    HTMLCS.addMessage(HTMLCS.ERROR, element, 'Empty anchor element found.', 'H91.A.EmptyNoId');
                }
            } else {
                // Giving a benefit of the doubt here - if a link has text and also
                // an ID, but no href, it might be because it is being manipulated by
                // a script.
                if (element.hasAttribute('id') === true) {
                    HTMLCS.addMessage(HTMLCS.WARNING, element, 'Anchor elements should not be used for defining an in-page link target. If not using the ID for other purposes (such as CSS or scripting), consider moving it to a parent element.', 'H91.A.NoHref');
                } else {
                    // HTML5 allows A elements with text but no href, "for where a
                    // link might otherwise have been placed, if it had been relevant".
                    HTMLCS.addMessage(HTMLCS.WARNING, element, 'Link found with text, but no href and ID. If this is not "where a link would have been placed if relevant", the A element should be removed.', 'H91.A.Placeholder');
                }
            }
        } else {
            if (/^\s*$/.test(content) === true) {
                // Href provided, but no content.
                // We only fire this message when there are no images in the content.
                // A link around an image with no alt text is already covered in SC
                // 1.1.1 (test H30).
                if (element.querySelectorAll('img').length === 0) {
                    HTMLCS.addMessage(HTMLCS.ERROR, element, 'Link contains a valid href attribute, but no content.', 'H91.A.NoContent');
                }
            }
        }
    },

    _processFormControls: function(element, top)
    {
        var requiredNames = {
            button: ['@title', '_content'],
            fieldset: ['legend'],
            input_button: ['@value'],
            input_text: ['label', '@title'],
            input_file: ['label', '@title'],
            input_password: ['label', '@title'],
            input_checkbox: ['label', '@title'],
            input_radio: ['label', '@title'],
            input_image: ['@alt', '@title'],
            select: ['label', '@title'],
            textarea: ['label', '@title']
        }

        var requiredValues = {
            input_text: '@value',
            select: 'option_selected'
        };

        var nodeName   = element.nodeName.toLowerCase();
        var msgSubCode = element.nodeName.substr(0, 1).toUpperCase() + element.nodeName.substr(1).toLowerCase();
        if (nodeName === 'input') {
            if (element.hasAttribute('type') === false) {
                // If no type attribute, default to text.
                nodeName += '_text';
            } else {
                nodeName += '_' + element.getAttribute('type').toLowerCase();
            }

            // Treat all input buttons as the same
            if ((nodeName === 'input_submit') || (nodeName === 'input_reset')) {
                nodeName = 'input_button';
            }

            // Get a format like "InputText".
            var msgSubCode = 'Input' + nodeName.substr(6, 1).toUpperCase() + nodeName.substr(7).toLowerCase();
        }//end if

        var requiredName  = requiredNames[nodeName];
        var requiredValue = requiredValues[nodeName];

        // Check all possible combinations of names to ensure that one exists.
        if (requiredName) {
            for (var i = 0; i < requiredNames[nodeName].length; i++) {
                var requiredName = requiredNames[nodeName][i];
                if (requiredName === '_content') {
                    // Work with content.
                    var content = HTMLCS.util.getElementTextContent(element);
                    if (/^\s*$/.test(content) === false) {
                        break;
                    }
                } else if (requiredName === 'label') {
                    // Label element.
                    if (element.hasAttribute('id')) {
                        var label = top.querySelector('label[for=' + element.getAttribute('id') + ']');
                        if (label !== null) {
                            break;
                        }
                    }
                } if (requiredName.charAt(0) === '@') {
                    // Attribute.
                    requiredName = requiredName.substr(1, requiredName.length);
                    if ((element.hasAttribute(requiredName) === true) && (/^\s*$/.test(element.getAttribute(requiredName)) === false)) {
                        break;
                    }
                } else {
                    // Sub-element contents.
                    var subEl = element.querySelector(requiredName);
                    if (subEl !== null) {
                        var content = HTMLCS.util.getElementTextContent(subEl);
                        if (/^\s*$/.test(content) === false) {
                            break;
                        }
                    }
                }//end if
            }//end for

            if (i === requiredNames[nodeName].length) {
                var msgNodeType = nodeName + ' element';
                if (nodeName.substr(0, 6) === 'input_') {
                    msgNodeType = nodeName.substr(6) + ' input element';
                }

                var builtAttrs = requiredNames[nodeName].slice(0, requiredNames[nodeName].length);
                for (var a = 0; a < builtAttrs.length; a++) {
                    if (builtAttrs[a] === '_content') {
                        builtAttrs[a] = 'element content';
                    } else if (builtAttrs[a].charAt(0) === '@') {
                        builtAttrs[a] = builtAttrs[a].substr(1) + ' attribute';
                    } else {
                        builtAttrs[a] = builtAttrs[a] + ' element';
                    }
                }

                HTMLCS.addMessage(HTMLCS.ERROR, element, 'This ' + msgNodeType + ' does not have a name available to an accessibility API. Valid names are: ' + builtAttrs.join(', ') + '.', 'H91.' + msgSubCode + '.Name');
            }
        }//end if

        var requiredValue = requiredValues[nodeName];
        var valueFound    = false;

        if (requiredValue === undefined) {
            // Nothing required of us.
            valueFound = true;
        } else if (requiredValue === '_content') {
            // Work with content.
            var content = HTMLCS.util.getElementTextContent(element);
            if (/^\s*$/.test(content) === false) {
                valueFound = true;
            }
        } else if (requiredValue === 'option_selected') {
            // Select lists need a selected Option element.
            var selected = element.querySelector('option[selected]');
            if (selected !== null) {
                valueFound = true;
            }
        } else if (requiredValue.charAt(0) === '@') {
            // Attribute.
            requiredValue = requiredValue.substr(1, requiredValue.length);
            if ((element.hasAttribute(requiredValue) === true)) {
                valueFound = true;
            }
        }//end if

        if (valueFound === false) {
            var msgNodeType = nodeName + ' element';
            if (nodeName.substr(0, 6) === 'input_') {
                msgNodeType = nodeName.substr(6) + ' input element';
            }

            var builtAttr = '';
            if (requiredValue === '_content') {
                builtAttr = 'by adding content to the element';
            } else if (requiredValue === 'option_selected') {
                builtAttr = 'by adding a "selected" attribute to one of its options';
            } else if (requiredValue.charAt(0) === '@') {
                builtAttr = 'using the ' + requiredValue + ' attribute';
            } else {
                builtAttr = 'using the ' +requiredValue + ' element';
            }

            HTMLCS.addMessage(HTMLCS.ERROR, element, 'This ' + msgNodeType + ' does not have a value available to an accessibility API. Add one ' + builtAttr + '.', 'H91.' + msgSubCode + '.Value');
        }
    }
};
<commit_msg>SC 4.1.2: - Where a name attribute is used to create an in-page anchor instead of id (the old method), provide a different message. - Now does not check for "for" attributes in role/state/value checks if the id attribute is present but empty.<commit_after>var HTMLCS_WCAG2AAA_Sniffs_Principle4_Guideline4_1_4_1_2 = {
    /**
     * Determines the elements to register for processing.
     *
     * Each element of the returned array can either be an element name, or "_top"
     * which is the top element of the tested code.
     *
     * @returns {Array} The list of elements.
     */
    register: function()
    {
        return [
            'a',
            'button',
            'fieldset',
            'input',
            'select',
            'textarea'
        ];

    },

    /**
     * Process the registered element.
     *
     * @param {DOMNode} element The element registered.
     * @param {DOMNode} top     The top element of the tested code.
     */
    process: function(element, top)
    {
        if (element.nodeName.toLowerCase() === 'a') {
            this._processLinks(element);
        } else {
            this._processFormControls(element, top);
        }
    },

    _processLinks: function(element)
    {
        // Name is title attr or content
        // Value is href

        var nameFound = false;
        var hrefFound = false;
        var content   = HTMLCS.util.getElementTextContent(element);

        if ((element.hasAttribute('title') === true) && (/^\s*$/.test(element.getAttribute('title')) === false)) {
            nameFound = true;
        } else if (/^\s*$/.test(content) === false) {
            nameFound = true;
        }

        if ((element.hasAttribute('href') === true) && (/^\s*$/.test(element.getAttribute('href')) === false)) {
            hrefFound = true;
        }

        if (hrefFound === false) {
            // No href. We don't want these because, although they are commonly used
            // to create targets, they can be picked up by screen readers and
            // displayed to the user as empty links. A elements are defined by H91 as
            // having an (ARIA) role of "link", and using them as targets are
            // essentially misusing them. Place an ID on a parent element instead.
            if (/^\s*$/.test(content) === true) {
                // Also no content. (eg.  or )
                if (element.hasAttribute('id') === true) {
                    HTMLCS.addMessage(HTMLCS.ERROR, element, 'Empty anchor elements should not be used for defining a in-page link target. Consider moving its ID to a parent or nearby element.', 'H91.A.Empty');
                } else if (element.hasAttribute('name') === true) {
                    HTMLCS.addMessage(HTMLCS.ERROR, element, 'Empty anchor elements should not be used for defining a in-page link target. Consider moving the name attribute to become an ID of a parent or nearby element.', 'H91.A.EmptyWithName');
                } else {
                    HTMLCS.addMessage(HTMLCS.ERROR, element, 'Empty anchor element found.', 'H91.A.EmptyNoId');
                }
            } else {
                // Giving a benefit of the doubt here - if a link has text and also
                // an ID, but no href, it might be because it is being manipulated by
                // a script.
                if (element.hasAttribute('id') === true) {
                    HTMLCS.addMessage(HTMLCS.WARNING, element, 'Anchor elements should not be used for defining an in-page link target. If not using the ID for other purposes (such as CSS or scripting), consider moving it to a parent element.', 'H91.A.NoHref');
                } else {
                    // HTML5 allows A elements with text but no href, "for where a
                    // link might otherwise have been placed, if it had been relevant".
                    HTMLCS.addMessage(HTMLCS.WARNING, element, 'Link found with text, but no href and ID. If this is not "where a link would have been placed if relevant", the A element should be removed.', 'H91.A.Placeholder');
                }
            }
        } else {
            if (/^\s*$/.test(content) === true) {
                // Href provided, but no content.
                // We only fire this message when there are no images in the content.
                // A link around an image with no alt text is already covered in SC
                // 1.1.1 (test H30).
                if (element.querySelectorAll('img').length === 0) {
                    HTMLCS.addMessage(HTMLCS.ERROR, element, 'Link contains a valid href attribute, but no content.', 'H91.A.NoContent');
                }
            }
        }
    },

    _processFormControls: function(element, top)
    {
        var requiredNames = {
            button: ['@title', '_content'],
            fieldset: ['legend'],
            input_button: ['@value'],
            input_text: ['label', '@title'],
            input_file: ['label', '@title'],
            input_password: ['label', '@title'],
            input_checkbox: ['label', '@title'],
            input_radio: ['label', '@title'],
            input_image: ['@alt', '@title'],
            select: ['label', '@title'],
            textarea: ['label', '@title']
        }

        var requiredValues = {
            input_text: '@value',
            select: 'option_selected'
        };

        var nodeName   = element.nodeName.toLowerCase();
        var msgSubCode = element.nodeName.substr(0, 1).toUpperCase() + element.nodeName.substr(1).toLowerCase();
        if (nodeName === 'input') {
            if (element.hasAttribute('type') === false) {
                // If no type attribute, default to text.
                nodeName += '_text';
            } else {
                nodeName += '_' + element.getAttribute('type').toLowerCase();
            }

            // Treat all input buttons as the same
            if ((nodeName === 'input_submit') || (nodeName === 'input_reset')) {
                nodeName = 'input_button';
            }

            // Get a format like "InputText".
            var msgSubCode = 'Input' + nodeName.substr(6, 1).toUpperCase() + nodeName.substr(7).toLowerCase();
        }//end if

        var requiredName  = requiredNames[nodeName];
        var requiredValue = requiredValues[nodeName];

        // Check all possible combinations of names to ensure that one exists.
        if (requiredName) {
            for (var i = 0; i < requiredNames[nodeName].length; i++) {
                var requiredName = requiredNames[nodeName][i];
                if (requiredName === '_content') {
                    // Work with content.
                    var content = HTMLCS.util.getElementTextContent(element);
                    if (/^\s*$/.test(content) === false) {
                        break;
                    }
                } else if (requiredName === 'label') {
                    // Label element.
                    if ((element.hasAttribute('id')) && (/^\s*$/.test(element.getAttribute('id')) === false)) {
                        var label = top.querySelector('label[for=' + element.getAttribute('id') + ']');
                        if (label !== null) {
                            break;
                        }
                    }
                } if (requiredName.charAt(0) === '@') {
                    // Attribute.
                    requiredName = requiredName.substr(1, requiredName.length);
                    if ((element.hasAttribute(requiredName) === true) && (/^\s*$/.test(element.getAttribute(requiredName)) === false)) {
                        break;
                    }
                } else {
                    // Sub-element contents.
                    var subEl = element.querySelector(requiredName);
                    if (subEl !== null) {
                        var content = HTMLCS.util.getElementTextContent(subEl);
                        if (/^\s*$/.test(content) === false) {
                            break;
                        }
                    }
                }//end if
            }//end for

            if (i === requiredNames[nodeName].length) {
                var msgNodeType = nodeName + ' element';
                if (nodeName.substr(0, 6) === 'input_') {
                    msgNodeType = nodeName.substr(6) + ' input element';
                }

                var builtAttrs = requiredNames[nodeName].slice(0, requiredNames[nodeName].length);
                for (var a = 0; a < builtAttrs.length; a++) {
                    if (builtAttrs[a] === '_content') {
                        builtAttrs[a] = 'element content';
                    } else if (builtAttrs[a].charAt(0) === '@') {
                        builtAttrs[a] = builtAttrs[a].substr(1) + ' attribute';
                    } else {
                        builtAttrs[a] = builtAttrs[a] + ' element';
                    }
                }

                HTMLCS.addMessage(HTMLCS.ERROR, element, 'This ' + msgNodeType + ' does not have a name available to an accessibility API. Valid names are: ' + builtAttrs.join(', ') + '.', 'H91.' + msgSubCode + '.Name');
            }
        }//end if

        var requiredValue = requiredValues[nodeName];
        var valueFound    = false;

        if (requiredValue === undefined) {
            // Nothing required of us.
            valueFound = true;
        } else if (requiredValue === '_content') {
            // Work with content.
            var content = HTMLCS.util.getElementTextContent(element);
            if (/^\s*$/.test(content) === false) {
                valueFound = true;
            }
        } else if (requiredValue === 'option_selected') {
            // Select lists need a selected Option element.
            var selected = element.querySelector('option[selected]');
            if (selected !== null) {
                valueFound = true;
            }
        } else if (requiredValue.charAt(0) === '@') {
            // Attribute.
            requiredValue = requiredValue.substr(1, requiredValue.length);
            if ((element.hasAttribute(requiredValue) === true)) {
                valueFound = true;
            }
        }//end if

        if (valueFound === false) {
            var msgNodeType = nodeName + ' element';
            if (nodeName.substr(0, 6) === 'input_') {
                msgNodeType = nodeName.substr(6) + ' input element';
            }

            var builtAttr = '';
            if (requiredValue === '_content') {
                builtAttr = 'by adding content to the element';
            } else if (requiredValue === 'option_selected') {
                builtAttr = 'by adding a "selected" attribute to one of its options';
            } else if (requiredValue.charAt(0) === '@') {
                builtAttr = 'using the ' + requiredValue + ' attribute';
            } else {
                builtAttr = 'using the ' +requiredValue + ' element';
            }

            HTMLCS.addMessage(HTMLCS.ERROR, element, 'This ' + msgNodeType + ' does not have a value available to an accessibility API. Add one ' + builtAttr + '.', 'H91.' + msgSubCode + '.Value');
        }
    }
};
<|endoftext|>


<commit_before>import { moduleForComponent, test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';

moduleForComponent('paper-toolbar', 'Integration | Component | paper toolbar', {
  integration: true
});

test('uses md-tall class tall=true', function(assert) {
  assert.expect(1);

  this.render(hbs`
    {{#paper-toolbar tall=true}}
    {{/paper-toolbar}}
  `);

  assert.ok(this.$('md-toolbar').hasClass('md-tall'));
});

test('paper-toolbar-tools uses .md-toolbar-tools class', function(assert) {
  assert.expect(1);

  this.render(hbs`
    {{#paper-toolbar tall=true}}
      {{#paper-toolbar-tools}}
      {{/paper-toolbar-tools}}
    {{/paper-toolbar}}
  `);

  assert.equal(this.$('.md-toolbar-tools').length, 1);
});<commit_msg>Add missing trailing EOL in paper-toolbar-test.js.<commit_after>import { moduleForComponent, test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';

moduleForComponent('paper-toolbar', 'Integration | Component | paper toolbar', {
  integration: true
});

test('uses md-tall class tall=true', function(assert) {
  assert.expect(1);

  this.render(hbs`
    {{#paper-toolbar tall=true}}
    {{/paper-toolbar}}
  `);

  assert.ok(this.$('md-toolbar').hasClass('md-tall'));
});

test('paper-toolbar-tools uses .md-toolbar-tools class', function(assert) {
  assert.expect(1);

  this.render(hbs`
    {{#paper-toolbar tall=true}}
      {{#paper-toolbar-tools}}
      {{/paper-toolbar-tools}}
    {{/paper-toolbar}}
  `);

  assert.equal(this.$('.md-toolbar-tools').length, 1);
});
<|endoftext|>