<commit_before>/*
 * Copyright 2012 Amadeus s.a.s.
 * 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.
 */

var promise = require("./promise.js");
var Loader = require('./loader.js');
var Resolver = require('./resolver.js');
var execScripts = require('../node-modules/execScripts.js');
var typeUtils = require('./type.js');
var noderError = require('./noderError.js');
var dirname = require('./path.js').dirname;
var jsEval = require('./jsEval.js');
var findRequires = require('./findRequires.js');
var noderPropertiesKey = "_noder";

var PROPERTY_DEFINITION = 0;
var PROPERTY_DEPENDENCIES = 1;
var PROPERTY_EXECUTING = 2;
var PROPERTY_PRELOADING = 3;
var PROPERTY_LOADING_DEFINITION = 4;
var PROPERTY_PRELOADING_PARENTS = 5;

var bind = function(fn, scope) {
    return function() {
        return fn.apply(scope, arguments);
    };
};

var bind1 = function(fn, scope, paramBind) {
    return function(param) {
        return fn.call(scope, paramBind, param);
    };
};

var Module = function(context, filename) {
    if (filename) {
        this.dirname = dirname(filename);
    } else {
        this.dirname = filename = '.';
    }
    this[noderPropertiesKey] = {};
    this.filename = filename;
    this.id = filename;
    this.require = bind1(context.moduleRequire, context, this);
    this.require.resolve = bind1(context.moduleResolve, context, this);
    this.require.cache = context.cache;
    this.parent = null;
    this.children = [];
    this.preloaded = false;
    this.loaded = false;
    this.exports = {};
};

var getModuleProperty = function(module, property) {
    return module[noderPropertiesKey][property];
};

var setModuleProperty = function(module, property, value) {
    module[noderPropertiesKey][property] = value;
    return value;
};

var start = function(context) {
    var config = context.config;
    var actions = promise.done;

    var main = config.main;
    actions = actions.thenSync(main ? function() {
        return context.execModuleCall(main);
    } : promise.empty /* if there is no main module, an empty parameter should be passed to onstart */ );

    actions = actions.thenSync(config.onstart);

    if (!("scriptsType" in config)) {
        config.scriptsType = config.varName;
    }
    var scriptsType = config.scriptsType;
    if (scriptsType) {
        actions = actions.thenSync(function() {
            return execScripts(context, scriptsType);
        });
    }

    return actions.always(function() {
        context = null;
        config = null;
        actions = null;
    });
};

var Context = function(config) {
    config = config || {};
    this.config = config;
    this.cache = {};

    var rootModule = new Module(this);
    rootModule.preloaded = true;
    rootModule.loaded = true;
    rootModule.define = this.define = bind(this.define, this);
    rootModule.asyncRequire = bind1(this.moduleAsyncRequire, this, rootModule);
    rootModule.execute = bind(this.jsModuleExecute, this);
    rootModule.createContext = Context.createContext;
    this.rootModule = rootModule;

    this.resolver = new Resolver(this);
    this.loader = new Loader(this);

    var globalVarName = config.varName;
    if (globalVarName) {
        global[globalVarName] = rootModule;
    }

    start(this).end();
};

var contextProto = Context.prototype = {};

var checkCircularDependency = function(module, lookInside) {
    if (lookInside === module) {
        return true;
    }
    var parents = getModuleProperty(lookInside, PROPERTY_PRELOADING_PARENTS);
    if (parents) {
        for (var i = 0; parents[i]; i++) {
            if (checkCircularDependency(module, parents[i])) {
                return true;
            }
        }
    }
    return false;
};

// Preloading a module means making it ready to be executed (loading its definition and preloading its
// dependencies)
contextProto.modulePreload = function(module, parent) {
    if (module.preloaded) {
        return promise.done;
    }
    var preloading = getModuleProperty(module, PROPERTY_PRELOADING);
    var preloadingParents = getModuleProperty(module, PROPERTY_PRELOADING_PARENTS);
    if (preloading || preloadingParents) {
        // If we get here, it may be because of a circular dependency
        if (parent) {
            if (checkCircularDependency(module, parent)) {
                return promise.done;
            }
            preloadingParents.push(parent);
        }
        if (!preloading) {
            throw noderError("modulePreloadRec", [module]);
        }
        return preloading;
    }
    var self = this;
    if (parent && parent.id != '.') {
        module.parent = parent;
        module.require.main = parent.require.main;
        parent.children.push(module);
    } else {
        module.require.main = module;
    }
    setModuleProperty(module, PROPERTY_PRELOADING_PARENTS, parent ? [parent] : []);
    return setModuleProperty(module, PROPERTY_PRELOADING, self.moduleLoadDefinition(module).thenSync(function() {
        return self.modulePreloadDependencies(module, getModuleProperty(module, PROPERTY_DEPENDENCIES));
    }).thenSync(function() {
        module.preloaded = true;
        setModuleProperty(module, PROPERTY_PRELOADING, false);
        setModuleProperty(module, PROPERTY_PRELOADING_PARENTS, null);
    }, function(error) {
        throw noderError("modulePreload", [module], error);
    }).always(function() {
        // clean up
        module = null;
        self = null;
        parent = null;
    }));
};

contextProto.moduleLoadDefinition = function(module) {
    if (getModuleProperty(module, PROPERTY_DEFINITION)) {
        return promise.done;
    }
    var res = getModuleProperty(module, PROPERTY_LOADING_DEFINITION);
    if (!res) {
        var filename = module.filename;
        if (this.builtinModules.hasOwnProperty(filename)) {
            this.moduleDefine(module, [], this.builtinModules[filename](this));
            res = promise.done;
        } else {
            var asyncOrError = true;
            var checkResult = function(error) {
                // check that the definition was correctly loaded:
                if (getModuleProperty(module, PROPERTY_DEFINITION)) {
                    asyncOrError = false;
                } else {
                    throw noderError("moduleLoadDefinition", [module], error);
                }
            };
            res = this.loader.moduleLoad(module).thenSync(checkResult, checkResult);
            if (asyncOrError) {
                setModuleProperty(module, PROPERTY_LOADING_DEFINITION, res);
            }
        }
    }
    return res;
};

contextProto.moduleProcessPlugin = function(module, pluginDef) {
    var allowedParameters = {
        "module": module,
        "__dirname": module.dirname,
        "__filename": module.filename
    };
    var parameters = pluginDef.args.slice(0);
    for (var i = 0, l = parameters.length; i < l; i++) {
        var curParameter = parameters[i];
        if (typeUtils.isArray(curParameter)) {
            curParameter = curParameter[0];
            if (!allowedParameters.hasOwnProperty(curParameter)) {
                return;
            }
            parameters[i] = allowedParameters[curParameter];
        }
    }
    return this.moduleExecute(this.getModule(this.moduleResolve(module, pluginDef.module))).thenSync(function(plugin) {
        var method = (plugin[pluginDef.method] || {}).$preload;
        if (method) {
            return method.apply(plugin, parameters);
        }
    }).thenSync(null, function(error) {
        throw noderError("moduleProcessPlugin", [module, pluginDef], error);
    });
};

contextProto.modulePreloadDependencies = function(module, dependencies) {
    var promises = [];
    for (var i = 0, l = dependencies.length; i < l; i++) {
        var curDependency = dependencies[i];
        var curPromise = typeUtils.isString(curDependency) ?
            this.modulePreload(this.getModule(this.moduleResolve(module, curDependency)), module) :
            this.moduleProcessPlugin(module, curDependency);
        promises.push(curPromise);
    }
    return promise.when(promises);
};

contextProto.moduleExecuteSync = function(module) {
    if (module.loaded || getModuleProperty(module, PROPERTY_EXECUTING)) { /* this.executing is true only in the case of a circular dependency */
        return module.exports;
    }
    if (this.modulePreload(module).state() != "resolved") {
        throw noderError("notPreloaded", [module]);
    }
    var exports = module.exports;
    setModuleProperty(module, PROPERTY_EXECUTING, true);
    try {
        getModuleProperty(module, PROPERTY_DEFINITION).call(exports, module, global);
        setModuleProperty(module, PROPERTY_DEFINITION, null);
        setModuleProperty(module, PROPERTY_DEPENDENCIES, null);
        module.loaded = true;
        return module.exports;
    } finally {
        setModuleProperty(module, PROPERTY_EXECUTING, false);
    }
};

contextProto.moduleResolve = function(module, id) {
    return this.resolver.moduleResolve(module, id);
};

contextProto.moduleRequire = function(module, id) {
    return this.moduleExecuteSync(this.getModule(this.moduleResolve(module, id)));
};

contextProto.getModule = function(moduleFilename) {
    if (!moduleFilename) {
        // anonymous module
        return new Module(this);
    }
    var res = this.cache[moduleFilename];
    if (!res) {
        this.cache[moduleFilename] = res = new Module(this, moduleFilename);
    }
    return res;
};

contextProto.define = function(moduleFilename, dependencies, body) {
    this.moduleDefine(this.getModule(moduleFilename), dependencies, body);
};

contextProto.moduleDefine = function(module, dependencies, body) {
    if (!getModuleProperty(module, PROPERTY_DEFINITION)) {
        // do not override an existing definition
        setModuleProperty(module, PROPERTY_DEFINITION, body);
        setModuleProperty(module, PROPERTY_DEPENDENCIES, dependencies);
        setModuleProperty(module, PROPERTY_LOADING_DEFINITION, false);
    }
    return module;
};

contextProto.moduleExecute = function(module) {
    var self = this;
    return self.modulePreload(module).thenSync(function() {
        return self.moduleExecuteSync(module);
    }).always(function() {
        self = null;
        module = null;
    });
};

contextProto.moduleAsyncRequire = function(module, id) {
    if (typeUtils.isArray(id)) {
        return this.modulePreloadDependencies(module, id);
    } else if (typeUtils.isString(id)) {
        return this.moduleRequire(module, id);
    }
};

contextProto.jsModuleDefine = function(jsCode, moduleFilename, url, lineDiff) {
    var dependencies = findRequires(jsCode, true);
    var body = this.jsModuleEval(jsCode, url || moduleFilename, lineDiff);
    return this.moduleDefine(this.getModule(moduleFilename), dependencies, body);
};

contextProto.jsModuleExecute = function(jsCode, moduleFilename, url) {
    return this.moduleExecute(this.jsModuleDefine(jsCode, moduleFilename, url));
};

contextProto.jsModuleEval = function(jsCode, url, lineDiff) {
    var code = ['(function(module, global){\nvar require = module.require, exports = module.exports, __filename = module.filename, __dirname = module.dirname;\n\n', jsCode, '\n\n})'];
    return jsEval(code.join(''), url, (lineDiff || 0) + 3 /* we are adding 3 lines compared to url */ );
};

contextProto.execModuleCall = function(moduleFilename) {
    return this.moduleExecute(this.getModule(this.moduleResolve(this.rootModule, moduleFilename)));
};

contextProto.builtinModules = {
    "noder-js/asyncRequire.js": function(context) {
        return function(module) {
            module.exports = {
                create: function(module) {
                    return function(id) {
                        return context.moduleAsyncRequire(module, id);
                    };
                }
            };
        };
    },
    "noder-js/currentContext.js": function(context) {
        return function(module) {
            module.exports = context;
        };
    }
};

contextProto.Context = Context;

Context.createContext = function(cfg) {
    return (new Context(cfg)).rootModule;
};

Context.expose = function(name, exports) {
    var body = function(module) {
        module.exports = exports;
    };
    contextProto.builtinModules[name] = function() {
        return body;
    };
};

module.exports = Context;
<commit_msg>Allowing the resolver and loader to be configured at run time.<commit_after>/*
 * Copyright 2012 Amadeus s.a.s.
 * 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.
 */

var promise = require("./promise.js");
var Loader = require('./loader.js');
var Resolver = require('./resolver.js');
var execScripts = require('../node-modules/execScripts.js');
var typeUtils = require('./type.js');
var noderError = require('./noderError.js');
var dirname = require('./path.js').dirname;
var jsEval = require('./jsEval.js');
var findRequires = require('./findRequires.js');
var noderPropertiesKey = "_noder";

var PROPERTY_DEFINITION = 0;
var PROPERTY_DEPENDENCIES = 1;
var PROPERTY_EXECUTING = 2;
var PROPERTY_PRELOADING = 3;
var PROPERTY_LOADING_DEFINITION = 4;
var PROPERTY_PRELOADING_PARENTS = 5;

var bind = function(fn, scope) {
    return function() {
        return fn.apply(scope, arguments);
    };
};

var bind1 = function(fn, scope, paramBind) {
    return function(param) {
        return fn.call(scope, paramBind, param);
    };
};

var Module = function(context, filename) {
    if (filename) {
        this.dirname = dirname(filename);
    } else {
        this.dirname = filename = '.';
    }
    this[noderPropertiesKey] = {};
    this.filename = filename;
    this.id = filename;
    this.require = bind1(context.moduleRequire, context, this);
    this.require.resolve = bind1(context.moduleResolve, context, this);
    this.require.cache = context.cache;
    this.parent = null;
    this.children = [];
    this.preloaded = false;
    this.loaded = false;
    this.exports = {};
};

var getModuleProperty = function(module, property) {
    return module[noderPropertiesKey][property];
};

var setModuleProperty = function(module, property, value) {
    module[noderPropertiesKey][property] = value;
    return value;
};

var start = function(context) {
    var config = context.config;
    var actions = promise.done;

    var main = config.main;
    actions = actions.thenSync(main ? function() {
        return context.execModuleCall(main);
    } : promise.empty /* if there is no main module, an empty parameter should be passed to onstart */ );

    actions = actions.thenSync(config.onstart);

    if (!("scriptsType" in config)) {
        config.scriptsType = config.varName;
    }
    var scriptsType = config.scriptsType;
    if (scriptsType) {
        actions = actions.thenSync(function() {
            return execScripts(context, scriptsType);
        });
    }

    return actions.always(function() {
        context = null;
        config = null;
        actions = null;
    });
};

var createInstance = function(configConstructor, defaultConstructor, param) {
    var Constructor = configConstructor || defaultConstructor;
    return new Constructor(param, defaultConstructor);
};

var Context = function(config) {
    config = config || {};
    this.config = config;
    this.cache = {};

    var rootModule = new Module(this);
    rootModule.preloaded = true;
    rootModule.loaded = true;
    rootModule.define = this.define = bind(this.define, this);
    rootModule.asyncRequire = bind1(this.moduleAsyncRequire, this, rootModule);
    rootModule.execute = bind(this.jsModuleExecute, this);
    rootModule.createContext = Context.createContext;
    this.rootModule = rootModule;

    this.resolver = createInstance(config.Resolver, Resolver, this);
    this.loader = createInstance(config.Loader, Loader, this);

    var globalVarName = config.varName;
    if (globalVarName) {
        global[globalVarName] = rootModule;
    }

    start(this).end();
};

var contextProto = Context.prototype = {};

var checkCircularDependency = function(module, lookInside) {
    if (lookInside === module) {
        return true;
    }
    var parents = getModuleProperty(lookInside, PROPERTY_PRELOADING_PARENTS);
    if (parents) {
        for (var i = 0; parents[i]; i++) {
            if (checkCircularDependency(module, parents[i])) {
                return true;
            }
        }
    }
    return false;
};

// Preloading a module means making it ready to be executed (loading its definition and preloading its
// dependencies)
contextProto.modulePreload = function(module, parent) {
    if (module.preloaded) {
        return promise.done;
    }
    var preloading = getModuleProperty(module, PROPERTY_PRELOADING);
    var preloadingParents = getModuleProperty(module, PROPERTY_PRELOADING_PARENTS);
    if (preloading || preloadingParents) {
        // If we get here, it may be because of a circular dependency
        if (parent) {
            if (checkCircularDependency(module, parent)) {
                return promise.done;
            }
            preloadingParents.push(parent);
        }
        if (!preloading) {
            throw noderError("modulePreloadRec", [module]);
        }
        return preloading;
    }
    var self = this;
    if (parent && parent.id != '.') {
        module.parent = parent;
        module.require.main = parent.require.main;
        parent.children.push(module);
    } else {
        module.require.main = module;
    }
    setModuleProperty(module, PROPERTY_PRELOADING_PARENTS, parent ? [parent] : []);
    return setModuleProperty(module, PROPERTY_PRELOADING, self.moduleLoadDefinition(module).thenSync(function() {
        return self.modulePreloadDependencies(module, getModuleProperty(module, PROPERTY_DEPENDENCIES));
    }).thenSync(function() {
        module.preloaded = true;
        setModuleProperty(module, PROPERTY_PRELOADING, false);
        setModuleProperty(module, PROPERTY_PRELOADING_PARENTS, null);
    }, function(error) {
        throw noderError("modulePreload", [module], error);
    }).always(function() {
        // clean up
        module = null;
        self = null;
        parent = null;
    }));
};

contextProto.moduleLoadDefinition = function(module) {
    if (getModuleProperty(module, PROPERTY_DEFINITION)) {
        return promise.done;
    }
    var res = getModuleProperty(module, PROPERTY_LOADING_DEFINITION);
    if (!res) {
        var filename = module.filename;
        if (this.builtinModules.hasOwnProperty(filename)) {
            this.moduleDefine(module, [], this.builtinModules[filename](this));
            res = promise.done;
        } else {
            var asyncOrError = true;
            var checkResult = function(error) {
                // check that the definition was correctly loaded:
                if (getModuleProperty(module, PROPERTY_DEFINITION)) {
                    asyncOrError = false;
                } else {
                    throw noderError("moduleLoadDefinition", [module], error);
                }
            };
            res = this.loader.moduleLoad(module).thenSync(checkResult, checkResult);
            if (asyncOrError) {
                setModuleProperty(module, PROPERTY_LOADING_DEFINITION, res);
            }
        }
    }
    return res;
};

contextProto.moduleProcessPlugin = function(module, pluginDef) {
    var allowedParameters = {
        "module": module,
        "__dirname": module.dirname,
        "__filename": module.filename
    };
    var parameters = pluginDef.args.slice(0);
    for (var i = 0, l = parameters.length; i < l; i++) {
        var curParameter = parameters[i];
        if (typeUtils.isArray(curParameter)) {
            curParameter = curParameter[0];
            if (!allowedParameters.hasOwnProperty(curParameter)) {
                return;
            }
            parameters[i] = allowedParameters[curParameter];
        }
    }
    return this.moduleExecute(this.getModule(this.moduleResolve(module, pluginDef.module))).thenSync(function(plugin) {
        var method = (plugin[pluginDef.method] || {}).$preload;
        if (method) {
            return method.apply(plugin, parameters);
        }
    }).thenSync(null, function(error) {
        throw noderError("moduleProcessPlugin", [module, pluginDef], error);
    });
};

contextProto.modulePreloadDependencies = function(module, dependencies) {
    var promises = [];
    for (var i = 0, l = dependencies.length; i < l; i++) {
        var curDependency = dependencies[i];
        var curPromise = typeUtils.isString(curDependency) ?
            this.modulePreload(this.getModule(this.moduleResolve(module, curDependency)), module) :
            this.moduleProcessPlugin(module, curDependency);
        promises.push(curPromise);
    }
    return promise.when(promises);
};

contextProto.moduleExecuteSync = function(module) {
    if (module.loaded || getModuleProperty(module, PROPERTY_EXECUTING)) { /* this.executing is true only in the case of a circular dependency */
        return module.exports;
    }
    if (this.modulePreload(module).state() != "resolved") {
        throw noderError("notPreloaded", [module]);
    }
    var exports = module.exports;
    setModuleProperty(module, PROPERTY_EXECUTING, true);
    try {
        getModuleProperty(module, PROPERTY_DEFINITION).call(exports, module, global);
        setModuleProperty(module, PROPERTY_DEFINITION, null);
        setModuleProperty(module, PROPERTY_DEPENDENCIES, null);
        module.loaded = true;
        return module.exports;
    } finally {
        setModuleProperty(module, PROPERTY_EXECUTING, false);
    }
};

contextProto.moduleResolve = function(module, id) {
    return this.resolver.moduleResolve(module, id);
};

contextProto.moduleRequire = function(module, id) {
    return this.moduleExecuteSync(this.getModule(this.moduleResolve(module, id)));
};

contextProto.getModule = function(moduleFilename) {
    if (!moduleFilename) {
        // anonymous module
        return new Module(this);
    }
    var res = this.cache[moduleFilename];
    if (!res) {
        this.cache[moduleFilename] = res = new Module(this, moduleFilename);
    }
    return res;
};

contextProto.define = function(moduleFilename, dependencies, body) {
    this.moduleDefine(this.getModule(moduleFilename), dependencies, body);
};

contextProto.moduleDefine = function(module, dependencies, body) {
    if (!getModuleProperty(module, PROPERTY_DEFINITION)) {
        // do not override an existing definition
        setModuleProperty(module, PROPERTY_DEFINITION, body);
        setModuleProperty(module, PROPERTY_DEPENDENCIES, dependencies);
        setModuleProperty(module, PROPERTY_LOADING_DEFINITION, false);
    }
    return module;
};

contextProto.moduleExecute = function(module) {
    var self = this;
    return self.modulePreload(module).thenSync(function() {
        return self.moduleExecuteSync(module);
    }).always(function() {
        self = null;
        module = null;
    });
};

contextProto.moduleAsyncRequire = function(module, id) {
    if (typeUtils.isArray(id)) {
        return this.modulePreloadDependencies(module, id);
    } else if (typeUtils.isString(id)) {
        return this.moduleRequire(module, id);
    }
};

contextProto.jsModuleDefine = function(jsCode, moduleFilename, url, lineDiff) {
    var dependencies = findRequires(jsCode, true);
    var body = this.jsModuleEval(jsCode, url || moduleFilename, lineDiff);
    return this.moduleDefine(this.getModule(moduleFilename), dependencies, body);
};

contextProto.jsModuleExecute = function(jsCode, moduleFilename, url) {
    return this.moduleExecute(this.jsModuleDefine(jsCode, moduleFilename, url));
};

contextProto.jsModuleEval = function(jsCode, url, lineDiff) {
    var code = ['(function(module, global){\nvar require = module.require, exports = module.exports, __filename = module.filename, __dirname = module.dirname;\n\n', jsCode, '\n\n})'];
    return jsEval(code.join(''), url, (lineDiff || 0) + 3 /* we are adding 3 lines compared to url */ );
};

contextProto.execModuleCall = function(moduleFilename) {
    return this.moduleExecute(this.getModule(this.moduleResolve(this.rootModule, moduleFilename)));
};

contextProto.builtinModules = {
    "noder-js/asyncRequire.js": function(context) {
        return function(module) {
            module.exports = {
                create: function(module) {
                    return function(id) {
                        return context.moduleAsyncRequire(module, id);
                    };
                }
            };
        };
    },
    "noder-js/currentContext.js": function(context) {
        return function(module) {
            module.exports = context;
        };
    }
};

contextProto.Context = Context;

Context.createContext = function(cfg) {
    return (new Context(cfg)).rootModule;
};

Context.expose = function(name, exports) {
    var body = function(module) {
        module.exports = exports;
    };
    contextProto.builtinModules[name] = function() {
        return body;
    };
};

module.exports = Context;
<|endoftext|>


<commit_before>import React from 'react';
import {
    WebView, View, StyleSheet, Dimensions,
} from 'react-native';
import Button from 'react-native-button';
import { observer } from 'mobx-react';
import { observable, computed, action } from 'mobx';
import Camera from 'react-native-camera';
import Bridge from './bridge';
import NetworkStatusModal from './network-status-modal';

import { onMessage, setRef } from './api';
import Config from './config';

let styles;

@observer
export default class ShowMakerWeb extends React.Component {

    @observable isScanning = false;
    @observable webView;

    constructor(props) {
        super(props);
        setRef(this);
    }

    sendCommand(cmd, payload) {
        const emit = `window.ShowMakerApp.emit('${cmd}', ${JSON.stringify(payload)})`;
        this.webView.injectJavaScript(emit);
    }

    @action.bound onBarcodeRead(ev) {
        this.isScanning = false;
        this.sendCommand('barcodeScan', ev);
    }

    @action.bound setWebViewRef(wv) {
        this.webView = wv;
    }

    @action.bound cancelCapture() {
        this.isScanning = false;
    }

    renderCamera() {
        if (!this.isScanning) { return null; }
        const { width } = Dimensions.get('window');

        return (
            <View
                style={{
                    position: 'absolute',
                    top: 100,
                    height: width * 0.6,
                    right: 20,
                    left: 20,
                    backgroundColor: 'black',
                }}
            >
                <Camera
                    style={styles.camera}
                    onBarCodeRead={this.onBarcodeRead}
                    aspect={Camera.constants.Aspect.fill}
                />

                <Button
                    containerStyle={{
                        padding: 10,
                        height: 45,
                        overflow: 'hidden',
                        backgroundColor: 'rgba(0,0,0,0.5)',
                    }}
                    style={{
                        position: 'absolute',
                        bottom: 0,
                        right: 0,
                        margin: 10,
                        color: 'white',
                    }}
                    onPress={this.cancelCapture}
                >
                    Cancel
                </Button>

            </View>
        );
    }

    render() {
        if (!Config.initialized) { return null; }
        return (
            <View style={styles.container}>
                <NetworkStatusModal />
                <WebView
                    ref={this.setWebViewRef}
                    bounces={false}
                    style={styles.webview}
                    injectedJavaScript={`(${Bridge.toString()})()`}
                    onMessage={onMessage}
                    source={{ uri: Config.url }}
                />
                {this.renderCamera()}
            </View>
        );
    }

}

styles = StyleSheet.create({
    container: {
        flex: 1,
        flexDirection: 'row',
    },
    webview: {
        flex: 1,
        justifyContent: 'flex-start',
    },
    camera: {
        flex: 1,
    },
});
<commit_msg>hide statusbar<commit_after>import React from 'react';
import {
    WebView, View, StyleSheet, Dimensions, StatusBar,
} from 'react-native';
import Button from 'react-native-button';
import { observer } from 'mobx-react';
import { observable, computed, action } from 'mobx';
import Camera from 'react-native-camera';
import Bridge from './bridge';
import NetworkStatusModal from './network-status-modal';

import { onMessage, setRef } from './api';
import Config from './config';

let styles;

@observer
export default class ShowMakerWeb extends React.Component {

    @observable isScanning = false;
    @observable webView;

    constructor(props) {
        super(props);
        setRef(this);
    }

    sendCommand(cmd, payload) {
        const emit = `window.ShowMakerApp.emit('${cmd}', ${JSON.stringify(payload)})`;
        this.webView.injectJavaScript(emit);
    }

    @action.bound onBarcodeRead(ev) {
        this.isScanning = false;
        this.sendCommand('barcodeScan', ev);
    }

    @action.bound setWebViewRef(wv) {
        this.webView = wv;
    }

    @action.bound cancelCapture() {
        this.isScanning = false;
    }

    renderCamera() {
        if (!this.isScanning) { return null; }
        const { width } = Dimensions.get('window');

        return (
            <View
                style={{
                    position: 'absolute',
                    top: 100,
                    height: width * 0.6,
                    right: 20,
                    left: 20,
                    backgroundColor: 'black',
                }}
            >
                <Camera
                    style={styles.camera}
                    onBarCodeRead={this.onBarcodeRead}
                    aspect={Camera.constants.Aspect.fill}
                />

                <Button
                    containerStyle={{
                        padding: 10,
                        height: 45,
                        overflow: 'hidden',
                        backgroundColor: 'rgba(0,0,0,0.5)',
                    }}
                    style={{
                        position: 'absolute',
                        bottom: 0,
                        right: 0,
                        margin: 10,
                        color: 'white',
                    }}
                    onPress={this.cancelCapture}
                >
                    Cancel
                </Button>

            </View>
        );
    }

    render() {
        if (!Config.initialized) { return null; }
        return (
            <View style={styles.container}>
                <NetworkStatusModal />
                <StatusBar hidden />
                <WebView
                    ref={this.setWebViewRef}
                    bounces={false}
                    style={styles.webview}
                    injectedJavaScript={`(${Bridge.toString()})()`}
                    onMessage={onMessage}
                    source={{ uri: Config.url }}
                />
                {this.renderCamera()}
            </View>
        );
    }

}

styles = StyleSheet.create({
    container: {
        flex: 1,
        flexDirection: 'row',
    },
    webview: {
        flex: 1,
        justifyContent: 'flex-start',
    },
    camera: {
        flex: 1,
    },
});
<|endoftext|>


<commit_before>/******************************************************************************
 * Copyright 2012 Intel Corporation.
 *
 * 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.
 *****************************************************************************/

/*****************************************************************************/

var dbus = { // hook object for dbus types not translated by python-json
		Double: function(value, level) {
			return value;
		}
};

/*****************************************************************************/

var cloudeebus = window.cloudeebus = {version: "0.2.1"};

cloudeebus.reset = function() {
	cloudeebus.sessionBus = null;
	cloudeebus.systemBus = null;
	cloudeebus.wampSession = null;
	cloudeebus.uri = null;
};

cloudeebus.log = function(msg) {
};

cloudeebus.connect = function(uri, manifest, successCB, errorCB) {
	cloudeebus.reset();
	cloudeebus.uri = uri;

	function onCloudeebusVersionCheckCB(version) {
		if (cloudeebus.version == version) {
			cloudeebus.log("Connected to " + cloudeebus.uri);
			if (successCB)
				successCB();
		} else {
			var errorMsg = "Cloudeebus server version " + version + " and client version " + cloudeebus.version + " mismatch";
			cloudeebus.log(errorMsg);
			if (errorCB)
				errorCB(errorMsg);
		}
	}

	function onWAMPSessionAuthErrorCB(error) {
		cloudeebus.log("Authentication error: " + error.desc);
		if (errorCB)
			errorCB(error.desc);
	}

	function onWAMPSessionAuthenticatedCB(permissions) {
		cloudeebus.sessionBus = new cloudeebus.BusConnection("session", cloudeebus.wampSession);
		cloudeebus.systemBus = new cloudeebus.BusConnection("system", cloudeebus.wampSession);
		cloudeebus.wampSession.call("getVersion").then(onCloudeebusVersionCheckCB, errorCB);
	}

	function onWAMPSessionChallengedCB(challenge) {
		var signature = cloudeebus.wampSession.authsign(challenge, manifest.key);
		cloudeebus.wampSession.auth(signature).then(onWAMPSessionAuthenticatedCB, onWAMPSessionAuthErrorCB);
	}

	function onWAMPSessionConnectedCB(session) {
		cloudeebus.wampSession = session;
		if (manifest)
			cloudeebus.wampSession.authreq(
					manifest.name,
					{permissions: JSON.stringify(manifest.permissions)}
				).then(onWAMPSessionChallengedCB, onWAMPSessionAuthErrorCB);
		else
			cloudeebus.wampSession.authreq().then(function() {
				cloudeebus.wampSession.auth().then(onWAMPSessionAuthenticatedCB, onWAMPSessionAuthErrorCB);
				}, onWAMPSessionAuthErrorCB);
	}

	function onWAMPSessionErrorCB(code, reason) {
		if (code == ab.CONNECTION_UNSUPPORTED) {
			cloudeebus.log("Browser is not supported");
		}
		else {
			cloudeebus.log("Failed to open session, code = " + code + ", reason = " + reason);
		}
		if (errorCB)
			errorCB(reason);
	}

	return ab.connect(cloudeebus.uri, onWAMPSessionConnectedCB, onWAMPSessionErrorCB);
};

cloudeebus.SessionBus = function() {
	return cloudeebus.sessionBus;
};

cloudeebus.SystemBus = function() {
	return cloudeebus.systemBus;
};

/*****************************************************************************/

cloudeebus.BusConnection = function(name, session) {
	this.name = name;
	this.wampSession = session;
	this.service = null;
	return this;
};

cloudeebus.BusConnection.prototype.getObject = function(busName, objectPath, introspectCB, errorCB) {
	var proxy = new cloudeebus.ProxyObject(this.wampSession, this, busName, objectPath);
	if (introspectCB)
		proxy._introspect(introspectCB, errorCB);
	return proxy;
};

cloudeebus.BusConnection.prototype.addService = function(serviceName, successCB, errorCB) {
	var self = this;

	cloudeebusService = new cloudeebus.Service(this.wampSession, this, serviceName);

	function busServiceAddedSuccessCB(service) {
		self.service = service;
		if (successCB)
			successCB(cloudeebusService);
	}

	function busServiceAddedErrorCB(error) {
		if (errorCB)
			errorCB();
	}

	cloudeebusService.add(busServiceAddedSuccessCB, busServiceAddedErrorCB);
};

/*****************************************************************************/

cloudeebus.Service = function(session, busConnection, name) {
	this.wampSession = session;
	this.busConnection = busConnection;
	this.name = name;
	this.isCreated = false;
	return this;
};

cloudeebus.Service.prototype.add = function(successCB, errorCB) {
	function ServiceAddSuccessCB(dbusService) {
		if (successCB) {
			try { // calling dbus hook object function for un-translated types
				successCB(dbusService);
			}
			catch (e) {
				alert(arguments.callee.name + "-> Method callback exception: " + e);
			}
		}
	}

	var arglist = [
	    this.busConnection,
	    this.name
	    ];

	// call dbusSend with bus type, destination, object, message and arguments
	this.wampSession.call("serviceAdd", arglist).then(ServiceAddSuccessCB, errorCB);
};

cloudeebus.Service.prototype.addAgent = function(objectPath, xmlTemplate, successCB, errorCB) {
	function ServiceAddAgentSuccessCB(dbusService) {
		if (successCB) {
			try { // calling dbus hook object function for un-translated types
				successCB(dbusService);
			}
			catch (e) {
				alert(arguments.callee.name + "-> Method callback exception: " + e);
			}
		}
	}

	var arglist = [
	    objectPath,
	    xmlTemplate
	    ];

	// call dbusSend with bus type, destination, object, message and arguments
	this.wampSession.call("serviceAddAgent", arglist).then(ServiceAddAgentSuccessCB, errorCB);
};

cloudeebus.Service.prototype.delAgent = function(objectPath, successCB, errorCB) {
	function ServiceDelAgentSuccessCB(agent) {
		if (successCB) {
			try { // calling dbus hook object function for un-translated types
				successCB(agent);
			}
			catch (e) {
				alert(arguments.callee.name + "-> Method callback exception: " + e);
			}
		}
	}

	var arglist = [
	    objectPath
	    ];

	// call dbusSend with bus type, destination, object, message and arguments
	this.wampSession.call("serviceDelAgent", arglist).then(ServiceDelAgentSuccessCB, errorCB);
};

cloudeebus.Service.prototype.registerMethod = function(methodId, methodHandler) {
	this.wampSession.subscribe(methodId, methodHandler);
};

cloudeebus.Service.prototype.returnMethod = function(methodId, success, result, successCB, errorCB) {
	var arglist = [
	    methodId,
	    success,
	    result
	    ];

	this.wampSession.call("returnMethod", arglist).then(successCB, errorCB);
};

/*****************************************************************************/

cloudeebus.ProxyObject = function(session, busConnection, busName, objectPath) {
	this.wampSession = session;
	this.busConnection = busConnection;
	this.busName = busName;
	this.objectPath = objectPath;
	return this;
};

cloudeebus.ProxyObject.prototype._introspect = function(successCB, errorCB) {

	var self = this;

	function getAllPropertiesSuccessCB(props) {
		for (var prop in props)
			self[prop] = props[prop];
		getAllPropertiesNextInterfaceCB();
	}

	function getAllPropertiesNextInterfaceCB() {
		if (self.propInterfaces.length > 0)
			self.callMethod("org.freedesktop.DBus.Properties",
				"GetAll",
				[self.propInterfaces.pop()],
				getAllPropertiesSuccessCB,
				errorCB ? errorCB : getAllPropertiesNextInterfaceCB);
		else {
			self.propInterfaces = null;
			if (successCB)
				successCB(self);
		}
	}

	function introspectSuccessCB(str) {
		var parser = new DOMParser();
		var xmlDoc = parser.parseFromString(str, "text/xml");
		var interfaces = xmlDoc.getElementsByTagName("interface");
		self.propInterfaces = [];
		var supportDBusProperties = false;
		for (var i=0; i < interfaces.length; i++) {
			var ifName = interfaces[i].attributes.getNamedItem("name").value;
			if (ifName == "org.freedesktop.DBus.Properties")
				supportDBusProperties = true;
			var hasProperties = false;
			var ifChild = interfaces[i].firstChild;
			while (ifChild) {
				if (ifChild.nodeName == "method") {
					var nArgs = 0;
					var metChild = ifChild.firstChild;
					while (metChild) {
						if (metChild.nodeName == "arg" &&
							metChild.attributes.getNamedItem("direction").value == "in")
								nArgs++;
						metChild = metChild.nextSibling;
					}
					self._addMethod(ifName,
							ifChild.attributes.getNamedItem("name").value,
							nArgs);
				}
				else if (ifChild.nodeName == "property") {
					if (!hasProperties)
						self.propInterfaces.push(ifName);
					hasProperties = true;
				}
				ifChild = ifChild.nextSibling;
			}
		}
		if (supportDBusProperties && self.propInterfaces.length > 0) {
			self.callMethod("org.freedesktop.DBus.Properties",
				"GetAll",
				[self.propInterfaces.pop()],
				getAllPropertiesSuccessCB,
				errorCB ? errorCB : getAllPropertiesNextInterfaceCB);
		}
		else {
			self.propInterfaces = null;
			if (successCB)
				successCB(self);
		}
	}

	// call Introspect on self
	self.callMethod("org.freedesktop.DBus.Introspectable", "Introspect", [], introspectSuccessCB, errorCB);
};

cloudeebus.ProxyObject.prototype._addMethod = function(ifName, method, nArgs) {

	var self = this;

	self[method] = function() {
		if (arguments.length < nArgs || arguments.length > nArgs + 2)
			throw "Error: method " + method + " takes " + nArgs + " parameters, got " + arguments.length + ".";
		var args = [];
		var successCB = null;
		var errorCB = null;
		for (var i=0; i < nArgs; i++ )
			args.push(arguments[i]);
		if (arguments.length > nArgs)
			successCB = arguments[nArgs];
		if (arguments.length > nArgs + 1)
			errorCB = arguments[nArgs + 1];
		self.callMethod(ifName, method, args, successCB, errorCB);
	};

};

cloudeebus.ProxyObject.prototype.callMethod = function(ifName, method, args, successCB, errorCB) {

	var self = this;

	function callMethodSuccessCB(str) {
		if (successCB) {
			try { // calling dbus hook object function for un-translated types
				successCB.apply(self, eval(str));
			}
			catch (e) {
				cloudeebus.log("Method callback exception: " + e);
				if (errorCB)
					errorCB(e);
			}
		}
	}

	function callMethodErrorCB(error) {
		cloudeebus.log("Error calling method: " + method + " on object: " + self.objectPath + " : " + error.desc);
		if (errorCB)
			errorCB(error.desc);
	}

	var arglist = [
		self.busConnection.name,
		self.busName,
		self.objectPath,
		ifName,
		method,
		JSON.stringify(args)
	];

	// call dbusSend with bus type, destination, object, message and arguments
	self.wampSession.call("dbusSend", arglist).then(callMethodSuccessCB, callMethodErrorCB);
};

cloudeebus.ProxyObject.prototype.connectToSignal = function(ifName, signal, successCB, errorCB) {

	var self = this;

	function signalHandler(id, data) {
		if (successCB) {
			try { // calling dbus hook object function for un-translated types
				successCB.apply(self, eval(data));
			}
			catch (e) {
				cloudeebus.log("Signal handler exception: " + e);
				if (errorCB)
					errorCB(e);
			}
		}
	}

	function connectToSignalSuccessCB(str) {
		try {
			self.wampSession.subscribe(str, signalHandler);
		}
		catch (e) {
			cloudeebus.log("Subscribe error: " + e);
		}
	}

	function connectToSignalErrorCB(error) {
		cloudeebus.log("Error connecting to signal: " + signal + " on object: " + self.objectPath + " : " + error.desc);
		if (errorCB)
			errorCB(error.desc);
	}

	var arglist = [
		self.busConnection.name,
		self.busName,
		self.objectPath,
		ifName,
		signal
	];

	// call dbusSend with bus type, destination, object, message and arguments
	self.wampSession.call("dbusRegister", arglist).then(connectToSignalSuccessCB, connectToSignalErrorCB);
};

cloudeebus.ProxyObject.prototype.disconnectSignal = function(ifName, signal) {
	try {
		this.wampSession.unsubscribe(this.busConnection.name + "#" + this.busName + "#" + this.objectPath + "#" + ifName + "#" + signal);
	}
	catch (e) {
		cloudeebus.log("Unsubscribe error: " + e);
	}
};
<commit_msg>dbus service: renaming parameters<commit_after>/******************************************************************************
 * Copyright 2012 Intel Corporation.
 *
 * 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.
 *****************************************************************************/

/*****************************************************************************/

var dbus = { // hook object for dbus types not translated by python-json
		Double: function(value, level) {
			return value;
		}
};

/*****************************************************************************/

var cloudeebus = window.cloudeebus = {version: "0.2.1"};

cloudeebus.reset = function() {
	cloudeebus.sessionBus = null;
	cloudeebus.systemBus = null;
	cloudeebus.wampSession = null;
	cloudeebus.uri = null;
};

cloudeebus.log = function(msg) {
};

cloudeebus.connect = function(uri, manifest, successCB, errorCB) {
	cloudeebus.reset();
	cloudeebus.uri = uri;

	function onCloudeebusVersionCheckCB(version) {
		if (cloudeebus.version == version) {
			cloudeebus.log("Connected to " + cloudeebus.uri);
			if (successCB)
				successCB();
		} else {
			var errorMsg = "Cloudeebus server version " + version + " and client version " + cloudeebus.version + " mismatch";
			cloudeebus.log(errorMsg);
			if (errorCB)
				errorCB(errorMsg);
		}
	}

	function onWAMPSessionAuthErrorCB(error) {
		cloudeebus.log("Authentication error: " + error.desc);
		if (errorCB)
			errorCB(error.desc);
	}

	function onWAMPSessionAuthenticatedCB(permissions) {
		cloudeebus.sessionBus = new cloudeebus.BusConnection("session", cloudeebus.wampSession);
		cloudeebus.systemBus = new cloudeebus.BusConnection("system", cloudeebus.wampSession);
		cloudeebus.wampSession.call("getVersion").then(onCloudeebusVersionCheckCB, errorCB);
	}

	function onWAMPSessionChallengedCB(challenge) {
		var signature = cloudeebus.wampSession.authsign(challenge, manifest.key);
		cloudeebus.wampSession.auth(signature).then(onWAMPSessionAuthenticatedCB, onWAMPSessionAuthErrorCB);
	}

	function onWAMPSessionConnectedCB(session) {
		cloudeebus.wampSession = session;
		if (manifest)
			cloudeebus.wampSession.authreq(
					manifest.name,
					{permissions: JSON.stringify(manifest.permissions)}
				).then(onWAMPSessionChallengedCB, onWAMPSessionAuthErrorCB);
		else
			cloudeebus.wampSession.authreq().then(function() {
				cloudeebus.wampSession.auth().then(onWAMPSessionAuthenticatedCB, onWAMPSessionAuthErrorCB);
				}, onWAMPSessionAuthErrorCB);
	}

	function onWAMPSessionErrorCB(code, reason) {
		if (code == ab.CONNECTION_UNSUPPORTED) {
			cloudeebus.log("Browser is not supported");
		}
		else {
			cloudeebus.log("Failed to open session, code = " + code + ", reason = " + reason);
		}
		if (errorCB)
			errorCB(reason);
	}

	return ab.connect(cloudeebus.uri, onWAMPSessionConnectedCB, onWAMPSessionErrorCB);
};

cloudeebus.SessionBus = function() {
	return cloudeebus.sessionBus;
};

cloudeebus.SystemBus = function() {
	return cloudeebus.systemBus;
};

/*****************************************************************************/

cloudeebus.BusConnection = function(name, session) {
	this.name = name;
	this.wampSession = session;
	this.service = null;
	return this;
};

cloudeebus.BusConnection.prototype.getObject = function(busName, objectPath, introspectCB, errorCB) {
	var proxy = new cloudeebus.ProxyObject(this.wampSession, this, busName, objectPath);
	if (introspectCB)
		proxy._introspect(introspectCB, errorCB);
	return proxy;
};

cloudeebus.BusConnection.prototype.addService = function(serviceName, successCB, errorCB) {
	var self = this;

	cloudeebusService = new cloudeebus.Service(this.wampSession, this, serviceName);

	function busServiceAddedSuccessCB(service) {
		self.service = service;
		if (successCB)
			successCB(cloudeebusService);
	}

	function busServiceAddedErrorCB(error) {
		if (errorCB)
			errorCB();
	}

	cloudeebusService.add(busServiceAddedSuccessCB, busServiceAddedErrorCB);
};

/*****************************************************************************/

cloudeebus.Service = function(session, busConnection, name) {
	this.wampSession = session;
	this.busConnection = busConnection;
	this.name = name;
	this.isCreated = false;
	return this;
};

cloudeebus.Service.prototype.add = function(successCB, errorCB) {
	function ServiceAddSuccessCB(dbusService) {
		if (successCB) {
			try { // calling dbus hook object function for un-translated types
				successCB(dbusService);
			}
			catch (e) {
				alert(arguments.callee.name + "-> Method callback exception: " + e);
			}
		}
	}

	var arglist = [
	    this.busConnection,
	    this.name
	    ];

	// call dbusSend with bus type, destination, object, message and arguments
	this.wampSession.call("serviceAdd", arglist).then(ServiceAddSuccessCB, errorCB);
};

cloudeebus.Service.prototype.addAgent = function(objectPath, xmlTemplate, successCB, errorCB) {
	function ServiceAddAgentSuccessCB(objPath) {
		if (successCB) {
			try { // calling dbus hook object function for un-translated types
				successCB(objPath);
			}
			catch (e) {
				alert(arguments.callee.name + "-> Method callback exception: " + e);
			}
		}
	}

	var arglist = [
	    objectPath,
	    xmlTemplate
	    ];

	// call dbusSend with bus type, destination, object, message and arguments
	this.wampSession.call("serviceAddAgent", arglist).then(ServiceAddAgentSuccessCB, errorCB);
};

cloudeebus.Service.prototype.delAgent = function(objectPath, successCB, errorCB) {
	function ServiceDelAgentSuccessCB(agent) {
		if (successCB) {
			try { // calling dbus hook object function for un-translated types
				successCB(agent);
			}
			catch (e) {
				alert(arguments.callee.name + "-> Method callback exception: " + e);
			}
		}
	}

	var arglist = [
	    objectPath
	    ];

	// call dbusSend with bus type, destination, object, message and arguments
	this.wampSession.call("serviceDelAgent", arglist).then(ServiceDelAgentSuccessCB, errorCB);
};

cloudeebus.Service.prototype.registerMethod = function(methodId, methodHandler) {
	this.wampSession.subscribe(methodId, methodHandler);
};

cloudeebus.Service.prototype.returnMethod = function(methodId, success, result, successCB, errorCB) {
	var arglist = [
	    methodId,
	    success,
	    result
	    ];

	this.wampSession.call("returnMethod", arglist).then(successCB, errorCB);
};

/*****************************************************************************/

cloudeebus.ProxyObject = function(session, busConnection, busName, objectPath) {
	this.wampSession = session;
	this.busConnection = busConnection;
	this.busName = busName;
	this.objectPath = objectPath;
	return this;
};

cloudeebus.ProxyObject.prototype._introspect = function(successCB, errorCB) {

	var self = this;

	function getAllPropertiesSuccessCB(props) {
		for (var prop in props)
			self[prop] = props[prop];
		getAllPropertiesNextInterfaceCB();
	}

	function getAllPropertiesNextInterfaceCB() {
		if (self.propInterfaces.length > 0)
			self.callMethod("org.freedesktop.DBus.Properties",
				"GetAll",
				[self.propInterfaces.pop()],
				getAllPropertiesSuccessCB,
				errorCB ? errorCB : getAllPropertiesNextInterfaceCB);
		else {
			self.propInterfaces = null;
			if (successCB)
				successCB(self);
		}
	}

	function introspectSuccessCB(str) {
		var parser = new DOMParser();
		var xmlDoc = parser.parseFromString(str, "text/xml");
		var interfaces = xmlDoc.getElementsByTagName("interface");
		self.propInterfaces = [];
		var supportDBusProperties = false;
		for (var i=0; i < interfaces.length; i++) {
			var ifName = interfaces[i].attributes.getNamedItem("name").value;
			if (ifName == "org.freedesktop.DBus.Properties")
				supportDBusProperties = true;
			var hasProperties = false;
			var ifChild = interfaces[i].firstChild;
			while (ifChild) {
				if (ifChild.nodeName == "method") {
					var nArgs = 0;
					var metChild = ifChild.firstChild;
					while (metChild) {
						if (metChild.nodeName == "arg" &&
							metChild.attributes.getNamedItem("direction").value == "in")
								nArgs++;
						metChild = metChild.nextSibling;
					}
					self._addMethod(ifName,
							ifChild.attributes.getNamedItem("name").value,
							nArgs);
				}
				else if (ifChild.nodeName == "property") {
					if (!hasProperties)
						self.propInterfaces.push(ifName);
					hasProperties = true;
				}
				ifChild = ifChild.nextSibling;
			}
		}
		if (supportDBusProperties && self.propInterfaces.length > 0) {
			self.callMethod("org.freedesktop.DBus.Properties",
				"GetAll",
				[self.propInterfaces.pop()],
				getAllPropertiesSuccessCB,
				errorCB ? errorCB : getAllPropertiesNextInterfaceCB);
		}
		else {
			self.propInterfaces = null;
			if (successCB)
				successCB(self);
		}
	}

	// call Introspect on self
	self.callMethod("org.freedesktop.DBus.Introspectable", "Introspect", [], introspectSuccessCB, errorCB);
};

cloudeebus.ProxyObject.prototype._addMethod = function(ifName, method, nArgs) {

	var self = this;

	self[method] = function() {
		if (arguments.length < nArgs || arguments.length > nArgs + 2)
			throw "Error: method " + method + " takes " + nArgs + " parameters, got " + arguments.length + ".";
		var args = [];
		var successCB = null;
		var errorCB = null;
		for (var i=0; i < nArgs; i++ )
			args.push(arguments[i]);
		if (arguments.length > nArgs)
			successCB = arguments[nArgs];
		if (arguments.length > nArgs + 1)
			errorCB = arguments[nArgs + 1];
		self.callMethod(ifName, method, args, successCB, errorCB);
	};

};

cloudeebus.ProxyObject.prototype.callMethod = function(ifName, method, args, successCB, errorCB) {

	var self = this;

	function callMethodSuccessCB(str) {
		if (successCB) {
			try { // calling dbus hook object function for un-translated types
				successCB.apply(self, eval(str));
			}
			catch (e) {
				cloudeebus.log("Method callback exception: " + e);
				if (errorCB)
					errorCB(e);
			}
		}
	}

	function callMethodErrorCB(error) {
		cloudeebus.log("Error calling method: " + method + " on object: " + self.objectPath + " : " + error.desc);
		if (errorCB)
			errorCB(error.desc);
	}

	var arglist = [
		self.busConnection.name,
		self.busName,
		self.objectPath,
		ifName,
		method,
		JSON.stringify(args)
	];

	// call dbusSend with bus type, destination, object, message and arguments
	self.wampSession.call("dbusSend", arglist).then(callMethodSuccessCB, callMethodErrorCB);
};

cloudeebus.ProxyObject.prototype.connectToSignal = function(ifName, signal, successCB, errorCB) {

	var self = this;

	function signalHandler(id, data) {
		if (successCB) {
			try { // calling dbus hook object function for un-translated types
				successCB.apply(self, eval(data));
			}
			catch (e) {
				cloudeebus.log("Signal handler exception: " + e);
				if (errorCB)
					errorCB(e);
			}
		}
	}

	function connectToSignalSuccessCB(str) {
		try {
			self.wampSession.subscribe(str, signalHandler);
		}
		catch (e) {
			cloudeebus.log("Subscribe error: " + e);
		}
	}

	function connectToSignalErrorCB(error) {
		cloudeebus.log("Error connecting to signal: " + signal + " on object: " + self.objectPath + " : " + error.desc);
		if (errorCB)
			errorCB(error.desc);
	}

	var arglist = [
		self.busConnection.name,
		self.busName,
		self.objectPath,
		ifName,
		signal
	];

	// call dbusSend with bus type, destination, object, message and arguments
	self.wampSession.call("dbusRegister", arglist).then(connectToSignalSuccessCB, connectToSignalErrorCB);
};

cloudeebus.ProxyObject.prototype.disconnectSignal = function(ifName, signal) {
	try {
		this.wampSession.unsubscribe(this.busConnection.name + "#" + this.busName + "#" + this.objectPath + "#" + ifName + "#" + signal);
	}
	catch (e) {
		cloudeebus.log("Unsubscribe error: " + e);
	}
};
<|endoftext|>


<commit_before>import SEGMENT_COMPONENTS from './components.json'
import SEGMENT_LOOKUP from './segment-lookup.json'
import { SEGMENT_UNKNOWN, SEGMENT_UNKNOWN_VARIANT } from './info'
import { uniq } from 'lodash'

/**
 * Retrieves the necessary information required to map the old segment data model to the
 * new segment data model for the specific segment using the segment's `type` and `variant`.
 *
 * @param {string} type
 * @param {string} variant
 * @returns {object|boolean} segmentLookup - returns an object in the shape of: { lanes, objects, vehicles } or `false` if not found.
 */
function getSegmentLookup (type, variant) {
  return SEGMENT_LOOKUP[type] && SEGMENT_LOOKUP[type][variant]
}

/**
 * Retrieves the specified segment information from the new segment data model using the
 * component group and the segment id.
 *
 * @param {string} group - component group, one of values "lanes", "vehicles" or "objects"
 * @param {string} id - name of segment component, e.g. "scooter"
 * @returns {object} segmentInfo
 */
function getSegmentInfo (group, id) {
  return (SEGMENT_COMPONENTS[group] && SEGMENT_COMPONENTS[group][id]) || SEGMENT_UNKNOWN
}

/**
 * Retrieves the information for all items that make up a particular component group by
 * looking up the component group and item id in `SEGMENT_COMPONENTS`.
 *
 * @param {string} group - component group name (i.e. `lanes`, `objects`, or `vehicles`)
 * @param {Array} groupItems - items that make up the component group in shape of [{ id, variants }]
 * @returns {object} componentGroupInfo - returns object in shape of { id: { characteristics, rules, variants } }
 */
function getComponentGroupInfo (group, groupItems) {
  return groupItems.reduce((obj, item) => {
    obj[item.id] = getSegmentInfo(group, item.id)
    return obj
  }, {})
}

/**
 * Retrieves all graphics definitions for the component group based on each `variant`
 * specified for each component group item.
 *
 * @param {Array} groupItems - items that make up the component group in shape of [ { id, variants } ]
 * @param {object} componentGroupInfo - definition of each item from `SEGMENT_COMPONENTS` in shape of { id: { characteristics, rules, variants } }
 * @returns {Array} componentGroupVariants - returns array of graphic definitions in shape of [ { graphics } ]
 */
function getComponentGroupVariants (groupItems, componentGroupInfo) {
  return groupItems.reduce((array, item) => {
    const { id, variants } = item
    // groupItemVariants - all variants possible for the particular group item
    const groupItemVariants = componentGroupInfo[id] && componentGroupInfo[id].variants

    if (groupItemVariants) {
      Object.entries(variants).forEach(([variantName, variantKey]) => {
        // variantInfo - graphics definition for specific variants defined by group item
        const variantInfo = (groupItemVariants[variantName] && groupItemVariants[variantName][variantKey]) || SEGMENT_UNKNOWN_VARIANT
        array.push(variantInfo.graphics)
      })
    }

    return array
  }, [])
}

/**
 * A segment may contain multiple graphics for the same graphics type ('left', 'right', 'repeat', 'center').
 * When encountering a new graphic for the same graphics type, this function creates a new array that
 * contains both the new graphic as well as the existing graphics.
 *
 * @param {Array|string} target
 * @param {Array|string} source
 * @returns {Array} graphicsInfo
 */
function appendVariantSprites (target, source) {
  const targetArray = Array.isArray(target) ? target : [target]
  const sourceArray = Array.isArray(source) ? source : [source]

  const graphicsInfo = targetArray.concat(sourceArray)
  return uniq(graphicsInfo)
}

/**
 * Merges the array of graphic definition objects needed to draw the segment into a single object.
 *
 * @param {Array} variantGraphics
 * @returns {object} graphics
 */
function mergeVariantGraphics (variantGraphics) {
  return variantGraphics.reduce((graphics, variantInfo) => {
    Object.keys(variantInfo).forEach((key) => {
      const target = graphics[key]
      const source = variantInfo[key]

      if (target) {
        graphics[key] = appendVariantSprites(target, source)
      } else {
        graphics[key] = source
      }
    })

    return graphics
  }, {})
}

/**
 * Collects all rules associated with any items that make up the component group into a single object.
 *
 * @param {Array} groupItems - items that make up the component group in shape of [{ id, variants }]
 * @param {object} componentGroupInfo - definition of each item from `SEGMENT_COMPONENTS` in shape of { id: { characteristics, rules, variants } }
 * @returns {object} componentGroupRules
 */
function getComponentGroupRules (groupItems, componentGroupInfo) {
  const componentGroupRules = groupItems.reduce((obj, item) => {
    const { id, variants } = item

    let groupItemRules = {}

    if (componentGroupInfo[id] && componentGroupInfo[id].rules) {
      groupItemRules = { ...componentGroupInfo[id].rules }
    }

    const groupItemVariants = componentGroupInfo[id] && componentGroupInfo[id].variants

    Object.keys(variants).forEach((variantName) => {
      if (groupItemVariants[variantName] && groupItemVariants[variantName].rules) {
        groupItemRules = { ...groupItemRules, ...groupItemVariants[variantName].rules }
      }
    })

    return { ...obj, ...groupItemRules }
  }, {})

  return Object.keys(componentGroupRules).length && componentGroupRules
}

/**
 * Maps the old segment data model to the new segment data model and returns the graphic sprites necessary
 * to draw the segment as well as any rules to follow, e.g. `minWidth` based on the `type` and `variant`.
 *
 * @param {string} type
 * @param {string} variant
 * @returns {object} variantInfo - returns an object in the shape of { graphics, ...rules }
 */
function getSegmentVariantInfo (type, variant) {
  const segmentLookup = getSegmentLookup(type, variant)

  if (!segmentLookup) {
    return SEGMENT_UNKNOWN_VARIANT
  }

  // 1) Loop through each component group that makes up the segment.
  const variantInfo = Object.entries(segmentLookup).reduce((variantInfo, componentGroup) => {
    const [ group, groupItems ] = componentGroup
    // 2) For each component group, look up the segment information for every item that makes up the component group.
    // componentGroupInfo = [ { characteristics, rules, variants } ]
    const componentGroupInfo = getComponentGroupInfo(group, groupItems)

    // componentGroupVariants = [ { graphics } ]
    // 3) For each component group, look up the segment variant graphics for every item that makes up the component group.
    const componentGroupVariants = getComponentGroupVariants(groupItems, componentGroupInfo)

    if (componentGroupVariants.length) {
      // 4) Combine the variant graphics for each component group into one array
      componentGroupVariants.forEach((groupItemVariants) => { variantInfo.graphics.push(groupItemVariants) })
    }

    // 5) For each component group, look up any rules associated with each of the items that make up the component group.
    const componentGroupRules = getComponentGroupRules(groupItems, componentGroupInfo)
    if (componentGroupRules) {
      return Object.assign(variantInfo, componentGroupRules)
    }

    return variantInfo
  }, { graphics: [] })

  // 6) Combine the variant graphics into one graphics definition object.
  variantInfo.graphics = mergeVariantGraphics(variantInfo.graphics)
  return variantInfo
}

/**
 * Temporary helper method that compares the original segment variant info with the variant info returned
 * by the new data model. If the new variant info contains all the keys from the original variant info, then
 * the variant info is correct.
 *
 * TODO - migrate helper method to become a test suite
 *
 * @param {object} originalVariantInfo
 * @param {object} newVariantInfo
 * @returns {boolean} correct
 */
function verifyCorrectness (originalVariantInfo, newVariantInfo) {
  const filteredKeys = Object.keys(originalVariantInfo).filter(key => !newVariantInfo[key])
  const filteredGraphics = Object.entries(originalVariantInfo.graphics).filter((item) => {
    const [ key, value ] = item
    const originalGraphics = Array.isArray(value) ? value.sort() : value
    const newGraphics = Array.isArray(newVariantInfo.graphics[key]) ? newVariantInfo.graphics[key].sort() : newVariantInfo.graphics[key]
    return !(JSON.stringify(originalGraphics) === JSON.stringify(newGraphics))
  })

  return (filteredKeys.length === 0 && filteredGraphics.length === 0)
}

/**
 * Tests the mapping of the old segment data model to the new segment data model and
 * returns the correct `variantInfo` needed to draw the segment.
 *
 * @param {string} type
 * @param {string} variant
 * @param {object} segmentVariantInfo
 * @returns {object} variantInfo
 */
export function testSegmentLookup (type, variant, segmentVariantInfo) {
  const newVariantInfo = getSegmentVariantInfo(type, variant)

  if (verifyCorrectness(segmentVariantInfo, newVariantInfo)) {
    console.log(variant, newVariantInfo)
    return newVariantInfo
  } else {
    return segmentVariantInfo
  }
}
<commit_msg>removed console log for verifying correctness of new segment data model<commit_after>import SEGMENT_COMPONENTS from './components.json'
import SEGMENT_LOOKUP from './segment-lookup.json'
import { SEGMENT_UNKNOWN, SEGMENT_UNKNOWN_VARIANT } from './info'
import { uniq } from 'lodash'

/**
 * Retrieves the necessary information required to map the old segment data model to the
 * new segment data model for the specific segment using the segment's `type` and `variant`.
 *
 * @param {string} type
 * @param {string} variant
 * @returns {object|boolean} segmentLookup - returns an object in the shape of: { lanes, objects, vehicles } or `false` if not found.
 */
function getSegmentLookup (type, variant) {
  return SEGMENT_LOOKUP[type] && SEGMENT_LOOKUP[type][variant]
}

/**
 * Retrieves the specified segment information from the new segment data model using the
 * component group and the segment id.
 *
 * @param {string} group - component group, one of values "lanes", "vehicles" or "objects"
 * @param {string} id - name of segment component, e.g. "scooter"
 * @returns {object} segmentInfo
 */
function getSegmentInfo (group, id) {
  return (SEGMENT_COMPONENTS[group] && SEGMENT_COMPONENTS[group][id]) || SEGMENT_UNKNOWN
}

/**
 * Retrieves the information for all items that make up a particular component group by
 * looking up the component group and item id in `SEGMENT_COMPONENTS`.
 *
 * @param {string} group - component group name (i.e. `lanes`, `objects`, or `vehicles`)
 * @param {Array} groupItems - items that make up the component group in shape of [{ id, variants }]
 * @returns {object} componentGroupInfo - returns object in shape of { id: { characteristics, rules, variants } }
 */
function getComponentGroupInfo (group, groupItems) {
  return groupItems.reduce((obj, item) => {
    obj[item.id] = getSegmentInfo(group, item.id)
    return obj
  }, {})
}

/**
 * Retrieves all graphics definitions for the component group based on each `variant`
 * specified for each component group item.
 *
 * @param {Array} groupItems - items that make up the component group in shape of [ { id, variants } ]
 * @param {object} componentGroupInfo - definition of each item from `SEGMENT_COMPONENTS` in shape of { id: { characteristics, rules, variants } }
 * @returns {Array} componentGroupVariants - returns array of graphic definitions in shape of [ { graphics } ]
 */
function getComponentGroupVariants (groupItems, componentGroupInfo) {
  return groupItems.reduce((array, item) => {
    const { id, variants } = item
    // groupItemVariants - all variants possible for the particular group item
    const groupItemVariants = componentGroupInfo[id] && componentGroupInfo[id].variants

    if (groupItemVariants) {
      Object.entries(variants).forEach(([variantName, variantKey]) => {
        // variantInfo - graphics definition for specific variants defined by group item
        const variantInfo = (groupItemVariants[variantName] && groupItemVariants[variantName][variantKey]) || SEGMENT_UNKNOWN_VARIANT
        array.push(variantInfo.graphics)
      })
    }

    return array
  }, [])
}

/**
 * A segment may contain multiple graphics for the same graphics type ('left', 'right', 'repeat', 'center').
 * When encountering a new graphic for the same graphics type, this function creates a new array that
 * contains both the new graphic as well as the existing graphics.
 *
 * @param {Array|string} target
 * @param {Array|string} source
 * @returns {Array} graphicsInfo
 */
function appendVariantSprites (target, source) {
  const targetArray = Array.isArray(target) ? target : [target]
  const sourceArray = Array.isArray(source) ? source : [source]

  const graphicsInfo = targetArray.concat(sourceArray)
  return uniq(graphicsInfo)
}

/**
 * Merges the array of graphic definition objects needed to draw the segment into a single object.
 *
 * @param {Array} variantGraphics
 * @returns {object} graphics
 */
function mergeVariantGraphics (variantGraphics) {
  return variantGraphics.reduce((graphics, variantInfo) => {
    Object.keys(variantInfo).forEach((key) => {
      const target = graphics[key]
      const source = variantInfo[key]

      if (target) {
        graphics[key] = appendVariantSprites(target, source)
      } else {
        graphics[key] = source
      }
    })

    return graphics
  }, {})
}

/**
 * Collects all rules associated with any items that make up the component group into a single object.
 *
 * @param {Array} groupItems - items that make up the component group in shape of [{ id, variants }]
 * @param {object} componentGroupInfo - definition of each item from `SEGMENT_COMPONENTS` in shape of { id: { characteristics, rules, variants } }
 * @returns {object} componentGroupRules
 */
function getComponentGroupRules (groupItems, componentGroupInfo) {
  const componentGroupRules = groupItems.reduce((obj, item) => {
    const { id, variants } = item

    let groupItemRules = {}

    if (componentGroupInfo[id] && componentGroupInfo[id].rules) {
      groupItemRules = { ...componentGroupInfo[id].rules }
    }

    const groupItemVariants = componentGroupInfo[id] && componentGroupInfo[id].variants

    Object.keys(variants).forEach((variantName) => {
      if (groupItemVariants[variantName] && groupItemVariants[variantName].rules) {
        groupItemRules = { ...groupItemRules, ...groupItemVariants[variantName].rules }
      }
    })

    return { ...obj, ...groupItemRules }
  }, {})

  return Object.keys(componentGroupRules).length && componentGroupRules
}

/**
 * Maps the old segment data model to the new segment data model and returns the graphic sprites necessary
 * to draw the segment as well as any rules to follow, e.g. `minWidth` based on the `type` and `variant`.
 *
 * @param {string} type
 * @param {string} variant
 * @returns {object} variantInfo - returns an object in the shape of { graphics, ...rules }
 */
function getSegmentVariantInfo (type, variant) {
  const segmentLookup = getSegmentLookup(type, variant)

  if (!segmentLookup) {
    return SEGMENT_UNKNOWN_VARIANT
  }

  // 1) Loop through each component group that makes up the segment.
  const variantInfo = Object.entries(segmentLookup).reduce((variantInfo, componentGroup) => {
    const [ group, groupItems ] = componentGroup
    // 2) For each component group, look up the segment information for every item that makes up the component group.
    // componentGroupInfo = [ { characteristics, rules, variants } ]
    const componentGroupInfo = getComponentGroupInfo(group, groupItems)

    // componentGroupVariants = [ { graphics } ]
    // 3) For each component group, look up the segment variant graphics for every item that makes up the component group.
    const componentGroupVariants = getComponentGroupVariants(groupItems, componentGroupInfo)

    if (componentGroupVariants.length) {
      // 4) Combine the variant graphics for each component group into one array
      componentGroupVariants.forEach((groupItemVariants) => { variantInfo.graphics.push(groupItemVariants) })
    }

    // 5) For each component group, look up any rules associated with each of the items that make up the component group.
    const componentGroupRules = getComponentGroupRules(groupItems, componentGroupInfo)
    if (componentGroupRules) {
      return Object.assign(variantInfo, componentGroupRules)
    }

    return variantInfo
  }, { graphics: [] })

  // 6) Combine the variant graphics into one graphics definition object.
  variantInfo.graphics = mergeVariantGraphics(variantInfo.graphics)
  return variantInfo
}

/**
 * Temporary helper method that compares the original segment variant info with the variant info returned
 * by the new data model. If the new variant info contains all the keys from the original variant info, then
 * the variant info is correct.
 *
 * TODO - migrate helper method to become a test suite
 *
 * @param {object} originalVariantInfo
 * @param {object} newVariantInfo
 * @returns {boolean} correct
 */
function verifyCorrectness (originalVariantInfo, newVariantInfo) {
  const filteredKeys = Object.keys(originalVariantInfo).filter(key => !newVariantInfo[key])
  const filteredGraphics = Object.entries(originalVariantInfo.graphics).filter((item) => {
    const [ key, value ] = item
    const originalGraphics = Array.isArray(value) ? value.sort() : value
    const newGraphics = Array.isArray(newVariantInfo.graphics[key]) ? newVariantInfo.graphics[key].sort() : newVariantInfo.graphics[key]
    return !(JSON.stringify(originalGraphics) === JSON.stringify(newGraphics))
  })

  return (filteredKeys.length === 0 && filteredGraphics.length === 0)
}

/**
 * Tests the mapping of the old segment data model to the new segment data model and
 * returns the correct `variantInfo` needed to draw the segment.
 *
 * @param {string} type
 * @param {string} variant
 * @param {object} segmentVariantInfo
 * @returns {object} variantInfo
 */
export function testSegmentLookup (type, variant, segmentVariantInfo) {
  const newVariantInfo = getSegmentVariantInfo(type, variant)

  if (verifyCorrectness(segmentVariantInfo, newVariantInfo)) {
    return newVariantInfo
  } else {
    return segmentVariantInfo
  }
}
<|endoftext|>


<commit_before>Ui.Rectangle.extend('Ui.Separator',
/** @lends Ui.Separator# */
{
	/**
	 * @constructs
	 * @class
	 * @extends Ui.Rectangle
	 */
	constructor: function(config) {
		this.setMargin(3);
		this.setHeight(1);
	}
},
/** @lends Ui.Separator# */
{
	onStyleChange: function() {
		this.setFill(this.getStyleProperty('color'));
	}
},
/** @lends Ui.Separator */
{
	style: {
		color: new Ui.Color({ r: 0, g: 0, b: 0 })
	}
});

<commit_msg>change Ui.Separator to allow vertical separator<commit_after>Ui.Rectangle.extend('Ui.Separator',
/** @lends Ui.Separator# */
{
	/**
	 * @constructs
	 * @class
	 * @extends Ui.Rectangle
	 */
	constructor: function(config) {
//		this.setMargin(3);
		this.setHeight(1);
		this.setWidth(1);
	}
},
/** @lends Ui.Separator# */
{
	onStyleChange: function() {
		this.setFill(this.getStyleProperty('color'));
	}
},
/** @lends Ui.Separator */
{
	style: {
		color: new Ui.Color({ r: 0, g: 0, b: 0 })
	}
});

<|endoftext|>


<commit_before>include('helma/webapp/response');
include('helma/engine');
include('helma/jsdoc');
require('core/array');

var log = require('helma/logging').getLogger(module.id);

exports.index = function index(req, module) {
    var repo = new ScriptRepository(getRepositories()[1]);
    if (module && module != "/") {
        var jsdoc = [];
        var res = repo.getScriptResource(module);
        var currentDoc;
        var exported = [];
        parseScriptResource(res, function(node) {
            // loop through all comments looking for dangling jsdocs
            if (node.type == Token.SCRIPT) {
                for each (var comment in node.comments.toArray()) {
                    if (comment.commentType == Token.CommentType.JSDOC) {
                        log.info("found jsdoc comment: " + comment.value);
                    }
                }
            }
            // export("foo")
            if (node.type == Token.CALL && node.target.type == Token.NAME && node.target.string == "export") {
                for each (var arg in ScriptableList(node.arguments)) {
                    if (arg.type == Token.STRING) exported.push(arg.value);
                }
            }
            // var foo = exports.foo = bar
            if (node.type == Token.VAR || node.type == Token.LET) {
                for each (var n in ScriptableList(node.variables)) {
                    if (n.initializer && n.initializer.type == Token.ASSIGN)
                        checkExports(n.initializer, node.jsDoc);
                }
            }
            // exports.foo = bar
            if (node.type == Token.ASSIGN) {
                checkExports(node, node.jsDoc);
            }
            if (node.jsDoc) {
                currentDoc = extractTags(node.jsDoc)
                // log.info(getTypeName(node) + " // " + getName(node));
                // log.info(currentDoc[0][1]);
                jsdoc.push(currentDoc);
            } else {
                // log.info(getTypeName(node) + " // " + getName(node));
                if (isName(node) && getName(node) != "exports" && currentDoc && !currentDoc.name) {
                    Object.defineProperty(currentDoc, 'name', {value: getName(node)});
                }
            }
            return true;
        });
        log.info("export()ed symbols: " + exported);
        return new SkinnedResponse(getResource('./skins/module.html'), {
            title: "Module " + res.moduleName,
            jsdoc: jsdoc
        });
    } else {
        var modules = repo.getScriptResources(true).sort(function(a, b) {
            return a.relativePath > b.relativePath ? 1 : -1;
        });
        return new SkinnedResponse(getResource('./skins/index.html'), {
            title: "API Documentation",
            modules: modules
        });
    }
}

function checkExports(node, jsdoc) {
    if (node.type == Token.ASSIGN) {
        if (node.left.type == Token.GETPROP
                && node.left.target.type == Token.NAME
                && node.left.target.string == "exports") {
            // exports.foo = bar
            log.info(node.left.property.string + ": " + jsdoc);
        } else if (node.left.type == Token.GETELEM
                && node.left.target.type == Token.NAME
                && node.left.target.string == "exports"
                && node.left.element.type == Token.STRING) {
            // exports["foo"] = bar
            log.info(node.left.element.value + ": " + jsdoc);
        }
    }

}
<commit_msg>More baby steps towards jsdoc bliss<commit_after>include('helma/webapp/response');
include('helma/engine');
include('helma/jsdoc');
require('core/array');

var log = require('helma/logging').getLogger(module.id);

exports.index = function index(req, module) {
    var repo = new ScriptRepository(getRepositories()[1]);
    if (module && module != "/") {
        var jsdoc = [];
        var res = repo.getScriptResource(module);
        var currentDoc;
        var exported = [];
        parseScriptResource(res, function(node) {
            // loop through all comments looking for dangling jsdocs
            if (node.type == Token.SCRIPT) {
                for each (var comment in node.comments.toArray()) {
                    if (comment.commentType == Token.CommentType.JSDOC) {
                        // check for top level module doc
                        // log.info("found jsdoc comment: " + comment.value);
                    }
                }
            }
            // export("foo")
            if (node.type == Token.CALL && node.target.type == Token.NAME && node.target.string == "export") {
                for each (var arg in ScriptableList(node.arguments)) {
                    if (arg.type == Token.STRING) exported.push(arg.value);
                }
            }
            // exported function
            if (node.type == Token.FUNCTION && exported.contains(node.name)) {
                log.info("found exported function " + node.name + ": " + node.jsDoc);
            }
            // var foo = exports.foo = bar
            if (node.type == Token.VAR || node.type == Token.LET) {
                for each (var n in ScriptableList(node.variables)) {
                    if (n.initializer && n.initializer.type == Token.ASSIGN)
                        checkExports(n.initializer, node.jsDoc);
                }
            }
            // exports.foo = bar
            if (node.type == Token.ASSIGN) {
                checkAssignment(node, node.jsDoc, exported);
            }
            if (node.jsDoc) {
                currentDoc = extractTags(node.jsDoc)
                // log.info(getTypeName(node) + " // " + getName(node));
                // log.info(currentDoc[0][1]);
                jsdoc.push(currentDoc);
            } else {
                // log.info(getTypeName(node) + " // " + getName(node));
                if (isName(node) && getName(node) != "exports" && currentDoc && !currentDoc.name) {
                    Object.defineProperty(currentDoc, 'name', {value: getName(node)});
                }
            }
            return true;
        });
        log.info("export()ed symbols: " + exported);
        return new SkinnedResponse(getResource('./skins/module.html'), {
            title: "Module " + res.moduleName,
            jsdoc: jsdoc
        });
    } else {
        var modules = repo.getScriptResources(true).sort(function(a, b) {
            return a.relativePath > b.relativePath ? 1 : -1;
        });
        return new SkinnedResponse(getResource('./skins/index.html'), {
            title: "API Documentation",
            modules: modules
        });
    }
}

function checkAssignment(node, jsdoc, exported) {
    if (node.type == Token.ASSIGN) {
        if (node.left.type == Token.GETPROP) {
            var target = node.left.target;
            var name = node.left.property.string;
            var chain = [name];
            while (target.type == Token.GETPROP) {
                chain.unshift(target.property.string);
                target = target.target;
            }
            if (target.type == Token.NAME) {
                chain.unshift(target.string);
                if (target.string == "exports") {
                    // exports.foo = bar
                    log.info(chain.join(".") + ": " + jsdoc);
                    exported.push(name);
                    return;
                }
                log.info(chain.join(".") + " --> " + exported.contains(target.string) + " // " + jsdoc);
            } else if (target.type == Token.THIS) {
                log.info("this." + name + " --> " + jsdoc);
            }
        } else if (node.left.type == Token.GETELEM
                && node.left.target.type == Token.NAME
                && node.left.target.string == "exports"
                && node.left.element.type == Token.STRING) {
            // exports["foo"] = bar
            log.info(node.left.element.value + ": " + jsdoc);
        }
    }

}
<|endoftext|>


<commit_before>import express from 'express';
import gql from 'graphql-tag';

import apolloMiddleware from 'react/apollo/middleware';
import setSeedMiddleware from 'apps/profile/middleware/setSeed';

import Routes from 'apps/profile/Routes';
import withStaticRouter from 'react/hocs/WithStaticRouter';

import profileMetaTagsFragment from 'react/pages/profile/ProfilePage/components/ProfileMetaTags/fragments/profileMetaTags';

const app = express();

const middlewareStack = [
  setSeedMiddleware,
  apolloMiddleware,
];

const extractIdentifiable = (client, id) => {
  const { identifiable } = client.readFragment({
    id: `$ROOT_QUERY.identity({"id":"${id}"})`,
    fragment: gql`
      fragment ProfileTitleAndMeta on Identity {
        identifiable {
          ... ProfileMetaTags
        }
      }
      ${profileMetaTagsFragment}
    `,
    fragmentName: 'ProfileTitleAndMeta',
  });

  return identifiable;
};

const resolve = [
  ...middlewareStack, (req, res, next) => {
    req.apollo.render(withStaticRouter(Routes))
      .then((apollo) => {
        if (apollo.error) throw apollo.error;

        const identifiable = extractIdentifiable(apollo.client, req.params.id);

        if (identifiable.__typename === 'Group') {
          const error = new Error('Not Found');
          error.status = 404;
          throw error;
        }

        const view = req.path.split('/').pop();

        res.render('index', {
          apollo,
          // meta.jade
          view,
          title: identifiable.title,
          name: identifiable.name,
          description: identifiable.description,
          canonical: identifiable.canonical,
          is_indexable: identifiable.is_indexable,
          href: identifiable.href,
        });
      })
      .catch(next);
  },
];

app
  .set('views', __dirname)
  .set('view engine', 'jade')

  .get('/:id/', ...resolve)
  .get('/:id/all', ...resolve)
  .get('/:id/blocks', ...resolve)
  .get('/:id/channels', ...resolve)
  .get('/:id/index', ...resolve)
  .get('/:id/followers', ...resolve)
  .get('/:id/following', ...resolve);

module.exports = app;
<commit_msg>Add route to profile app<commit_after>import express from 'express';
import gql from 'graphql-tag';

import apolloMiddleware from 'react/apollo/middleware';
import setSeedMiddleware from 'apps/profile/middleware/setSeed';

import Routes from 'apps/profile/Routes';
import withStaticRouter from 'react/hocs/WithStaticRouter';

import profileMetaTagsFragment from 'react/pages/profile/ProfilePage/components/ProfileMetaTags/fragments/profileMetaTags';

const app = express();

const middlewareStack = [
  setSeedMiddleware,
  apolloMiddleware,
];

const extractIdentifiable = (client, id) => {
  const { identifiable } = client.readFragment({
    id: `$ROOT_QUERY.identity({"id":"${id}"})`,
    fragment: gql`
      fragment ProfileTitleAndMeta on Identity {
        identifiable {
          ... ProfileMetaTags
        }
      }
      ${profileMetaTagsFragment}
    `,
    fragmentName: 'ProfileTitleAndMeta',
  });

  return identifiable;
};

const resolve = [
  ...middlewareStack, (req, res, next) => {
    req.apollo.render(withStaticRouter(Routes))
      .then((apollo) => {
        if (apollo.error) throw apollo.error;

        const identifiable = extractIdentifiable(apollo.client, req.params.id);

        if (identifiable.__typename === 'Group') {
          const error = new Error('Not Found');
          error.status = 404;
          throw error;
        }

        const view = req.path.split('/').pop();

        res.render('index', {
          apollo,
          // meta.jade
          view,
          title: identifiable.title,
          name: identifiable.name,
          description: identifiable.description,
          canonical: identifiable.canonical,
          is_indexable: identifiable.is_indexable,
          href: identifiable.href,
        });
      })
      .catch(next);
  },
];

app
  .set('views', __dirname)
  .set('view engine', 'jade')

  .get('/:id/', ...resolve)
  .get('/:id/all', ...resolve)
  .get('/:id/blocks', ...resolve)
  .get('/:id/channels', ...resolve)
  .get('/:id/index', ...resolve)
  .get('/:id/groups', ...resolve)
  .get('/:id/followers', ...resolve)
  .get('/:id/following', ...resolve);

module.exports = app;
<|endoftext|>