<commit_before>define([
    'bluebird',
    'kb_common/html',
    'kb_common/domEvent',
    'kb_service/client/workspace',
    'bootstrap'
], function (
    Promise,
    html,
    DomEvents,
    Workspace
) {
    var t = html.tag,
        div = t('div'),
        h2 = t('h2'),
        ul = t('ul'),
        li = t('li'),
        a = t('a'),
        table = t('table'),
        tr = t('tr'),
        th = t('th'),
        td = t('td'),
        button = t('button'),
        form = t('form'),
        select = t('select'),
        option = t('option'),
        p = t('p'),
        iframe = t('iframe');

    function factory(config) {
        var hostNode, container,
            runtime = config.runtime;

        function attach(node) {
            return Promise.try(function () {
                hostNode = node;
                container = hostNode.appendChild(document.createElement('div'));
            });
        }

        function buildHtmlDoc() {
            var t = html.tag,
                htmlTag = t('html'),
                head = t('head'),
                body = t('body'),
                script = t('script');
            return 'not yet';
            var clientId = '295942161521-qhsqomsg7629f861s60kdvc9kr2tqm1b.apps.googleusercontent.com';
            return htmlTag([
                head([
                    script({
                        src: 'https://apis.google.com/js/platform.js',
                        async: true,
                        defer: true
                    })
                ]),
                body({
                    style: {
                        margin: '0px',
                        padding: '0px',
                        overflow: 'auto'
                    }
                }, [
                    script([
                        'gapi.client.init({',
                        ' clientId: ' + clientId + ',',
                        '})',
                        '.then'
                    ])
                ])
            ]);
        }

        function render(events, token, sessionInfo, tokenIntrospection, accountInfo, wsInfo) {
            var iframeContent = buildHtmlDoc().replace(/"/g, '"')
            return Promise.try(function () {
                    return div({
                        class: 'container-fluid'
                    }, [
                        div({
                            class: 'row'
                        }, [
                            div({
                                class: 'col-md-12'
                            }, [
                                h2('Auth2 Info'),
                                table({
                                    class: 'table table-striped'
                                }, [
                                    tr([
                                        th('Token'),
                                        td(token)
                                    ]),
                                    tr([
                                        th('Session'),
                                        td(sessionInfo)
                                    ]),
                                    tr([
                                        th('Introspection'),
                                        td(div([
                                            p('Results of the call to the auth2 "introspection" method.'),
                                            tokenIntrospection
                                        ]))
                                    ]),
                                    tr([
                                        th('Account'),
                                         td(div([
                                            p('Results of the call to the auth2 "me" method.'),
                                            accountInfo
                                        ]))
                                    ]),
                                    tr([
                                        th('Account'),
                                        td(wsInfo)
                                    ]),
                                    tr([
                                        th('Authorized?'),
                                        td(runtime.service('session').isLoggedIn() ? 'yes' : 'no')
                                    ])
                                ])
                                // div({
                                //     style: {
                                //         border: '2px red solid'
                                //     }
                                // }, [
                                //     iframe({
                                //         srcdoc: iframeContent
                                //     })
                                // ])
                            ])
                        ])
                    ]);
                })
                .catch(function (err) {
                    return err.message;
                });
        }

        function buildPresentableJson(data) {
            switch (typeof data) {
            case 'string':
                return data;
            case 'number':
                return String(data);
            case 'boolean':
                return String(data);
            case 'object':
                if (data === null) {
                    return 'NULL';
                }
                if (data instanceof Array) {
                    return table({ class: 'table table-striped' },
                        data.map(function (datum, index) {
                            return tr([
                                th(String(index)),
                                td(buildPresentableJson(datum))
                            ]);
                        }).join('\n')
                    );
                }
                return table({ class: 'table table-striped' },
                    Object.keys(data).map(function (key) {
                        return tr([th(key), td(buildPresentableJson(data[key]))]);
                    }).join('\n')
                );
            default:
                return 'Not representable: ' + (typeof data);
            }
        }

        function doLogin() {
            var auth2 = Auth2.make({
                cookieName: runtime.config('services.auth2.cookieName'),
                authBaseUrl: runtime.config('services.auth2.url')
            });
            var providerSelect = document.querySelector('[data-element="login-form"] [name="provider"]');
            var providerId = providerSelect.item(providerSelect.selectedIndex).value;

            auth2.login({
                redirectUrl: 'https://authdev.kbase.us#auth2/login/success',
                provider: providerId,
                stayLoggedIn: false,
                node: container
            });
        }

        function doLogout() {
            var auth2 = Auth2.make({
                cookieName: runtime.config('services.auth2.cookieName'),
                authBaseUrl: runtime.config('services.auth2.url')
            });
            auth2.logout({
                redirectUrl: 'https://authdev.kbase.us#auth2/login/success'
            });
        }

        function renderForm() {
            var form = html.tag('form'),
                input = html.tag('input'),
                button = html.tag('button'),
                div = html.tag('div'),
                p = html.tag('p'),
                h1 = html.tag('h1'),
                legend = html.tag('legend'),
                i = html.tag('i'),
                a = html.tag('a');

            /* TODO: use the actual next path */
            // Variables for form.
            var nextPath = 'next path',
                nextURL = 'next url';

            // eventMan.reset();
            // var doodlePath = Plugin.plugin.fullPath + '/doodle.png';

            return div({ class: 'container', style: 'margin-top: 4em', dataWidget: 'login' }, [
                div({}, [
                    div({
                        style: {
                            position: 'absolute',
                            // backgroundImage: 'url(' + doodlePath + ')',
                            // backgroundRepeat: 'no-repeat',
                            // backgroundSize: '35%',
                            top: '0',
                            left: '0',
                            bottom: '0',
                            right: '0',
                            opacity: '0.1',
                            zIndex: '-1000'
                        }
                    })
                ]),
                div({ class: 'row' }, [
                    div({ class: 'col-sm-7 col-sm-offset-1' }, [
                        h1({ style: 'font-size:1.6em' }, ['Welcome to KBase']),
                        p([
                            'After signing in, you can start working with KBase. Upload your experimental data and perform comparative genomics and systems biology analyses by creating ',
                            i('Narratives'),
                            ': interactive, dynamic, and shareable documents. Narratives include all your analysis steps, commentary, and visualizations.'
                        ]),
                        p([
                            'Want to learn more?  Check out the ',
                            a({ href: runtime.config('resources.documentation.narrativeGuide.url') }, 'Narrative Interface User Guide'),
                            ' or the ',
                            a({ href: 'https://youtu.be/6ql7HAUzU7U' }, 'Narrative Interface video tutorial'),
                            ', and a ',
                            a({ href: runtime.config('resources.documentation.tutorials.url') }, 'library of tutorials'),
                            ' that show you how to use various KBase apps to analyze your data.'
                        ])
                    ]),
                    div({ class: 'col-sm-3' }, [
                        div({ class: 'well well-kbase' }, [
                            form({ class: 'form login-form', id: events.addEvent('submit', handleLogin) }, [
                                input({ type: 'hidden', value: nextPath }),
                                input({ type: 'hidden', value: nextURL }),
                                legend({ style: 'text-align: center' }, 'KBase Sign In'),
                                div({ class: 'form-group' }, [
                                    input({ name: 'username', type: 'text', placeholder: 'username', id: events.addEvent('keyup', handleUsernameKeyup), dataElement: 'username', autocomplete: 'off', class: 'form-control form-control-kbase', tabindex: '1' }),
                                    div({ dataElement: 'username-message', class: 'alert', style: { display: 'none' } })
                                ]),
                                div({ class: 'form-group' }, [
                                    input({ name: 'password', type: 'password', placeholder: 'password', id: 'kbase_password', dataElement: 'password', autocomplete: 'off', class: 'form-control form-control-kbase', tabindex: '2' })
                                ]),
                                div({ class: 'form-group' }, [
                                    button({ id: 'signinbtn', type: 'submit', class: 'btn btn-primary btn-block btn-kbase', tabindex: '3', 'data-element': 'sign-in' }, [
                                        i({ class: 'fa fa-sign-in', style: 'margin-right: 1em;' }),
                                        'Sign In'
                                    ]),
                                    button({ id: 'signinbtn', type: 'submit', class: 'btn btn-primary btn-block btn-kbase', style: 'display:none;', tabindex: '3', 'data-element': 'signing-in' }, [
                                        i({ class: 'fa fa-spinner fa-spin', style: 'margin-right: 1em;' }),
                                        'Signing In...'
                                    ]),
                                    div({ 'data-element': 'error', class: 'alert alert-danger alert-kbase', style: 'display:none; margin-top: 1em' })
                                ]),
                                div({ class: 'form-group', style: 'margin-top: 3em; margin-bottom: 0;' }, [
                                    a({ target: '_blank', href: runtime.config('resources.userAccount.signUp.url'), class: 'btn btn-block btn-link' }, 'New to KBase? Sign Up'),
                                    a({ target: '_blank', href: runtime.config('resources.userAccount.resetPassword.url'), class: 'btn btn-block btn-link' }, 'Forgot your password?'),
                                    a({ target: '_blank', href: runtime.config('resources.documentation.loginHelp.url'), class: 'btn btn-block btn-link' }, 'Help')
                                ])
                            ])
                        ])
                    ])
                ])
            ]);

        }

        function buildError(err) {
            return div({
                class: 'container-fluid'
            }, [
                div({
                    class: 'row'
                }, [
                    div({
                        class: 'col-md-12'
                    }, [
                        div({
                            class: 'alert alert-danger'
                        }, err.message || (err.error && err.error.message))
                    ])
                ])
            ]);
        }

        function buildMessage(message) {
            return div({
                class: 'container-fluid'
            }, [
                div({
                    class: 'row'
                }, [
                    div({
                        class: 'col-md-12'
                    }, [
                         div({
                            class: 'alert alert-warning'
                        }, message)
                    ])
                ])
            ]);
        }

        function start() {
            return Promise.try(function () {
                var events = DomEvents.make({
                    node: container
                });
                var auth2 = runtime.service('session');
                var token = auth2.getAuthToken();
                runtime.send('ui', 'setTitle', 'Auth2 Info');

                if (!token) {
                    container.innerHTML = buildMessage('Sorry, you do not have a token');
                    return;
                }

                var sessionInfo = {
                    username: runtime.service('session').getUsername(),
                    realname: runtime.service('session').getRealname(),
                    created: 'n/a',
                    lifetime: 'n/a',
                    sessionTimeLeft: 'n/a',
                };

                Promise.all([
                    auth2.getIntrospection(),
                    auth2.getAccount(),
                    'n/a'
                ])
                .spread(function (tokenInfo, accountInfo, wsInfo) {
                        return render(events, token, buildPresentableJson(sessionInfo), buildPresentableJson(tokenInfo), buildPresentableJson(accountInfo), buildPresentableJson(wsInfo))
                    })
                    .then(function (content) {
                        container.innerHTML = content;
                        events.attachEvents();
                    })
                    .catch(function (err) {
                        console.error('ERROR', err);
                        container.innerHTML = buildError(err);
                    });

            });
        }

        function stop() {
            return Promise.try(function () {

            });
        }

        function detach() {
            return Promise.try(function () {
                if (hostNode && container) {
                    hostNode.removeChild(container);
                }
            });
        }

        return {
            attach: attach,
            start: start,
            stop: stop,
            detach: detach
        };
    }

    return {
        make: function (config) {
            return factory(config);
        }
    };
});<commit_msg>api change: getIntrospection -> getTokenInfo<commit_after>define([
    'bluebird',
    'kb_common/html',
    'kb_common/domEvent',
    'kb_service/client/workspace',
    'bootstrap'
], function (
    Promise,
    html,
    DomEvents,
    Workspace
) {
    var t = html.tag,
        div = t('div'),
        h2 = t('h2'),
        ul = t('ul'),
        li = t('li'),
        a = t('a'),
        table = t('table'),
        tr = t('tr'),
        th = t('th'),
        td = t('td'),
        button = t('button'),
        form = t('form'),
        select = t('select'),
        option = t('option'),
        p = t('p'),
        iframe = t('iframe');

    function factory(config) {
        var hostNode, container,
            runtime = config.runtime;

        function attach(node) {
            return Promise.try(function () {
                hostNode = node;
                container = hostNode.appendChild(document.createElement('div'));
            });
        }

        function buildHtmlDoc() {
            var t = html.tag,
                htmlTag = t('html'),
                head = t('head'),
                body = t('body'),
                script = t('script');
            return 'not yet';
            var clientId = '295942161521-qhsqomsg7629f861s60kdvc9kr2tqm1b.apps.googleusercontent.com';
            return htmlTag([
                head([
                    script({
                        src: 'https://apis.google.com/js/platform.js',
                        async: true,
                        defer: true
                    })
                ]),
                body({
                    style: {
                        margin: '0px',
                        padding: '0px',
                        overflow: 'auto'
                    }
                }, [
                    script([
                        'gapi.client.init({',
                        ' clientId: ' + clientId + ',',
                        '})',
                        '.then'
                    ])
                ])
            ]);
        }

        function render(events, token, sessionInfo, tokenIntrospection, accountInfo, wsInfo) {
            var iframeContent = buildHtmlDoc().replace(/"/g, '"')
            return Promise.try(function () {
                    return div({
                        class: 'container-fluid'
                    }, [
                        div({
                            class: 'row'
                        }, [
                            div({
                                class: 'col-md-12'
                            }, [
                                h2('Auth2 Info'),
                                table({
                                    class: 'table table-striped'
                                }, [
                                    tr([
                                        th('Token'),
                                        td(token)
                                    ]),
                                    tr([
                                        th('Session'),
                                        td(sessionInfo)
                                    ]),
                                    tr([
                                        th('Introspection'),
                                        td(div([
                                            p('Results of the call to the auth2 "introspection" method.'),
                                            tokenIntrospection
                                        ]))
                                    ]),
                                    tr([
                                        th('Account'),
                                         td(div([
                                            p('Results of the call to the auth2 "me" method.'),
                                            accountInfo
                                        ]))
                                    ]),
                                    tr([
                                        th('Account'),
                                        td(wsInfo)
                                    ]),
                                    tr([
                                        th('Authorized?'),
                                        td(runtime.service('session').isLoggedIn() ? 'yes' : 'no')
                                    ])
                                ])
                                // div({
                                //     style: {
                                //         border: '2px red solid'
                                //     }
                                // }, [
                                //     iframe({
                                //         srcdoc: iframeContent
                                //     })
                                // ])
                            ])
                        ])
                    ]);
                })
                .catch(function (err) {
                    return err.message;
                });
        }

        function buildPresentableJson(data) {
            switch (typeof data) {
            case 'string':
                return data;
            case 'number':
                return String(data);
            case 'boolean':
                return String(data);
            case 'object':
                if (data === null) {
                    return 'NULL';
                }
                if (data instanceof Array) {
                    return table({ class: 'table table-striped' },
                        data.map(function (datum, index) {
                            return tr([
                                th(String(index)),
                                td(buildPresentableJson(datum))
                            ]);
                        }).join('\n')
                    );
                }
                return table({ class: 'table table-striped' },
                    Object.keys(data).map(function (key) {
                        return tr([th(key), td(buildPresentableJson(data[key]))]);
                    }).join('\n')
                );
            default:
                return 'Not representable: ' + (typeof data);
            }
        }

        function doLogin() {
            var auth2 = Auth2.make({
                cookieName: runtime.config('services.auth2.cookieName'),
                authBaseUrl: runtime.config('services.auth2.url')
            });
            var providerSelect = document.querySelector('[data-element="login-form"] [name="provider"]');
            var providerId = providerSelect.item(providerSelect.selectedIndex).value;

            auth2.login({
                redirectUrl: 'https://authdev.kbase.us#auth2/login/success',
                provider: providerId,
                stayLoggedIn: false,
                node: container
            });
        }

        function doLogout() {
            var auth2 = Auth2.make({
                cookieName: runtime.config('services.auth2.cookieName'),
                authBaseUrl: runtime.config('services.auth2.url')
            });
            auth2.logout({
                redirectUrl: 'https://authdev.kbase.us#auth2/login/success'
            });
        }

        function renderForm() {
            var form = html.tag('form'),
                input = html.tag('input'),
                button = html.tag('button'),
                div = html.tag('div'),
                p = html.tag('p'),
                h1 = html.tag('h1'),
                legend = html.tag('legend'),
                i = html.tag('i'),
                a = html.tag('a');

            /* TODO: use the actual next path */
            // Variables for form.
            var nextPath = 'next path',
                nextURL = 'next url';

            // eventMan.reset();
            // var doodlePath = Plugin.plugin.fullPath + '/doodle.png';

            return div({ class: 'container', style: 'margin-top: 4em', dataWidget: 'login' }, [
                div({}, [
                    div({
                        style: {
                            position: 'absolute',
                            // backgroundImage: 'url(' + doodlePath + ')',
                            // backgroundRepeat: 'no-repeat',
                            // backgroundSize: '35%',
                            top: '0',
                            left: '0',
                            bottom: '0',
                            right: '0',
                            opacity: '0.1',
                            zIndex: '-1000'
                        }
                    })
                ]),
                div({ class: 'row' }, [
                    div({ class: 'col-sm-7 col-sm-offset-1' }, [
                        h1({ style: 'font-size:1.6em' }, ['Welcome to KBase']),
                        p([
                            'After signing in, you can start working with KBase. Upload your experimental data and perform comparative genomics and systems biology analyses by creating ',
                            i('Narratives'),
                            ': interactive, dynamic, and shareable documents. Narratives include all your analysis steps, commentary, and visualizations.'
                        ]),
                        p([
                            'Want to learn more?  Check out the ',
                            a({ href: runtime.config('resources.documentation.narrativeGuide.url') }, 'Narrative Interface User Guide'),
                            ' or the ',
                            a({ href: 'https://youtu.be/6ql7HAUzU7U' }, 'Narrative Interface video tutorial'),
                            ', and a ',
                            a({ href: runtime.config('resources.documentation.tutorials.url') }, 'library of tutorials'),
                            ' that show you how to use various KBase apps to analyze your data.'
                        ])
                    ]),
                    div({ class: 'col-sm-3' }, [
                        div({ class: 'well well-kbase' }, [
                            form({ class: 'form login-form', id: events.addEvent('submit', handleLogin) }, [
                                input({ type: 'hidden', value: nextPath }),
                                input({ type: 'hidden', value: nextURL }),
                                legend({ style: 'text-align: center' }, 'KBase Sign In'),
                                div({ class: 'form-group' }, [
                                    input({ name: 'username', type: 'text', placeholder: 'username', id: events.addEvent('keyup', handleUsernameKeyup), dataElement: 'username', autocomplete: 'off', class: 'form-control form-control-kbase', tabindex: '1' }),
                                    div({ dataElement: 'username-message', class: 'alert', style: { display: 'none' } })
                                ]),
                                div({ class: 'form-group' }, [
                                    input({ name: 'password', type: 'password', placeholder: 'password', id: 'kbase_password', dataElement: 'password', autocomplete: 'off', class: 'form-control form-control-kbase', tabindex: '2' })
                                ]),
                                div({ class: 'form-group' }, [
                                    button({ id: 'signinbtn', type: 'submit', class: 'btn btn-primary btn-block btn-kbase', tabindex: '3', 'data-element': 'sign-in' }, [
                                        i({ class: 'fa fa-sign-in', style: 'margin-right: 1em;' }),
                                        'Sign In'
                                    ]),
                                    button({ id: 'signinbtn', type: 'submit', class: 'btn btn-primary btn-block btn-kbase', style: 'display:none;', tabindex: '3', 'data-element': 'signing-in' }, [
                                        i({ class: 'fa fa-spinner fa-spin', style: 'margin-right: 1em;' }),
                                        'Signing In...'
                                    ]),
                                    div({ 'data-element': 'error', class: 'alert alert-danger alert-kbase', style: 'display:none; margin-top: 1em' })
                                ]),
                                div({ class: 'form-group', style: 'margin-top: 3em; margin-bottom: 0;' }, [
                                    a({ target: '_blank', href: runtime.config('resources.userAccount.signUp.url'), class: 'btn btn-block btn-link' }, 'New to KBase? Sign Up'),
                                    a({ target: '_blank', href: runtime.config('resources.userAccount.resetPassword.url'), class: 'btn btn-block btn-link' }, 'Forgot your password?'),
                                    a({ target: '_blank', href: runtime.config('resources.documentation.loginHelp.url'), class: 'btn btn-block btn-link' }, 'Help')
                                ])
                            ])
                        ])
                    ])
                ])
            ]);

        }

        function buildError(err) {
            return div({
                class: 'container-fluid'
            }, [
                div({
                    class: 'row'
                }, [
                    div({
                        class: 'col-md-12'
                    }, [
                        div({
                            class: 'alert alert-danger'
                        }, err.message || (err.error && err.error.message))
                    ])
                ])
            ]);
        }

        function buildMessage(message) {
            return div({
                class: 'container-fluid'
            }, [
                div({
                    class: 'row'
                }, [
                    div({
                        class: 'col-md-12'
                    }, [
                         div({
                            class: 'alert alert-warning'
                        }, message)
                    ])
                ])
            ]);
        }

        function start() {
            return Promise.try(function () {
                var events = DomEvents.make({
                    node: container
                });
                var auth2 = runtime.service('session');
                var token = auth2.getAuthToken();
                runtime.send('ui', 'setTitle', 'Auth2 Info');

                if (!token) {
                    container.innerHTML = buildMessage('Sorry, you do not have a token');
                    return;
                }

                var sessionInfo = {
                    username: runtime.service('session').getUsername(),
                    realname: runtime.service('session').getRealname(),
                    created: 'n/a',
                    lifetime: 'n/a',
                    sessionTimeLeft: 'n/a',
                };

                Promise.all([
                    auth2.getTokenInfo(),
                    auth2.getAccount(),
                    'n/a'
                ])
                .spread(function (tokenInfo, accountInfo, wsInfo) {
                        return render(events, token, buildPresentableJson(sessionInfo), buildPresentableJson(tokenInfo), buildPresentableJson(accountInfo), buildPresentableJson(wsInfo))
                    })
                    .then(function (content) {
                        container.innerHTML = content;
                        events.attachEvents();
                    })
                    .catch(function (err) {
                        console.error('ERROR', err);
                        container.innerHTML = buildError(err);
                    });

            });
        }

        function stop() {
            return Promise.try(function () {

            });
        }

        function detach() {
            return Promise.try(function () {
                if (hostNode && container) {
                    hostNode.removeChild(container);
                }
            });
        }

        return {
            attach: attach,
            start: start,
            stop: stop,
            detach: detach
        };
    }

    return {
        make: function (config) {
            return factory(config);
        }
    };
});<|endoftext|>


<commit_before>// import Utils from '../core/Utils'
import Plugin from './Plugin'
// temporarily using superagent
import request from 'superagent'

export default class Drive extends Plugin {
  constructor (core, opts) {
    super(core, opts)
    this.type = 'selecter'
    this.authenticate = this.authenticate.bind(this)
    this.connect = this.connect.bind(this)
    this.render = this.render.bind(this)
    this.renderAuthentication = this.renderAuthentication.bind(this)
    this.checkAuthentication = this.checkAuthentication.bind(this)
    this.files = []
    this.currentDir = '/'

    this.checkAuthentication()
  }

  connect (target) {
    if (!this.isAuthenticated) {
      target.innerHTML = this.renderAuthentication()
    } else {
      this.getDirectory()
      .then(this.render)
    }
  }

  checkAuthentication () {
    fetch('http://localhost:3002/drive/auth/authorize', {
      method: 'get',
      credentials: 'include',
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json'
      }
    })
    .then(res => {
      if (res.status >= 200 && res.status <= 300) {
        return res.json().then(data => {
          this.isAuthenticated = data.isAuthenticated
          this.authUrl = data.authUrl
        })
      } else {
        let error = new Error(response.statusText)
        error.response = res
        throw error
      }
    })
  }

  authenticate () {
  }

  addFile () {

  }

  getDirectory () {
    fetch('http://localhost:3002/drive/get', {
      method: 'get',
      credentials: 'include',
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json'
      }
    })
    .then(res => {
      if (res.status >= 200 && res.status <= 300) {
        return res.json().then(data => {
          console.log(data)
        })
      }
    })
  }

  run (results) {

  }

  renderAuthentication () {
    return `<div><h1>Authenticate With Google Drive</h1><a href=${ this.authUrl || '#' }>Authenticate</a></div>`
  }

  render (files) {
    // for each file in the directory, create a list item element
    const elems = files.map((file, i) => {
      const icon = (file.isFolder) ? 'folder' : 'file'
      return `<li data-type="${icon}" data-name="${file.name}"><span>${icon}: </span><span> ${file.name}</span></li>`
    })

    // appends the list items to the target
    this._target.innerHTML = elems.sort().join('')

    if (this.currentDir.length > 1) {
      const parent = document.createElement('LI')
      parent.setAttribute('data-type', 'parent')
      parent.innerHTML = '...'
      this._target.appendChild(parent)
    }

    // add an onClick to each list item
    const fileElems = this._target.querySelectorAll('li')

    Array.prototype.forEach.call(fileElems, element => {
      const type = element.getAttribute('data-type')

      if (type === 'file') {
        element.addEventListener('click', () => {
          this.files.push(element.getAttribute('data-name'))
          console.log(`files: ${this.files}`)
        })
      } else {
        element.addEventListener('dblclick', () => {
          const length = this.currentDir.split('/').length

          if (type === 'folder') {
            this.currentDir = `${this.currentDir}${element.getAttribute('data-name')}/`
          } else if (type === 'parent') {
            this.currentDir = `${this.currentDir.split('/').slice(0, length - 2).join('/')}/`
          }
          console.log(this.currentDir)
          this.getDirectory()
        })
      }
    })
  }
}
<commit_msg>Lint.<commit_after>// import Utils from '../core/Utils'
import Plugin from './Plugin'

export default class Drive extends Plugin {
  constructor (core, opts) {
    super(core, opts)
    this.type = 'selecter'
    this.authenticate = this.authenticate.bind(this)
    this.connect = this.connect.bind(this)
    this.render = this.render.bind(this)
    this.renderAuthentication = this.renderAuthentication.bind(this)
    this.checkAuthentication = this.checkAuthentication.bind(this)
    this.files = []
    this.currentDir = '/'

    this.checkAuthentication()
  }

  connect (target) {
    if (!this.isAuthenticated) {
      target.innerHTML = this.renderAuthentication()
    } else {
      this.getDirectory()
      .then(this.render)
    }
  }

  checkAuthentication () {
    fetch('http://localhost:3002/drive/auth/authorize', {
      method: 'get',
      credentials: 'include',
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json'
      }
    })
    .then(res => {
      if (res.status >= 200 && res.status <= 300) {
        return res.json().then(data => {
          this.isAuthenticated = data.isAuthenticated
          this.authUrl = data.authUrl
        })
      } else {
        let error = new Error(res.statusText)
        error.response = res
        throw error
      }
    })
  }

  authenticate () {
  }

  addFile () {

  }

  getDirectory () {
    fetch('http://localhost:3002/drive/get', {
      method: 'get',
      credentials: 'include',
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json'
      }
    })
    .then(res => {
      if (res.status >= 200 && res.status <= 300) {
        return res.json().then(data => {
          console.log(data)
        })
      }
    })
  }

  run (results) {

  }

  renderAuthentication () {
    return `<div><h1>Authenticate With Google Drive</h1><a href=${ this.authUrl || '#' }>Authenticate</a></div>`
  }

  render (files) {
    // for each file in the directory, create a list item element
    const elems = files.map((file, i) => {
      const icon = (file.isFolder) ? 'folder' : 'file'
      return `<li data-type="${icon}" data-name="${file.name}"><span>${icon}: </span><span> ${file.name}</span></li>`
    })

    // appends the list items to the target
    this._target.innerHTML = elems.sort().join('')

    if (this.currentDir.length > 1) {
      const parent = document.createElement('LI')
      parent.setAttribute('data-type', 'parent')
      parent.innerHTML = '...'
      this._target.appendChild(parent)
    }

    // add an onClick to each list item
    const fileElems = this._target.querySelectorAll('li')

    Array.prototype.forEach.call(fileElems, element => {
      const type = element.getAttribute('data-type')

      if (type === 'file') {
        element.addEventListener('click', () => {
          this.files.push(element.getAttribute('data-name'))
          console.log(`files: ${this.files}`)
        })
      } else {
        element.addEventListener('dblclick', () => {
          const length = this.currentDir.split('/').length

          if (type === 'folder') {
            this.currentDir = `${this.currentDir}${element.getAttribute('data-name')}/`
          } else if (type === 'parent') {
            this.currentDir = `${this.currentDir.split('/').slice(0, length - 2).join('/')}/`
          }
          console.log(this.currentDir)
          this.getDirectory()
        })
      }
    })
  }
}
<|endoftext|>


<commit_before>var newButton;
var editor = [];
var menu;
var fileEntry;
var hasWriteAcces, output, html, css, js;

const {
	remote,
	clipboard
} = require('electron');

const {
	Menu,
	MenuItem,
	dialog
} = remote;
const fs = require("fs");

//Global variables
var scripts = "";
var styles = "";

//Functions for AddIns
const getScr = () => scripts;

const getSty = () => styles;

function newFile() {
	fileEntry = null;
	hasWriteAccess = false;
}

function setFile(theFileEntry, isWritable) {
	fileEntry = theFileEntry;
	hasWriteAccess = isWritable;
}

function handleNewButton(i) {
	if (false) {
		newFile();
		editor[i].setValue("");
	} else {
		window.open('file://' + __dirname + '/index.html');
	}
}

//Context menu init()
function initContextMenu(i) {
	menu = new Menu();
	menu.append(new MenuItem({
		label: 'Copy',
		click: function () {
			clipboard.writeText(editor[i].getSelection(), 'copy');
		}
	}));
	menu.append(new MenuItem({
		label: 'Cut',
		click: function () {
			clipboard.writeText(editor[i].getSelection(), 'copy');
			editor[i].replaceSelection('');
		}
	}));
	menu.append(new MenuItem({
		label: 'Paste',
		click: function () {
			editor[i].replaceSelection(clipboard.readText('copy'));
		}
	}));

	window.addEventListener('contextmenu', function (ev) {
		ev.preventDefault();
		menu.popup(remote.getCurrentWindow(), ev.x, ev.y);
	}, false);
}

//Main Functions for Electron
onload = function () {
	initContextMenu();

	document.getElementById("min-button").addEventListener("click", function (e) {
		const window = remote.getCurrentWindow();
		window.minimize();
		console.log('Minimize Triggered!');
	});

	document.getElementById("max-button").addEventListener("click", function (e) {
		const window = remote.getCurrentWindow();
		if (!window.isMaximized()) {
			window.maximize();
		} else {
			window.unmaximize();
		}
		console.log('Maximize Triggered!');
		console.log(document.getElementById('close-button'));
	});

	document.getElementById("close-button").addEventListener("click", function (e) {
		const window = remote.getCurrentWindow();
		window.close();
	});

	document.getElementById("close-window").addEventListener("click", function (e) {
		const window = remote.getCurrentWindow();
		window.close();
	});
	document.getElementById("new").addEventListener("click", handleNewButton);

	editor[0] = CodeMirror(
		document.getElementById("html-editor"), {
			mode: {
				name: "htmlmixed",
			},
			lineNumbers: true,
			lineWrapping: true,
			autofocus: true,
			indentWithTabs: true,
			scrollbarStyle: "overlay",
			theme: "base16-ocean-dark"
		});

	editor[1] = CodeMirror(
		document.getElementById("css-editor"), {
			mode: {
				name: "css",
			},
			lineNumbers: true,
			lineWrapping: true,
			indentWithTabs: true,
			//Having issues with smartIndent. Therfore, turned off.
			smartIndent: false,
			scrollbarStyle: "overlay",
			theme: "base16-ocean-dark"
		});

	editor[2] = CodeMirror(
		document.getElementById("js-editor"), {
			mode: {
				name: "javascript",
				json: true
			},
			lineNumbers: true,
			lineWrapping: true,
			indentWithTabs: true,
			scrollbarStyle: "overlay",
			theme: "base16-ocean-dark"
		});

	output = document.getElementById("output");

	html = editor[0];
	css = editor[1];
	js = editor[2];

	addScript();
	addStyle();
	newFile();
	onresize();
};

onresize = function () {
	for (i = 0; i < 3; i++)
		editor[i].refresh();
}

function paint(script, style) {
	outputSource = '' + '' + style + '' + '' + '' + html.getValue() + script + '' + '' + '';
	console.log(outputSource);
	output.srcdoc = outputSource;
}

function paint(script,style) {
	outputSource = '' + ''+ style + '' + '' + '' + html.getValue() + script +  '' + '' + '';
	console.log(outputSource);
	output.srcdoc = outputSource;
}

// TODO: Use CodeMirror.change instead
document.addEventListener("keyup", function (e) {
	scr = getScr();
	sty = getSty();
	paint(scr,sty);
});

// TODO: Limit execution to 1 ❌
// DONE: All JS and CSS can be added at once ✔
// TODO: Append all Js libraries to inUse[] and refresh outputSource ❌
// TODO: Scripts added in order they are clicked no way to change order later on
function addScript() {
	var JSMemu = document.getElementById("JSMenu");
	var JSbuttons = JSMemu.getElementsByTagName('a');
	var ScrFlags = [0,0,0];
	JSbuttons[0].addEventListener("click", function (e) {
		console.log("JS 0");
		if(ScrFlags[1] === 0)
		{
			var jQStr = ""
			scripts += bootjsStr;
			ScrFlags[0] = 1;
			console.log("Bootstrap added!");
		}
	});
	JSbuttons[1].addEventListener("click", function (e) {
		console.log("JS 1");
		if(ScrFlags[1] === 0)
		{
			var jQStr = ""
			scripts += jQStr;
			ScrFlags[1] = 1;
			console.log("jQuery added!");
		}
	});
	JSbuttons[2].addEventListener("click", function (e) {
		console.log("JS 2");
		if(ScrFlags[2] === 0)
		{
			var js3Str = ""
			scripts += js3Str;
			ScrFlags[2] = 1;
			console.log("Three.js added!");
		}
	});
};

function addStyle() {
	var CSSMenu = document.getElementById("CSSMenu");
	var CSSbuttons = CSSMenu.getElementsByTagName('a');
	var StyFlags = [0,0,0,0];
	CSSbuttons[0].addEventListener("click", function (e) {
		console.log("CSS 0");
		if(StyFlags[0] === 0)
		{
			var aniStr = "<link rel='stylesheet' type='text/css' href='lib/animate.css'>"
			styles += aniStr;
			StyFlags[0] = 1;
			console.log("Animate added!");
		}
	});
	CSSbuttons[1].addEventListener("click", function (e) {
		console.log("CSS 1");
		if(StyFlags[1] === 1)
		{
			var bootStr = "<link rel='stylesheet' type='text/css' href='lib/bootstrap.min.css'>";
			styles += bootStr;
			StyFlags[1] = 1;
			console.log("Bootstrap added!");
		}
	});
	CSSbuttons[2].addEventListener("click", function (e) {
		console.log("CSS 2");
		if(StyFlags[2] === 0)
		{
			var faStr = "<link rel='stylesheet' type='text/css' href='lib/font-awesome.min.css'>"
			styles += fsStr;
			StyFlags[2] = 1;
			console.log("Font Awesome added!");
		}
	});
	CSSbuttons[3].addEventListener("click", function (e) {
		console.log("CSS 3");
		if(StyFlags[3] === 0)
		{
			var matStr = "<link href='lib/materialize.min.css'>"
			styles += matStr;
			StyFlags[3] = 1;
			console.log("Materialize added!");
		}
	});
};<commit_msg>minor fixes<commit_after>var newButton;
var editor = [];
var menu;
var fileEntry;
var hasWriteAcces, output, html, css, js;

const {
	remote,
	clipboard
} = require('electron');

const {
	Menu,
	MenuItem,
	dialog
} = remote;
const fs = require("fs");

//Global variables
var scripts = "";
var styles = "";

//Functions for AddIns
const getScr = () => scripts;

const getSty = () => styles;

function newFile() {
	fileEntry = null;
	hasWriteAccess = false;
}

function setFile(theFileEntry, isWritable) {
	fileEntry = theFileEntry;
	hasWriteAccess = isWritable;
}

function handleNewButton(i) {
	if (false) {
		newFile();
		editor[i].setValue("");
	} else {
		window.open('file://' + __dirname + '/index.html');
	}
}

//Context menu init()
function initContextMenu(i) {
	menu = new Menu();
	menu.append(new MenuItem({
		label: 'Copy',
		click: function () {
			clipboard.writeText(editor[i].getSelection(), 'copy');
		}
	}));
	menu.append(new MenuItem({
		label: 'Cut',
		click: function () {
			clipboard.writeText(editor[i].getSelection(), 'copy');
			editor[i].replaceSelection('');
		}
	}));
	menu.append(new MenuItem({
		label: 'Paste',
		click: function () {
			editor[i].replaceSelection(clipboard.readText('copy'));
		}
	}));

	window.addEventListener('contextmenu', function (ev) {
		ev.preventDefault();
		menu.popup(remote.getCurrentWindow(), ev.x, ev.y);
	}, false);
}

//Main Functions for Electron
onload = function () {
	initContextMenu();

	document.getElementById("min-button").addEventListener("click", function (e) {
		const window = remote.getCurrentWindow();
		window.minimize();
		console.log('Minimize Triggered!');
	});

	document.getElementById("max-button").addEventListener("click", function (e) {
		const window = remote.getCurrentWindow();
		if (!window.isMaximized()) {
			window.maximize();
		} else {
			window.unmaximize();
		}
		console.log('Maximize Triggered!');
		console.log(document.getElementById('close-button'));
	});

	document.getElementById("close-button").addEventListener("click", function (e) {
		const window = remote.getCurrentWindow();
		window.close();
	});

	document.getElementById("close-window").addEventListener("click", function (e) {
		const window = remote.getCurrentWindow();
		window.close();
	});
	document.getElementById("new").addEventListener("click", handleNewButton);

	editor[0] = CodeMirror(
		document.getElementById("html-editor"), {
			mode: {
				name: "htmlmixed",
			},
			lineNumbers: true,
			lineWrapping: true,
			autofocus: true,
			indentWithTabs: true,
			scrollbarStyle: "overlay",
			theme: "base16-ocean-dark"
		});

	editor[1] = CodeMirror(
		document.getElementById("css-editor"), {
			mode: {
				name: "css",
			},
			lineNumbers: true,
			lineWrapping: true,
			indentWithTabs: true,
			//Having issues with smartIndent. Therfore, turned off.
			smartIndent: false,
			scrollbarStyle: "overlay",
			theme: "base16-ocean-dark"
		});

	editor[2] = CodeMirror(
		document.getElementById("js-editor"), {
			mode: {
				name: "javascript",
				json: true
			},
			lineNumbers: true,
			lineWrapping: true,
			indentWithTabs: true,
			scrollbarStyle: "overlay",
			theme: "base16-ocean-dark"
		});

	output = document.getElementById("output");

	html = editor[0];
	css = editor[1];
	js = editor[2];

	addScript();
	addStyle();
	newFile();
	onresize();
};

onresize = function () {
	for (i = 0; i < 3; i++)
		editor[i].refresh();
}

function paint(script, style) {
	outputSource = '' + '' + style + '' + '' + '' + html.getValue() + script + '' + '' + '';
	console.log(outputSource);
	output.srcdoc = outputSource;
}

function paint(script,style) {
	outputSource = '' + ''+ style + '' + '' + '' + html.getValue() + script +  '' + '' + '';
	console.log(outputSource);
	output.srcdoc = outputSource;
}

// TODO: Use CodeMirror.change instead
document.addEventListener("keyup", function (e) {
	scr = getScr();
	sty = getSty();
	paint(scr,sty);
});

// TODO: Limit execution to 1 ✔
// DONE: All JS and CSS can be added at once ✔
// TODO: Append all Js libraries to inUse[] and refresh outputSource ❌
// DONE: Scripts added once wouldn't be added again
function addScript() {
	var JSMemu = document.getElementById("JSMenu");
	var JSbuttons = JSMemu.getElementsByTagName('a');
	var ScrFlags = [0,0,0];
	JSbuttons[0].addEventListener("click", function (e) {
		console.log("JS 0");
		if(ScrFlags[1] === 0)
		{
			var jQStr = ""
			scripts += bootjsStr;
			ScrFlags[0] = 1;
			console.log("Bootstrap added!");
		}
	});
	JSbuttons[1].addEventListener("click", function (e) {
		console.log("JS 1");
		if(ScrFlags[1] === 0)
		{
			var jQStr = ""
			scripts += jQStr;
			ScrFlags[1] = 1;
			console.log("jQuery added!");
		}
	});
	JSbuttons[2].addEventListener("click", function (e) {
		console.log("JS 2");
		if(ScrFlags[2] === 0)
		{
			var js3Str = ""
			scripts += js3Str;
			ScrFlags[2] = 1;
			console.log("Three.js added!");
		}
	});
};

function addStyle() {
	var CSSMenu = document.getElementById("CSSMenu");
	var CSSbuttons = CSSMenu.getElementsByTagName('a');
	var StyFlags = [0,0,0,0];
	CSSbuttons[0].addEventListener("click", function (e) {
		console.log("CSS 0");
		if(StyFlags[0] === 0)
		{
			var aniStr = "<link rel='stylesheet' type='text/css' href='lib/animate.css'>"
			styles += aniStr;
			StyFlags[0] = 1;
			console.log("Animate added!");
		}
	});
	CSSbuttons[1].addEventListener("click", function (e) {
		console.log("CSS 1");
		if(StyFlags[1] === 1)
		{
			var bootStr = "<link rel='stylesheet' type='text/css' href='lib/bootstrap.min.css'>";
			styles += bootStr;
			StyFlags[1] = 1;
			console.log("Bootstrap added!");
		}
	});
	CSSbuttons[2].addEventListener("click", function (e) {
		console.log("CSS 2");
		if(StyFlags[2] === 0)
		{
			var faStr = "<link rel='stylesheet' type='text/css' href='lib/font-awesome.min.css'>"
			styles += faStr;
			StyFlags[2] = 1;
			console.log("Font Awesome added!");
		}
	});
	CSSbuttons[3].addEventListener("click", function (e) {
		console.log("CSS 3");
		if(StyFlags[3] === 0)
		{
			var matStr = "<link href='lib/materialize.min.css'>"
			styles += matStr;
			StyFlags[3] = 1;
			console.log("Materialize added!");
		}
	});
};<|endoftext|>


<commit_before>module('Symbol & Placed Symbol');

test('placedSymbol bounds', function() {
	var path = new Path.Circle([50, 50], 50);
	path.strokeColor = 'black';
	path.strokeWidth = 1;
	path.strokeCap = 'round';
	path.strokeJoin = 'round';
	compareRectangles(path.strokeBounds,
		{ x: -0.5, y: -0.5, width: 101, height: 101 },
		'Path initial bounds.');
	var symbol = new Symbol(path);
	var placedSymbol = new PlacedSymbol(symbol);

	compareRectangles(placedSymbol.bounds,
		new Rectangle(-50.5, -50.5, 101, 101),
		'PlacedSymbol initial bounds.');

	placedSymbol.scale(1, 0.5);
	compareRectangles(placedSymbol.bounds,
		{ x: -50.5, y: -25.25, width: 101, height: 50.5 },
		'Bounds after scale.');

	placedSymbol.rotate(40);
	compareRectangles(placedSymbol.bounds,
		{ x: -42.04736, y: -37.91846, width: 84.09473, height: 75.83691 },
		'Bounds after rotation.');
});

test('Symbol definition selection', function() {
	var path = new Path.Circle([50, 50], 50);
	path.selected = true;
	var symbol = new Symbol(path);
	equals(function() {
		return symbol.definition.selected == false;
	}, true);
	equals(function() {
		return paper.project.selectedItems.length == 0;
	}, true);
});<commit_msg>Add tests for Symbol#place<commit_after>module('Symbol & Placed Symbol');

test('placedSymbol bounds', function() {
	var path = new Path.Circle([50, 50], 50);
	path.strokeColor = 'black';
	path.strokeWidth = 1;
	path.strokeCap = 'round';
	path.strokeJoin = 'round';
	compareRectangles(path.strokeBounds,
		{ x: -0.5, y: -0.5, width: 101, height: 101 },
		'Path initial bounds.');
	var symbol = new Symbol(path);
	var placedSymbol = new PlacedSymbol(symbol);

	compareRectangles(placedSymbol.bounds,
		new Rectangle(-50.5, -50.5, 101, 101),
		'PlacedSymbol initial bounds.');

	placedSymbol.scale(1, 0.5);
	compareRectangles(placedSymbol.bounds,
		{ x: -50.5, y: -25.25, width: 101, height: 50.5 },
		'Bounds after scale.');

	placedSymbol.rotate(40);
	compareRectangles(placedSymbol.bounds,
		{ x: -42.04736, y: -37.91846, width: 84.09473, height: 75.83691 },
		'Bounds after rotation.');
});

test('Symbol definition selection', function() {
	var path = new Path.Circle([50, 50], 50);
	path.selected = true;
	var symbol = new Symbol(path);
	equals(function() {
		return symbol.definition.selected == false;
	}, true);
	equals(function() {
		return paper.project.selectedItems.length == 0;
	}, true);
});

test('Symbol#place()', function() {
	var path = new Path.Circle([50, 50], 50);
	var symbol = new Symbol(path);
	var placedSymbol = symbol.place();
	equals(function() {
		return placedSymbol.parent == paper.project.activeLayer;
	}, true);

	equals(function() {
		return placedSymbol.symbol == symbol;
	}, true);

	equals(function() {
		return placedSymbol.position.toString();
	}, '{ x: 0, y: 0 }');
});

test('Symbol#place(position)', function() {
	var path = new Path.Circle([50, 50], 50);
	var symbol = new Symbol(path);
	var placedSymbol = symbol.place(new Point(100, 100));
	equals(function() {
		return placedSymbol.position.toString();
	}, '{ x: 100, y: 100 }');
});
<|endoftext|>


<commit_before>var _ = require("lodash");

module.exports = function(network, chan, cmd, args) {
	if (cmd !== "part" && cmd !== "leave" && cmd !== "close") {
		return;
	}
	var client = this;
	if (chan.type === "query") {
		network.channels = _.without(network.channels, chan);
		client.emit("part", {
			chan: chan.id
		});
	} else {
		var irc = network.irc;
		if (args.length === 0) {
			args.push(chan.name);
		}
		irc.part(args);
	}
};
<commit_msg>Fix #30: Close channel on the client as soon as close event is registered<commit_after>var _ = require("lodash");

module.exports = function(network, chan, cmd, args) {
	if (cmd !== "part" && cmd !== "leave" && cmd !== "close") {
		return;
	}
	if (chan.type !== "query") {
		var irc = network.irc;
		if (args.length === 0) {
			args.push(chan.name);
		}
		irc.part(args);
	}
	network.channels = _.without(network.channels, chan);
	this.emit("part", {
		chan: chan.id
	});
};
<|endoftext|>


<commit_before>/**
 * Add shim config for configuring the dependencies and exports for
 * older, traditional "browser globals" scripts that do not use define()
 * to declare the dependencies and set a module value.
 */
(function(seajs, global) {

  // shimConfig = {
  //   "jquery": {
  //     exports: "jQuery" or function
  //   },
  //   "jquery.plugins": {
  //     // URI matches, such as jquery.easing.js, jquery.keystop.js
  //     match: /jquery[.][a-z]/,
  //     exports: "jQuery",
  //     deps: ["jquery"]
  //   }
  // }
  var shimConfig = {}

  function parseConfig(data) {
    each(data.shim, function(item, key) {
      shimConfig[key] = item
      if (!item.match) {
        item.match = seajs.resolve(key)
      }
    })
  }

  seajs.on("config", parseConfig)

  // Parse config here to make previous shim config available
  parseConfig(seajs.config.data)

  seajs.on("initialized", function(mod) {
    var uri = mod.uri

    each(shimConfig, function(item) {
      var deps = item.deps

      if (deps && match(item, uri)) {
        for (var i = 0; i < deps.length; i++) {
          mod.dependencies.push(deps[i])
        }
        return false
      }

    })
  })

  seajs.on("compile", function(mod) {
    var uri = mod.uri

    each(shimConfig, function(item) {
      var exports = item.exports

      if (exports && match(item, uri)) {
        mod.exports = isFunction(exports) ? exports() : global[exports]
        return false
      }

    })
  })

  // Helpers

  function each(obj, fn) {
    for (var p in obj) {
      if (obj.hasOwnProperty(p)) {
        if (fn(obj[p], p, obj) === false) {
          break
        }
      }
    }
  }

  function match(item, uri) {
    var match = item.match
    return match.test ? match.test(uri) : uri === match
  }

  function isFunction(obj) {
    return typeof obj === "function"
  }

})(seajs, this);

<commit_msg>Modify comments<commit_after>/**
 * Add shim config for configuring the dependencies and exports for
 * older, traditional "browser globals" scripts that do not use define()
 * to declare the dependencies and set a module value.
 */
(function(seajs, global) {

  // seajs.config( {
  // shim: {
  //   "jquery": {
  //     exports: "jQuery" or function
  //   },
  //   "jquery.plugins": {
  //     // URI matches such as jquery.easing.js, jquery.keystop.js
  //     match: /jquery\.[a-z].*\.js/,
  //     deps: ["jquery"]
  //   }
  // })
  var shimConfig = {}

  function parseConfig(data) {
    each(data.shim, function(item, key) {
      shimConfig[key] = item
      if (!item.match) {
        item.match = seajs.resolve(key)
      }
    })
  }

  seajs.on("config", parseConfig)

  // Parse config here to make previous shim config available
  parseConfig(seajs.config.data)

  seajs.on("initialized", function(mod) {
    var uri = mod.uri

    each(shimConfig, function(item) {
      var deps = item.deps

      if (deps && match(item, uri)) {
        for (var i = 0; i < deps.length; i++) {
          mod.dependencies.push(deps[i])
        }
        return false
      }

    })
  })

  seajs.on("compile", function(mod) {
    var uri = mod.uri

    each(shimConfig, function(item) {
      var exports = item.exports

      if (exports && match(item, uri)) {
        mod.exports = isFunction(exports) ? exports() : global[exports]
        return false
      }

    })
  })

  // Helpers

  function each(obj, fn) {
    for (var p in obj) {
      if (obj.hasOwnProperty(p)) {
        if (fn(obj[p], p, obj) === false) {
          break
        }
      }
    }
  }

  function match(item, uri) {
    var match = item.match
    return match.test ? match.test(uri) : uri === match
  }

  function isFunction(obj) {
    return typeof obj === "function"
  }

})(seajs, this);

<|endoftext|>


<commit_before>define([
    'src/util/api',
    'src/util/ui',
    './libs'
    ], function (API, UI, libs) {
    var OCLE = libs.OCLE;
    var CCE = libs.CCE;

    class MF {
        constructor(sample) {
            this.sample = sample;

            // if no mf we calculate from molfile
            console.log(API.getData('mf')+'');)
            if (! (API.getData('mf')+'')) {
                console.log("No MF ?!",API.getData('mf'))
                this.fromMolfile();
            }
        }

        fromMolfile() {
            var chemcalc=this._chemcalcFromMolfile();
            if (chemcalc && this.previousEM !== chemcalc.em) {
                this.previousEM = chemcalc.em;

                var general=API.getData('general');
                general.mf=chemcalc.mf;
                general.em=chemcalc.em;
                general.mw=chemcalc.mw;
                general.triggerChange();
            }
            API.createData('mfBGColor','white');
        }

        _chemcalcFromMolfile() {
            var molfile=API.getData('molfile')+'';
            if (molfile) {
                var molecule=OCLE.Molecule.fromMolfile(molfile);
                var mf=molecule.getMolecularFormula().formula;
                try {
                    return CCE.analyseMF(mf);
                } catch (e) {
                    UI.showNotification('Could not calculate molecular formula: '+e);
                }
            }
            return undefined;
        }

        fromMF() {
            var chemcalc=CCE.analyseMF(API.getData('mf')+'');
            if (chemcalc && this.previousEM !== chemcalc.em) {
                this.previousEM = chemcalc.em;
                var general=API.getData('general');
                general.mw=chemcalc.mw;
                general.em=chemcalc.em;
                general.triggerChange();
            }
        }

        _mfColor() {
            var existingMF=API.getData('mf')+"";
            if (molfile) {
                var molecule=OCLE.Molecule.fromMolfile(molfile);
                var mf=molecule.getMolecularFormula().formula;
                var existingMW=existingMF ? CCE.analyseMF(existingMF).mw : 0;
                var newMW=mf ? CCE.analyseMF(mf).mw : 0;
                if (newMW!=existingMW) {
                    API.createData('mfBGColor','pink');
                } else {
                    API.createData('mfBGColor','white');
                }
            } else {
                API.createData('mfBGColor','white');
            }
        }

        handleAction(action) {
            if (!action) return;
            switch (action.name) {

                default:
                    return false;
            }
            return true;
        }
    }

    return MF;
});<commit_msg>Fix bug<commit_after>define([
    'src/util/api',
    'src/util/ui',
    './libs'
    ], function (API, UI, libs) {
    var OCLE = libs.OCLE;
    var CCE = libs.CCE;

    class MF {
        constructor(sample) {
            this.sample = sample;

            // if no mf we calculate from molfile
            console.log(API.getData('mf')+'');
            if (! (API.getData('mf')+'')) {
                console.log("No MF ?!",API.getData('mf'))
                this.fromMolfile();
            }
        }

        fromMolfile() {
            var chemcalc=this._chemcalcFromMolfile();
            if (chemcalc && this.previousEM !== chemcalc.em) {
                this.previousEM = chemcalc.em;

                var general=API.getData('general');
                general.mf=chemcalc.mf;
                general.em=chemcalc.em;
                general.mw=chemcalc.mw;
                general.triggerChange();
            }
            API.createData('mfBGColor','white');
        }

        _chemcalcFromMolfile() {
            var molfile=API.getData('molfile')+'';
            if (molfile) {
                var molecule=OCLE.Molecule.fromMolfile(molfile);
                var mf=molecule.getMolecularFormula().formula;
                try {
                    return CCE.analyseMF(mf);
                } catch (e) {
                    UI.showNotification('Could not calculate molecular formula: '+e);
                }
            }
            return undefined;
        }

        fromMF() {
            var chemcalc=CCE.analyseMF(API.getData('mf')+'');
            if (chemcalc && this.previousEM !== chemcalc.em) {
                this.previousEM = chemcalc.em;
                var general=API.getData('general');
                general.mw=chemcalc.mw;
                general.em=chemcalc.em;
                general.triggerChange();
            }
        }

        _mfColor() {
            var existingMF=API.getData('mf')+"";
            if (molfile) {
                var molecule=OCLE.Molecule.fromMolfile(molfile);
                var mf=molecule.getMolecularFormula().formula;
                var existingMW=existingMF ? CCE.analyseMF(existingMF).mw : 0;
                var newMW=mf ? CCE.analyseMF(mf).mw : 0;
                if (newMW!=existingMW) {
                    API.createData('mfBGColor','pink');
                } else {
                    API.createData('mfBGColor','white');
                }
            } else {
                API.createData('mfBGColor','white');
            }
        }

        handleAction(action) {
            if (!action) return;
            switch (action.name) {

                default:
                    return false;
            }
            return true;
        }
    }

    return MF;
});<|endoftext|>


<commit_before>var test = require('tap').test;
var Thread = require('../../src/engine/thread');

test('spec', function (t) {
    t.type(Thread, 'function');
    // @todo
    t.end();
});
<commit_msg>Added some unit tests for some thread functions<commit_after>var test = require('tap').test;
var Thread = require('../../src/engine/thread');

test('spec', function (t) {
    t.type(Thread, 'function');

    var th = new Thread('arbitraryString');
    t.type(th, 'object');
    t.ok(th instanceof Thread);
    t.type(th.pushStack, 'function');
    t.type(th.reuseStackForNextBlock, 'function');
    t.type(th.popStack, 'function');
    t.type(th.stopThisScript, 'function');
    t.type(th.peekStack, 'function');
    t.type(th.peekStackFrame, 'function');
    t.type(th.peekParentStackFrame, 'function');
    t.type(th.pushReportedValue, 'function');
    t.type(th.pushParam, 'function');
    t.type(th.peekStack, 'function');
    t.type(th.getParam, 'function');
    t.type(th.atStackTop, 'function');
    t.type(th.goToNextBlock, 'function');
    t.type(th.isRecursiveCall, 'function');

    t.end();
});

test('pushStack', function (t) {
    var th = new Thread('arbitraryString');
    th.pushStack('arbitraryString');

    t.end();
});

test('popStack', function (t) {
    var th = new Thread('arbitraryString');
    th.pushStack('arbitraryString');
    t.strictEquals(th.popStack(), 'arbitraryString');
    t.strictEquals(th.popStack(), undefined);

    t.end();
});

test('atStackTop', function (t) {
    var th = new Thread('arbitraryString');
    th.pushStack('arbitraryString');
    th.pushStack('secondString');
    t.strictEquals(th.atStackTop(), false);
    th.popStack();
    t.strictEquals(th.atStackTop(), true);

    t.end();
});

test('reuseStackForNextBlock', function (t) {
    var th = new Thread('arbitraryString');
    th.pushStack('arbitraryString');
    th.reuseStackForNextBlock('secondString');
    t.strictEquals(th.popStack(), 'secondString');

    t.end();
});

test('peekStackFrame', function (t) {
    var th = new Thread('arbitraryString');
    th.pushStack('arbitraryString');
    t.strictEquals(th.peekStackFrame().warpMode, false);
    th.popStack();
    t.strictEquals(th.peekStackFrame(), null);

    t.end();
});

test('peekParentStackFrame', function (t) {
    var th = new Thread('arbitraryString');
    th.pushStack('arbitraryString');
    th.peekStackFrame().warpMode = true;
    t.strictEquals(th.peekParentStackFrame(), null);
    th.pushStack('secondString');
    t.strictEquals(th.peekParentStackFrame().warpMode, true);

    t.end();
});

test('pushReportedValue', function (t) {
    var th = new Thread('arbitraryString');
    th.pushStack('arbitraryString');
    th.pushStack('secondString');
    th.pushReportedValue('value');
    t.strictEquals(th.peekParentStackFrame().reported.null, 'value');

    t.end();
});

test('peekStack', function (t) {
    var th = new Thread('arbitraryString');
    th.pushStack('arbitraryString');
    t.strictEquals(th.peekStack(), 'arbitraryString');
    th.popStack();
    t.strictEquals(th.peekStack(), null);

    t.end();
});

test('PushGetParam', function (t) {
    var th = new Thread('arbitraryString');
    th.pushStack('arbitraryString');
    th.pushParam('testParam', 'testValue');
    t.strictEquals(th.peekStackFrame().params.testParam, 'testValue');
    t.strictEquals(th.getParam('testParam'), 'testValue');

    t.end();
});
<|endoftext|>


<commit_before>var
  should = require('should'),
  winston = require('winston'),
  rewire = require('rewire'),
  params = require('rc')('kuzzle'),
  Kuzzle = require('root-require')('lib/api/Kuzzle'),
  RequestObject = require('root-require')('lib/api/core/models/requestObject'),
  Worker = rewire('../../lib/workers/write');

require('should-promised');

describe('Testing: write worker', function () {
  var
    kuzzle,
    requestObject;

  before(function (done) {
    kuzzle = new Kuzzle();
    kuzzle.log = new (winston.Logger)({transports: [new (winston.transports.Console)({level: 'silent'})]});

    kuzzle.start(params, {dummy: true})
      .then(function () {
        kuzzle.services.init = function () {};

        // we test successful write commands using a mockup 'create' action...
        kuzzle.services.list.writeEngine.create = function (request) { return Promise.resolve(request); };

        // ...and failed write command with a mockup 'update' action
        kuzzle.services.list.writeEngine.update = function () { return Promise.reject(new Error('rejected')); };

        done();
      });
  });

  beforeEach(function () {
    requestObject = new RequestObject({
      controller: 'write',
      action: 'create',
      protocol: 'protocol',
      requestId: 'My name is Ozymandias, king of kings',
      collection: 'Look on my works, ye Mighty, and despair!',
      body: {}
    });
  });

  it('should contain an init() function', function () {
    var writeWorker = new Worker(kuzzle);
    should(writeWorker.init).not.be.undefined().and.be.a.Function();
  });

  it('should return a promise when initializing', function () {
    var
      writeWorker = new Worker(kuzzle),
      result = writeWorker.init();

    should(result).be.a.Promise();
    return should(result).be.fulfilled();
  });

  it('should listen to the write task queue', function (done) {
    var
      brokerListenCalled = false,
      saveListen = kuzzle.services.list.broker.listen,
      writeWorker;

    this.timeout(50);

    kuzzle.services.list.broker.listen = function (taskQueue) {
      brokerListenCalled = true;

      try {
        should(taskQueue).be.exactly(kuzzle.config.queues.workerWriteTaskQueue);
      }
      catch (error) {
        done(error);
      }
    };

    writeWorker = new Worker(kuzzle);
    writeWorker.init()
      .then(function () {
        kuzzle.services.list.broker.listen = saveListen;
        should(brokerListenCalled).be.true();
        done();
      })
      .catch(function (error) {
        done(error);
      });
  });

  it('should respond with an error if an unknown action has been submitted', function () {
    var
      callback = Worker.__get__('onListenCB'),
      saveAdd = kuzzle.services.list.broker.add,
      responded = false;

    kuzzle.services.list.broker.add = function(queue, response) {
      try {
        should(queue).be.exactly(kuzzle.config.queues.workerWriteResponseQueue);
        should(response.error).not.be.null();
        should(response.error).be.a.String().and.be.exactly('Write Worker: unknown action <foobar>');
      }
      catch (error) {
        done(error);
      }
      responded = true;
    };

    requestObject.action = 'foobar';
    callback.call(kuzzle, requestObject);
    kuzzle.services.list.broker.add = saveAdd;

    should(responded).be.true();
  });

  it('should emit events when successfully submitting a query and receiving a response', function (done) {
    var
      callback = Worker.__get__('onListenCB'),
      emittedStartEvent = false,
      emittedStopEvent = false,
      saveEventEmitter = kuzzle.emit;

    this.timeout(50);

    kuzzle.emit = function (eventName, data) {
      try {
        should(data).match(requestObject);
      } catch (error) {
        done(error);
      }

      if (eventName === ('worker:write:' + requestObject.protocol + ':start')) {
        emittedStartEvent = true;
      }
      else if (eventName === ('worker:write:' + requestObject.protocol + ':stop')) {
        emittedStopEvent = true;
      }
    };

    callback.call(kuzzle, requestObject);

    setTimeout(function () {
      try {
        should(emittedStartEvent).be.true();
        should(emittedStopEvent).be.true();
        kuzzle.emit = saveEventEmitter;
        done();
      }
      catch (error) {
        done(error);
      }
    }, 20);
  });

  it('should respond to the response queue and to the notifier queue when a query is successfully completed', function (done) {
    var
      callback = Worker.__get__('onListenCB'),
      notifierQueue = false,
      responseQueue = false,
      saveBrokerAdd = kuzzle.services.list.broker.add;

    this.timeout(50);

    kuzzle.services.list.broker.add = function (queue, data) {
      try {
        should(data).match(requestObject);
      } catch (error) {
        done(error);
      }

      if (queue === kuzzle.config.queues.workerWriteResponseQueue) {
        responseQueue = true;
      }
      else if (queue === kuzzle.config.queues.coreNotifierTaskQueue) {
        notifierQueue = true;
      }
    };

    callback.call(kuzzle, requestObject);

    setTimeout(function () {
      try {
        should(responseQueue).be.true();
        should(notifierQueue).be.true();
        kuzzle.services.list.broker.add = saveBrokerAdd;
        done();
      }
      catch (error) {
        done(error);
      }
    }, 20);
  });

  it('should respond to the client when an error occurs', function (done) {
    var
      callback = Worker.__get__('onListenCB'),
      notifierQueue = false,
      responseQueue = false,
      saveBrokerAdd = kuzzle.services.list.broker.add;

    this.timeout(50);

    kuzzle.services.list.broker.add = function (queue, data) {
      try {
        should(data).be.an.Object();
        should(data.error).not.be.undefined().and.not.be.null();
        should(data.error).be.a.String().and.be.exactly('Error: rejected');
      } catch (error) {
        done(error);
      }

      if (queue === kuzzle.config.queues.workerWriteResponseQueue) {
        responseQueue = true;
      }
      else if (queue === kuzzle.config.queues.coreNotifierTaskQueue) {
        notifierQueue = true;
      }
      else {
        done(new Error('Message sent to an unknown queue: ' + queue));
      }
    };

    requestObject.action = 'update';
    callback.call(kuzzle, requestObject);

    setTimeout(function () {
      try {
        should(responseQueue).be.true();
        should(notifierQueue).be.false();
        kuzzle.services.list.broker.add = saveBrokerAdd;
        done();
      }
      catch (error) {
        done(error);
      }
    }, 20);
  });
});
<commit_msg>fixed random errors on workers unit tests because of new plugin events<commit_after>var
  should = require('should'),
  winston = require('winston'),
  rewire = require('rewire'),
  params = require('rc')('kuzzle'),
  Kuzzle = require('root-require')('lib/api/Kuzzle'),
  RequestObject = require('root-require')('lib/api/core/models/requestObject'),
  Worker = rewire('../../lib/workers/write');

require('should-promised');

describe('Testing: write worker', function () {
  var
    kuzzle,
    requestObject;

  before(function (done) {
    kuzzle = new Kuzzle();
    kuzzle.log = new (winston.Logger)({transports: [new (winston.transports.Console)({level: 'silent'})]});

    kuzzle.start(params, {dummy: true})
      .then(function () {
        kuzzle.services.init = function () {};

        // we test successful write commands using a mockup 'create' action...
        kuzzle.services.list.writeEngine.create = function (request) { return Promise.resolve(request); };

        // ...and failed write command with a mockup 'update' action
        kuzzle.services.list.writeEngine.update = function () { return Promise.reject(new Error('rejected')); };

        done();
      });
  });

  beforeEach(function () {
    requestObject = new RequestObject({
      controller: 'write',
      action: 'create',
      protocol: 'protocol',
      requestId: 'My name is Ozymandias, king of kings',
      collection: 'Look on my works, ye Mighty, and despair!',
      body: {}
    });
  });

  it('should contain an init() function', function () {
    var writeWorker = new Worker(kuzzle);
    should(writeWorker.init).not.be.undefined().and.be.a.Function();
  });

  it('should return a promise when initializing', function () {
    var
      writeWorker = new Worker(kuzzle),
      result = writeWorker.init();

    should(result).be.a.Promise();
    return should(result).be.fulfilled();
  });

  it('should listen to the write task queue', function (done) {
    var
      brokerListenCalled = false,
      saveListen = kuzzle.services.list.broker.listen,
      writeWorker;

    this.timeout(50);

    kuzzle.services.list.broker.listen = function (taskQueue) {
      brokerListenCalled = true;

      try {
        should(taskQueue).be.exactly(kuzzle.config.queues.workerWriteTaskQueue);
      }
      catch (error) {
        done(error);
      }
    };

    writeWorker = new Worker(kuzzle);
    writeWorker.init()
      .then(function () {
        kuzzle.services.list.broker.listen = saveListen;
        should(brokerListenCalled).be.true();
        done();
      })
      .catch(function (error) {
        done(error);
      });
  });

  it('should respond with an error if an unknown action has been submitted', function () {
    var
      callback = Worker.__get__('onListenCB'),
      saveAdd = kuzzle.services.list.broker.add,
      responded = false;

    kuzzle.services.list.broker.add = function(queue, response) {
      try {
        should(queue).be.exactly(kuzzle.config.queues.workerWriteResponseQueue);
        should(response.error).not.be.null();
        should(response.error).be.a.String().and.be.exactly('Write Worker: unknown action <foobar>');
      }
      catch (error) {
        done(error);
      }
      responded = true;
    };

    requestObject.action = 'foobar';
    callback.call(kuzzle, requestObject);
    kuzzle.services.list.broker.add = saveAdd;

    should(responded).be.true();
  });

  it('should emit events when successfully submitting a query and receiving a response', function (done) {
    var
      callback = Worker.__get__('onListenCB'),
      emittedStartEvent = false,
      emittedStopEvent = false,
      saveEventEmitter = kuzzle.emit;

    this.timeout(50);

    kuzzle.emit = function (eventName, data) {
      if (eventName.startsWith('worker:write:' + requestObject.protocol)) {
        try {
          should(data).match(requestObject);
        } catch (error) {
          done(error);
        }

        if (eventName === ('worker:write:' + requestObject.protocol + ':start')) {
          emittedStartEvent = true;
        }
        else if (eventName === ('worker:write:' + requestObject.protocol + ':stop')) {
          emittedStopEvent = true;
        }
      }
    };

    callback.call(kuzzle, requestObject);

    setTimeout(function () {
      try {
        should(emittedStartEvent).be.true();
        should(emittedStopEvent).be.true();
        kuzzle.emit = saveEventEmitter;
        done();
      }
      catch (error) {
        done(error);
      }
    }, 20);
  });

  it('should respond to the response queue and to the notifier queue when a query is successfully completed', function (done) {
    var
      callback = Worker.__get__('onListenCB'),
      notifierQueue = false,
      responseQueue = false,
      saveBrokerAdd = kuzzle.services.list.broker.add;

    this.timeout(50);

    kuzzle.services.list.broker.add = function (queue, data) {
      try {
        should(data).match(requestObject);
      } catch (error) {
        done(error);
      }

      if (queue === kuzzle.config.queues.workerWriteResponseQueue) {
        responseQueue = true;
      }
      else if (queue === kuzzle.config.queues.coreNotifierTaskQueue) {
        notifierQueue = true;
      }
    };

    callback.call(kuzzle, requestObject);

    setTimeout(function () {
      try {
        should(responseQueue).be.true();
        should(notifierQueue).be.true();
        kuzzle.services.list.broker.add = saveBrokerAdd;
        done();
      }
      catch (error) {
        done(error);
      }
    }, 20);
  });

  it('should respond to the client when an error occurs', function (done) {
    var
      callback = Worker.__get__('onListenCB'),
      notifierQueue = false,
      responseQueue = false,
      saveBrokerAdd = kuzzle.services.list.broker.add;

    this.timeout(50);

    kuzzle.services.list.broker.add = function (queue, data) {
      try {
        should(data).be.an.Object();
        should(data.error).not.be.undefined().and.not.be.null();
        should(data.error).be.a.String().and.be.exactly('Error: rejected');
      } catch (error) {
        done(error);
      }

      if (queue === kuzzle.config.queues.workerWriteResponseQueue) {
        responseQueue = true;
      }
      else if (queue === kuzzle.config.queues.coreNotifierTaskQueue) {
        notifierQueue = true;
      }
      else {
        done(new Error('Message sent to an unknown queue: ' + queue));
      }
    };

    requestObject.action = 'update';
    callback.call(kuzzle, requestObject);

    setTimeout(function () {
      try {
        should(responseQueue).be.true();
        should(notifierQueue).be.false();
        kuzzle.services.list.broker.add = saveBrokerAdd;
        done();
      }
      catch (error) {
        done(error);
      }
    }, 20);
  });
});
<|endoftext|>


<commit_before>/*
 * Copyright 2014 Hippo B.V. (http://www.onehippo.com)
 *
 * 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';

    angular.module('hippo.theme')

        /**
         * @ngdoc directive
         * @name hippo.theme.directive:tree
         * @restrict A
         *
         * @description
         * Tree component for the Hippo Theme based on [NestedSortable](https://github.com/JimLiu/Angular-NestedSortable).
         *
         * @param {array} items The items to use for the Tree. Each item is an object with `title` (String) and `items` (Array) property.
         * @param {callbacks} The callbacks to call when a new node in the Tree is selected (TODO: describe callback names
         * or list them explicitly as arguments and create the callbacks object internally)
         */
        .directive('hippo.theme.tree', ['$compile', '$templateCache', function($compile, $templateCache) {
            $templateCache.put('hippo.theme.tree.include', ''
                + '

'
                + '
'
                + '

'
                + '
'
            );

            return {
                restrict: 'A',
                transclude: true,
                scope: {
                    treeItems: '=items',
                    options: '=callbacks'
                },
                template: ''
                    + '
'
                    + '

'
                    + '
',
                controller: 'hippo.theme.tree.TreeCtrl'
            };
        }])

        .controller('hippo.theme.tree.TreeCtrl', ['$transclude', function($transclude) {
            this.renderTreeTemplate = $transclude;
        }])

        .directive('hippo.theme.tree.template', function() {
            return {
                require: '^hippo.theme.tree',
                link: function(scope, element, attrs, controller) {
                    controller.renderTreeTemplate(scope, function(dom) {
                        element.append(dom);
                    });
                }
            };
        });

})();
<commit_msg>RD-2069 Fix docs issue<commit_after>/*
 * Copyright 2014 Hippo B.V. (http://www.onehippo.com)
 *
 * 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';

    angular.module('hippo.theme')

        /**
         * @ngdoc directive
         * @name hippo.theme.directive:tree
         * @restrict A
         *
         * @description
         * Tree component for the Hippo Theme based on [NestedSortable](https://github.com/JimLiu/Angular-NestedSortable).
         *
         * @param {array} items The items to use for the Tree. Each item is an object with `title` (String) and `items` (Array) property.
         * @param {callbacks} callbacks The callbacks to call when a new node in the Tree is selected (TODO: describe callback names
         * or list them explicitly as arguments and create the callbacks object internally)
         */
        .directive('hippo.theme.tree', ['$compile', '$templateCache', function($compile, $templateCache) {
            $templateCache.put('hippo.theme.tree.include', ''
                + '

'
                + '
'
                + '

'
                + '
'
            );

            return {
                restrict: 'A',
                transclude: true,
                scope: {
                    treeItems: '=items',
                    options: '=callbacks'
                },
                template: ''
                    + '
'
                    + '

'
                    + '
',
                controller: 'hippo.theme.tree.TreeCtrl'
            };
        }])

        .controller('hippo.theme.tree.TreeCtrl', ['$transclude', function($transclude) {
            this.renderTreeTemplate = $transclude;
        }])

        .directive('hippo.theme.tree.template', function() {
            return {
                require: '^hippo.theme.tree',
                link: function(scope, element, attrs, controller) {
                    controller.renderTreeTemplate(scope, function(dom) {
                        element.append(dom);
                    });
                }
            };
        });

})();
<|endoftext|>