<commit_before>/*!
 *  READTHIS: https://github.com/monkeyraptor/math_operation
 *  Version 2015-09-02
 *  MIT License (https://github.com/monkeyraptor/math_operation/blob/master/LICENSE.md)
 *  Authored by Monkey Raptor
 */

// GLOBAL VARIABLES
var math, misc_math;

// "math" variable definitions
math = {
    /*****************************************/
    //[1] Factorial
    factorial: function (n) {
        "use strict";
        var i, result;
        i = 1;
        result = 1;
        n = Number(n);
        if (n >= 0) {
            n = Math.floor(n);
            if (n > 1) {
                while (i <= n) {
                    result *= i;
                    i += 1;
                }
            }
        } else {
            result = "INPUT ERROR: n >= 0";
        }
        if (!!misc_math.check(result)) {
            result = "Result is too LARGE: " + result;
        }
        return result;
    },

    /*****************************************/
    //[2] Combination
    combination: function (n, k) {
        "use strict";
        var start, numerator, denumerator, i, result;
        numerator = 1;
        denumerator = 1;
        i = 1;
        n = Number(n);
        k = Number(k);
        if (n - k >= 0 && n >= 0 && k >= 0) {
            n = Math.floor(n);
            k = Math.floor(k);

            if (n === k) {
                result = 1;
            } else if (k === 1) {
                result = n;
            } else {
                start = n - k + 1;

                while (i <= k) {
                    denumerator *= i;
                    i += 1;
                }
                while (start <= n) {
                    numerator *= start;
                    start += 1;
                }
                result = Math.floor(numerator / denumerator);
            }
        } else {
            result = "INPUT ERROR: n >= k, n >= 0, k >= 0";
        }
        if (!!misc_math.check(result)) {
            result = "Result is too LARGE: " + result;
        }
        return result;
    },

    /*****************************************/
    //[3] Permutation
    permutation: function (n, k) {
        "use strict";
        var start, numerator, result;
        numerator = 1;
        n = Number(n);
        k = Number(k);
        if (n - k >= 0 && n >= 0 && k >= 0) {
            n = Math.floor(n);
            k = Math.floor(k);
            if (n === 0 || k === 0) {
                result = 1;
            } else if (n === k) {
                result = math.factorial(n);
            } else if (k === 1) {
                result = n;
            } else {
                start = n - k + 1;
                while (start <= n) {
                    numerator *= start;
                    start += 1;
                }
                result = numerator;
            }
        } else {
            result = "INPUT ERROR: n >= k, n >= 0, k >= 0";
        }
        if (!!misc_math.check(result)) {
            result = "Result is too LARGE: " + result;
        }
        return result;
    },

    /*****************************************/
    //[4] Adding comma to large integer
    addcomma: function (your_number) {
        "use strict";
        var f, p, r, i;
        f = [];
        i = 1;
        your_number = Number(your_number);
        if (!misc_math.check(your_number)) {
            if (your_number < 0) {
                p = "-";
            } else {
                p = "";
            }

            r = Math.abs(Math.floor(your_number)).toString();
            f = r.split("").reverse();

            while (i <= Math.floor(f.length / 4)) {
                f.splice((4 * i - 1), 0, ",");
                i += 1;
            }
            your_number = p + f.reverse().join("");
        } else {
            your_number = "INPUT ERROR: must be number or too large";
        }
        return your_number;
    },

    /*****************************************/
    //[5] Generating Fibonacci sequence
    fibonacci: function (first, second, how_many) {
        "use strict";
        var i, result, array;
        i = 2;
        first = Number(first);
        second = Number(second);
        how_many = Number(how_many);
        if (!!first && !!second && how_many > 0) {
            first = Math.floor(first);
            second = Math.floor(second);
            how_many = Math.floor(how_many);
            array = [first, second];

            while (i <= how_many + 1) {
                array.push(array[i - 1] + array[i - 2]);
                i += 1;
            }
            result = array.join(", ");
        } else {
            result = "INPUT ERROR: only accepts integer for 1st and 2nd numbers, and natural number for 3rd number (N*)";
        }
        return result;
    },

    /*****************************************/
    //[6] Get the factor of a positive integer
    factorof: function (a, b) {
        "use strict";
        var result, i, j, k, array, left, right, a_l, divider;
        i = 1;
        j = 0;
        k = 0;
        array = [];
        left = [];
        right = [];
        a = Number(a);
        b = Number(b);
        if (a !== 0) { //check if number and non-zero
            if (a < 0) { //convert it to positive integer and round down
                a = Math.abs(Math.floor(a));
            }
            while (i <= a) {
                if (a % i === 0) {
                    array.push(i);
                }
                i += 1;
            }

            if (Number(b) === 1) { //flag for displaying multiplication of the factors
                a_l = array.length;

                if (a_l % 2 === 0) { //if the array length is even
                    divider = a_l / 2;

                    while (j < divider) {
                        left.push(array[j]);
                        right.push(array[j + divider]);
                        j += 1;
                    }

                    right.reverse();
                    array = [];

                    while (k < left.length) {
                        array.push(left[k] + " * " + right[k]);
                        k += 1;
                    }
                } else { //for odd array length
                    divider = Math.floor(a_l / 2);

                    while (j < divider) {
                        left.push(array[j]);
                        right.push(array[j + divider + 1]);
                        j += 1;
                    }

                    left.push(array[divider]);
                    right.reverse().push(left[left.length - 1]);
                    array = [];

                    while (k < left.length) {
                        array.push(left[k] + " * " + right[k]);
                        k += 1;
                    }
                }
            } else if (Number(b) !== 0 && Number(b) !== 1) {
                array = ["no", "such", "flag!"];
            }
            if (!!array[1] && !!array[1].toString().match(/such/gi)) {
                result = array.join(" ");
            } else {
                result = array.join(", ");
            }
        } else {
            result = "INPUT ERROR: only accepts non-zero integer";
        }
        return result;
    },

    /*****************************************/
    //[7] Checking prime number
    prime_check: function (a) {
        "use strict";
        var result, i, limit;
        i = 2;
        a = Number(a);
        //maximum digit length = 20 (999,999,999,999,999,999,999)
        if (!misc_math.check(a)) {
            if (a > 1) {
                a = Math.floor(a);
                limit = Math.floor(Math.sqrt(a));
                result = "PRIME number";

                while (i <= limit) {
                    if (a % i === 0) {
                        result = "Not a prime number";
                        break;
                    }
                    i += 1;
                }

            } else {
                result = "INPUT ERROR: only positive integer > 1";
            }

        } else {
            result = "INPUT ERROR: digit length <= 21";
        }

        return result;
    },

    /*****************************************/
    //[8] Generate prime numbers
    generate_prime: function (start, how_many) {
        "use strict";
        var result, primes = [];
        start = Number(start);
        how_many = Number(how_many);
        if (start > 1 && how_many > 0) {
            start = Math.floor(start);
            how_many = Math.floor(how_many);

            while (how_many > 0) {
                if (!math.prime_check(start).match(/not/gi)) {
                    primes.push(start);
                    how_many -= 1;
                }
                start += 1;
            }

            result = primes.join(", ");
        } else {
            result = "INPUT ERROR: only positive integer, how_many > 0, start > 1";
        }

        return result;
    },

    /*****************************************/
    //[9] Generate Pascal's triangle sequence (one particular line or many lines)
    pascal_triangle: function (a, b) {
        "use strict";
        var array, i, j, k, result, store;
        array = [];
        i = 0;
        k = 0;
        result = {};
        store = [];
        function pt(n, r) { //pt as in *Pascal's Triangle*
            //SPLENDID arithmetic method from http://www.ywhmaths.webs.com/Arithmetic/Pascal.html
            var buffer;
            if (n > 1 && r > 0 && r < n) {
                buffer = pt(n - 1, r - 1) + pt(n - 1, r);
            } else {
                buffer = 1;
            }
            return buffer;
        }
        a = Number(a);
        b = Number(b);
        if (a > 0) {
            a = Math.floor(a);

            while (i < a) {
                j = 0;
                array = []; //empty the *array* buffer
                while (j <= i) {
                    array.push(pt(i, j)); //fill it again
                    j += 1;
                }
                result[i] = array; //fill the *result* object with the *array*
                i += 1;
            }
            if (b === 0) { //only a particular line
                result = result[a - 1].join(", "); //array to string

            } else if (b === 1) { //show all lines until the limit number given
                while (k < a) {
                    store.push(result[k].join(" ")); //this can be changed to fit your layout.
                    k += 1;
                }

                result = store.join(" | "); //this can be changed to fit your layout.

            } else {
                result = "INPUT ERROR: 0 or 1 for flag";
            }
        } else {
            result = "INPUT ERROR: must be natural number (N*)";
        }

        return result; //string
    },

    /*****************************************/
    //[10] Least common multiple (LCM)
    lcm: function (a, b, c) { //min 2 inputs, max of 3
        "use strict";
        var gcf, result, t, u, v, z;
        v = [];
        z = [];
        a = Number(a);
        b = Number(b);
        c = Number(c);
        if (!c) { //only 2 inputs provided
            if (a > 0 && b > 0) {
                a = Math.floor(a);
                b = Math.floor(b);
                v = [a, b];
                z = v.sort(misc_math.hl);
                t = z[0] % z[1];

                if (t === 0) {
                    result = z[0];

                } else {
                    gcf = math.gcf(z[0], z[1]); //GCF
                    result = z[0] * z[1] / gcf;
                }
            } else {
                result = "INPUT ERROR: min 2 inputs and natural number (N*)";
            }

        } else { //3rd input is provided
            if (a > 0 && b > 0 && c > 0) {
                a = Math.floor(a);
                b = Math.floor(b);
                c = Math.floor(c);
                v = [a, b, c];
                z = v.sort(misc_math.hl);
                t = math.lcm(z[0], z[1], undefined);
                u = math.lcm(t, z[2], undefined);
                result = math.lcm(t, u, undefined);
            } else {
                result = "INPUT ERROR: inputs must be natural number (N*)";
            }
        }

        return result; //number
    },

    /*****************************************/
    //[11] Greatest common factor (GCF)
    gcf: function (a, b, c) { //min 2 inputs, max of 3
        "use strict";
        var num_1, num_2, num_3, result;
        a = Number(a);
        b = Number(b);
        c = Number(c);
        if (!c) { //3rd input undefined
            if (a > 0 && b > 0) {
                a = Math.floor(a);
                b = Math.floor(b);

                //get factors - convert string to array
                num_1 = math.factorof(a, 0).split(", ");
                num_2 = math.factorof(b, 0).split(", ");
                //put result
                result = misc_math.c_a(num_1, num_2).same_elements
                    .sort(misc_math.hl)[0];
            } else {
                result = "INPUT ERROR: min 2 inputs and natural number (N*)";
            }
        } else if (c > 0) { //3rd input is provided
            a = Math.floor(a);
            b = Math.floor(b);
            c = Math.floor(c);

            //get factors - convert string to array
            num_1 = math.factorof(a, 0).split(", ");
            num_2 = math.factorof(b, 0).split(", ");
            num_3 = math.factorof(c, 0).split(", ");
            //put result
            result = misc_math.c_a(misc_math.c_a(num_1, num_2).same_elements, num_3)
                .same_elements.sort(misc_math.hl)[0];
        } else {
            result = "INPUT ERROR: inputs must be natural number (N*)";
        }

        return result; //number
    }
};

/***************************************************************************/
// "misc_math" variable definitions
misc_math = {
    // compare two arrays
    // https://github.com/monkeyraptor/compare_2_arrays/blob/master/compare_arrays_3.js
    c_a: function (a, b) {
        "use strict";
        var c, d, obj;
        obj = {
            difference: [],
            same_elements: []
        };
        function process_it(k, l) {
            var same = [];
            function trim(a) {
                var i = a.length;
                while (i >= 0) {
                    if (a[i] === "_*deleted*_") {
                        a.splice(i, 1);
                    }
                    i -= 1;
                }
                return a;
            }
            l.forEach(function (v, i) {
                k.forEach(function (vv, ii) {
                    if (v === vv) {
                        same.push(vv);
                        l.splice(i, 1, "_*deleted*_");
                        k.splice(ii, 1, "_*deleted*_");
                    }
                });
            });
            return {
                difference: trim(l.concat(k)),
                same_elements: same
            };
        }
        if (a instanceof Array && b instanceof Array) {
            c = a.slice();
            d = b.slice();
            if (c.length >= d.length) {
                obj = process_it(c, d);
            } else {
                obj = process_it(d, c);
            }
        }
        return obj;
    },

    //checking the compacted digit or infinity
    check: function (a) {
        "use strict";
        var result = 0;
        if (/e\+/i.test(a.toString()) || !isFinite(a)) {
            result = 1;
        }
        return result;
    },

    //HIGH to low (numeral) sorter
    hl: function (a, b) {
        "use strict";
        return parseInt(b, 10) - parseInt(a, 10);
    },

    //LOW to high (numeral) sorter
    lh: function (a, b) {
        "use strict";
        return parseInt(a, 10) - parseInt(b, 10);
    }
};
<commit_msg>Update custom_math.js<commit_after>/*!
 *  READTHIS: https://github.com/monkeyraptor/math_operation
 *  Version 2015-09-02
 *  MIT License (https://github.com/monkeyraptor/math_operation/blob/master/LICENSE.md)
 *  Authored by Monkey Raptor
 */

// GLOBAL VARIABLES
var math, misc_math;

// "math" variable definitions
math = {
    /*****************************************/
    //[1] Factorial
    factorial: function (n) {
        "use strict";
        var i, result;
        i = 1;
        result = 1;
        n = Number(n);
        if (n >= 0) {
            n = Math.floor(n);
            if (n > 1) {
                while (i <= n) {
                    result *= i;
                    i += 1;
                }
            }
        } else {
            result = "INPUT ERROR: n >= 0";
        }
        if (!!misc_math.check(result)) {
            result = "Result is too LARGE: " + result;
        }
        return result;
    },

    /*****************************************/
    //[2] Combination
    combination: function (n, k) {
        "use strict";
        var start, numerator, denumerator, i, result;
        numerator = 1;
        denumerator = 1;
        i = 1;
        n = Number(n);
        k = Number(k);
        if (n - k >= 0 && n >= 0 && k >= 0) {
            n = Math.floor(n);
            k = Math.floor(k);

            if (n === k) {
                result = 1;
            } else if (k === 1) {
                result = n;
            } else {
                start = n - k + 1;

                while (i <= k) {
                    denumerator *= i;
                    i += 1;
                }
                while (start <= n) {
                    numerator *= start;
                    start += 1;
                }
                result = Math.floor(numerator / denumerator);
            }
        } else {
            result = "INPUT ERROR: n >= k, n >= 0, k >= 0";
        }
        if (!!misc_math.check(result)) {
            result = "Result is too LARGE: " + result;
        }
        return result;
    },

    /*****************************************/
    //[3] Permutation
    permutation: function (n, k) {
        "use strict";
        var start, numerator, result;
        numerator = 1;
        n = Number(n);
        k = Number(k);
        if (n - k >= 0 && n >= 0 && k >= 0) {
            n = Math.floor(n);
            k = Math.floor(k);
            if (n === 0 || k === 0) {
                result = 1;
            } else if (n === k) {
                result = math.factorial(n);
            } else if (k === 1) {
                result = n;
            } else {
                start = n - k + 1;
                while (start <= n) {
                    numerator *= start;
                    start += 1;
                }
                result = numerator;
            }
        } else {
            result = "INPUT ERROR: n >= k, n >= 0, k >= 0";
        }
        if (!!misc_math.check(result)) {
            result = "Result is too LARGE: " + result;
        }
        return result;
    },

    /*****************************************/
    //[4] Adding comma to large integer
    addcomma: function (your_number) {
        "use strict";
        var f, p, r, i;
        f = [];
        i = 1;
        your_number = Number(your_number);
        if (!misc_math.check(your_number)) {
            if (your_number < 0) {
                p = "-";
            } else {
                p = "";
            }

            r = Math.abs(Math.floor(your_number)).toString();
            f = r.split("").reverse();

            while (i <= Math.floor(f.length / 4)) {
                f.splice((4 * i - 1), 0, ",");
                i += 1;
            }
            your_number = p + f.reverse().join("");
        } else {
            your_number = "INPUT ERROR: must be number or too large";
        }
        return your_number;
    },

    /*****************************************/
    //[5] Generating Fibonacci sequence
    fibonacci: function (first, second, how_many) {
        "use strict";
        var i, result, array;
        i = 2;
        first = Number(first);
        second = Number(second);
        how_many = Number(how_many);
        if (!!first && !!second && how_many > 0) {
            first = Math.floor(first);
            second = Math.floor(second);
            how_many = Math.floor(how_many);
            array = [first, second];

            while (i <= how_many + 1) {
                array.push(array[i - 1] + array[i - 2]);
                i += 1;
            }
            result = array.join(", ");
        } else {
            result = "INPUT ERROR: only accepts integer for 1st and 2nd numbers, and natural number for 3rd number (N*)";
        }
        return result;
    },

    /*****************************************/
    //[6] Get the factor of a positive integer
    factorof: function (a, b) {
        "use strict";
        var result, i, j, k, array, left, right, a_l, divider;
        i = 1;
        j = 0;
        k = 0;
        array = [];
        left = [];
        right = [];
        a = Number(a);
        b = Number(b);
        if (a !== 0) { //check if number and non-zero
            if (a < 0) { //convert it to positive integer and round down
                a = Math.abs(Math.floor(a));
            }
            while (i <= a) {
                if (a % i === 0) {
                    array.push(i);
                }
                i += 1;
            }

            if (Number(b) === 1) { //flag for displaying multiplication of the factors
                a_l = array.length;

                if (a_l % 2 === 0) { //if the array length is even
                    divider = a_l / 2;

                    while (j < divider) {
                        left.push(array[j]);
                        right.push(array[j + divider]);
                        j += 1;
                    }

                    right.reverse();
                    array = [];

                    while (k < left.length) {
                        array.push(left[k] + " * " + right[k]);
                        k += 1;
                    }
                } else { //for odd array length
                    divider = Math.floor(a_l / 2);

                    while (j < divider) {
                        left.push(array[j]);
                        right.push(array[j + divider + 1]);
                        j += 1;
                    }

                    left.push(array[divider]);
                    right.reverse().push(left[left.length - 1]);
                    array = [];

                    while (k < left.length) {
                        array.push(left[k] + " * " + right[k]);
                        k += 1;
                    }
                }
            } else if (Number(b) !== 0 && Number(b) !== 1) {
                array = ["no", "such", "flag!"];
            }
            if (!!array[1] && !!array[1].toString().match(/such/gi)) {
                result = array.join(" ");
            } else {
                result = array.join(", ");
            }
        } else {
            result = "INPUT ERROR: only accepts non-zero integer";
        }
        return result;
    },

    /*****************************************/
    //[7] Checking prime number
    prime_check: function (a) {
        "use strict";
        var result, i, limit;
        i = 2;
        a = Number(a);
        if (!misc_math.check(a)) {
            if (a > 1) {
                a = Math.floor(a);
                limit = Math.floor(Math.sqrt(a));
                result = "PRIME number";

                while (i <= limit) {
                    if (a % i === 0) {
                        result = "Not a prime number";
                        break;
                    }
                    i += 1;
                }

            } else {
                result = "INPUT ERROR: only positive integer > 1";
            }

        } else {
            result = "INPUT ERROR: digit length <= 21";
        }

        return result;
    },

    /*****************************************/
    //[8] Generate prime numbers
    generate_prime: function (start, how_many) {
        "use strict";
        var result, primes = [];
        start = Number(start);
        how_many = Number(how_many);
        if (start > 1 && how_many > 0) {
            start = Math.floor(start);
            how_many = Math.floor(how_many);

            while (how_many > 0) {
                if (!math.prime_check(start).match(/not/gi)) {
                    primes.push(start);
                    how_many -= 1;
                }
                start += 1;
            }

            result = primes.join(", ");
        } else {
            result = "INPUT ERROR: only positive integer, how_many > 0, start > 1";
        }

        return result;
    },

    /*****************************************/
    //[9] Generate Pascal's triangle sequence (one particular line or many lines)
    pascal_triangle: function (a, b) {
        "use strict";
        var array, i, j, k, result, store;
        array = [];
        i = 0;
        k = 0;
        result = {};
        store = [];
        function pt(n, r) { //pt as in *Pascal's Triangle*
            //SPLENDID arithmetic method from http://www.ywhmaths.webs.com/Arithmetic/Pascal.html
            var buffer;
            if (n > 1 && r > 0 && r < n) {
                buffer = pt(n - 1, r - 1) + pt(n - 1, r);
            } else {
                buffer = 1;
            }
            return buffer;
        }
        a = Number(a);
        b = Number(b);
        if (a > 0) {
            a = Math.floor(a);

            while (i < a) {
                j = 0;
                array = []; //empty the *array* buffer
                while (j <= i) {
                    array.push(pt(i, j)); //fill it again
                    j += 1;
                }
                result[i] = array; //fill the *result* object with the *array*
                i += 1;
            }
            if (b === 0) { //only a particular line
                result = result[a - 1].join(", "); //array to string

            } else if (b === 1) { //show all lines until the limit number given
                while (k < a) {
                    store.push(result[k].join(" ")); //this can be changed to fit your layout.
                    k += 1;
                }

                result = store.join(" | "); //this can be changed to fit your layout.

            } else {
                result = "INPUT ERROR: 0 or 1 for flag";
            }
        } else {
            result = "INPUT ERROR: must be natural number (N*)";
        }

        return result; //string
    },

    /*****************************************/
    //[10] Least common multiple (LCM)
    lcm: function (a, b, c) { //min 2 inputs, max of 3
        "use strict";
        var gcf, result, t, u, v, z;
        v = [];
        z = [];
        a = Number(a);
        b = Number(b);
        c = Number(c);
        if (!c) { //only 2 inputs provided
            if (a > 0 && b > 0) {
                a = Math.floor(a);
                b = Math.floor(b);
                v = [a, b];
                z = v.sort(misc_math.hl);
                t = z[0] % z[1];

                if (t === 0) {
                    result = z[0];

                } else {
                    gcf = math.gcf(z[0], z[1]); //GCF
                    result = z[0] * z[1] / gcf;
                }
            } else {
                result = "INPUT ERROR: min 2 inputs and natural number (N*)";
            }

        } else { //3rd input is provided
            if (a > 0 && b > 0 && c > 0) {
                a = Math.floor(a);
                b = Math.floor(b);
                c = Math.floor(c);
                v = [a, b, c];
                z = v.sort(misc_math.hl);
                t = math.lcm(z[0], z[1], undefined);
                u = math.lcm(t, z[2], undefined);
                result = math.lcm(t, u, undefined);
            } else {
                result = "INPUT ERROR: inputs must be natural number (N*)";
            }
        }

        return result; //number
    },

    /*****************************************/
    //[11] Greatest common factor (GCF)
    gcf: function (a, b, c) { //min 2 inputs, max of 3
        "use strict";
        var num_1, num_2, num_3, result;
        a = Number(a);
        b = Number(b);
        c = Number(c);
        if (!c) { //3rd input undefined
            if (a > 0 && b > 0) {
                a = Math.floor(a);
                b = Math.floor(b);

                //get factors - convert string to array
                num_1 = math.factorof(a, 0).split(", ");
                num_2 = math.factorof(b, 0).split(", ");
                //put result
                result = misc_math.c_a(num_1, num_2).same_elements
                    .sort(misc_math.hl)[0];
            } else {
                result = "INPUT ERROR: min 2 inputs and natural number (N*)";
            }
        } else if (c > 0) { //3rd input is provided
            a = Math.floor(a);
            b = Math.floor(b);
            c = Math.floor(c);

            //get factors - convert string to array
            num_1 = math.factorof(a, 0).split(", ");
            num_2 = math.factorof(b, 0).split(", ");
            num_3 = math.factorof(c, 0).split(", ");
            //put result
            result = misc_math.c_a(misc_math.c_a(num_1, num_2).same_elements, num_3)
                .same_elements.sort(misc_math.hl)[0];
        } else {
            result = "INPUT ERROR: inputs must be natural number (N*)";
        }

        return result; //number
    }
};

/***************************************************************************/
// "misc_math" variable definitions
misc_math = {
    // compare two arrays
    // https://github.com/monkeyraptor/compare_2_arrays/blob/master/compare_arrays_3.js
    c_a: function (a, b) {
        "use strict";
        var c, d, obj;
        obj = {
            difference: [],
            same_elements: []
        };
        function process_it(k, l) {
            var same = [];
            function trim(a) {
                var i = a.length;
                while (i >= 0) {
                    if (a[i] === "_*deleted*_") {
                        a.splice(i, 1);
                    }
                    i -= 1;
                }
                return a;
            }
            l.forEach(function (v, i) {
                k.forEach(function (vv, ii) {
                    if (v === vv) {
                        same.push(vv);
                        l.splice(i, 1, "_*deleted*_");
                        k.splice(ii, 1, "_*deleted*_");
                    }
                });
            });
            return {
                difference: trim(l.concat(k)),
                same_elements: same
            };
        }
        if (a instanceof Array && b instanceof Array) {
            c = a.slice();
            d = b.slice();
            if (c.length >= d.length) {
                obj = process_it(c, d);
            } else {
                obj = process_it(d, c);
            }
        }
        return obj;
    },

    //checking the compacted digit or infinity
    check: function (a) {
        "use strict";
        var result = 0;
        if (/e\+/i.test(a.toString()) || !isFinite(a)) {
            result = 1;
        }
        return result;
    },

    //HIGH to low (numeral) sorter
    hl: function (a, b) {
        "use strict";
        return parseInt(b, 10) - parseInt(a, 10);
    },

    //LOW to high (numeral) sorter
    lh: function (a, b) {
        "use strict";
        return parseInt(a, 10) - parseInt(b, 10);
    }
};
<|endoftext|>


<commit_before>
require('canvas-testbed')(render, start)

var vec = require('gl-vec2')
var array = require('array-range')

var smoothstep = require('smoothstep')
var delaunay = require('delaunay-triangulate')
var drawTriangles = require('./draw-triangles')
var xtend = require('xtend')
var random = require('randf')

var World = require('../')
var Point = require('verlet-point')

//a mouse vector
var mouse = require('touch-position')({ position: [-10000, -10000] })

//for mobile, prevent page swiping
require('add-event-listener')(window, 'touchstart', function (ev) {
    ev.preventDefault()
})

var system,
    particles,
    positions,
    cells,
    dir = vec.create()

var MAX_PARTICLES = 50

function render(ctx, width, height, dt) {
    ctx.clearRect(0, 0, width, height)
    ctx.fillStyle = '#1f1f1f'
    ctx.fillRect(0, 0, width, height)

    update(width, height, dt)
    draw(ctx)
}

function start(ctx, width, height) {
    system = World()

    particles = array(MAX_PARTICLES).map(function(i) {
        var angle = i/(MAX_PARTICLES-1) * Math.PI * 20
        var scale = 100

        var rot = [
            Math.cos(angle) * scale,
            Math.sin(angle) * scale
        ]

        var force = vec.scale([], rot, -angle*0.001)

        return Point({
            position: vec.add([], rot, [width/2, height/2])
        }).addForce(force)
    })
}

function update(width, height, dt) {
    //do some mouse motion
    particles.forEach(function(p) {
        var s = 0.05

        //get direction of mouse to this particle
        vec.sub(dir, mouse, p.position)
        vec.normalize(dir, dir)

        //perform some mouse motion on the vertices
        var dist = smoothstep(100, 50, vec.distance(p.position, mouse))
        vec.scale(dir, dir, dist*0.5)
        p.addForce(dir)
    })

    //constrain world
    system.max = [width, height]
    system.min = [0, 0]

    //step the physics
    system.integrate(particles, dt/1000)

    //perform triangulation on all points
    positions = particles.map(function(p) {
        return p.position
    })
    cells = delaunay(positions)
}

function draw(ctx) {
    ctx.beginPath()
    particles.forEach(function(p) {
        ctx.moveTo(p.position[0], p.position[1])
        ctx.arc(p.position[0], p.position[1], 2, Math.PI*2, 0, false)
    })
    ctx.fillStyle = '#3be543'
    ctx.globalAlpha = 1.0
    ctx.fill()

    ctx.beginPath()
    drawTriangles(ctx, positions, cells)
    ctx.strokeStyle = '#fff'
    ctx.globalAlpha = 0.25
    ctx.stroke()
}
<commit_msg>fixing typo with new gl-vec2<commit_after>
require('canvas-testbed')(render, start)

var vec = require('gl-vec2')
var array = require('array-range')

var smoothstep = require('smoothstep')
var delaunay = require('delaunay-triangulate')
var drawTriangles = require('./draw-triangles')
var xtend = require('xtend')
var random = require('randf')

var World = require('../')
var Point = require('verlet-point')

//a mouse vector
var mouse = require('touch-position')({ position: [-10000, -10000] })

//for mobile, prevent page swiping
require('add-event-listener')(window, 'touchstart', function (ev) {
    ev.preventDefault()
})

var system,
    particles,
    positions,
    cells,
    dir = vec.create()

var MAX_PARTICLES = 50

function render(ctx, width, height, dt) {
    ctx.clearRect(0, 0, width, height)
    ctx.fillStyle = '#1f1f1f'
    ctx.fillRect(0, 0, width, height)

    update(width, height, dt)
    draw(ctx)
}

function start(ctx, width, height) {
    system = World()

    particles = array(MAX_PARTICLES).map(function(i) {
        var angle = i/(MAX_PARTICLES-1) * Math.PI * 20
        var scale = 100

        var rot = [
            Math.cos(angle) * scale,
            Math.sin(angle) * scale
        ]

        var force = vec.scale([], rot, -angle*0.001)

        return Point({
            position: vec.add([], rot, [width/2, height/2])
        }).addForce(force)
    })
}

function update(width, height, dt) {
    //do some mouse motion
    particles.forEach(function(p) {
        var s = 0.05

        //get direction of mouse to this particle
        vec.subtract(dir, mouse, p.position)
        vec.normalize(dir, dir)

        //perform some mouse motion on the vertices
        var dist = smoothstep(100, 50, vec.distance(p.position, mouse))
        vec.scale(dir, dir, dist*0.5)
        p.addForce(dir)
    })

    //constrain world
    system.max = [width, height]
    system.min = [0, 0]

    //step the physics
    system.integrate(particles, dt/1000)

    //perform triangulation on all points
    positions = particles.map(function(p) {
        return p.position
    })
    cells = delaunay(positions)
}

function draw(ctx) {
    ctx.beginPath()
    particles.forEach(function(p) {
        ctx.moveTo(p.position[0], p.position[1])
        ctx.arc(p.position[0], p.position[1], 2, Math.PI*2, 0, false)
    })
    ctx.fillStyle = '#3be543'
    ctx.globalAlpha = 1.0
    ctx.fill()

    ctx.beginPath()
    drawTriangles(ctx, positions, cells)
    ctx.strokeStyle = '#fff'
    ctx.globalAlpha = 0.25
    ctx.stroke()
}
<|endoftext|>


<commit_before>ccm_setNewsflowPagingArrowHeight = function() {
	if ($("#ccm-marketplace-detail").length > 0) {
		var $ovl = $("#ccm-marketplace-detail");
	} else {
		var $ovl = $("#newsflow-main");
	}

	var h = $ovl.height();
	$(".newsflow-paging-previous a, .newsflow-paging-next a").css('height', h + 'px');
	$(".newsflow-paging-previous, .newsflow-paging-next").css('height', h + 'px');
	$(".newsflow-paging-next").show();
	$(".newsflow-paging-previous").show();

}

ccm_getNewsflowOverlayWindow = function() {
	if ($('#ccm-dashboard-content').length > 0 && $("#newsflow-main").length > 0 && $("#newsflow-overlay").length == 0) {
		var $ovl = $("#newsflow-main").parent();
	} else {
		// Ok. we're going to use #newsflow-overlay but we don't know if it's been added to the page yet
		if ($("#newsflow-overlay").length > 0) {
			var $ovl = $("#newsflow-overlay");
		} else {
			var $ovl = $('
').attr('id', 'newsflow-overlay').attr('class', 'ccm-ui').css('display','none').appendTo(document.body);
		}
	}
	return $ovl;
}
/**
 * Newsflow
 */

ccm_showNewsflowOverlayWindow = function(url, callback) {

	// if we're NOT showing newsflow on a dashboard page, we load an overlay
	if ($('#ccm-dashboard-content').length > 0 && $("#newsflow-main").length > 0) {

	} else {
		if ($('.ui-widget-overlay').length < 1) {
			var $overlay = $('

').hide().appendTo('body');
		}
		$('.ui-widget-overlay').show();
	}

	// Make the overlay resize when a browser window is resized
	$(window).resize(function(){
		ccm_setNewsflowOverlayDimensions();
	});

	// load the content into it.
	// we get the div we're loading content into
	// if we're in the dashboard, it's going to be newsflow-main
	$ovl = ccm_getNewsflowOverlayWindow();
	$ovl.load(url, function() {
		// if we're showing the overlay, we hide it
		$ovl.hide();

		// hide all the arrows too
		$(".newsflow-paging-next").hide();
		$(".newsflow-paging-previous").hide();

		$ovl.html($(this).html());

		if (callback) {
			callback();
		}

		ccm_setNewsflowOverlayDimensions();
		ccm_setupTrickleUpNewsflowStyles();

		$ovl.fadeIn('300', 'easeOutExpo', function() {
			ccm_setNewsflowPagingArrowHeight();
		});

	});
}

ccm_setupTrickleUpNewsflowStyles = function() {
	ovl = ccm_getNewsflowOverlayWindow();
	ovl.find('.newsflow-em1').each(function() {
		$(this).parent().addClass('newsflow-em1');
	});
}

ccm_showDashboardNewsflowWelcome = function() {
	jQuery.fn.dialog.showLoader(ccmi18n.newsflowLoading);
	ccm_showNewsflowOverlayWindow(CCM_DISPATCHER_FILENAME + '/dashboard/home?_ccm_dashboard_external=1', function() {
		jQuery.fn.dialog.hideLoader();
	});
}

ccm_showNewsflowOffsite = function(id) {
	jQuery.fn.dialog.showLoader();
	ccm_showNewsflowOverlayWindow(CCM_TOOLS_PATH + '/newsflow?cID=' + id, function() {
		jQuery.fn.dialog.hideLoader();
	});
}

ccm_showAppIntroduction = function() {
	ccm_showNewsflowOverlayWindow(CCM_DISPATCHER_FILENAME + '/dashboard/welcome?_ccm_dashboard_external=1');
}

ccm_getNewsflowByPath = function(path) {
	jQuery.fn.dialog.showLoader();
	ccm_showNewsflowOverlayWindow(CCM_TOOLS_PATH + '/newsflow?cPath=' + path, function() {
		jQuery.fn.dialog.hideLoader();
	});
}
<commit_msg>removing old newsflow<commit_after><|endoftext|>


<commit_before>import React from 'react';
import {NavLink, navigateAction} from 'fluxible-router';
import classNames from 'classnames/bind';
import {connectToStores} from 'fluxible-addons-react';
import ContentUtil from '../util/ContentUtil';
import DeckTreeStore from '../../../../stores/DeckTreeStore';
import UserProfileStore from '../../../../stores/UserProfileStore';
import addTreeNodeAndNavigate from '../../../../actions/decktree/addTreeNodeAndNavigate';
import deleteTreeNodeAndNavigate from '../../../../actions/decktree/deleteTreeNodeAndNavigate';
import AttachSubdeck from '../AttachSubdeck/AttachSubdeckModal';
import AttachSlides from '../AttachSubdeck/AttachSlidesModal';
import PermissionsStore from '../../../../stores/PermissionsStore';
import ContentStore from '../../../../stores/ContentStore';
import showNoPermissionsModal from '../../../../actions/permissions/showNoPermissionsModal';
import saveClick from '../../../../actions/slide/saveClick';
import cancelClick from '../../../../actions/slide/cancelClick';
import undoClick from '../../../../actions/slide/undoClick';
import redoClick from '../../../../actions/slide/redoClick';
import {defineMessages} from 'react-intl';

class ContentActionsHeader extends React.Component {
    constructor(props){
        super(props);
        this.messages = defineMessages({
            viewButtonText:{
                id: 'ContentActionsHeader.viewButtonText',
                defaultMessage:'View'
            },
            viewButtonAriaText:{
                id: 'ContentActionsHeader.viewButtonAriaText',
                defaultMessage:'View Mode'
            },
            editButtonText:{
                id: 'ContentActionsHeader.editButtonText',
                defaultMessage:'Edit'
            },
            editButtonAriaText:{
                id: 'ContentActionsHeader.editButtonAriaText',
                defaultMessage:'Edit Mode'
            },
            addSlideButtonAriaText:{
                id: 'ContentActionsHeader.addSlideButtonAriaText',
                defaultMessage:'Add Slide'
            },
            addDeckButtonAriaText:{
                id: 'ContentActionsHeader.addDeckButtonAriaText',
                defaultMessage:'Add Deck'
            },
            duplicateAriaText:{
                id: 'ContentActionsHeader.duplicateAriaText',
                defaultMessage:'Duplicate'
            },
            deleteAriaText:{
                id: 'ContentActionsHeader.deleteAriaText',
                defaultMessage:'Delete'
            },

        });

    }

    handleAddNode(selector, nodeSpec) {
        //selector: Object {id: "56", stype: "deck", sid: 67, spath: "67:2"}
        //nodeSec: Object {type: "slide", id: "0"}
        this.context.executeAction(addTreeNodeAndNavigate, {selector: selector, nodeSpec: nodeSpec});
    }

    handleDeleteNode(selector) {
        this.context.executeAction(deleteTreeNodeAndNavigate, selector);
    }

    handleSaveButtonClick(){
        this.context.executeAction(saveClick, {});
    }
    handleUndoButtonClick (){
        //this.context.executeAction(undoClick, {});
        //console.log('undo');
    }
    handleRedoButtonClick(){
        //this.context.executeAction(redoClick, {});
        //console.log('redo');
    }
    handleCancelButtonClick(selector){
        this.context.executeAction(cancelClick, {
            selector: selector
        });
    }
    handleViewButton(selector) {
        const nodeURL = ContentUtil.makeNodeURL(selector, 'view');
        this.context.executeAction(navigateAction, {
            url: nodeURL
        });

    }

    handleEditButton(selector) {
        const nodeURL = ContentUtil.makeNodeURL(selector, 'edit');
        if (this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit) {
            this.context.executeAction(showNoPermissionsModal, {selector: selector, user: this.props.UserProfileStore.userid, permissions: this.props.PermissionsStore.permissions});
        } else {
            this.context.executeAction(navigateAction, {
                url: nodeURL
            });
        }
    }
    render() {
        const contentDetails = this.props.ContentStore;
        //config buttons based on the selected item
        const editClass = classNames({
            'ui button attached basic': true,
            //'disabled': this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'
        });
        const viewClass = classNames({
            'ui basic button': true,
            'disabled': contentDetails.mode ==='view'
        });
        const addSlideClass = classNames({
            'ui basic button': true,
            'disabled': this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'
        });
        const addDeckClass = classNames({
            'ui basic button': true,
            'disabled': this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'
        });
        const duplicateItemClass = classNames({
            'ui basic button': true,
            'disabled': contentDetails.selector.id === contentDetails.selector.sid || contentDetails.selector.stype==='deck' || this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'
        });
        const deleteItemClass = classNames({
            'ui basic button': true,
            'disabled': contentDetails.selector.id === contentDetails.selector.sid || this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'
        });
        const red = {
            backgroundColor: 'red'
        };

        let selectorImm = this.props.DeckTreeStore.selector;
        let selector = {id: selectorImm.get('id'), stype: selectorImm.get('stype'), sid: selectorImm.get('sid'), spath: selectorImm.get('spath')};

        let buttonStyle = {
            classNames : classNames({
                'ui basic button':true,
                'disabled': this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'
            }),
            iconSize : 'large',
            noTabIndex : this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'
        } ;
        let editButton, saveButton, cancelButton, undoButton, redoButton;

        if ((contentDetails.mode === 'edit' || contentDetails.mode === 'markdownEdit') && this.props.UserProfileStore.username !== ''){
            //edit mode & logged UserProfileStore
            editButton = '';
            //ref="" --> we can't use string refs as they are legacy. ref={(refName)=>{this.refName=refName}}
            if(contentDetails.selector.stype === 'slide'){
                saveButton =
                    <button tabIndex="0"  className="ui button primary " onClick={this.handleSaveButtonClick.bind(this)} onChange={this.handleSaveButtonClick.bind(this)}>

                        Save
                    </button>;
                cancelButton =
                    <button tabIndex="0"  className="ui button " onClick={this.handleCancelButtonClick.bind(this, selector)} onChange={this.handleCancelButtonClick.bind(this, selector)}>

                        Cancel
                    </button>;
            } else {
                saveButton ='';
                cancelButton ='';
            }

            /*It were not displayed in master...but the code is prepared for it*/
            undoButton ='';
            redoButton ='';

            /* discomment when we want to see them
            undoButton =
                    <button tabIndex="0"  className="ui orange button " onClick={this.handleUndoButtonClick.bind(this)} onChange={this.handleUndoButtonClick.bind(this)}>

                    </button>;
            redoButton =
                    <button tabIndex="0"  className="ui orange button " onClick={this.handleRedoButtonClick.bind(this)} onChange={this.handleRedoButtonClick.bind(this)}>

                    </button>;
            */

        } else{ //No buttons
            if(this.props.UserProfileStore.username !== '') /* Edit button only visible if logged user*/
            {
                editButton =
                    <button className={editClass} onClick={this.handleEditButton.bind(this,selector)}
                        type="button"
                        aria-label={this.context.intl.formatMessage(this.messages.editButtonAriaText)}
                        tabIndex = {contentDetails.mode ==='edit'?-1:0}
                        >

                        {this.context.intl.formatMessage(this.messages.editButtonText)}

                    </button>;
            }
            saveButton ='';
            cancelButton ='';
            undoButton ='';
            redoButton ='';

        }
        /*
        <button className={viewClass} onClick={this.handleViewButton.bind(this,selector)}
          type="button"
          aria-label={this.context.intl.formatMessage(this.messages.viewButtonAriaText)}
          data-tooltip={this.context.intl.formatMessage(this.messages.viewButtonAriaText)}
          tabIndex = {contentDetails.mode ==='edit'?0:-1}
        >
          {this.context.intl.formatMessage(this.messages.viewButtonText)}
        </button>
        */

        return (

                        {editButton}
                        {saveButton}
                        {cancelButton}
                        {undoButton}
                        {redoButton}

                    {this.props.UserProfileStore.username === '' ? '' :

                        <button className={addSlideClass} onClick={this.handleAddNode.bind(this, selector, {type: 'slide', id: '0'}) }
                            type="button"
                            aria-label={this.context.intl.formatMessage(this.messages.addSlideButtonAriaText)}
                            data-tooltip={this.context.intl.formatMessage(this.messages.addSlideButtonAriaText)}
                            tabIndex={this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'?-1:0}>

                        </button>
                        <AttachSlides buttonStyle={buttonStyle} selector={selector} />
                        <button className={addDeckClass} onClick={this.handleAddNode.bind(this, selector, {type: 'deck', id: '0'})}
                            type="button"
                            aria-label={this.context.intl.formatMessage(this.messages.addDeckButtonAriaText)}
                            data-tooltip={this.context.intl.formatMessage(this.messages.addDeckButtonAriaText)}
                            tabIndex={this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'?-1:0}>

                        </button>
                        <AttachSubdeck buttonStyle={buttonStyle} selector={selector} />
                        <button className={duplicateItemClass} onClick={this.handleAddNode.bind(this, selector, {type: selector.stype, id: selector.sid})}
                            type="button"
                            aria-label={this.context.intl.formatMessage(this.messages.duplicateAriaText)}
                            data-tooltip={this.context.intl.formatMessage(this.messages.duplicateAriaText)}
                            tabIndex={contentDetails.selector.id === contentDetails.selector.sid || contentDetails.selector.stype==='deck' || this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'?-1:0}>

                        </button>
                        <button className={deleteItemClass} onClick={this.handleDeleteNode.bind(this, selector)}
                            type="button"
                            aria-label={this.context.intl.formatMessage(this.messages.deleteAriaText)}
                            data-tooltip={this.context.intl.formatMessage(this.messages.deleteAriaText)}
                            tabIndex={contentDetails.selector.id === contentDetails.selector.sid || this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'?-1:0}>

                        </button>
                        {/*
                          <button className="item ui small basic right attached disabled button">

                          </button>
                          */}

                    }

        );
    }
}
ContentActionsHeader.contextTypes = {
    executeAction: React.PropTypes.func.isRequired,
    intl: React.PropTypes.object.isRequired
};
//it should listen to decktree store in order to handle adding slides/decks
ContentActionsHeader = connectToStores(ContentActionsHeader, [DeckTreeStore, UserProfileStore, PermissionsStore, ContentStore], (context, props) => {
    return {
        DeckTreeStore: context.getStore(DeckTreeStore).getState(),
        UserProfileStore: context.getStore(UserProfileStore).getState(),
        PermissionsStore: context.getStore(PermissionsStore).getState(),
        ContentStore: context.getStore(ContentStore).getState()
    };
});
export default ContentActionsHeader;
<commit_msg>added Markdown Editor button<commit_after>import React from 'react';
import {NavLink, navigateAction} from 'fluxible-router';
import classNames from 'classnames/bind';
import {connectToStores} from 'fluxible-addons-react';
import ContentUtil from '../util/ContentUtil';
import DeckTreeStore from '../../../../stores/DeckTreeStore';
import UserProfileStore from '../../../../stores/UserProfileStore';
import addTreeNodeAndNavigate from '../../../../actions/decktree/addTreeNodeAndNavigate';
import deleteTreeNodeAndNavigate from '../../../../actions/decktree/deleteTreeNodeAndNavigate';
import AttachSubdeck from '../AttachSubdeck/AttachSubdeckModal';
import AttachSlides from '../AttachSubdeck/AttachSlidesModal';
import PermissionsStore from '../../../../stores/PermissionsStore';
import ContentStore from '../../../../stores/ContentStore';
import showNoPermissionsModal from '../../../../actions/permissions/showNoPermissionsModal';
import saveClick from '../../../../actions/slide/saveClick';
import cancelClick from '../../../../actions/slide/cancelClick';
import undoClick from '../../../../actions/slide/undoClick';
import redoClick from '../../../../actions/slide/redoClick';
import {defineMessages} from 'react-intl';

class ContentActionsHeader extends React.Component {
    constructor(props){
        super(props);
        this.messages = defineMessages({
            viewButtonText:{
                id: 'ContentActionsHeader.viewButtonText',
                defaultMessage:'View'
            },
            viewButtonAriaText:{
                id: 'ContentActionsHeader.viewButtonAriaText',
                defaultMessage:'View Mode'
            },
            editButtonText:{
                id: 'ContentActionsHeader.editButtonText',
                defaultMessage:'Edit'
            },
            editButtonAriaText:{
                id: 'ContentActionsHeader.editButtonAriaText',
                defaultMessage:'Edit Mode'
            },
            addSlideButtonAriaText:{
                id: 'ContentActionsHeader.addSlideButtonAriaText',
                defaultMessage:'Add Slide'
            },
            addDeckButtonAriaText:{
                id: 'ContentActionsHeader.addDeckButtonAriaText',
                defaultMessage:'Add Deck'
            },
            duplicateAriaText:{
                id: 'ContentActionsHeader.duplicateAriaText',
                defaultMessage:'Duplicate'
            },
            deleteAriaText:{
                id: 'ContentActionsHeader.deleteAriaText',
                defaultMessage:'Delete'
            },

        });

    }

    handleAddNode(selector, nodeSpec) {
        //selector: Object {id: "56", stype: "deck", sid: 67, spath: "67:2"}
        //nodeSec: Object {type: "slide", id: "0"}
        this.context.executeAction(addTreeNodeAndNavigate, {selector: selector, nodeSpec: nodeSpec});
    }

    handleDeleteNode(selector) {
        this.context.executeAction(deleteTreeNodeAndNavigate, selector);
    }

    handleSaveButtonClick(){
        this.context.executeAction(saveClick, {});
    }
    handleUndoButtonClick (){
        //this.context.executeAction(undoClick, {});
        //console.log('undo');
    }
    handleRedoButtonClick(){
        //this.context.executeAction(redoClick, {});
        //console.log('redo');
    }
    handleCancelButtonClick(selector){
        this.context.executeAction(cancelClick, {
            selector: selector
        });
    }
    handleViewButton(selector) {
        const nodeURL = ContentUtil.makeNodeURL(selector, 'view');
        this.context.executeAction(navigateAction, {
            url: nodeURL
        });

    }

    handleEditButton(selector) {
        const nodeURL = ContentUtil.makeNodeURL(selector, 'edit');
        if (this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit) {
            this.context.executeAction(showNoPermissionsModal, {selector: selector, user: this.props.UserProfileStore.userid, permissions: this.props.PermissionsStore.permissions});
        } else {
            this.context.executeAction(navigateAction, {
                url: nodeURL
            });
        }
    }
    handleMarkdownEditButton(selector) {
        const nodeURL = ContentUtil.makeNodeURL(selector, 'markdownEdit');
        if (this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit) {
            this.context.executeAction(showNoPermissionsModal, {selector: selector, user: this.props.UserProfileStore.userid, permissions: this.props.PermissionsStore.permissions});
        } else {
            this.context.executeAction(navigateAction, {
                url: nodeURL
            });
        }
    }
    render() {
        const contentDetails = this.props.ContentStore;
        //config buttons based on the selected item
        const editClass = classNames({
            'ui button attached basic': true,
            //'disabled': this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'
        });
        const viewClass = classNames({
            'ui basic button': true,
            'disabled': contentDetails.mode ==='view'
        });
        const addSlideClass = classNames({
            'ui basic button': true,
            'disabled': this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'
        });
        const addDeckClass = classNames({
            'ui basic button': true,
            'disabled': this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'
        });
        const duplicateItemClass = classNames({
            'ui basic button': true,
            'disabled': contentDetails.selector.id === contentDetails.selector.sid || contentDetails.selector.stype==='deck' || this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'
        });
        const deleteItemClass = classNames({
            'ui basic button': true,
            'disabled': contentDetails.selector.id === contentDetails.selector.sid || this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'
        });
        const red = {
            backgroundColor: 'red'
        };

        let selectorImm = this.props.DeckTreeStore.selector;
        let selector = {id: selectorImm.get('id'), stype: selectorImm.get('stype'), sid: selectorImm.get('sid'), spath: selectorImm.get('spath')};

        let buttonStyle = {
            classNames : classNames({
                'ui basic button':true,
                'disabled': this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'
            }),
            iconSize : 'large',
            noTabIndex : this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'
        } ;
        let editButton, markdownEditButton, saveButton, cancelButton, undoButton, redoButton;

        if ((contentDetails.mode === 'edit' || contentDetails.mode === 'markdownEdit') && this.props.UserProfileStore.username !== ''){
            //edit mode & logged UserProfileStore
            editButton = '';
            markdownEditButton = '';
            //ref="" --> we can't use string refs as they are legacy. ref={(refName)=>{this.refName=refName}}
            if(contentDetails.selector.stype === 'slide'){
                saveButton =
                    <button tabIndex="0"  className="ui button primary " onClick={this.handleSaveButtonClick.bind(this)} onChange={this.handleSaveButtonClick.bind(this)}>

                        Save
                    </button>;
                cancelButton =
                    <button tabIndex="0"  className="ui button " onClick={this.handleCancelButtonClick.bind(this, selector)} onChange={this.handleCancelButtonClick.bind(this, selector)}>

                        Cancel
                    </button>;
            } else {
                saveButton ='';
                cancelButton ='';
            }

            /*It were not displayed in master...but the code is prepared for it*/
            undoButton ='';
            redoButton ='';

            /* discomment when we want to see them
            undoButton =
                    <button tabIndex="0"  className="ui orange button " onClick={this.handleUndoButtonClick.bind(this)} onChange={this.handleUndoButtonClick.bind(this)}>

                    </button>;
            redoButton =
                    <button tabIndex="0"  className="ui orange button " onClick={this.handleRedoButtonClick.bind(this)} onChange={this.handleRedoButtonClick.bind(this)}>

                    </button>;
            */

        } else{ //No buttons
            if(this.props.UserProfileStore.username !== '') /* Edit button only visible if logged user*/
            {
                editButton =
                    <button className={editClass} onClick={this.handleEditButton.bind(this,selector)}
                        type="button"
                        aria-label={this.context.intl.formatMessage(this.messages.editButtonAriaText)}
                        tabIndex = {contentDetails.mode ==='edit'?-1:0}
                        >

                        {this.context.intl.formatMessage(this.messages.editButtonText)}

                    </button>;
                markdownEditButton =
                    <button className={editClass} onClick={this.handleMarkdownEditButton.bind(this,selector)}
                        type="button"
                        aria-label={this.context.intl.formatMessage(this.messages.editButtonAriaText)}
                        tabIndex = {contentDetails.mode ==='markdownEdit'?-1:0}
                        >

                        Markdown Editor

                    </button>;
            }
            saveButton ='';
            cancelButton ='';
            undoButton ='';
            redoButton ='';

        }
        /*
        <button className={viewClass} onClick={this.handleViewButton.bind(this,selector)}
          type="button"
          aria-label={this.context.intl.formatMessage(this.messages.viewButtonAriaText)}
          data-tooltip={this.context.intl.formatMessage(this.messages.viewButtonAriaText)}
          tabIndex = {contentDetails.mode ==='edit'?0:-1}
        >
          {this.context.intl.formatMessage(this.messages.viewButtonText)}
        </button>
        */

        return (

                        {editButton}
                        {markdownEditButton}
                        {saveButton}
                        {cancelButton}
                        {undoButton}
                        {redoButton}

                    {this.props.UserProfileStore.username === '' ? '' :

                        <button className={addSlideClass} onClick={this.handleAddNode.bind(this, selector, {type: 'slide', id: '0'}) }
                            type="button"
                            aria-label={this.context.intl.formatMessage(this.messages.addSlideButtonAriaText)}
                            data-tooltip={this.context.intl.formatMessage(this.messages.addSlideButtonAriaText)}
                            tabIndex={this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'?-1:0}>

                        </button>
                        <AttachSlides buttonStyle={buttonStyle} selector={selector} />
                        <button className={addDeckClass} onClick={this.handleAddNode.bind(this, selector, {type: 'deck', id: '0'})}
                            type="button"
                            aria-label={this.context.intl.formatMessage(this.messages.addDeckButtonAriaText)}
                            data-tooltip={this.context.intl.formatMessage(this.messages.addDeckButtonAriaText)}
                            tabIndex={this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'?-1:0}>

                        </button>
                        <AttachSubdeck buttonStyle={buttonStyle} selector={selector} />
                        <button className={duplicateItemClass} onClick={this.handleAddNode.bind(this, selector, {type: selector.stype, id: selector.sid})}
                            type="button"
                            aria-label={this.context.intl.formatMessage(this.messages.duplicateAriaText)}
                            data-tooltip={this.context.intl.formatMessage(this.messages.duplicateAriaText)}
                            tabIndex={contentDetails.selector.id === contentDetails.selector.sid || contentDetails.selector.stype==='deck' || this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'?-1:0}>

                        </button>
                        <button className={deleteItemClass} onClick={this.handleDeleteNode.bind(this, selector)}
                            type="button"
                            aria-label={this.context.intl.formatMessage(this.messages.deleteAriaText)}
                            data-tooltip={this.context.intl.formatMessage(this.messages.deleteAriaText)}
                            tabIndex={contentDetails.selector.id === contentDetails.selector.sid || this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'?-1:0}>

                        </button>
                        {/*
                          <button className="item ui small basic right attached disabled button">

                          </button>
                          */}

                    }

        );
    }
}
ContentActionsHeader.contextTypes = {
    executeAction: React.PropTypes.func.isRequired,
    intl: React.PropTypes.object.isRequired
};
//it should listen to decktree store in order to handle adding slides/decks
ContentActionsHeader = connectToStores(ContentActionsHeader, [DeckTreeStore, UserProfileStore, PermissionsStore, ContentStore], (context, props) => {
    return {
        DeckTreeStore: context.getStore(DeckTreeStore).getState(),
        UserProfileStore: context.getStore(UserProfileStore).getState(),
        PermissionsStore: context.getStore(PermissionsStore).getState(),
        ContentStore: context.getStore(ContentStore).getState()
    };
});
export default ContentActionsHeader;
<|endoftext|>


<commit_before>import React from 'react';
import {NavLink, navigateAction} from 'fluxible-router';
import classNames from 'classnames/bind';
import {connectToStores} from 'fluxible-addons-react';
import ContentUtil from '../util/ContentUtil';
import DeckTreeStore from '../../../../stores/DeckTreeStore';
import UserProfileStore from '../../../../stores/UserProfileStore';
import addTreeNodeAndNavigate from '../../../../actions/decktree/addTreeNodeAndNavigate';
import deleteTreeNodeAndNavigate from '../../../../actions/decktree/deleteTreeNodeAndNavigate';
import AttachSubdeck from '../AttachSubdeck/AttachSubdeckModal';
import AttachSlides from '../AttachSubdeck/AttachSlidesModal';
import PermissionsStore from '../../../../stores/PermissionsStore';
import ContentStore from '../../../../stores/ContentStore';
import showNoPermissionsModal from '../../../../actions/permissions/showNoPermissionsModal';
import saveClick from '../../../../actions/slide/saveClick';
import cancelClick from '../../../../actions/slide/cancelClick';
import undoClick from '../../../../actions/slide/undoClick';
import redoClick from '../../../../actions/slide/redoClick';
import {defineMessages} from 'react-intl';

class ContentActionsHeader extends React.Component {
    constructor(props){
        super(props);
        this.messages = defineMessages({
            viewButtonText:{
                id: 'ContentActionsHeader.viewButtonText',
                defaultMessage:'View'
            },
            viewButtonAriaText:{
                id: 'ContentActionsHeader.viewButtonAriaText',
                defaultMessage:'View Mode'
            },
            editButtonText:{
                id: 'ContentActionsHeader.editButtonText',
                defaultMessage:'Edit'
            },
            editButtonAriaText:{
                id: 'ContentActionsHeader.editButtonAriaText',
                defaultMessage:'Edit Mode'
            },
            addSlideButtonAriaText:{
                id: 'ContentActionsHeader.addSlideButtonAriaText',
                defaultMessage:'Add Slide'
            },
            addDeckButtonAriaText:{
                id: 'ContentActionsHeader.addDeckButtonAriaText',
                defaultMessage:'Add Deck'
            },
            duplicateAriaText:{
                id: 'ContentActionsHeader.duplicateAriaText',
                defaultMessage:'Duplicate'
            },
            deleteAriaText:{
                id: 'ContentActionsHeader.deleteAriaText',
                defaultMessage:'Delete'
            },

        });

    }

    handleAddNode(selector, nodeSpec) {
        //selector: Object {id: "56", stype: "deck", sid: 67, spath: "67:2"}
        //nodeSec: Object {type: "slide", id: "0"}
        this.context.executeAction(addTreeNodeAndNavigate, {selector: selector, nodeSpec: nodeSpec});
    }

    handleDeleteNode(selector) {
        this.context.executeAction(deleteTreeNodeAndNavigate, selector);
    }

    handleSaveButtonClick(){
        this.context.executeAction(saveClick, {});
    }
    handleUndoButtonClick (){
        //this.context.executeAction(undoClick, {});
        //console.log('undo');
    }
    handleRedoButtonClick(){
        //this.context.executeAction(redoClick, {});
        //console.log('redo');
    }
    handleCancelButtonClick(selector){
        this.context.executeAction(cancelClick, {
            selector: selector
        });
    }
    handleViewButton(selector) {
        const nodeURL = ContentUtil.makeNodeURL(selector, 'view');
        this.context.executeAction(navigateAction, {
            url: nodeURL
        });

    }

    handleEditButton(selector) {
        const nodeURL = ContentUtil.makeNodeURL(selector, 'edit');
        if (this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit) {
            this.context.executeAction(showNoPermissionsModal, {selector: selector, user: this.props.UserProfileStore.userid, permissions: this.props.PermissionsStore.permissions});
        } else {
            this.context.executeAction(navigateAction, {
                url: nodeURL
            });
        }
    }
    render() {
        const contentDetails = this.props.ContentStore;
        //config buttons based on the selected item
        const editClass = classNames({
            'item ui button': true,
            'disabled': this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'
        });
        const viewClass = classNames({
            'item ui small basic button': true,
            'disabled': contentDetails.mode ==='view'
        });
        const addSlideClass = classNames({
            'item ui small basic left attached button': true,
            'disabled': this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'
        });
        const addDeckClass = classNames({
            'item ui small basic left attached button': true,
            'disabled': this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'
        });
        const duplicateItemClass = classNames({
            'item ui small basic left attached button': true,
            'disabled': contentDetails.selector.id === contentDetails.selector.sid || contentDetails.selector.stype==='deck' || this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'
        });
        const deleteItemClass = classNames({
            'item ui small basic left attached button': true,
            'disabled': contentDetails.selector.id === contentDetails.selector.sid || this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'
        });
        const red = {
            backgroundColor: 'red'
        };

        let selectorImm = this.props.DeckTreeStore.selector;
        let selector = {id: selectorImm.get('id'), stype: selectorImm.get('stype'), sid: selectorImm.get('sid'), spath: selectorImm.get('spath')};

        let buttonStyle = {
            classNames : classNames({
                'item small attached left':true,
                'disabled': this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'
            }),
            iconSize : 'large',
            attached : 'left',
            noTabIndex : this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'
        } ;
        let editButton, saveButton, cancelButton, undoButton, redoButton;

        if (contentDetails.mode === 'edit' && this.props.UserProfileStore.username !== ''){
            //edit mode & logged UserProfileStore
            editButton = '';
            //ref="" --> we can't use string refs as they are legacy. ref={(refName)=>{this.refName=refName}}
            if(contentDetails.selector.stype === 'slide'){
                saveButton =
                        <button tabIndex="0"  className="ui button blue primary " onClick={this.handleSaveButtonClick.bind(this)} onChange={this.handleSaveButtonClick.bind(this)}>

                             Save
                        </button>;
                cancelButton =
                        <button tabIndex="0"  className="ui button " onClick={this.handleCancelButtonClick.bind(this, selector)} onChange={this.handleCancelButtonClick.bind(this, selector)}>

                             cancel
                        </button>;
            } else {
                saveButton ='';
                cancelButton ='';
            }

            /*It were not displayed in master...but the code is prepared for it*/
            undoButton ='';
            redoButton ='';

            /* discomment when we want to see them
            undoButton =
                    <button tabIndex="0"  className="ui orange button " onClick={this.handleUndoButtonClick.bind(this)} onChange={this.handleUndoButtonClick.bind(this)}>

                    </button>;
            redoButton =
                    <button tabIndex="0"  className="ui orange button " onClick={this.handleRedoButtonClick.bind(this)} onChange={this.handleRedoButtonClick.bind(this)}>

                    </button>;
            */

        } else{ //No buttons
            if(this.props.UserProfileStore.username !== '') /* Edit button only visible if logged user*/
            {
                editButton =
                                <button className={editClass} onClick={this.handleEditButton.bind(this,selector)}
                                  type="button"
                                  aria-label={this.context.intl.formatMessage(this.messages.editButtonAriaText)}
                                  /*data-tooltip={this.context.intl.formatMessage(this.messages.editButtonAriaText)}*/
                                  tabIndex = {contentDetails.mode ==='edit'?-1:0}
                                >
                                  {this.context.intl.formatMessage(this.messages.editButtonText)}
                                </button>;
            }
            saveButton ='';
            cancelButton ='';
            undoButton ='';
            redoButton ='';

        }
        /*
        <button className={viewClass} onClick={this.handleViewButton.bind(this,selector)}
          type="button"
          aria-label={this.context.intl.formatMessage(this.messages.viewButtonAriaText)}
          data-tooltip={this.context.intl.formatMessage(this.messages.viewButtonAriaText)}
          tabIndex = {contentDetails.mode ==='edit'?0:-1}
        >
          {this.context.intl.formatMessage(this.messages.viewButtonText)}
        </button>
        */

        return (

                {editButton}
                {saveButton}
                {cancelButton}
                {undoButton}
                {redoButton}

                {this.props.UserProfileStore.username === '' ? '' :

                        <button className={addSlideClass} onClick={this.handleAddNode.bind(this, selector, {type: 'slide', id: '0'}) }
                          type="button"
                          aria-label={this.context.intl.formatMessage(this.messages.addSlideButtonAriaText)}
                          data-tooltip={this.context.intl.formatMessage(this.messages.addSlideButtonAriaText)}
                          tabIndex={this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'?-1:0}>

                        </button>
                        <AttachSlides buttonStyle={buttonStyle} selector={selector} />
                        <button className={addDeckClass} onClick={this.handleAddNode.bind(this, selector, {type: 'deck', id: '0'})}
                           type="button"
                           aria-label={this.context.intl.formatMessage(this.messages.addDeckButtonAriaText)}
                           data-tooltip={this.context.intl.formatMessage(this.messages.addDeckButtonAriaText)}
                           tabIndex={this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'?-1:0}>

                        </button>
                        <AttachSubdeck buttonStyle={buttonStyle} selector={selector} />
                        <button className={duplicateItemClass} onClick={this.handleAddNode.bind(this, selector, {type: selector.stype, id: selector.sid})}
                           type="button"
                           aria-label={this.context.intl.formatMessage(this.messages.duplicateAriaText)}
                           data-tooltip={this.context.intl.formatMessage(this.messages.duplicateAriaText)}
                           tabIndex={contentDetails.selector.id === contentDetails.selector.sid || contentDetails.selector.stype==='deck' || this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'?-1:0}>

                        </button>
                        <button className={deleteItemClass} onClick={this.handleDeleteNode.bind(this, selector)}
                            type="button"
                            aria-label={this.context.intl.formatMessage(this.messages.deleteAriaText)}
                            data-tooltip={this.context.intl.formatMessage(this.messages.deleteAriaText)}
                            tabIndex={this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'?-1:0}>

                        </button>
                          {/*
                          <button className="item ui small basic right attached disabled button">

                          </button>
                          */}

                  }

        );
    }
  }
ContentActionsHeader.contextTypes = {
    executeAction: React.PropTypes.func.isRequired,
    intl: React.PropTypes.object.isRequired
};
//it should listen to decktree store in order to handle adding slides/decks
ContentActionsHeader = connectToStores(ContentActionsHeader, [DeckTreeStore, UserProfileStore, PermissionsStore, ContentStore], (context, props) => {
    return {
        DeckTreeStore: context.getStore(DeckTreeStore).getState(),
        UserProfileStore: context.getStore(UserProfileStore).getState(),
        PermissionsStore: context.getStore(PermissionsStore).getState(),
        ContentStore: context.getStore(ContentStore).getState()
    };
});
export default ContentActionsHeader;
<commit_msg>fixed edit button style<commit_after>import React from 'react';
import {NavLink, navigateAction} from 'fluxible-router';
import classNames from 'classnames/bind';
import {connectToStores} from 'fluxible-addons-react';
import ContentUtil from '../util/ContentUtil';
import DeckTreeStore from '../../../../stores/DeckTreeStore';
import UserProfileStore from '../../../../stores/UserProfileStore';
import addTreeNodeAndNavigate from '../../../../actions/decktree/addTreeNodeAndNavigate';
import deleteTreeNodeAndNavigate from '../../../../actions/decktree/deleteTreeNodeAndNavigate';
import AttachSubdeck from '../AttachSubdeck/AttachSubdeckModal';
import AttachSlides from '../AttachSubdeck/AttachSlidesModal';
import PermissionsStore from '../../../../stores/PermissionsStore';
import ContentStore from '../../../../stores/ContentStore';
import showNoPermissionsModal from '../../../../actions/permissions/showNoPermissionsModal';
import saveClick from '../../../../actions/slide/saveClick';
import cancelClick from '../../../../actions/slide/cancelClick';
import undoClick from '../../../../actions/slide/undoClick';
import redoClick from '../../../../actions/slide/redoClick';
import {defineMessages} from 'react-intl';

class ContentActionsHeader extends React.Component {
    constructor(props){
        super(props);
        this.messages = defineMessages({
            viewButtonText:{
                id: 'ContentActionsHeader.viewButtonText',
                defaultMessage:'View'
            },
            viewButtonAriaText:{
                id: 'ContentActionsHeader.viewButtonAriaText',
                defaultMessage:'View Mode'
            },
            editButtonText:{
                id: 'ContentActionsHeader.editButtonText',
                defaultMessage:'Edit'
            },
            editButtonAriaText:{
                id: 'ContentActionsHeader.editButtonAriaText',
                defaultMessage:'Edit Mode'
            },
            addSlideButtonAriaText:{
                id: 'ContentActionsHeader.addSlideButtonAriaText',
                defaultMessage:'Add Slide'
            },
            addDeckButtonAriaText:{
                id: 'ContentActionsHeader.addDeckButtonAriaText',
                defaultMessage:'Add Deck'
            },
            duplicateAriaText:{
                id: 'ContentActionsHeader.duplicateAriaText',
                defaultMessage:'Duplicate'
            },
            deleteAriaText:{
                id: 'ContentActionsHeader.deleteAriaText',
                defaultMessage:'Delete'
            },

        });

    }

    handleAddNode(selector, nodeSpec) {
        //selector: Object {id: "56", stype: "deck", sid: 67, spath: "67:2"}
        //nodeSec: Object {type: "slide", id: "0"}
        this.context.executeAction(addTreeNodeAndNavigate, {selector: selector, nodeSpec: nodeSpec});
    }

    handleDeleteNode(selector) {
        this.context.executeAction(deleteTreeNodeAndNavigate, selector);
    }

    handleSaveButtonClick(){
        this.context.executeAction(saveClick, {});
    }
    handleUndoButtonClick (){
        //this.context.executeAction(undoClick, {});
        //console.log('undo');
    }
    handleRedoButtonClick(){
        //this.context.executeAction(redoClick, {});
        //console.log('redo');
    }
    handleCancelButtonClick(selector){
        this.context.executeAction(cancelClick, {
            selector: selector
        });
    }
    handleViewButton(selector) {
        const nodeURL = ContentUtil.makeNodeURL(selector, 'view');
        this.context.executeAction(navigateAction, {
            url: nodeURL
        });

    }

    handleEditButton(selector) {
        const nodeURL = ContentUtil.makeNodeURL(selector, 'edit');
        if (this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit) {
            this.context.executeAction(showNoPermissionsModal, {selector: selector, user: this.props.UserProfileStore.userid, permissions: this.props.PermissionsStore.permissions});
        } else {
            this.context.executeAction(navigateAction, {
                url: nodeURL
            });
        }
    }
    render() {
        const contentDetails = this.props.ContentStore;
        //config buttons based on the selected item
        const editClass = classNames({
            'ui button basic primary': true,
            'disabled': this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'
        });
        const viewClass = classNames({
            ' ui small basic button': true,
            'disabled': contentDetails.mode ==='view'
        });
        const addSlideClass = classNames({
            'ui small basic left attached button': true,
            'disabled': this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'
        });
        const addDeckClass = classNames({
            'ui small basic left attached button': true,
            'disabled': this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'
        });
        const duplicateItemClass = classNames({
            'ui small basic left attached button': true,
            'disabled': contentDetails.selector.id === contentDetails.selector.sid || contentDetails.selector.stype==='deck' || this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'
        });
        const deleteItemClass = classNames({
            'ui small basic left attached button': true,
            'disabled': contentDetails.selector.id === contentDetails.selector.sid || this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'
        });
        const red = {
            backgroundColor: 'red'
        };

        let selectorImm = this.props.DeckTreeStore.selector;
        let selector = {id: selectorImm.get('id'), stype: selectorImm.get('stype'), sid: selectorImm.get('sid'), spath: selectorImm.get('spath')};

        let buttonStyle = {
            classNames : classNames({
                'ui small basic left attached button':true,
                'disabled': this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'
            }),
            iconSize : 'large',
            attached : 'left',
            noTabIndex : this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'
        } ;
        let editButton, saveButton, cancelButton, undoButton, redoButton;

        if (contentDetails.mode === 'edit' && this.props.UserProfileStore.username !== ''){
            //edit mode & logged UserProfileStore
            editButton = '';
            //ref="" --> we can't use string refs as they are legacy. ref={(refName)=>{this.refName=refName}}
            if(contentDetails.selector.stype === 'slide'){
                saveButton =
                        <button tabIndex="0"  className="ui button blue primary " onClick={this.handleSaveButtonClick.bind(this)} onChange={this.handleSaveButtonClick.bind(this)}>

                             Save
                        </button>;
                cancelButton =
                        <button tabIndex="0"  className="ui button " onClick={this.handleCancelButtonClick.bind(this, selector)} onChange={this.handleCancelButtonClick.bind(this, selector)}>

                             Cancel
                        </button>;
            } else {
                saveButton ='';
                cancelButton ='';
            }

            /*It were not displayed in master...but the code is prepared for it*/
            undoButton ='';
            redoButton ='';

            /* discomment when we want to see them
            undoButton =
                    <button tabIndex="0"  className="ui orange button " onClick={this.handleUndoButtonClick.bind(this)} onChange={this.handleUndoButtonClick.bind(this)}>

                    </button>;
            redoButton =
                    <button tabIndex="0"  className="ui orange button " onClick={this.handleRedoButtonClick.bind(this)} onChange={this.handleRedoButtonClick.bind(this)}>

                    </button>;
            */

        } else{ //No buttons
            if(this.props.UserProfileStore.username !== '') /* Edit button only visible if logged user*/
            {
                editButton =
                                <button className={editClass} onClick={this.handleEditButton.bind(this,selector)}
                                  type="button"
                                  aria-label={this.context.intl.formatMessage(this.messages.editButtonAriaText)}
                                  /*data-tooltip={this.context.intl.formatMessage(this.messages.editButtonAriaText)}*/
                                  tabIndex = {contentDetails.mode ==='edit'?-1:0}
                                >
                                  {this.context.intl.formatMessage(this.messages.editButtonText)}
                                </button>;
            }
            saveButton ='';
            cancelButton ='';
            undoButton ='';
            redoButton ='';

        }
        /*
        <button className={viewClass} onClick={this.handleViewButton.bind(this,selector)}
          type="button"
          aria-label={this.context.intl.formatMessage(this.messages.viewButtonAriaText)}
          data-tooltip={this.context.intl.formatMessage(this.messages.viewButtonAriaText)}
          tabIndex = {contentDetails.mode ==='edit'?0:-1}
        >
          {this.context.intl.formatMessage(this.messages.viewButtonText)}
        </button>
        */

        return (

                {editButton}
                {saveButton}
                {cancelButton}
                {undoButton}
                {redoButton}

                {this.props.UserProfileStore.username === '' ? '' :

                        <button className={addSlideClass} onClick={this.handleAddNode.bind(this, selector, {type: 'slide', id: '0'}) }
                          type="button"
                          aria-label={this.context.intl.formatMessage(this.messages.addSlideButtonAriaText)}
                          data-tooltip={this.context.intl.formatMessage(this.messages.addSlideButtonAriaText)}
                          tabIndex={this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'?-1:0}>

                        </button>
                        <AttachSlides buttonStyle={buttonStyle} selector={selector} />
                        <button className={addDeckClass} onClick={this.handleAddNode.bind(this, selector, {type: 'deck', id: '0'})}
                           type="button"
                           aria-label={this.context.intl.formatMessage(this.messages.addDeckButtonAriaText)}
                           data-tooltip={this.context.intl.formatMessage(this.messages.addDeckButtonAriaText)}
                           tabIndex={this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'?-1:0}>

                        </button>
                        <AttachSubdeck buttonStyle={buttonStyle} selector={selector} />
                        <button className={duplicateItemClass} onClick={this.handleAddNode.bind(this, selector, {type: selector.stype, id: selector.sid})}
                           type="button"
                           aria-label={this.context.intl.formatMessage(this.messages.duplicateAriaText)}
                           data-tooltip={this.context.intl.formatMessage(this.messages.duplicateAriaText)}
                           tabIndex={contentDetails.selector.id === contentDetails.selector.sid || contentDetails.selector.stype==='deck' || this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'?-1:0}>

                        </button>
                        <button className={deleteItemClass} onClick={this.handleDeleteNode.bind(this, selector)}
                            type="button"
                            aria-label={this.context.intl.formatMessage(this.messages.deleteAriaText)}
                            data-tooltip={this.context.intl.formatMessage(this.messages.deleteAriaText)}
                            tabIndex={this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'?-1:0}>

                        </button>
                          {/*
                          <button className="item ui small basic right attached disabled button">

                          </button>
                          */}

                  }

        );
    }
  }
ContentActionsHeader.contextTypes = {
    executeAction: React.PropTypes.func.isRequired,
    intl: React.PropTypes.object.isRequired
};
//it should listen to decktree store in order to handle adding slides/decks
ContentActionsHeader = connectToStores(ContentActionsHeader, [DeckTreeStore, UserProfileStore, PermissionsStore, ContentStore], (context, props) => {
    return {
        DeckTreeStore: context.getStore(DeckTreeStore).getState(),
        UserProfileStore: context.getStore(UserProfileStore).getState(),
        PermissionsStore: context.getStore(PermissionsStore).getState(),
        ContentStore: context.getStore(ContentStore).getState()
    };
});
export default ContentActionsHeader;
<|endoftext|>