<commit_before>const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const webpack = require("webpack");

let og_image_url = process.env.RIOT_OG_IMAGE_URL;
if (!og_image_url) og_image_url = 'https://riot.im/app/themes/riot/img/logos/riot-im-logo-black-text.png';

module.exports = (env, argv) => {
    if (process.env.CI_PACKAGE) {
        // Don't run minification for CI builds (this is only set for runs on develop)
        argv.mode = "development";
    }

    const development = {};
    if (argv.mode !== "production") {
        // This makes the sourcemaps human readable for developers. We use eval-source-map
        // because the plain source-map devtool ruins the alignment.
        development['devtool'] = 'eval-source-map';
    }

    return {
        ...development,

        entry: {
            "bundle": "./src/vector/index.js",
            "indexeddb-worker": "./src/vector/indexeddb-worker.js",
            "mobileguide": "./src/vector/mobile_guide/index.js",

            // CSS themes
            "theme-light": "./node_modules/matrix-react-sdk/res/themes/light/css/light.scss",
            "theme-dark": "./node_modules/matrix-react-sdk/res/themes/dark/css/dark.scss",
            "theme-light-custom": "./node_modules/matrix-react-sdk/res/themes/light-custom/css/light-custom.scss",
            "theme-dark-custom": "./node_modules/matrix-react-sdk/res/themes/dark-custom/css/dark-custom.scss",
        },

        optimization: {
            // Put all of our CSS into one useful place - this is needed for MiniCssExtractPlugin.
            // Previously we used a different extraction plugin that did this magic for us, but
            // now we need to consider that the CSS needs to be bundled up together.
            splitChunks: {
                cacheGroups: {
                    styles: {
                        name: 'styles',
                        test: /\.css$/,
                        enforce: true,
                        // Do not add `chunks: 'all'` here because you'll break the app entry point.
                    },
                },
            },

            // This fixes duplicate files showing up in chrome with sourcemaps enabled.
            // See https://github.com/webpack/webpack/issues/7128 for more info.
            namedModules: false,

            // Minification is normally enabled by default for webpack in production mode, but
            // we use a CSS optimizer too and need to manage it ourselves.
            minimize: argv.mode === 'production',
            minimizer: argv.mode === 'production' ? [new TerserPlugin({}), new OptimizeCSSAssetsPlugin({})] : [],
        },

        resolve: {
            // We define an alternative import path so we can safely use src/ across the react-sdk
            // and js-sdk. We already import from src/ where possible to ensure our source maps are
            // extremely accurate (and because we're capable of compiling the layers manually rather
            // than relying on partially-mangled output from babel), though we do need to fix the
            // package level import (stuff like `import {Thing} from "matrix-js-sdk"` for example).
            // We can't use the aliasing down below to point at src/ because that'll fail to resolve
            // the package.json for the dependency. Instead, we rely on the package.json of each
            // layer to have our custom alternate fields to load things in the right order. These are
            // the defaults of webpack prepended with `matrix_src_`.
            mainFields: ['matrix_src_browser', 'matrix_src_main', 'browser', 'main'],
            aliasFields: ['matrix_src_browser', 'browser'],

            // We need to specify that TS can be resolved without an extension
            extensions: ['.js', '.json', '.ts'],
            alias: {
                // alias any requires to the react module to the one in our path,
                // otherwise we tend to get the react source included twice when
                // using `npm link` / `yarn link`.
                "react": path.resolve(__dirname, 'node_modules/react'),
                "react-dom": path.resolve(__dirname, 'node_modules/react-dom'),

                // same goes for js-sdk - we don't need two copies.
                "matrix-js-sdk": path.resolve(__dirname, 'node_modules/matrix-js-sdk'),

                // Define a variable so the i18n stuff can load
                "$webapp": path.resolve(__dirname, 'webapp'),
            },
        },

        module: {
            noParse: [
                // for cross platform compatibility use [\\\/] as the path separator
                // this ensures that the regex trips on both Windows and *nix

                // don't parse the languages within highlight.js. They cause stack
                // overflows (https://github.com/webpack/webpack/issues/1721), and
                // there is no need for webpack to parse them - they can just be
                // included as-is.
                /highlight\.js[\\\/]lib[\\\/]languages/,

                // olm takes ages for webpack to process, and it's already heavily
                // optimised, so there is little to gain by us uglifying it.
                /olm[\\\/](javascript[\\\/])?olm\.js$/,
            ],
            rules: [
                {
                    test: /\.(ts|js)x?$/,
                    include: (f) => {
                        // we use the original source files of react-sdk and js-sdk, so we need to
                        // run them through babel.
                        if (f.startsWith(path.resolve(__dirname, 'node_modules', 'matrix-js-sdk'))) return true;
                        if (f.startsWith(path.resolve(__dirname, 'node_modules', 'matrix-react-sdk'))) return true;
                        // but we can't run all of our dependencies through babel (many of them still
                        // use module.exports which breaks if babel injects an 'include' for its
                        // polyfills: probably fixable but babeling all our dependencies is probably
                        // not necessary anyway).
                        if (f.startsWith(path.resolve(__dirname, 'node_modules'))) return false;
                        // anything else gets babeled (our own source files, and also modules that
                        // are yarn linked from somewhere else because this tests the absolute,
                        // resolved path, so react-sdk and js-sdk fall under this case in a standard
                        // dev setup. This will presumably start running any other module through
                        // babel if yarn linked... caveat emptor.
                        return true;
                    },
                    loader: 'babel-loader',
                    options: {
                        cacheDirectory: true
                    }
                },
                {
                    test: /\.css$/,
                    use: [
                        MiniCssExtractPlugin.loader,
                        {
                            loader: 'css-loader',
                            options: {
                                importLoaders: 1,
                                sourceMap: true,
                            }
                        },
                        {
                            loader: 'postcss-loader',
                            ident: 'postcss',
                            options: {
                                sourceMap: true,
                                plugins: () => [
                                    // Note that we use significantly fewer plugins on the plain
                                    // CSS parser. If we start to parse plain CSS, we end with all
                                    // kinds of nasty problems (like stylesheets not loading).
                                    //
                                    // You might have noticed that we're also sending regular CSS
                                    // through PostCSS. This looks weird, and in fact is probably
                                    // not what you'd expect, however in order for our CSS build
                                    // to work nicely we have to do this. Because down the line
                                    // our SCSS stylesheets reference plain CSS we have to load
                                    // the plain CSS through PostCSS so it can find it safely. This
                                    // also acts like a babel-for-css by transpiling our (S)CSS
                                    // down/up to the right browser support (prefixes, etc).
                                    // Further, if we don't do this then PostCSS assumes that our
                                    // plain CSS is SCSS and it really doesn't like that, even
                                    // though plain CSS should be compatible. The chunking options
                                    // at the top of this webpack config help group the SCSS and
                                    // plain CSS together for the bundler.

                                    require("postcss-simple-vars")(),
                                    require("postcss-strip-inline-comments")(),

                                    // It's important that this plugin is last otherwise we end
                                    // up with broken CSS.
                                    require('postcss-preset-env')({stage: 3, browsers: 'last 2 versions'}),
                                ],
                                parser: "postcss-scss",
                                "local-plugins": true,
                            },
                        },
                    ]
                },
                {
                    test: /\.scss$/,
                    use: [
                        MiniCssExtractPlugin.loader,
                        {
                            loader: 'css-loader',
                            options: {
                                importLoaders: 1,
                                sourceMap: true,
                            }
                        },
                        {
                            loader: 'postcss-loader',
                            ident: 'postcss',
                            options: {
                                sourceMap: true,
                                plugins: () => [
                                    // Note that we use slightly different plugins for SCSS.

                                    require('postcss-import')(),
                                    require("postcss-simple-vars")(),
                                    require("postcss-extend")(),
                                    require("postcss-nested")(),
                                    require("postcss-mixins")(),
                                    require("postcss-easings")(),
                                    require("postcss-strip-inline-comments")(),

                                    // It's important that this plugin is last otherwise we end
                                    // up with broken CSS.
                                    require('postcss-preset-env')({stage: 3, browsers: 'last 2 versions'}),
                                ],
                                parser: "postcss-scss",
                                "local-plugins": true,
                            },
                        },
                    ]
                },
                {
                    test: /\.wasm$/,
                    loader: "file-loader",
                    type: "javascript/auto", // https://github.com/webpack/webpack/issues/6725
                    options: {
                        name: '[name].[hash:7].[ext]',
                        outputPath: '.',
                    },
                },
                {
                    // cache-bust languages.json file placed in
                    // riot-web/webapp/i18n during build by copy-res.js
                    test: /\.*languages.json$/,
                    type: "javascript/auto",
                    loader: 'file-loader',
                    options: {
                        name: 'i18n/[name].[hash:7].[ext]',
                    },
                },
                {
                    test: /\.(gif|png|svg|ttf|woff|woff2|xml|ico)$/,
                    // Use a content-based hash in the name so that we can set a long cache
                    // lifetime for assets while still delivering changes quickly.
                    oneOf: [
                        {
                            // Assets referenced in CSS files
                            issuer: /\.(scss|css)$/,
                            loader: 'file-loader',
                            options: {
                                esModule: false,
                                name: '[name].[hash:7].[ext]',
                                outputPath: getImgOutputPath,
                                publicPath: function(url, resourcePath) {
                                    // CSS image usages end up in the `bundles/[hash]` output
                                    // directory, so we adjust the final path to navigate up
                                    // twice.
                                    const outputPath = getImgOutputPath(url, resourcePath);
                                    return toPublicPath(path.join("../..", outputPath));
                                },
                            },
                        },
                        {
                            // Assets referenced in HTML and JS files
                            loader: 'file-loader',
                            options: {
                                esModule: false,
                                name: '[name].[hash:7].[ext]',
                                outputPath: getImgOutputPath,
                                publicPath: function(url, resourcePath) {
                                    const outputPath = getImgOutputPath(url, resourcePath);
                                    return toPublicPath(outputPath);
                                },
                            },
                        },
                    ],
                },
            ]
        },

        plugins: [
            new webpack.DefinePlugin({
                'process.env': {
                    NODE_ENV: JSON.stringify(process.env.NODE_ENV),
                },
            }),

            // This exports our CSS using the splitChunks and loaders above.
            new MiniCssExtractPlugin({
                filename: 'bundles/[hash]/[name].css',
                ignoreOrder: false, // Enable to remove warnings about conflicting order
            }),

            // This is the app's main entry point.
            new HtmlWebpackPlugin({
                template: './src/vector/index.html',

                // we inject the links ourselves via the template, because
                // HtmlWebpackPlugin will screw up our formatting like the names
                // of the themes and which chunks we actually care about.
                inject: false,
                excludeChunks: ['mobileguide'],
                minify: argv.mode === 'production',
                vars: {
                    og_image_url: og_image_url,
                },
            }),

            // This is the mobile guide's entry point (separate for faster mobile loading)
            new HtmlWebpackPlugin({
                template: './src/vector/mobile_guide/index.html',
                filename: 'mobile_guide/index.html',
                minify: argv.mode === 'production',
                chunks: ['mobileguide'],
            }),
        ],

        output: {
            path: path.join(__dirname, "webapp"),

            // The generated JS (and CSS, from the extraction plugin) are put in a
            // unique subdirectory for the build. There will only be one such
            // 'bundle' directory in the generated tarball; however, hosting
            // servers can collect 'bundles' from multiple versions into one
            // directory and symlink it into place - this allows users who loaded
            // an older version of the application to continue to access webpack
            // chunks even after the app is redeployed.
            filename: "bundles/[hash]/[name].js",
            chunkFilename: "bundles/[hash]/[name].js",
        },

        // configuration for the webpack-dev-server
        devServer: {
            // serve unwebpacked assets from webapp.
            contentBase: './webapp',

            stats: {
                // don't fill the console up with a mahoosive list of modules
                chunks: false,
            },

            // hot module replacement doesn't work (I think we'd need react-hot-reload?)
            // so webpack-dev-server reloads the page on every update which is quite
            // tedious in Riot since that can take a while.
            hot: false,
            inline: false,
        },
    };
};

/**
 * Merge assets found via CSS and imports into a single tree, while also preserving
 * directories under `res`.
 *
 * @param {string} url The adjusted name of the file, such as `warning.1234567.svg`.
 * @param {string} resourcePath The absolute path to the source file with unmodified name.
 * @return {string} The returned paths will look like `img/warning.1234567.svg`.
 */
function getImgOutputPath(url, resourcePath) {
    const prefix = /^.*[/\\]res[/\\]/;
    const outputDir = path.dirname(resourcePath).replace(prefix, "");
    return path.join(outputDir, path.basename(url));
}

/**
 * Convert path to public path format, which always uses forward slashes, since it will
 * be placed directly into things like CSS files.
 *
 * @param {string} path Some path to a file.
 */
function toPublicPath(path) {
    return path.replace(/\\/g, '/');
}
<commit_msg>Fix build to not babel modules inside js/react sdk<commit_after>const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const webpack = require("webpack");

let og_image_url = process.env.RIOT_OG_IMAGE_URL;
if (!og_image_url) og_image_url = 'https://riot.im/app/themes/riot/img/logos/riot-im-logo-black-text.png';

module.exports = (env, argv) => {
    if (process.env.CI_PACKAGE) {
        // Don't run minification for CI builds (this is only set for runs on develop)
        argv.mode = "development";
    }

    const development = {};
    if (argv.mode !== "production") {
        // This makes the sourcemaps human readable for developers. We use eval-source-map
        // because the plain source-map devtool ruins the alignment.
        development['devtool'] = 'eval-source-map';
    }

    return {
        ...development,

        entry: {
            "bundle": "./src/vector/index.js",
            "indexeddb-worker": "./src/vector/indexeddb-worker.js",
            "mobileguide": "./src/vector/mobile_guide/index.js",

            // CSS themes
            "theme-light": "./node_modules/matrix-react-sdk/res/themes/light/css/light.scss",
            "theme-dark": "./node_modules/matrix-react-sdk/res/themes/dark/css/dark.scss",
            "theme-light-custom": "./node_modules/matrix-react-sdk/res/themes/light-custom/css/light-custom.scss",
            "theme-dark-custom": "./node_modules/matrix-react-sdk/res/themes/dark-custom/css/dark-custom.scss",
        },

        optimization: {
            // Put all of our CSS into one useful place - this is needed for MiniCssExtractPlugin.
            // Previously we used a different extraction plugin that did this magic for us, but
            // now we need to consider that the CSS needs to be bundled up together.
            splitChunks: {
                cacheGroups: {
                    styles: {
                        name: 'styles',
                        test: /\.css$/,
                        enforce: true,
                        // Do not add `chunks: 'all'` here because you'll break the app entry point.
                    },
                },
            },

            // This fixes duplicate files showing up in chrome with sourcemaps enabled.
            // See https://github.com/webpack/webpack/issues/7128 for more info.
            namedModules: false,

            // Minification is normally enabled by default for webpack in production mode, but
            // we use a CSS optimizer too and need to manage it ourselves.
            minimize: argv.mode === 'production',
            minimizer: argv.mode === 'production' ? [new TerserPlugin({}), new OptimizeCSSAssetsPlugin({})] : [],
        },

        resolve: {
            // We define an alternative import path so we can safely use src/ across the react-sdk
            // and js-sdk. We already import from src/ where possible to ensure our source maps are
            // extremely accurate (and because we're capable of compiling the layers manually rather
            // than relying on partially-mangled output from babel), though we do need to fix the
            // package level import (stuff like `import {Thing} from "matrix-js-sdk"` for example).
            // We can't use the aliasing down below to point at src/ because that'll fail to resolve
            // the package.json for the dependency. Instead, we rely on the package.json of each
            // layer to have our custom alternate fields to load things in the right order. These are
            // the defaults of webpack prepended with `matrix_src_`.
            mainFields: ['matrix_src_browser', 'matrix_src_main', 'browser', 'main'],
            aliasFields: ['matrix_src_browser', 'browser'],

            // We need to specify that TS can be resolved without an extension
            extensions: ['.js', '.json', '.ts'],
            alias: {
                // alias any requires to the react module to the one in our path,
                // otherwise we tend to get the react source included twice when
                // using `npm link` / `yarn link`.
                "react": path.resolve(__dirname, 'node_modules/react'),
                "react-dom": path.resolve(__dirname, 'node_modules/react-dom'),

                // same goes for js-sdk - we don't need two copies.
                "matrix-js-sdk": path.resolve(__dirname, 'node_modules/matrix-js-sdk'),

                // Define a variable so the i18n stuff can load
                "$webapp": path.resolve(__dirname, 'webapp'),
            },
        },

        module: {
            noParse: [
                // for cross platform compatibility use [\\\/] as the path separator
                // this ensures that the regex trips on both Windows and *nix

                // don't parse the languages within highlight.js. They cause stack
                // overflows (https://github.com/webpack/webpack/issues/1721), and
                // there is no need for webpack to parse them - they can just be
                // included as-is.
                /highlight\.js[\\\/]lib[\\\/]languages/,

                // olm takes ages for webpack to process, and it's already heavily
                // optimised, so there is little to gain by us uglifying it.
                /olm[\\\/](javascript[\\\/])?olm\.js$/,
            ],
            rules: [
                {
                    test: /\.(ts|js)x?$/,
                    include: (f) => {
                        // we use the original source files of react-sdk and js-sdk, so we need to
                        // run them through babel.
                        if (f.startsWith(path.resolve(__dirname, 'node_modules', 'matrix-js-sdk', 'src'))) return true;
                        if (f.startsWith(path.resolve(__dirname, 'node_modules', 'matrix-react-sdk', 'src'))) return true;
                        // but we can't run all of our dependencies through babel (many of them still
                        // use module.exports which breaks if babel injects an 'include' for its
                        // polyfills: probably fixable but babeling all our dependencies is probably
                        // not necessary anyway).
                        if (f.startsWith(path.resolve(__dirname, 'node_modules'))) return false;
                        // anything else gets babeled (our own source files, and also modules that
                        // are yarn linked from somewhere else because this tests the absolute,
                        // resolved path, so react-sdk and js-sdk fall under this case in a standard
                        // dev setup. This will presumably start running any other module through
                        // babel if yarn linked... caveat emptor.
                        return true;
                    },
                    loader: 'babel-loader',
                    options: {
                        cacheDirectory: true
                    }
                },
                {
                    test: /\.css$/,
                    use: [
                        MiniCssExtractPlugin.loader,
                        {
                            loader: 'css-loader',
                            options: {
                                importLoaders: 1,
                                sourceMap: true,
                            }
                        },
                        {
                            loader: 'postcss-loader',
                            ident: 'postcss',
                            options: {
                                sourceMap: true,
                                plugins: () => [
                                    // Note that we use significantly fewer plugins on the plain
                                    // CSS parser. If we start to parse plain CSS, we end with all
                                    // kinds of nasty problems (like stylesheets not loading).
                                    //
                                    // You might have noticed that we're also sending regular CSS
                                    // through PostCSS. This looks weird, and in fact is probably
                                    // not what you'd expect, however in order for our CSS build
                                    // to work nicely we have to do this. Because down the line
                                    // our SCSS stylesheets reference plain CSS we have to load
                                    // the plain CSS through PostCSS so it can find it safely. This
                                    // also acts like a babel-for-css by transpiling our (S)CSS
                                    // down/up to the right browser support (prefixes, etc).
                                    // Further, if we don't do this then PostCSS assumes that our
                                    // plain CSS is SCSS and it really doesn't like that, even
                                    // though plain CSS should be compatible. The chunking options
                                    // at the top of this webpack config help group the SCSS and
                                    // plain CSS together for the bundler.

                                    require("postcss-simple-vars")(),
                                    require("postcss-strip-inline-comments")(),

                                    // It's important that this plugin is last otherwise we end
                                    // up with broken CSS.
                                    require('postcss-preset-env')({stage: 3, browsers: 'last 2 versions'}),
                                ],
                                parser: "postcss-scss",
                                "local-plugins": true,
                            },
                        },
                    ]
                },
                {
                    test: /\.scss$/,
                    use: [
                        MiniCssExtractPlugin.loader,
                        {
                            loader: 'css-loader',
                            options: {
                                importLoaders: 1,
                                sourceMap: true,
                            }
                        },
                        {
                            loader: 'postcss-loader',
                            ident: 'postcss',
                            options: {
                                sourceMap: true,
                                plugins: () => [
                                    // Note that we use slightly different plugins for SCSS.

                                    require('postcss-import')(),
                                    require("postcss-simple-vars")(),
                                    require("postcss-extend")(),
                                    require("postcss-nested")(),
                                    require("postcss-mixins")(),
                                    require("postcss-easings")(),
                                    require("postcss-strip-inline-comments")(),

                                    // It's important that this plugin is last otherwise we end
                                    // up with broken CSS.
                                    require('postcss-preset-env')({stage: 3, browsers: 'last 2 versions'}),
                                ],
                                parser: "postcss-scss",
                                "local-plugins": true,
                            },
                        },
                    ]
                },
                {
                    test: /\.wasm$/,
                    loader: "file-loader",
                    type: "javascript/auto", // https://github.com/webpack/webpack/issues/6725
                    options: {
                        name: '[name].[hash:7].[ext]',
                        outputPath: '.',
                    },
                },
                {
                    // cache-bust languages.json file placed in
                    // riot-web/webapp/i18n during build by copy-res.js
                    test: /\.*languages.json$/,
                    type: "javascript/auto",
                    loader: 'file-loader',
                    options: {
                        name: 'i18n/[name].[hash:7].[ext]',
                    },
                },
                {
                    test: /\.(gif|png|svg|ttf|woff|woff2|xml|ico)$/,
                    // Use a content-based hash in the name so that we can set a long cache
                    // lifetime for assets while still delivering changes quickly.
                    oneOf: [
                        {
                            // Assets referenced in CSS files
                            issuer: /\.(scss|css)$/,
                            loader: 'file-loader',
                            options: {
                                esModule: false,
                                name: '[name].[hash:7].[ext]',
                                outputPath: getImgOutputPath,
                                publicPath: function(url, resourcePath) {
                                    // CSS image usages end up in the `bundles/[hash]` output
                                    // directory, so we adjust the final path to navigate up
                                    // twice.
                                    const outputPath = getImgOutputPath(url, resourcePath);
                                    return toPublicPath(path.join("../..", outputPath));
                                },
                            },
                        },
                        {
                            // Assets referenced in HTML and JS files
                            loader: 'file-loader',
                            options: {
                                esModule: false,
                                name: '[name].[hash:7].[ext]',
                                outputPath: getImgOutputPath,
                                publicPath: function(url, resourcePath) {
                                    const outputPath = getImgOutputPath(url, resourcePath);
                                    return toPublicPath(outputPath);
                                },
                            },
                        },
                    ],
                },
            ]
        },

        plugins: [
            new webpack.DefinePlugin({
                'process.env': {
                    NODE_ENV: JSON.stringify(process.env.NODE_ENV),
                },
            }),

            // This exports our CSS using the splitChunks and loaders above.
            new MiniCssExtractPlugin({
                filename: 'bundles/[hash]/[name].css',
                ignoreOrder: false, // Enable to remove warnings about conflicting order
            }),

            // This is the app's main entry point.
            new HtmlWebpackPlugin({
                template: './src/vector/index.html',

                // we inject the links ourselves via the template, because
                // HtmlWebpackPlugin will screw up our formatting like the names
                // of the themes and which chunks we actually care about.
                inject: false,
                excludeChunks: ['mobileguide'],
                minify: argv.mode === 'production',
                vars: {
                    og_image_url: og_image_url,
                },
            }),

            // This is the mobile guide's entry point (separate for faster mobile loading)
            new HtmlWebpackPlugin({
                template: './src/vector/mobile_guide/index.html',
                filename: 'mobile_guide/index.html',
                minify: argv.mode === 'production',
                chunks: ['mobileguide'],
            }),
        ],

        output: {
            path: path.join(__dirname, "webapp"),

            // The generated JS (and CSS, from the extraction plugin) are put in a
            // unique subdirectory for the build. There will only be one such
            // 'bundle' directory in the generated tarball; however, hosting
            // servers can collect 'bundles' from multiple versions into one
            // directory and symlink it into place - this allows users who loaded
            // an older version of the application to continue to access webpack
            // chunks even after the app is redeployed.
            filename: "bundles/[hash]/[name].js",
            chunkFilename: "bundles/[hash]/[name].js",
        },

        // configuration for the webpack-dev-server
        devServer: {
            // serve unwebpacked assets from webapp.
            contentBase: './webapp',

            stats: {
                // don't fill the console up with a mahoosive list of modules
                chunks: false,
            },

            // hot module replacement doesn't work (I think we'd need react-hot-reload?)
            // so webpack-dev-server reloads the page on every update which is quite
            // tedious in Riot since that can take a while.
            hot: false,
            inline: false,
        },
    };
};

/**
 * Merge assets found via CSS and imports into a single tree, while also preserving
 * directories under `res`.
 *
 * @param {string} url The adjusted name of the file, such as `warning.1234567.svg`.
 * @param {string} resourcePath The absolute path to the source file with unmodified name.
 * @return {string} The returned paths will look like `img/warning.1234567.svg`.
 */
function getImgOutputPath(url, resourcePath) {
    const prefix = /^.*[/\\]res[/\\]/;
    const outputDir = path.dirname(resourcePath).replace(prefix, "");
    return path.join(outputDir, path.basename(url));
}

/**
 * Convert path to public path format, which always uses forward slashes, since it will
 * be placed directly into things like CSS files.
 *
 * @param {string} path Some path to a file.
 */
function toPublicPath(path) {
    return path.replace(/\\/g, '/');
}
<|endoftext|>


<commit_before>const BabiliPlugin = require('babili-webpack-plugin');
const CopyPlugin = require('copy-webpack-plugin');
const HtmlPluign = require('html-webpack-plugin');
const path = require('path');
const DefinePlugin = require('webpack/lib/DefinePlugin');
const pkg = require('./package.json');

process.env.NODE_ENV = process.env.NODE_ENV || 'development';

module.exports = {
  devtool: process.env.NODE_ENV === 'development' ? 'cheap-module-eval-source-map' : 'source-map',
  entry: path.join(__dirname, 'src', 'client.jsx'),
  module: {
    loaders: [
      {
        exclude: /node_modules/,
        loader: 'babel',
        test: /\.jsx?$/,
      },
      {
        loaders: [
          'isomorphic-style',
          'css',
        ],
        test: /\.css$/,
      },
      {
        loader: 'handlebars',
        test: /\.hbs/,
      },
    ],
  },
  output: {
    filename: process.env.NODE_ENV === 'development' ? '[name].js?[chunkhash]' : '[name].[chunkhash].js',
    path: path.join(__dirname, 'build', 'public'),
    publicPath: '/',
  },
  plugins: [
    new HtmlPluign({
      minify: {
        collapseBooleanAttributes: true,
        collapseWhitespace: true,
        removeAttributeQuotes: true,
        removeOptionalTags: true,
        removeScriptTypeAttributes: true,
        removeStyleLinkTypeAttributes: true,
      },
      template: path.join(__dirname, 'src', 'templates', 'index.hbs'),
      title: process.env.BABERU_TV_SITE_NAME || `${pkg.name} (v${pkg.version})`,
    }),
    new DefinePlugin({
      'process.env.NODE_ENV': `'${process.env.NODE_ENV}'`,
    }),
    new CopyPlugin([
      {
        from: path.join(__dirname, 'src', 'assets', 'favicon.ico'),
        to: path.join(__dirname, 'build', 'public', 'favicon.ico'),
      },
    ]),
    ...(process.env.NODE_ENV !== 'development' ? [
      new BabiliPlugin(),
    ] : []),
  ],
  resolve: {
    extensions: [
      '.js',
      '.jsx',
    ],
  },
};
<commit_msg>Add webpack optimize plugins Close #90 (#104)<commit_after>const BabiliPlugin = require('babili-webpack-plugin');
const CopyPlugin = require('copy-webpack-plugin');
const HtmlPluign = require('html-webpack-plugin');
const path = require('path');
const DefinePlugin = require('webpack/lib/DefinePlugin');
const DedupePlugin = require('webpack/lib/optimize/DedupePlugin');
const OccurrenceOrderPlugin = require('webpack/lib/optimize/OccurrenceOrderPlugin');
const pkg = require('./package.json');

process.env.NODE_ENV = process.env.NODE_ENV || 'development';

module.exports = {
  devtool: process.env.NODE_ENV === 'development' ? 'cheap-module-eval-source-map' : 'source-map',
  entry: path.join(__dirname, 'src', 'client.jsx'),
  module: {
    loaders: [
      {
        exclude: /node_modules/,
        loader: 'babel',
        test: /\.jsx?$/,
      },
      {
        loaders: [
          'isomorphic-style',
          'css',
        ],
        test: /\.css$/,
      },
      {
        loader: 'handlebars',
        test: /\.hbs/,
      },
    ],
  },
  output: {
    filename: process.env.NODE_ENV === 'development' ? '[name].js?[chunkhash]' : '[name].[chunkhash].js',
    path: path.join(__dirname, 'build', 'public'),
    publicPath: '/',
  },
  plugins: [
    new HtmlPluign({
      minify: {
        collapseBooleanAttributes: true,
        collapseWhitespace: true,
        removeAttributeQuotes: true,
        removeOptionalTags: true,
        removeScriptTypeAttributes: true,
        removeStyleLinkTypeAttributes: true,
      },
      template: path.join(__dirname, 'src', 'templates', 'index.hbs'),
      title: process.env.BABERU_TV_SITE_NAME || `${pkg.name} (v${pkg.version})`,
    }),
    new DefinePlugin({
      'process.env.NODE_ENV': `'${process.env.NODE_ENV}'`,
    }),
    new CopyPlugin([
      {
        from: path.join(__dirname, 'src', 'assets', 'favicon.ico'),
        to: path.join(__dirname, 'build', 'public', 'favicon.ico'),
      },
    ]),
    ...(process.env.NODE_ENV !== 'development' ? [
      new DedupePlugin(),
      new OccurrenceOrderPlugin(),
      new BabiliPlugin(),
    ] : []),
  ],
  resolve: {
    extensions: [
      '.js',
      '.jsx',
    ],
  },
};
<|endoftext|>


<commit_before>const path = require('path');
const webpack = require('webpack');

module.exports = {
  entry: {
    index: './src/js/index.js',
    options: './src/js/options.js',
    content: './src/js/content.js',
    background: './src/js/background.js'
  },
  output: {
    path: path.resolve(__dirname, 'build'),
    filename: '[name].bundle.js'
  },
  plugins: [
    new webpack.ProvidePlugin({
      jQuery: 'jquery' // for jquery.esarea
    })
  ]
};
<commit_msg>Comment needless plugin<commit_after>const path = require('path');
const webpack = require('webpack');

module.exports = {
  entry: {
    index: './src/js/index.js',
    options: './src/js/options.js',
    content: './src/js/content.js',
    background: './src/js/background.js'
  },
  output: {
    path: path.resolve(__dirname, 'build'),
    filename: '[name].bundle.js'
  }
  // plugins: [
  //   new webpack.ProvidePlugin({
  //     jQuery: 'jquery'
  //   })
  // ]
};
<|endoftext|>


<commit_before>// Place your application-specific JavaScript functions and classes here
// This file is automatically included by javascript_include_tag :defaults

/* Fire up the slideshow -Jared 11/30/10 */
$(document).ready(function(){
	$('#gallery-container').show();
	$('#gallery').galleria({
		autoplay: 5000
		, image_crop: true
		, transition: 'fade'
		, transition_speed: 1000
	});
});

function add_round (link, association, content) {
  var new_id = new Date().getTime();
  var regexp = new RegExp("new_" + association, "g")
  $('.rounds-container').append( content.replace(regexp, new_id) );
}

function remove_round (elm) {
  /* Mark the hidden _destroy field for this round -Jared 1/25/11 */
  var hiddenField = $(elm).siblings('.tournament-round-destroy');
  if (hiddenField.length != 1) { throw 'Unable to find exactly one hidden field'; }
  hiddenField.val(1);

  /* Hide the set of inputs for this round -Jared 1/25/11 */
  var round = $(elm).parent('.tournament-round');
  if (round.length != 1) { throw 'Unable to find exactly one round'; }
  round.hide();
}<commit_msg>whitespace only<commit_after>// Place your application-specific JavaScript functions and classes here
// This file is automatically included by javascript_include_tag :defaults

/* Fire up the slideshow -Jared 11/30/10 */
$(document).ready(function(){
	$('#gallery-container').show();
	$('#gallery').galleria({
		autoplay: 5000
		, image_crop: true
		, transition: 'fade'
		, transition_speed: 1000
	});
});

function add_round (link, association, content) {
  var new_id = new Date().getTime();
  var regexp = new RegExp("new_" + association, "g")
  $('.rounds-container').append( content.replace(regexp, new_id) );
}

function remove_round (elm) {
  /* Mark the hidden _destroy field for this round -Jared 1/25/11 */
  var hiddenField = $(elm).siblings('.tournament-round-destroy');
  if (hiddenField.length != 1) { throw 'Unable to find exactly one hidden field'; }
  hiddenField.val(1);

  /* Hide the set of inputs for this round -Jared 1/25/11 */
  var round = $(elm).parent('.tournament-round');
  if (round.length != 1) { throw 'Unable to find exactly one round'; }
  round.hide();
}
<|endoftext|>


<commit_before>// @ts-check
// Helper: root() is defined at the bottom
const path = require('path');
const webpack = require('webpack');

// Webpack Plugins
const CommonsChunkPlugin = webpack.optimize.CommonsChunkPlugin;
const autoprefixer = require('autoprefixer');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const { TsConfigPathsPlugin } = require('awesome-typescript-loader');

/**
 * Env
 * Get npm lifecycle event to identify the environment
 */
const ENV = process.env.npm_lifecycle_event;
const isProd = ENV === 'build-demo';

module.exports = function makeWebpackConfig() {
    /**
     * Config
     * Reference: http://webpack.github.io/docs/configuration.html
     * This is the object where all configuration gets set
     */
    let config = {};

    /**
     * Devtool
     * Reference: http://webpack.github.io/docs/configuration.html#devtool
     * Type of sourcemap to use per build type
     */
    if (isProd) {
        config.devtool = 'source-map';
    } else {
        config.devtool = 'eval-source-map';
    }

    /**
       * Entry
       * Reference: http://webpack.github.io/docs/configuration.html#entry
       */
    config.entry = {
        'app': './src/demo/main.ts', // our angular app,
        'polyfills': './src/demo/polyfills.ts',
        'vendor': './src/demo/vendor.ts',
    };

    /**
     * Output
     * Reference: http://webpack.github.io/docs/configuration.html#output
     */
    config.output = {
        path: root('dist'),
        publicPath: isProd ? 'ng-select' : 'http://localhost:8080/',
        filename: isProd ? 'js/[name].[hash].js' : 'js/[name].js',
        chunkFilename: isProd ? '[id].[hash].chunk.js' : '[id].chunk.js'
    };

    /**
     * Resolve
     * Reference: http://webpack.github.io/docs/configuration.html#resolve
     */
    config.resolve = {
        // only discover files that have those extensions
        extensions: ['.ts', '.js', '.json', '.css', '.scss', '.html'],
        plugins: [
            new TsConfigPathsPlugin({
                configFileName: 'src/demo/tsconfig.json',
                compiler: 'typescript'
            })
        ]
    };

    /**
     * Loaders
     * Reference: http://webpack.github.io/docs/configuration.html#module-loaders
     * List: http://webpack.github.io/docs/list-of-loaders.html
     * This handles most of the magic responsible for converting modules
     */
    config.module = {
        rules: [
            // Support for .ts files.
            {
                test: /\.ts$/,
                loaders: ['awesome-typescript-loader?configFileName=./src/demo/tsconfig.json', 'angular2-template-loader', '@angularclass/hmr-loader'],
                exclude: [/\.(spec|e2e)\.ts$/, /node_modules\/(?!(ng2-.+))/],
            },

            // copy those assets to output
            {
                test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
                loader: 'file-loader?name=fonts/[name].[hash].[ext]?'
            },

            // Support for *.json files.
            { test: /\.json$/, loader: 'json-loader' },

            // all scss files in app demo style will be merged to index.html
            {
                test: /\.scss$/,
                include: root('src', 'demo', 'style'),
                loader: ExtractTextPlugin.extract({fallback: 'style-loader', use: ['css-loader', 'postcss-loader']})
            },

            // all css required in src/lib files will be merged in js files
            {test: /\.(scss|sass)$/, exclude: root('src', 'demo', 'style'), loader: 'raw-loader!postcss-loader!sass-loader'},

            // support for .html as raw text
            // todo: change the loader to something that adds a hash to images
            { test: /\.html$/, loader: 'raw-loader', exclude: root('src', 'public') }
        ]
    };

    config.module.rules.push({
        test: /\.ts$/,
        enforce: 'pre',
        loader: 'tslint-loader'
    });

    /**
     * Plugins
     * Reference: http://webpack.github.io/docs/configuration.html#plugins
     * List: http://webpack.github.io/docs/list-of-plugins.html
     */
    config.plugins = [
        // Define env constiables to help with builds
        // Reference: https://webpack.github.io/docs/list-of-plugins.html#defineplugin
        new webpack.DefinePlugin({
            // Environment helpers
            'process.env': {
                ENV: JSON.stringify(ENV)
            }
        }),

        // Workaround needed for angular 2 angular/angular#11580
        new webpack.ContextReplacementPlugin(
            // The (\\|\/) piece accounts for path separators in *nix and Windows
            /angular(\\|\/)core(\\|\/)@angular/,
            root('./src/demo/') // location of your src
        ),

        // Tslint configuration for webpack 2
        new webpack.LoaderOptionsPlugin({
            options: {
                /**
                 * Apply the tslint loader as pre/postLoader
                 * Reference: https://github.com/wbuchwalter/tslint-loader
                 */
                tslint: {
                    emitErrors: false,
                    failOnHint: false
                },
                /**
                 * Sass
                 * Reference: https://github.com/jtangelder/sass-loader
                 * Transforms .scss files to .css
                 */
                sassLoader: {
                    //includePaths: [path.resolve(__dirname, "node_modules/foundation-sites/scss")]
                },
                /**
                 * PostCSS
                 * Reference: https://github.com/postcss/autoprefixer-core
                 * Add vendor prefixes to your css
                 */
                postcss: [
                    autoprefixer({
                        browsers: ['last 2 version']
                    })
                ]
            }
        })
    ];

    config.plugins.push(
        // Generate common chunks if necessary
        // Reference: https://webpack.github.io/docs/code-splitting.html
        // Reference: https://webpack.github.io/docs/list-of-plugins.html#commonschunkplugin
        new CommonsChunkPlugin({
            names: ['vendor', 'polyfills']
        }),

        // Inject script and link tags into html files
        // Reference: https://github.com/ampedandwired/html-webpack-plugin
        new HtmlWebpackPlugin({
            template: './src/demo/index.ejs',
            chunksSortMode: 'dependency',
            basePath: isProd ? '/ng-select' : '/'
        }),

        // Extract css files
        // Reference: https://github.com/webpack/extract-text-webpack-plugin
        // Disabled when in test mode or not in build mode
        new ExtractTextPlugin({ filename: 'css/[name].[hash].css', disable: !isProd })
    );

    // Add build specific plugins
    if (isProd) {
        config.plugins.push(
            // Reference: http://webpack.github.io/docs/list-of-plugins.html#noerrorsplugin
            // Only emit files when there are no errors
            new webpack.NoEmitOnErrorsPlugin(),

            // // Reference: http://webpack.github.io/docs/list-of-plugins.html#dedupeplugin
            // // Dedupe modules in the output
            // new webpack.optimize.DedupePlugin(),

            // Reference: http://webpack.github.io/docs/list-of-plugins.html#uglifyjsplugin
            // Minify all javascript, switch loaders to minimizing mode
            new webpack.optimize.UglifyJsPlugin({ sourceMap: true, mangle: { keep_fnames: true } })
        );
    }

    config.plugins.push(
        // Copy assets from the public folder
        // Reference: https://github.com/kevlened/copy-webpack-plugin
        new CopyWebpackPlugin([{
            from: root('src/demo/assets')
        }])
    );

    /**
     * Dev server configuration
     * Reference: http://webpack.github.io/docs/configuration.html#devserver
     * Reference: http://webpack.github.io/docs/webpack-dev-server.html
     */
    config.devServer = {
        contentBase: './src/demo',
        historyApiFallback: true,
        quiet: true,
        stats: 'normal' // none (or false), errors-only, minimal, normal (or true) and verbose
    };

    return config;
}();

// Helper functions
function root(args) {
    args = Array.prototype.slice.call(arguments, 0);
    return path.join.apply(path, [__dirname].concat(args));
}<commit_msg>Copy package.json<commit_after>// @ts-check
// Helper: root() is defined at the bottom
const path = require('path');
const webpack = require('webpack');

// Webpack Plugins
const CommonsChunkPlugin = webpack.optimize.CommonsChunkPlugin;
const autoprefixer = require('autoprefixer');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const { TsConfigPathsPlugin } = require('awesome-typescript-loader');

/**
 * Env
 * Get npm lifecycle event to identify the environment
 */
const ENV = process.env.npm_lifecycle_event;
const isProd = ENV === 'build-demo';

module.exports = function makeWebpackConfig() {
    /**
     * Config
     * Reference: http://webpack.github.io/docs/configuration.html
     * This is the object where all configuration gets set
     */
    let config = {};

    /**
     * Devtool
     * Reference: http://webpack.github.io/docs/configuration.html#devtool
     * Type of sourcemap to use per build type
     */
    if (isProd) {
        config.devtool = 'source-map';
    } else {
        config.devtool = 'eval-source-map';
    }

    /**
       * Entry
       * Reference: http://webpack.github.io/docs/configuration.html#entry
       */
    config.entry = {
        'app': './src/demo/main.ts', // our angular app,
        'polyfills': './src/demo/polyfills.ts',
        'vendor': './src/demo/vendor.ts',
    };

    /**
     * Output
     * Reference: http://webpack.github.io/docs/configuration.html#output
     */
    config.output = {
        path: root('dist'),
        publicPath: isProd ? 'ng-select' : 'http://localhost:8080/',
        filename: isProd ? 'js/[name].[hash].js' : 'js/[name].js',
        chunkFilename: isProd ? '[id].[hash].chunk.js' : '[id].chunk.js'
    };

    /**
     * Resolve
     * Reference: http://webpack.github.io/docs/configuration.html#resolve
     */
    config.resolve = {
        // only discover files that have those extensions
        extensions: ['.ts', '.js', '.json', '.css', '.scss', '.html'],
        plugins: [
            new TsConfigPathsPlugin({
                configFileName: 'src/demo/tsconfig.json',
                compiler: 'typescript'
            })
        ]
    };

    /**
     * Loaders
     * Reference: http://webpack.github.io/docs/configuration.html#module-loaders
     * List: http://webpack.github.io/docs/list-of-loaders.html
     * This handles most of the magic responsible for converting modules
     */
    config.module = {
        rules: [
            // Support for .ts files.
            {
                test: /\.ts$/,
                loaders: ['awesome-typescript-loader?configFileName=./src/demo/tsconfig.json', 'angular2-template-loader', '@angularclass/hmr-loader'],
                exclude: [/\.(spec|e2e)\.ts$/, /node_modules\/(?!(ng2-.+))/],
            },

            // copy those assets to output
            {
                test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
                loader: 'file-loader?name=fonts/[name].[hash].[ext]?'
            },

            // Support for *.json files.
            { test: /\.json$/, loader: 'json-loader' },

            // all scss files in app demo style will be merged to index.html
            {
                test: /\.scss$/,
                include: root('src', 'demo', 'style'),
                loader: ExtractTextPlugin.extract({ fallback: 'style-loader', use: ['css-loader', 'postcss-loader'] })
            },

            // all css required in src/lib files will be merged in js files
            { test: /\.(scss|sass)$/, exclude: root('src', 'demo', 'style'), loader: 'raw-loader!postcss-loader!sass-loader' },

            // support for .html as raw text
            // todo: change the loader to something that adds a hash to images
            { test: /\.html$/, loader: 'raw-loader', exclude: root('src', 'public') }
        ]
    };

    config.module.rules.push({
        test: /\.ts$/,
        enforce: 'pre',
        loader: 'tslint-loader'
    });

    /**
     * Plugins
     * Reference: http://webpack.github.io/docs/configuration.html#plugins
     * List: http://webpack.github.io/docs/list-of-plugins.html
     */
    config.plugins = [
        // Define env constiables to help with builds
        // Reference: https://webpack.github.io/docs/list-of-plugins.html#defineplugin
        new webpack.DefinePlugin({
            // Environment helpers
            'process.env': {
                ENV: JSON.stringify(ENV)
            }
        }),

        // Workaround needed for angular 2 angular/angular#11580
        new webpack.ContextReplacementPlugin(
            // The (\\|\/) piece accounts for path separators in *nix and Windows
            /angular(\\|\/)core(\\|\/)@angular/,
            root('./src/demo/') // location of your src
        ),

        // Tslint configuration for webpack 2
        new webpack.LoaderOptionsPlugin({
            options: {
                /**
                 * Apply the tslint loader as pre/postLoader
                 * Reference: https://github.com/wbuchwalter/tslint-loader
                 */
                tslint: {
                    emitErrors: false,
                    failOnHint: false
                },
                /**
                 * Sass
                 * Reference: https://github.com/jtangelder/sass-loader
                 * Transforms .scss files to .css
                 */
                sassLoader: {
                    //includePaths: [path.resolve(__dirname, "node_modules/foundation-sites/scss")]
                },
                /**
                 * PostCSS
                 * Reference: https://github.com/postcss/autoprefixer-core
                 * Add vendor prefixes to your css
                 */
                postcss: [
                    autoprefixer({
                        browsers: ['last 2 version']
                    })
                ]
            }
        })
    ];

    config.plugins.push(
        // Generate common chunks if necessary
        // Reference: https://webpack.github.io/docs/code-splitting.html
        // Reference: https://webpack.github.io/docs/list-of-plugins.html#commonschunkplugin
        new CommonsChunkPlugin({
            names: ['vendor', 'polyfills']
        }),

        // Inject script and link tags into html files
        // Reference: https://github.com/ampedandwired/html-webpack-plugin
        new HtmlWebpackPlugin({
            template: './src/demo/index.ejs',
            chunksSortMode: 'dependency',
            basePath: isProd ? '/ng-select' : '/'
        }),

        // Extract css files
        // Reference: https://github.com/webpack/extract-text-webpack-plugin
        // Disabled when in test mode or not in build mode
        new ExtractTextPlugin({ filename: 'css/[name].[hash].css', disable: !isProd })
    );

    // Add build specific plugins
    if (isProd) {
        config.plugins.push(
            // Reference: http://webpack.github.io/docs/list-of-plugins.html#noerrorsplugin
            // Only emit files when there are no errors
            new webpack.NoEmitOnErrorsPlugin(),

            // // Reference: http://webpack.github.io/docs/list-of-plugins.html#dedupeplugin
            // // Dedupe modules in the output
            // new webpack.optimize.DedupePlugin(),

            // Reference: http://webpack.github.io/docs/list-of-plugins.html#uglifyjsplugin
            // Minify all javascript, switch loaders to minimizing mode
            new webpack.optimize.UglifyJsPlugin({ sourceMap: true, mangle: { keep_fnames: true } })
        );
    }

    config.plugins.push(
        // Copy assets from the public folder
        // Reference: https://github.com/kevlened/copy-webpack-plugin
        new CopyWebpackPlugin([
            {
                from: root('src/demo/assets')
            },
            {
                from: root('package.json')
            }
        ])
    );

    /**
     * Dev server configuration
     * Reference: http://webpack.github.io/docs/configuration.html#devserver
     * Reference: http://webpack.github.io/docs/webpack-dev-server.html
     */
    config.devServer = {
        contentBase: './src/demo',
        historyApiFallback: true,
        quiet: true,
        stats: 'normal' // none (or false), errors-only, minimal, normal (or true) and verbose
    };

    return config;
}();

// Helper functions
function root(args) {
    args = Array.prototype.slice.call(arguments, 0);
    return path.join.apply(path, [__dirname].concat(args));
}<|endoftext|>


<commit_before>$(document).ready(function() {
  $(".toggleable").not(".open").hide();

  $(".toggle-handler").live("click", function() {
    $(this).children(".toggleable").toggle("blind");
  });

  $(".activate-keywords").bind("click", function(e) {
    e.preventDefault();
    $("body").toggleClass("highlight-keywords", 1000);
  });
});<commit_msg>Blinky cursor thing\!<commit_after>var blink = function(element, speed) {
  if (speed === undefined) {
    speed = 50;
  }

  var antispeed = 1000 - speed;
  element.fadeOut(speed, function() {
    setTimeout(function() { element.fadeIn(speed, function() {
      setTimeout(function() { blink(element) }, antispeed)
    }) }, antispeed);
  });
};

$(document).ready(function() {
  $(".toggleable").not(".open").hide();

  // Obnoxious blinky cursor!
  blink($(".cursor"));

  $(".toggle-handler").live("click", function() {
    $(this).children(".toggleable").toggle("blind");
  });

  $(".activate-keywords").bind("click", function(e) {
    e.preventDefault();
    $("#content").toggleClass("highlight-keywords", 1000);
  });
});<|endoftext|>


<commit_before>const os = require('os');
const path = require('path');
const webpack = require('webpack');
const StyleLintPlugin = require('stylelint-webpack-plugin');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const WebappWebpackPlugin = require('webapp-webpack-plugin')

const src = path.resolve(__dirname, 'src');

const cacheLoader = {
  loader: 'cache-loader',
  options: {
    cacheDirectory: path.resolve(os.tmpdir(), 'steady', 'cache'),
  },
};

const tsLoader = {
  loader: 'ts-loader',
  options: {
    happyPackMode: true,
  },
};

const cssLoader = {
  loader: 'css-loader',
  options: {
    importLoaders: 2,
  }
};

const stats = {
  children: false,
  hash: false,
  modules: false,
  version: false,
};

module.exports = mode => ((process.env.NODE_ENV = mode), {
  mode,

  entry: {
    app: ['index.tsx', 'index.scss'],
  },

  output: {
    filename: '[name].[hash].js',
  },

  resolve: {
    extensions: ['.js', '.jsx', '.ts', '.tsx', '.json'],
    modules: [src, 'node_modules'],
  },

  module: {
    rules: [
      {
        test: /\.tsx?$/,
        loader: 'tslint-loader',
        exclude: /node_modules/,
        enforce: 'pre',
        options: {
          typeCheck: true,
        },
      },

      {
        test: /\.tsx?$/,
        use: [cacheLoader, 'thread-loader', 'babel-loader', tsLoader],
        exclude: /node_modules/,
      },

      {
        test: /\.svg$/,
        issuer: /\.tsx$/,
        use: [cacheLoader, 'thread-loader', 'babel-loader', 'svg-react-loader'],
      },

      {
        test: /\.s?css$/,
        use: ExtractTextPlugin.extract({
          fallback: 'style-loader',
          use: [cacheLoader, cssLoader, 'postcss-loader', 'sass-loader'],
        })
      },

      {
        test: /\.html$/,
        loader: 'html-loader',
      },

      {
        test: /\.svg$/,
        issuer: /\.html$/,
        loader: 'url-loader',
      },
    ]
  },

  stats,

  devServer: {
    stats,
    overlay: true,
  },

  optimization: {
    splitChunks: {
      chunks: 'all',
      name: 'vendors',
    },
  },

  plugins: [
    mode === 'production'
      ? new webpack.HashedModuleIdsPlugin()
      : new webpack.NamedModulesPlugin()
    ,

    new StyleLintPlugin({
      glob: `${src}/**/*.scss`,
      emitErrors: false,
    }),

    new ForkTsCheckerWebpackPlugin({
      async: false,
      checkSyntacticErrors: true,
    }),

    new HtmlWebpackPlugin({
      inject: 'body',
      template: path.resolve(src, 'index.html'),
    }),

    new ExtractTextPlugin({
      filename: '[name].[hash].css',
      disable: mode !== 'production',
    }),

    new WebappWebpackPlugin({
      logo: 'icon/brand.svg',
      prefix: 'assets.[hash]/',
      favicons: {
        start_url: '/steady',
        theme_color: '#343a40',
        background: '#343a40',
        icons: {
          coast: false,
          firefox: false,
          yandex: false,
        },
      },
    }),
  ]
});
<commit_msg>do not emit Windows 8 tile icons<commit_after>const os = require('os');
const path = require('path');
const webpack = require('webpack');
const StyleLintPlugin = require('stylelint-webpack-plugin');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const WebappWebpackPlugin = require('webapp-webpack-plugin')

const src = path.resolve(__dirname, 'src');

const cacheLoader = {
  loader: 'cache-loader',
  options: {
    cacheDirectory: path.resolve(os.tmpdir(), 'steady', 'cache'),
  },
};

const tsLoader = {
  loader: 'ts-loader',
  options: {
    happyPackMode: true,
  },
};

const cssLoader = {
  loader: 'css-loader',
  options: {
    importLoaders: 2,
  }
};

const stats = {
  children: false,
  hash: false,
  modules: false,
  version: false,
};

module.exports = mode => ((process.env.NODE_ENV = mode), {
  mode,

  entry: {
    app: ['index.tsx', 'index.scss'],
  },

  output: {
    filename: '[name].[hash].js',
  },

  resolve: {
    extensions: ['.js', '.jsx', '.ts', '.tsx', '.json'],
    modules: [src, 'node_modules'],
  },

  module: {
    rules: [
      {
        test: /\.tsx?$/,
        loader: 'tslint-loader',
        exclude: /node_modules/,
        enforce: 'pre',
        options: {
          typeCheck: true,
        },
      },

      {
        test: /\.tsx?$/,
        use: [cacheLoader, 'thread-loader', 'babel-loader', tsLoader],
        exclude: /node_modules/,
      },

      {
        test: /\.svg$/,
        issuer: /\.tsx$/,
        use: [cacheLoader, 'thread-loader', 'babel-loader', 'svg-react-loader'],
      },

      {
        test: /\.s?css$/,
        use: ExtractTextPlugin.extract({
          fallback: 'style-loader',
          use: [cacheLoader, cssLoader, 'postcss-loader', 'sass-loader'],
        })
      },

      {
        test: /\.html$/,
        loader: 'html-loader',
      },

      {
        test: /\.svg$/,
        issuer: /\.html$/,
        loader: 'url-loader',
      },
    ]
  },

  stats,

  devServer: {
    stats,
    overlay: true,
  },

  optimization: {
    splitChunks: {
      chunks: 'all',
      name: 'vendors',
    },
  },

  plugins: [
    mode === 'production'
      ? new webpack.HashedModuleIdsPlugin()
      : new webpack.NamedModulesPlugin()
    ,

    new StyleLintPlugin({
      glob: `${src}/**/*.scss`,
      emitErrors: false,
    }),

    new ForkTsCheckerWebpackPlugin({
      async: false,
      checkSyntacticErrors: true,
    }),

    new HtmlWebpackPlugin({
      inject: 'body',
      template: path.resolve(src, 'index.html'),
    }),

    new ExtractTextPlugin({
      filename: '[name].[hash].css',
      disable: mode !== 'production',
    }),

    new WebappWebpackPlugin({
      logo: 'icon/brand.svg',
      prefix: 'assets.[hash]/',
      favicons: {
        start_url: '/steady',
        theme_color: '#343a40',
        background: '#343a40',
        icons: {
          coast: false,
          firefox: false,
          windows: false,
          yandex: false,
        },
      },
    }),
  ]
});
<|endoftext|>


<commit_before>/* eslint-env node */
/* eslint-disable no-var, func-names, prefer-arrow-callback, prefer-template */
var path = require('path');
var webpack = require('webpack');
var BundleTracker = require('webpack-bundle-tracker');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var argv = require('yargs').argv;
var childProcess = require('child_process');

const BOLD = '\u001b[1m';
const END_BOLD = '\u001b[39m\u001b[22m';
const production = process.env.NODE_ENV === 'production';

var plugins = [
  new BundleTracker({ filename: './webpack-stats.json' }),
  new webpack.optimize.OccurrenceOrderPlugin(true),
  new ExtractTextPlugin(production ? '[name]-[hash].css' : '[name].css'),
  new webpack.DefinePlugin({
    PRODUCTION: production,
    DEVELOPMENT: !production,
    process: {
      env: {
        NODE_ENV: production ? '"production"' : '"development"',
      },
    },
  }),
];

if (production) {
  plugins = plugins.concat([
    new webpack.optimize.DedupePlugin(),
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false,
      },
    }),
  ]);
} else {
  plugins = plugins.concat([
    new webpack.NoErrorsPlugin(),
  ]);
}

module.exports = [
  {
    context: __dirname,
    devtool: production ? undefined : 'cheap-module-eval-source-map',

    entry: {
      selfrepair: [
        'babel-polyfill',
        './client/selfrepair/self_repair.js',
      ],
      control: [
        'babel-polyfill',
        './client/control/index.js',
        './client/control/sass/control.scss',
        './node_modules/font-awesome/scss/font-awesome.scss',
      ],
    },

    output: {
      path: path.resolve('./assets/bundles/'),
      filename: production ? '[name]-[hash].js' : '[name].js',
      chunkFilename: '[id].bundle.js',
    },
    externals: {
      'react/lib/ExecutionEnvironment': true,
      'react/lib/ReactContext': true,
      'react/addons': true,
    },

    plugins,

    module: {
      loaders: [
        {
          test: /\.js$/,
          exclude: /node_modules/,
          loader: 'babel',
        },
        {
          test: /\.json$/,
          loader: 'json-loader',
        },
        {
          test: /\.scss$/,
          loader: ExtractTextPlugin.extract('style', 'css?sourceMap!postcss!sass?sourceMap'),
        },
        {
          test: /\.(ttf|eot|svg|woff(2)?)(\?[a-z0-9=&.]+)?$/,
          loader: 'file-loader',
        },
      ],
    },

    resolve: {
      alias: {
        app: path.resolve(__dirname, './client/control/app.js'),
        stores: path.resolve(__dirname, './client/control/stores'),
        reducers: path.resolve(__dirname, './client/control/reducers'),
        actions: path.resolve(__dirname, './client/control/actions'),
        components: path.resolve(__dirname, './client/control/components'),
      },
    },
  },
  {
    devtool: production ? undefined : 'cheap-module-eval-source-map',

    entry: {
      'console-log': './client/actions/console-log/index',
      'show-heartbeat': './client/actions/show-heartbeat/index',
    },

    plugins: [
      new BundleTracker({ filename: './webpack-stats-actions.json' }),
      new webpack.optimize.DedupePlugin(),
      new webpack.optimize.OccurrenceOrderPlugin(),
      new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false } }),

        // Small plugin to update the actions in the database if
        // --update-actions was passed.
      function updateActions() {
        this.plugin('done', function () {
          var cmd;
          if (argv['update-actions']) {
            // Don't disable actions since this is mostly for development.
            cmd = 'python manage.py update_actions';

            childProcess.exec(cmd, function (err, stdout, stderr) {
              console.log('\n' + BOLD + 'Updating Actions' + END_BOLD);
              console.log(stdout);
              if (stderr) {
                console.error(stderr);
              }
            });
          }
        });
      },
    ],

    output: {
      path: path.resolve('./assets/bundles/'),
      filename: production ? '[name]-[hash].js' : '[name].js',
    },

    module: {
      loaders: [
        {
          test: /\.js$/,
          exclude: /node_modules/,
          loader: 'babel-loader',
          query: {
            plugins: [
                ['transform-runtime', {
                  polyfill: false,
                  regenerator: true,
                }],
            ],
          },
        },
      ],
    },
  },
];
<commit_msg>Add test, rout, selfrepair aliases<commit_after>/* eslint-env node */
/* eslint-disable no-var, func-names, prefer-arrow-callback, prefer-template */
var path = require('path');
var webpack = require('webpack');
var BundleTracker = require('webpack-bundle-tracker');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var argv = require('yargs').argv;
var childProcess = require('child_process');

const BOLD = '\u001b[1m';
const END_BOLD = '\u001b[39m\u001b[22m';
const production = process.env.NODE_ENV === 'production';

var plugins = [
  new BundleTracker({ filename: './webpack-stats.json' }),
  new webpack.optimize.OccurrenceOrderPlugin(true),
  new ExtractTextPlugin(production ? '[name]-[hash].css' : '[name].css'),
  new webpack.DefinePlugin({
    PRODUCTION: production,
    DEVELOPMENT: !production,
    process: {
      env: {
        NODE_ENV: production ? '"production"' : '"development"',
      },
    },
  }),
];

if (production) {
  plugins = plugins.concat([
    new webpack.optimize.DedupePlugin(),
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false,
      },
    }),
  ]);
} else {
  plugins = plugins.concat([
    new webpack.NoErrorsPlugin(),
  ]);
}

module.exports = [
  {
    context: __dirname,
    devtool: production ? undefined : 'cheap-module-eval-source-map',

    entry: {
      selfrepair: [
        'babel-polyfill',
        './client/selfrepair/self_repair.js',
      ],
      control: [
        'babel-polyfill',
        './client/control/index.js',
        './client/control/sass/control.scss',
        './node_modules/font-awesome/scss/font-awesome.scss',
      ],
    },

    output: {
      path: path.resolve('./assets/bundles/'),
      filename: production ? '[name]-[hash].js' : '[name].js',
      chunkFilename: '[id].bundle.js',
    },
    externals: {
      'react/lib/ExecutionEnvironment': true,
      'react/lib/ReactContext': true,
      'react/addons': true,
    },

    plugins,

    module: {
      loaders: [
        {
          test: /\.js$/,
          exclude: /node_modules/,
          loader: 'babel',
        },
        {
          test: /\.json$/,
          loader: 'json-loader',
        },
        {
          test: /\.scss$/,
          loader: ExtractTextPlugin.extract('style', 'css?sourceMap!postcss!sass?sourceMap'),
        },
        {
          test: /\.(ttf|eot|svg|woff(2)?)(\?[a-z0-9=&.]+)?$/,
          loader: 'file-loader',
        },
      ],
    },

    resolve: {
      alias: {
        app: path.resolve(__dirname, './client/control/app.js'),
        routes: path.resolve(__dirname, './client/control/routes.js'),
        stores: path.resolve(__dirname, './client/control/stores'),
        reducers: path.resolve(__dirname, './client/control/reducers'),
        actions: path.resolve(__dirname, './client/control/actions'),
        components: path.resolve(__dirname, './client/control/components'),
        tests: path.resolve(__dirname, './client/control/tests'),
        selfrepair: path.resolve(__dirname, './client/selfrepair'),
      },
    },
  },
  {
    devtool: production ? undefined : 'cheap-module-eval-source-map',

    entry: {
      'console-log': './client/actions/console-log/index',
      'show-heartbeat': './client/actions/show-heartbeat/index',
    },

    plugins: [
      new BundleTracker({ filename: './webpack-stats-actions.json' }),
      new webpack.optimize.DedupePlugin(),
      new webpack.optimize.OccurrenceOrderPlugin(),
      new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false } }),

        // Small plugin to update the actions in the database if
        // --update-actions was passed.
      function updateActions() {
        this.plugin('done', function () {
          var cmd;
          if (argv['update-actions']) {
            // Don't disable actions since this is mostly for development.
            cmd = 'python manage.py update_actions';

            childProcess.exec(cmd, function (err, stdout, stderr) {
              console.log('\n' + BOLD + 'Updating Actions' + END_BOLD);
              console.log(stdout);
              if (stderr) {
                console.error(stderr);
              }
            });
          }
        });
      },
    ],

    output: {
      path: path.resolve('./assets/bundles/'),
      filename: production ? '[name]-[hash].js' : '[name].js',
    },

    module: {
      loaders: [
        {
          test: /\.js$/,
          exclude: /node_modules/,
          loader: 'babel-loader',
          query: {
            plugins: [
                ['transform-runtime', {
                  polyfill: false,
                  regenerator: true,
                }],
            ],
          },
        },
      ],
    },
  },
];
<|endoftext|>


<commit_before>// application events
$(function() {
  //table sorting
  $(".items_list th a").live("click", function(e) {
    $.getScript(this.href);
    //fallback for old browsers
    if (!('pushState' in window.history)) return true
    //ensure middle, control and command clicks act normally
    //if (e.which == 2 || e.metaKey || e.ctrlKey) return true
    //push history!
    history.pushState(null, document.title, this.href);
    e.preventDefault();
  });

  //TODO: test it (Jasmine?)
  //machine 'virtual' toggling
  $('input#machine_virtual').live('change', function(e) {
    $('#machine-maintenance, #machine-physical-hardware').toggle();
    if ($('input#machine_virtual').attr('checked') == true) {
      $('#machine-hardware-title').html("Ressources");
    } else {
      $('#machine-hardware-title').html("Matériel");
    }
  });

  //filters observer
  submitFilters = function() {
    $.get($("form#filters").attr("action"), $("form#filters").serialize(), null, "script");
    //fallback for old browsers
    if (!('replaceState' in window.history)) return true
    //push our search to history
    var filters = jQuery.param( jQuery.grep( $('form#filters').serializeArray(), function(o){ return o.value != "" } ) )
    var url = $("form#filters").attr("action").split("?")[0] + "?" + filters
    history.replaceState(null, document.title, url);
  }
  $(".filters input").bindWithDelay("keyup", submitFilters, 300);
  $(".filters select").change(submitFilters);

  //back button for pushState's
  $(window).bind("popstate", function() {
    //commented out since it makes calls to ".js"'s urls even when not necessary at all (welcome page for instance)
    //TODO: switch to jquery-pjax ftw!
    //$.getScript(location.href);
  });

  //multiselect with bsmSelect plugin
  $("select[multiple]").bsmSelect({
    showEffect: function($el){ $el.fadeIn(); },
    hideEffect: function($el){ $el.fadeOut(function(){ $(this).remove();}); },
    title: 'Sélectionnez...',
    highlight: 'highlight',
    addItemTarget: 'original',
    removeLabel: 'x',
    containerClass: 'bsmContainer',                // Class for container that wraps this widget
    listClass: 'bsmList-custom',                   // Class for the list ($ol)
    listItemClass: 'bsmListItem-custom',           // Class for the
 list items
    listItemLabelClass: 'bsmListItemLabel-custom', // Class for the label text that appears in list items
    removeClass: 'bsmListItemRemove-custom',       // Class given to the "remove" link
  });
});

// context
$(function(){
  $(".contextswitch").each(function(){
    var a=$(this), d=a.find(".toggle");
    d.click(function(){
      a.hasClass("nochoices") || a.toggleClass("activated")
    })
  })
});

<commit_msg>Do not include 'utf8=<tick>' in replaceState() calls<commit_after>// application events
$(function() {
  //table sorting
  $(".items_list th a").live("click", function(e) {
    $.getScript(this.href);
    //fallback for old browsers
    if (!('pushState' in window.history)) return true
    //ensure middle, control and command clicks act normally
    //if (e.which == 2 || e.metaKey || e.ctrlKey) return true
    //push history!
    history.pushState(null, document.title, this.href);
    e.preventDefault();
  });

  //TODO: test it (Jasmine?)
  //machine 'virtual' toggling
  $('input#machine_virtual').live('change', function(e) {
    $('#machine-maintenance, #machine-physical-hardware').toggle();
    if ($('input#machine_virtual').attr('checked') == true) {
      $('#machine-hardware-title').html("Ressources");
    } else {
      $('#machine-hardware-title').html("Matériel");
    }
  });

  //filters observer
  submitFilters = function() {
    $.get($("form#filters").attr("action"), $("form#filters").serialize(), null, "script");
    //fallback for old browsers
    if (!('replaceState' in window.history)) return true
    //push our search to history
    var filters = jQuery.param( jQuery.grep( $('form#filters').serializeArray(), function(o){ return o.name != "utf8" && o.value != "" } ) )
    var url = $("form#filters").attr("action").split("?")[0] + "?" + filters
    history.replaceState(null, document.title, url);
  }
  $(".filters input").bindWithDelay("keyup", submitFilters, 300);
  $(".filters select").change(submitFilters);

  //back button for pushState's
  $(window).bind("popstate", function() {
    //commented out since it makes calls to ".js"'s urls even when not necessary at all (welcome page for instance)
    //TODO: switch to jquery-pjax ftw!
    //$.getScript(location.href);
  });

  //multiselect with bsmSelect plugin
  $("select[multiple]").bsmSelect({
    showEffect: function($el){ $el.fadeIn(); },
    hideEffect: function($el){ $el.fadeOut(function(){ $(this).remove();}); },
    title: 'Sélectionnez...',
    highlight: 'highlight',
    addItemTarget: 'original',
    removeLabel: 'x',
    containerClass: 'bsmContainer',                // Class for container that wraps this widget
    listClass: 'bsmList-custom',                   // Class for the list ($ol)
    listItemClass: 'bsmListItem-custom',           // Class for the
 list items
    listItemLabelClass: 'bsmListItemLabel-custom', // Class for the label text that appears in list items
    removeClass: 'bsmListItemRemove-custom',       // Class given to the "remove" link
  });
});

// context
$(function(){
  $(".contextswitch").each(function(){
    var a=$(this), d=a.find(".toggle");
    d.click(function(){
      a.hasClass("nochoices") || a.toggleClass("activated")
    })
  })
});

<|endoftext|>


<commit_before>var webpack = require('webpack');
var path = require('path');
module.exports = {
    entry: './src/_entry.js',
    output: {
        path: __dirname,
        filename: './www/build/bundle.js'
    },
    plugins: [
        new webpack.optimize.OccurenceOrderPlugin(true)
    ],
    // resolve: {
    //     extensions: ['', '.js'],
    //     root: [
    //         __dirname + '/node_modules'
    //     ]
    // },
    module: {
        loaders: [
            {
                test: /\.jsx?$/,
                // TODO(ns): need to include the yunity-webapp-common when it is not npm link'd
                exclude: /(node_modules|bower_components)/,
                loaders: ['babel-loader']
            },
            {
                test: /\.html$/,
                include: path.resolve(__dirname, 'src/components'),
                loader: 'html'
            },
            {
                test: /\.less$/,
                include: path.resolve(__dirname, 'src/assets/less'),
                loader: 'style!css!less'
            }
        ]
    }
};<commit_msg>Included yunity-webapp-common (in node_modules) into webpack, so it is built. Removed some comments.<commit_after>var webpack = require('webpack');
var path = require('path');
module.exports = {
    entry: './src/_entry.js',
    output: {
        path: __dirname,
        filename: './www/build/bundle.js'
    },
    plugins: [
        new webpack.optimize.OccurenceOrderPlugin(true)
    ],
    module: {
        loaders: [
            {
                test: /\.jsx?$/,
                include: [
                    path.resolve(__dirname, 'node_modules/yunity-webapp-common'),
                    path.resolve(__dirname, 'src')
                ],
                loaders: ['babel-loader']
            },
            {
                test: /\.html$/,
                include: path.resolve(__dirname, 'src/components'),
                loader: 'html'
            },
            {
                test: /\.less$/,
                include: path.resolve(__dirname, 'src/assets/less'),
                loader: 'style!css!less'
            }
        ]
    }
};<|endoftext|>


<commit_before>/*   Copyright (c) 2010, Diaspora Inc.  This file is
 *   licensed under the Affero General Public License version 3 or later.  See
 *   the COPYRIGHT file.
 */

var AspectEdit = {

  initialize: function() {
    $("ul .person").draggable({
      revert: true,
      start: AspectEdit.startDrag,
      drag: AspectEdit.duringDrag,
      stop: AspectEdit.stopDrag
    });

    $(".aspect ul.dropzone").droppable({
      hoverClass: 'active',
      drop: AspectEdit.onDropMove
    });

    $("#manage_aspect_zones").find(".delete").live("click", AspectEdit.deletePerson);
    $(".aspect h3").live('focus', AspectEdit.changeName);
  },

  startDrag: function() {
    AspectEdit.animateImage($(this).find("img").first());
    $(".draggable_info").fadeIn(100);
  },

  animateImage: function(image) {
    image.animate({'height':80, 'width':80, 'opacity':0.8}, 200);
    image.tipsy("hide");
  },

  duringDrag: function(event, ui) {
    $(this).find("img").first().tipsy("hide"); //ensure this is hidden
  },

  stopDrag: function(event, ui) {
    $(this).find("img").first().animate({'height':50, 'width':50, 'opacity':1}, 200);
    $(".draggable_info").fadeOut(100);
  },

  onDropMove: function(event, ui) {
    var dropzone = $(this);
    var person = ui.draggable;

    if (person.hasClass('request')) {
      $.ajax({
        type: "DELETE",
        url: "/requests/" + person.attr('data-guid'),
        data: {
          "accept": true,
          "aspect_id": dropzone.attr('data-aspect_id')
        },
        success: function() {
          AspectEdit.onDeleteRequestSuccess(person, dropzone);
        }
      });
    }

    if (person.attr('data-aspect_id') != undefined && // a request doesn't have a data-aspect_id, but an existing contact does
        dropzone.attr('data-aspect_id') != person.attr('data-aspect_id')) {
      $.ajax({
        url: "/aspects/move_contact/",
        data: {
          "person_id": person.attr('data-guid'),
          "from": person.attr('data-aspect_id'),
          "to": {
            "to": dropzone.attr('data-aspect_id')
          }
        },
        success: function(data) {
          AspectEdit.onMovePersonSuccess(person, dropzone, data);
        }
      });
    }

    dropzone.closest("ul").append(person);
  },

  onDeleteRequestSuccess: function(person, dropzone) {
    person.removeClass('request');
    person.attr('data-aspect_id', dropzone.attr('data-aspect_id'));
    person.removeAttr('data-person_id');
  },

  onMovePersonSuccess: function(person, dropzone, data) {
    View.flashes.render(data);
    person.attr('data-aspect_id', dropzone.attr('data-aspect_id'));
  },

  deletePersonFromAspect: function(person) {
    var person_id = person.attr('data-guid');

    if( $(".person[data-guid='"+ person_id +"']").length == 1) {
      Diaspora.widgets.alert.alert("Error removing contact", "You cannot remove the person from the last aspect");
    } else {
      if (!person.hasClass('request')) {

        $.ajax({
          type: "POST",
          url: "/aspects/remove_from_aspect",
          data: {
            'person_id': person_id,
            'aspect_id': person.attr('data-aspect_id')
          }
        });
      }
      person.fadeOut(400, function() {
        person.remove();
      });
    }
  },

  changeName:  function() {
    var $this = $(this),
      id = $this.closest(".aspect").attr("data-guid"),
      link = "/aspects/" + id;

    $this.keyup(function() {
      if (e.which == 13) {
        e.preventDefault();
        $this.blur();

        //save changes
        $.ajax({
          type: "PUT",
          url: link,
          data: {
            "aspect": {
              "name" : $this.text()
            }
          }
        });
      }

      //update all other aspect links
      $("#aspect_nav li[data-guid='" + id + "'] a").text($this.text());
    });
  },

  deletePerson: function() {
    var person = $(this).closest("li.person");

    if (person.hasClass('request')) {
      if (confirm("Ignore request?")) {
        var request_id = person.attr("data-guid");

        $.ajax({
          type: "DELETE",
          url: "/requests/" + request_id,
          success: function () {
            person.fadeOut(400, function() {
              person.remove();
            });
          }
        });
      }
    } else {
      if (confirm("Remove this person from aspect?")) {
        AspectEdit.deletePersonFromAspect(person);
      }
    }
  }
};

$(document).ready(AspectEdit.initialize);
<commit_msg>our spec would complain about the data of the ajax request not being there, move it into the callback instead<commit_after>/*   Copyright (c) 2010, Diaspora Inc.  This file is
 *   licensed under the Affero General Public License version 3 or later.  See
 *   the COPYRIGHT file.
 */

var AspectEdit = {

  initialize: function() {
    $("ul .person").draggable({
      revert: true,
      start: AspectEdit.startDrag,
      drag: AspectEdit.duringDrag,
      stop: AspectEdit.stopDrag
    });

    $(".aspect ul.dropzone").droppable({
      hoverClass: 'active',
      drop: AspectEdit.onDropMove
    });

    $("#manage_aspect_zones").find(".delete").live("click", AspectEdit.deletePerson);
    $(".aspect h3").live('focus', AspectEdit.changeName);
  },

  startDrag: function() {
    AspectEdit.animateImage($(this).find("img").first());
    $(".draggable_info").fadeIn(100);
  },

  animateImage: function(image) {
    image.animate({'height':80, 'width':80, 'opacity':0.8}, 200);
    image.tipsy("hide");
  },

  duringDrag: function(event, ui) {
    $(this).find("img").first().tipsy("hide"); //ensure this is hidden
  },

  stopDrag: function(event, ui) {
    $(this).find("img").first().animate({'height':50, 'width':50, 'opacity':1}, 200);
    $(".draggable_info").fadeOut(100);
  },

  onDropMove: function(event, ui) {
    var dropzone = $(this);
    var person = ui.draggable;

    if (person.hasClass('request')) {
      $.ajax({
        type: "DELETE",
        url: "/requests/" + person.attr('data-guid'),
        data: {
          "accept": true,
          "aspect_id": dropzone.attr('data-aspect_id')
        },
        success: function() {
          AspectEdit.onDeleteRequestSuccess(person, dropzone);
        }
      });
    }

    if (person.attr('data-aspect_id') != undefined && // a request doesn't have a data-aspect_id, but an existing contact does
        dropzone.attr('data-aspect_id') != person.attr('data-aspect_id')) {
      $.ajax({
        url: "/aspects/move_contact/",
        data: {
          "person_id": person.attr('data-guid'),
          "from": person.attr('data-aspect_id'),
          "to": {
            "to": dropzone.attr('data-aspect_id')
          }
        },
        success: function(data) {
          AspectEdit.onMovePersonSuccess(person, dropzone);
          View.flashes.render($.parseJSON(data));
        }
      });
    }

    dropzone.closest("ul").append(person);
  },

  onDeleteRequestSuccess: function(person, dropzone) {
    person.removeClass('request');
    person.attr('data-aspect_id', dropzone.attr('data-aspect_id'));
    person.removeAttr('data-person_id');
  },

  onMovePersonSuccess: function(person, dropzone) {
    person.attr('data-aspect_id', dropzone.attr('data-aspect_id'));
  },

  deletePersonFromAspect: function(person) {
    var person_id = person.attr('data-guid');

    if( $(".person[data-guid='"+ person_id +"']").length == 1) {
      Diaspora.widgets.alert.alert("Error removing contact", "You cannot remove the person from the last aspect");
    } else {
      if (!person.hasClass('request')) {

        $.ajax({
          type: "POST",
          url: "/aspects/remove_from_aspect",
          data: {
            'person_id': person_id,
            'aspect_id': person.attr('data-aspect_id')
          }
        });
      }
      person.fadeOut(400, function() {
        person.remove();
      });
    }
  },

  changeName:  function() {
    var $this = $(this),
      id = $this.closest(".aspect").attr("data-guid"),
      link = "/aspects/" + id;

    $this.keyup(function() {
      if (e.which == 13) {
        e.preventDefault();
        $this.blur();

        //save changes
        $.ajax({
          type: "PUT",
          url: link,
          data: {
            "aspect": {
              "name" : $this.text()
            }
          }
        });
      }

      //update all other aspect links
      $("#aspect_nav li[data-guid='" + id + "'] a").text($this.text());
    });
  },

  deletePerson: function() {
    var person = $(this).closest("li.person");

    if (person.hasClass('request')) {
      if (confirm("Ignore request?")) {
        var request_id = person.attr("data-guid");

        $.ajax({
          type: "DELETE",
          url: "/requests/" + request_id,
          success: function () {
            person.fadeOut(400, function() {
              person.remove();
            });
          }
        });
      }
    } else {
      if (confirm("Remove this person from aspect?")) {
        AspectEdit.deletePersonFromAspect(person);
      }
    }
  }
};

$(document).ready(AspectEdit.initialize);
<|endoftext|>