<commit_before>/*############################################################################
#
#    OpenERP, Open Source Management Solution
#    Copyright (C) 2011 OpenERP SA (<http://openerp.com>).
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
############################################################################*/

var __lc_buttons = [];

openerp.web_livechat = function (openerp) {

openerp.web_livechat.Livechat = openerp.web.Widget.extend({
    template: 'Header-LiveChat',

    start: function() {
        this._super();
        if (!this.session)
            return;
        var self = this;
        var pwc = new openerp.web.Model(self.session, "publisher_warranty.contract");
        pwc.get_func('get_default_livechat_text')().then(function(text) {
            self.$element.html(text);
            console.log('receiving text', text);
            self.do_update();
        }).then(function() {
            pwc.get_func('is_livechat_enable')().then(function(res) {
                console.log('result', res);
                if(res) {
                    self.$element.find('a').click(self.do_load_livechat);
                } else {
                    self.do_action({type: 'ir.act.url', url: 'http://www.openerp.com/support-or-publisher-warranty-contract'});
                }
            })
        });

        openerp.webclient.header.do_update.add_last(this.do_update);
    },

    do_update: function() {
        var self = this;
        if (!this.session) {
            self.$element.remove();
            return;
        }
     },

    do_load_livechat: function(evt) {
        evt.preventDefault();
        var self = this;

        this.$element.find('Header_Livechat').unbind('click', this.do_load_livechat);

        var lc_id = _.uniqueId('livechat_');
        this.$element.attr('id', lc_id);

        var pwc = new openerp.web.Model(self.session, "publisher_warranty.contract");

        pwc.get_func('is_livechat_enable')().then(function(res) {
            console.log('res', res);
            if(!res) {
                //return;
            }
        // connect to LiveChat
        __lc_load();

            __lc_buttons.push({
                elementId: lc_id, //'livechat_status',
                language: 'en',
                skill: '0',
                type: 'text',
                labels: {
                    online: 'Support',
                    offline: 'Support',
                }
            });
        });
    }
});

if (openerp.webclient) {
    // tracking code from LiveChat
    var license = '1035052',
        params = '',
        lang = 'en',
        skill = '0';
    __lc_load = function (p) {
      if (typeof __lc_loaded != 'function')
        if (p) {
          var d = document,
            l = d.createElement('script'),
            s = d.getElementsByTagName('script')[0],
            a = unescape('%26'),
            h = ('https:' == d.location.protocol ? 'https://' : 'http://');
          l.type = 'text/javascript';
          l.async = true;
          l.src = h + 'gis' + p +'.livechatinc.com/gis.cgi?serverType=control'+a+'licenseID='+license+a+'jsonp=__lc_load';
          if (!(typeof p['server'] !== 'string' || typeof __lc_serv === 'string')) {
            l.src = h + (__lc_serv = p['server']) + '/licence/'+license+'/script.cgi?lang='+lang+a+'groups='+skill;
            l.src += (params == '') ? '' : a+'params='+encodeURIComponent(encodeURIComponent(params));
            s.parentNode.insertBefore(l, s);
          } else
            setTimeout(__lc_load, 1000);
          if(typeof __lc_serv != 'string'){
            s.parentNode.insertBefore(l, s);
          }
        } else __lc_load(Math.ceil(Math.random()*5));
    }

    // and add widget to webclient
    openerp.webclient.livechat = new openerp.web_livechat.Livechat(openerp.webclient);
    openerp.webclient.livechat.prependTo('div.header_corner');
}

};
<commit_msg>modified according to review<commit_after>/*############################################################################
#
#    OpenERP, Open Source Management Solution
#    Copyright (C) 2011 OpenERP SA (<http://openerp.com>).
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
############################################################################*/

var __lc_buttons = [];

openerp.web_livechat = function (openerp) {

openerp.web_livechat.Livechat = openerp.web.Widget.extend({
    template: 'Header-LiveChat',

    start: function() {
        this._super();
        if (!this.session)
            return;
        var self = this;
        var pwc = new openerp.web.Model(self.session, "publisher_warranty.contract");
        pwc.get_func('get_default_livechat_text')().then(function(text) {
            self.$element.html(text);
            console.log('receiving text', text);
            self.do_update();
        }).then(function() {
            pwc.get_func('is_livechat_enable')().then(function(res) {
                console.log('result', res);
                if(res) {
                    self.$element.click(self.do_load_livechat);
                } else {
                    self.do_action({type: 'ir.act.url', url: 'http://www.openerp.com/support-or-publisher-warranty-contract'});
                }
            })
        });

        openerp.webclient.header.do_update.add_last(this.do_update);
    },

    do_update: function() {
        var self = this;
        if (!this.session) {
            self.$element.remove();
            return;
        }
     },

    do_load_livechat: function(evt) {
        evt.preventDefault();
        var self = this;

        this.$element.unbind('click', this.do_load_livechat);

        var lc_id = _.uniqueId('livechat_');
        this.$element.attr('id', lc_id);

        var pwc = new openerp.web.Model(self.session, "publisher_warranty.contract");

        pwc.get_func('is_livechat_enable')().then(function(res) {
            console.log('res', res);
            if(!res) {
                //return;
            }
        // connect to LiveChat
        __lc_load();

            __lc_buttons.push({
                elementId: lc_id, //'livechat_status',
                language: 'en',
                skill: '0',
                type: 'text',
                labels: {
                    online: 'Support',
                    offline: 'Support',
                }
            });
        });
    }
});

if (openerp.webclient) {
    // tracking code from LiveChat
    var license = '1035052',
        params = '',
        lang = 'en',
        skill = '0';
    __lc_load = function (p) {
      if (typeof __lc_loaded != 'function')
        if (p) {
          var d = document,
            l = d.createElement('script'),
            s = d.getElementsByTagName('script')[0],
            a = unescape('%26'),
            h = ('https:' == d.location.protocol ? 'https://' : 'http://');
          l.type = 'text/javascript';
          l.async = true;
          l.src = h + 'gis' + p +'.livechatinc.com/gis.cgi?serverType=control'+a+'licenseID='+license+a+'jsonp=__lc_load';
          if (!(typeof p['server'] !== 'string' || typeof __lc_serv === 'string')) {
            l.src = h + (__lc_serv = p['server']) + '/licence/'+license+'/script.cgi?lang='+lang+a+'groups='+skill;
            l.src += (params == '') ? '' : a+'params='+encodeURIComponent(encodeURIComponent(params));
            s.parentNode.insertBefore(l, s);
          } else
            setTimeout(__lc_load, 1000);
          if(typeof __lc_serv != 'string'){
            s.parentNode.insertBefore(l, s);
          }
        } else __lc_load(Math.ceil(Math.random()*5));
    }

    // and add widget to webclient
    openerp.webclient.livechat = new openerp.web_livechat.Livechat(openerp.webclient);
    openerp.webclient.livechat.prependTo('div.header_corner');
}

};
<|endoftext|>


<commit_before>(function (a) {

var pageScriptsDone = false;
var wikiRootRgx = new RegExp((adminifier.wikiRoot + '/').replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'));

// this is for if pageScriptsDone event is added
// and the page scripts are already done
Element.Events.pageScriptsLoaded = {
	onAdd: function (fn) {
		if (pageScriptsDone)
            fn.call(this);
	}
};

Element.implement('onEnter', function (func) {
    this.addEvent('keyup', function (e) {
        if (e.key != 'enter')
            return;
        func.call(this, e);
    });
});

function SSV (str) {
    if (typeof str != 'string' || !str.length)
        return [];
    return str.split(' ');
}

// EXPORTS

// update page title
a.updatePageTitle = function (title, titleTagOnly) {
    if (!titleTagOnly)
        $('page-title').getElement('span').innerText = title;
    document.title = title + ' | ' + a.wikiName;
};

// update page icon
a.updateIcon = function (icon) {
	$('page-title').getElement('i').set('class', 'fa fa-' + icon);
};

// safe page/category name
a.safeName = function (name) {
    return name.replace(/[^\w\.\-]/g, '_');
};

// load a script
a.loadScript = function (src) {
	a.loadScripts([src]);
};

var scriptsToLoad = [], firedPageScriptsLoaded;
function scriptLoaded () {
	if (typeof jQuery != 'undefined')
		jQuery.noConflict();

	// there are still more to load
	if (scriptsToLoad.length) {
		loadNextScript();
		return;
	}

	// this was the last one
	$('content').setStyle('user-select', 'all');
	a.updateIcon(a.currentData['data-icon']);
	pageScriptsDone = true;
	if (firedPageScriptsLoaded) return;
	document.fireEvent('pageScriptsLoaded');
	firedPageScriptsLoaded = true;
}

function loadNextScript () {
	var script = scriptsToLoad.shift();
	if (!script)
		return;
	document.head.appendChild(script);
}

// load several scripts
a.loadScripts = function (srcs) {
    var sticky = false;
	srcs.each(function (src) {
        if (!src.length) return;

        // ace editor is special-- since it's large, load once and do not unload.
		if (src == 'ace') {
            if (window.ace)
                return;
            src = adminifier.staticRoot + '/ext/ace/src-min/ace.js';
            sticky = true;
        }

        // other distributions
		else if (src == 'pikaday')
			src = adminifier.staticRoot + '/ext/pikaday/pikaday.js';
		else if (src == 'jquery')
			src = '//cdnjs.cloudflare.com/ajax/libs/jquery/2.2.3/jquery.js';
		else if (src == 'diff2html')
			src = adminifier.staticRoot + '/ext/diff2html/dist/diff2html.js';
		else if (src == 'colorpicker')
			src = adminifier.staticRoot + '/ext/colorpicker/DynamicColorPicker.js';
		else if (src == 'prettify')
            src = 'https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js';

        // normal script
		else
            src = adminifier.staticRoot + '/script/' + src + '.js';

        // create script
        var script = new Element('script', { src: src });

        // remember it's dynamic so as to unload it later, UNLESS it's sticky
        if (!sticky)
            script.addClass('dynamic');

        // on load, call scriptLoaded
        script.addEvent('load', scriptLoaded);

        // add to the list to load
		scriptsToLoad.push(script);
	});

	// call once in case there are no scripts
	scriptLoaded();
}

// adopts an element to an invisible container in the DOM so that dimension
// properties become available before displaying it
a.fakeAdopt = function (child) {
    var parent = $('fake-parent');
    if (!parent) {
        parent = new Element('div', {
            id: 'fake-parent',
            styles: { display: 'none' }
        });
        document.body.appendChild(parent);
    }
    parent.appendChild(child);
};

document.addEvent('domready', 	loadURL);
document.addEvent('domready',	searchHandler);
document.addEvent('domready',   addDocumentFrameClickHandler);
document.addEvent('keyup',		handleEscapeKey);

// PAGE LOADING

function addDocumentFrameClickHandler () {
    addFrameClickHandler($$('a.frame-click'));
}

// clicking a frame link
a.addFrameClickHandler = addFrameClickHandler;
function addFrameClickHandler (where) {
    if (typeOf(where) == 'element')
        where = [where];
    where.each(function (a) {
        a.addEvent('click', function (e) {
            console.log("HANDLED IT FOR "+ a.href);
            e.preventDefault();
            var page = a.href.replace(/^.*\/\/[^\/]+/, '').replace(wikiRootRgx, '');
            history.pushState(page, '', adminifier.wikiRoot + '/' + page);
            loadURL();
        });
    });
    return where[0];
}

// load a page
function frameLoad (page) {

	// same page
    if (a.currentPage == page)
        return;

	// unload old page
    document.fireEvent('pageUnloaded');
    a.currentPage = page;
    console.log("Loading " + page);

	a.updateIcon('circle-o-notch fa-spin');
    var request = new Request({
        url: 'frame/' + page,
        onSuccess: function (html) {

            // the page may start with JSON metadata...
            if (!html.indexOf('<!--JSON')) {
                var json = JSON.parse(html.split('\n', 3)[1]);
                a.currentJSONMetadata = json;
            }

            // // some frames (editor) might request not to change the innerHTML until an event is fired
            // $('editor').setStyle('display', 'none');
            // if (typeof a.currentJSONMetadata == 'object' && a.currentJSONMetadata.wait)
            //     document.addEvent(a.currentJSONMetadata.wait, function () {
            //         $('editor').setStyle('display', 'block');
            // });

            // set the content
            $('content').innerHTML = html;

            // apply click handlers
            addFrameClickHandler($('content').getElements('a'));

            // find HTML metadata
            var meta = $('content').getElement('meta');
            if (meta) {
                var attrs = meta.attributes;
				[].forEach.call(meta.attributes, function(attr) {
				    if (/^data-/.test(attr.name))
				        attrs[attr.name] = attr.value;
				});

                // // Tools for all pages
                // 'data-redirect',    // javascript frame redirect
                // 'data-wredirect',   // window redirect
                // 'data-nav',         // navigation item identifier to highlight
                // 'data-title',       // page title for top bar
                // 'data-icon',        // page icon name for top bar
                // 'data-scripts',     // SSV script names w/o extensions
                // 'data-styles',      // SSV css names w/o extensions
                // 'data-flags',       // SSV page flags
				// 'data-search', 		// name of function to call on search
				// 'data-buttons', 	// buttons to display in top bar
				//
                // // Used by specific pages
				//
                // 'data-sort'         // sort option, used by file lists

                handlePageData(attrs);
            }
        },
        onFail: function (html) {
        }
    });
    request.get();
}

// load frame based on the current URL
function loadURL() {
    var loc = window.location.pathname;
    frameLoad(loc.replace(wikiRootRgx, '') + window.location.search);
}

// page options
var flagOptions = {
    'no-margin': {
        init: function () {
            $('content').addClass('no-margin');
        },
        destroy: function () {
            $('content').removeClass('no-margin');
        }
    },
    'compact-sidebar': {
        init: function () {
			document.getElement('span.wiki-title').tween('min-width', '75px');
            $('navigation-sidebar').tween('width', '50px');
            $('content').tween('margin-left', '50px');
            $$('#navigation-sidebar li a').each(function (a) {
                a.getElement('span').fade('out');
                a.addEvents({
                    mouseenter: handleCompactSidebarMouseenter,
                    mouseleave: handleCompactSidebarMouseleave
                });
            });
        },
        destroy: function () {
			document.getElement('span.wiki-title').tween('min-width', '140px');
            $('navigation-sidebar').tween('width', '170px');
            $('content').tween('margin-left', '170px');
            $$('#navigation-sidebar li a').each(function (a) {
                a.getElement('span').fade('in');
                a.removeEvents({
                    mouseenter: handleCompactSidebarMouseenter,
                    mouseleave: handleCompactSidebarMouseleave
                });
            });
            $$('div.navigation-popover').each(function (p) {
                p.parentElement.eliminate('popover');
                p.parentElement.removeChild(p);
            });
        }
    },
	search: {
		init: function () {
			$('top-search').set('value', '');
			$('top-search').setStyle('display', 'inline-block');
			searchUpdate();
		},
		destroy: function () {
			$('top-search').setStyle('display', 'none');
		}
	},
	buttons: {
		init: function () {
			if (!a.currentData || !a.currentData['data-buttons'])
				return;
			SSV(a.currentData['data-buttons']).each(function (buttonID) {

				// find opts
				var buttonStuff = a.currentData['data-button-' + buttonID];
				if (!buttonStuff) {
					console.warn('Button ' + buttonID + ' is not configured');
					return;
				}

				// parse psuedo-JSON
				buttonStuff = JSON.decode(buttonStuff.replace(/'/g, '"'));
				if (!buttonStuff) {
					console.warn('Failed to parse JSON for button ' + buttonID);
					return;
				}

				var but = new Element('span', {
					id:		'top-button-' + buttonID,
					class: 	'top-title top-button injected'
				});

				// hide
				if (buttonStuff.hide)
					but.setStyle('display', 'none');

				// title
				var anchor = new Element('a', {
					href: buttonStuff.href || '#'
				});
				anchor.set('text', buttonStuff.title);
				but.appendChild(anchor);

				// icon
				if (buttonStuff.icon) {
					anchor.set('text', ' ' + anchor.get('text'));
					var i = new Element('i', {
						'class': 'fa fa-' + buttonStuff.icon
					});
					i.inject(anchor, 'top');
				}

				// click event if func is provided
				if (buttonStuff.func) anchor.addEvent('click', function (e) {
					e.preventDefault();
					var func = window[buttonStuff.func];
					if (!func) {
						console.warn(
							'Button ' + buttonID + ' function ' +
							buttonStuff.func + ' does not exist'
						);
						return;
					}
					func();
				});

				but.inject($$('.top-button').getLast(), 'after');
			});
		},
		destroy: function () {
			$$('.top-button.injected').each(function (but) {
				but.destroy();
			});
		}
	}
};

// handle page data on request completion
function handlePageData (data) {
    pageScriptsDone = false;

    console.log(data);
    a.currentData = data;
    $('content').setStyle('user-select', 'none');

    // window redirect
    var target = data['data-wredirect'];
    if (target) {
        console.log('Redirecting to ' + target);
        window.location = target;
        return;
    }

    // page redirect
    target = data['data-redirect'];
    if (target) {
        console.log('Redirecting to ' + target);
        history.pushState(page, '', adminifier.wikiRoot + '/' + target);
        loadURL();
        return;
    }

    // page title and icon
    a.updatePageTitle(data['data-title']);
    window.scrollTo(0, 0);
    // ^ not sure if scrolling necessary when setting display: none

    // highlight navigation item
    var li = $$('li[data-nav="' + data['data-nav'] + '"]')[0];
    if (li) {
        $$('li.active').each(function (li) { li.removeClass('active') });
        li.addClass('active');
    }

    // inject scripts
    $$('script.dynamic').each(function (script) { script.destroy(); });
	firedPageScriptsLoaded = false;
    a.loadScripts(SSV(data['data-scripts']));

    // inject styles
    $$('link.dynamic').each(function (link) { link.destroy(); });
    SSV(data['data-styles']).each(function (style) {
        if (!style.length) return;

		var href;
		if (style == 'colorpicker')
			href = 'ext/colorpicker/colorpicker.css';
		else if (style == 'diff2html')
			href = 'ext/diff2html/dist/diff2html.css';
		else if (style == 'pikaday')
			href = 'ext/pikaday-custom.css';
		else
			href = 'style/' + style + '.css';

        var link = new Element('link', {
            href:   adminifier.staticRoot + '/' + href,
            class: 'dynamic',
            type:  'text/css',
            rel:   'stylesheet'
        });
		// link.addEvent('load', scriptLoaded);
        document.head.appendChild(link);
    });

    // handle page flags
    if (a.currentFlags)
        a.currentFlags.each(function (flag) {
            if (flag.destroy)
                flag.destroy();
        });
    a.currentFlags = [];
    SSV(data['data-flags']).each(function (flagName) {
        var flag = flagOptions[flagName];
        if (!flag) return;
        a.currentFlags.push(flag);
        flag.init();
    });
}

// escape key pressed
function handleEscapeKey (e) {
    if (e.key != 'esc')
        return;
    var container = document.getElement('.modal-container');
    if (container)
        container.retrieve('modal').destroy();
}

// SEARCH

function searchHandler () {
	$('top-search').addEvent('input', searchUpdate);
}

function searchUpdate () {
	var text = $('top-search').get('value');
	if (!a.currentData || !a.currentData['data-search'])
		return;
	var searchFunc = window[a.currentData['data-search']];
	if (!searchFunc)
		return;
	searchFunc(text);
}

// COMPACT SIDEBAR

function handleCompactSidebarMouseenter (e) {
    var a = e.target;
    var p = a.retrieve('popover');
    if (!p) {
        p = new Element('div', { class: 'navigation-popover' });
        p.innerHTML = a.getElement('span').innerHTML;
        a.appendChild(p);
        p.set('morph', { duration: 150 });
        a.store('popover', p);
    }
    a.setStyle('overflow', 'visible');
    p.setStyle('background-color', '#444');
    p.morph({
        width: '90px',
        paddingLeft: '10px'
    });
}

function handleCompactSidebarMouseleave (e) {
    var a = e.target;
    var p = a.retrieve('popover');
    if (!p) return;
    p.setStyle('background-color', '#333');
    p.morph({
        width: '0px',
        paddingLeft: '0px'
    });
    setTimeout(function () {
        a.setStyle('overflow', 'hidden');
    }, 200);
}

})(adminifier);
<commit_msg>cleanup in adminifier.js<commit_after>(function (a) {

// regex to remove the wiki root
var wikiRootRgx = new RegExp((adminifier.wikiRoot + '/').replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'));

// whether this page's scripts have been loaded yet
var pageScriptsDone = false;

// this is for if pageScriptsDone event is added
// and the page scripts are already done
Element.Events.pageScriptsLoaded = {
	onAdd: function (fn) {
		if (pageScriptsDone)
            fn.call(this);
	}
};

// onEnter event
Element.implement('onEnter', function (func) {
    this.addEvent('keyup', function (e) {
        if (e.key != 'enter')
            return;
        func.call(this, e);
    });
});

// "space-separated values" splitter
function SSV (str) {
    if (typeof str != 'string' || !str.length)
        return [];
    return str.split(' ');
}

// EXPORTS

// update page title
a.updatePageTitle = function (title, titleTagOnly) {
    if (!titleTagOnly)
        $('page-title').getElement('span').innerText = title;
    document.title = title + ' | ' + a.wikiName;
};

// update page icon
a.updateIcon = function (icon) {
	$('page-title').getElement('i').set('class', 'fa fa-' + icon);
};

// normalize page/category name
a.safeName = function (name) {
    return name.replace(/[^\w\.\-]/g, '_');
};

// load a script
a.loadScript = function (src) {
	a.loadScripts([src]);
};

// this is called when each script is loaded, so we can proceed to load the next
var scriptsToLoad = [], firedPageScriptsLoaded;
function scriptLoaded () {
	if (typeof jQuery != 'undefined')
		jQuery.noConflict();

	// there are still more to load
	if (scriptsToLoad.length) {
		loadNextScript();
		return;
	}

	// this was the last one
	$('content').setStyle('user-select', 'all');
	a.updateIcon(a.currentData['data-icon']);
	pageScriptsDone = true;
	if (firedPageScriptsLoaded) return;
	document.fireEvent('pageScriptsLoaded');
	firedPageScriptsLoaded = true;
}

// this is called when the next pending script should be loaded
function loadNextScript () {
	var script = scriptsToLoad.shift();
	if (!script)
		return;
	document.head.appendChild(script);
}

// load several scripts
a.loadScripts = function (srcs) {
    var sticky = false;
	srcs.each(function (src) {
        if (!src.length) return;

        // ace editor is special-- since it's large, load once and do not unload.
		if (src == 'ace') {
            if (window.ace)
                return;
            src = adminifier.staticRoot + '/ext/ace/src-min/ace.js';
            sticky = true;
        }

        // other distributions
		else if (src == 'pikaday')
			src = adminifier.staticRoot + '/ext/pikaday/pikaday.js';
		else if (src == 'jquery')
			src = '//cdnjs.cloudflare.com/ajax/libs/jquery/2.2.3/jquery.js';
		else if (src == 'diff2html')
			src = adminifier.staticRoot + '/ext/diff2html/dist/diff2html.js';
		else if (src == 'colorpicker')
			src = adminifier.staticRoot + '/ext/colorpicker/DynamicColorPicker.js';
		else if (src == 'prettify')
            src = 'https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js';

        // normal script
		else
            src = adminifier.staticRoot + '/script/' + src + '.js';

        // create script
        var script = new Element('script', { src: src });

        // remember it's dynamic so as to unload it later, UNLESS it's sticky
        if (!sticky)
            script.addClass('dynamic');

        // on load, call scriptLoaded
        script.addEvent('load', scriptLoaded);

        // add to the list to load
		scriptsToLoad.push(script);
	});

	// call once in case there are no scripts
	scriptLoaded();
}

// utility to adopt an element to an invisible container in the DOM so that dimension
// properties become available before displaying it
a.fakeAdopt = function (child) {
    var parent = $('fake-parent');
    if (!parent) {
        parent = new Element('div', {
            id: 'fake-parent',
            styles: { display: 'none' }
        });
        document.body.appendChild(parent);
    }
    parent.appendChild(child);
};

document.addEvent('domready', 	loadURL);
document.addEvent('domready',	searchHandler);
document.addEvent('domready',   addDocumentFrameClickHandler);
document.addEvent('keyup',		handleEscapeKey);

// PAGE LOADING

// this adds the frame click handler to all .frame-click anchors in the DOM
function addDocumentFrameClickHandler () {
    addFrameClickHandler($$('a.frame-click'));
}

// export addFrameClickHandler so that dynamically created anchors from other scripts
// can be handled properly
a.addFrameClickHandler = addFrameClickHandler;
function addFrameClickHandler (where) {
    if (typeOf(where) == 'element')
        where = [where];
    where.each(function (a) {
        a.addEvent('click', function (e) {
            console.log("HANDLED IT FOR "+ a.href);
            e.preventDefault();
            var page = a.href.replace(/^.*\/\/[^\/]+/, '').replace(wikiRootRgx, '');
            history.pushState(page, '', adminifier.wikiRoot + '/' + page);
            loadURL();
        });
    });
    return where[0];
}

// load a page
function frameLoad (page) {

	// same page
    if (a.currentPage == page)
        return;

	// unload old page
    document.fireEvent('pageUnloaded');
    a.currentPage = page;
    console.log("Loading " + page);

	a.updateIcon('circle-o-notch fa-spin');
    var request = new Request({
        url: 'frame/' + page,
        onSuccess: function (html) {

            // the page may start with JSON metadata...
            if (!html.indexOf('<!--JSON')) {
                var json = JSON.parse(html.split('\n', 3)[1]);
                a.currentJSONMetadata = json;
            }

            // // some frames (editor) might request not to change the innerHTML until an event is fired
            // $('editor').setStyle('display', 'none');
            // if (typeof a.currentJSONMetadata == 'object' && a.currentJSONMetadata.wait)
            //     document.addEvent(a.currentJSONMetadata.wait, function () {
            //         $('editor').setStyle('display', 'block');
            // });

            // set the content
            $('content').innerHTML = html;

            // apply click handlers
            addFrameClickHandler($('content').getElements('a'));

            // find HTML metadata
            var meta = $('content').getElement('meta');
            if (meta) {
                var attrs = meta.attributes;
				[].forEach.call(meta.attributes, function(attr) {
				    if (/^data-/.test(attr.name))
				        attrs[attr.name] = attr.value;
				});

                // // Tools for all pages
                // 'data-redirect',    // javascript frame redirect
                // 'data-wredirect',   // window redirect
                // 'data-nav',         // navigation item identifier to highlight
                // 'data-title',       // page title for top bar
                // 'data-icon',        // page icon name for top bar
                // 'data-scripts',     // SSV script names w/o extensions
                // 'data-styles',      // SSV css names w/o extensions
                // 'data-flags',       // SSV page flags
				// 'data-search', 		// name of function to call on search
				// 'data-buttons', 	// buttons to display in top bar
				//
                // // Used by specific pages
				//
                // 'data-sort'         // sort option, used by file lists

                handlePageData(attrs);
            }
        },
        onFail: function (html) {
        }
    });
    request.get();
}

// extract the page from the current URL and load it
function loadURL() {
    var loc = window.location.pathname;
    frameLoad(loc.replace(wikiRootRgx, '') + window.location.search);
}

// page options
var flagOptions = {

    // disable margins on #content
    'no-margin': {
        init: function () {
            $('content').addClass('no-margin');
        },
        destroy: function () {
            $('content').removeClass('no-margin');
        }
    },

    // minimize the sidebar to just icons
    'compact-sidebar': {
        init: function () {
			document.getElement('span.wiki-title').tween('min-width', '75px');
            $('navigation-sidebar').tween('width', '50px');
            $('content').tween('margin-left', '50px');
            $$('#navigation-sidebar li a').each(function (a) {
                a.getElement('span').fade('out');
                a.addEvents({
                    mouseenter: handleCompactSidebarMouseenter,
                    mouseleave: handleCompactSidebarMouseleave
                });
            });
        },
        destroy: function () {
			document.getElement('span.wiki-title').tween('min-width', '140px');
            $('navigation-sidebar').tween('width', '170px');
            $('content').tween('margin-left', '170px');
            $$('#navigation-sidebar li a').each(function (a) {
                a.getElement('span').fade('in');
                a.removeEvents({
                    mouseenter: handleCompactSidebarMouseenter,
                    mouseleave: handleCompactSidebarMouseleave
                });
            });
            $$('div.navigation-popover').each(function (p) {
                p.parentElement.eliminate('popover');
                p.parentElement.removeChild(p);
            });
        }
    },

    // display the search bar
	search: {
		init: function () {
			$('top-search').set('value', '');
			$('top-search').setStyle('display', 'inline-block');
			searchUpdate();
		},
		destroy: function () {
			$('top-search').setStyle('display', 'none');
		}
    },

    // top bar buttons
	buttons: {
		init: function () {
			if (!a.currentData || !a.currentData['data-buttons'])
				return;
			SSV(a.currentData['data-buttons']).each(function (buttonID) {

				// find opts
				var buttonStuff = a.currentData['data-button-' + buttonID];
				if (!buttonStuff) {
					console.warn('Button ' + buttonID + ' is not configured');
					return;
				}

				// parse psuedo-JSON
				buttonStuff = JSON.decode(buttonStuff.replace(/'/g, '"'));
				if (!buttonStuff) {
					console.warn('Failed to parse JSON for button ' + buttonID);
					return;
                }

				// create button
				var but = new Element('span', {
					id:		'top-button-' + buttonID,
					class: 	'top-title top-button injected'
				});

				// hide if default state is to hide
				if (buttonStuff.hide)
					but.setStyle('display', 'none');

				// title
				var anchor = new Element('a', {
					href: buttonStuff.href || '#'
				});
				anchor.set('text', buttonStuff.title);
				but.appendChild(anchor);

				// icon
				if (buttonStuff.icon) {
					anchor.set('text', ' ' + anchor.get('text'));
					var i = new Element('i', {
						'class': 'fa fa-' + buttonStuff.icon
					});
					i.inject(anchor, 'top');
				}

				// click click event if callback func is provided
				if (buttonStuff.func) anchor.addEvent('click', function (e) {
					e.preventDefault();
					var func = window[buttonStuff.func];
					if (!func) {
						console.warn(
							'Button ' + buttonID + ' function ' +
							buttonStuff.func + ' does not exist'
						);
						return;
					}
					func();
				});

                // inject the button
				but.inject($$('.top-button').getLast(), 'after');
			});
		},
		destroy: function () {
			$$('.top-button.injected').each(function (but) {
				but.destroy();
			});
		}
	}
};

// handle page data on request completion
function handlePageData (data) {
    pageScriptsDone = false;

    console.log(data);
    a.currentData = data;
    $('content').setStyle('user-select', 'none');

    // window redirect
    var target = data['data-wredirect'];
    if (target) {
        console.log('Redirecting to ' + target);
        window.location = target;
        return;
    }

    // page redirect
    target = data['data-redirect'];
    if (target) {
        console.log('Redirecting to ' + target);
        history.pushState(page, '', adminifier.wikiRoot + '/' + target);
        loadURL();
        return;
    }

    // page title and icon
    a.updatePageTitle(data['data-title']);
    window.scrollTo(0, 0);
    // ^ not sure if scrolling necessary when setting display: none

    // highlight navigation item
    var li = $$('li[data-nav="' + data['data-nav'] + '"]')[0];
    if (li) {
        $$('li.active').each(function (li) { li.removeClass('active'); });
        li.addClass('active');
    }

    // destroy old scripts
    $$('script.dynamic').each(function (script) { script.destroy(); });

    // load new scripts
	firedPageScriptsLoaded = false;
    a.loadScripts(SSV(data['data-scripts']));

    // destroy old styles
    $$('link.dynamic').each(function (link) { link.destroy(); });

    // inject new styles
    SSV(data['data-styles']).each(function (style) {
        if (!style.length) return;
		var href;
		if (style == 'colorpicker')
			href = 'ext/colorpicker/colorpicker.css';
		else if (style == 'diff2html')
			href = 'ext/diff2html/dist/diff2html.css';
		else if (style == 'pikaday')
			href = 'ext/pikaday-custom.css';
		else
			href = 'style/' + style + '.css';

        var link = new Element('link', {
            href:   adminifier.staticRoot + '/' + href,
            class: 'dynamic',
            type:  'text/css',
            rel:   'stylesheet'
        });
        document.head.appendChild(link);
    });

    // deinitialize old page flags
    if (a.currentFlags) a.currentFlags.each(function (flag) {
        if (flag.destroy)
            flag.destroy();
    });

    // initialize new page flags
    a.currentFlags = [];
    SSV(data['data-flags']).each(function (flagName) {
        var flag = flagOptions[flagName];
        if (!flag) return;
        a.currentFlags.push(flag);
        flag.init();
    });
}

// escape key pressed
function handleEscapeKey (e) {
    if (e.key != 'esc')
        return;
    var container = document.getElement('.modal-container');
    if (container)
        container.retrieve('modal').destroy();
}

// SEARCH

// domready event to add searchUpdate responder
function searchHandler () {
	$('top-search').addEvent('input', searchUpdate);
}

// callback for when search field changes
function searchUpdate () {
    var text = $('top-search').get('value');

    // the page with search function has since been destroyed
	if (!a.currentData || !a.currentData['data-search'])
        return;

    // the page provides no search handler
	var searchFunc = window[a.currentData['data-search']];
	if (!searchFunc)
        return;

    // call the search handler provided by the page
	searchFunc(text);
}

// COMPACT SIDEBAR

// on mouseover, expand the text
function handleCompactSidebarMouseenter (e) {
    var a = e.target;
    var p = a.retrieve('popover');
    if (!p) {
        p = new Element('div', { class: 'navigation-popover' });
        p.innerHTML = a.getElement('span').innerHTML;
        a.appendChild(p);
        p.set('morph', { duration: 150 });
        a.store('popover', p);
    }
    a.setStyle('overflow', 'visible');
    p.setStyle('background-color', '#444');
    p.morph({
        width: '90px',
        paddingLeft: '10px'
    });
}

// on mouseleave, retract to just icon
function handleCompactSidebarMouseleave (e) {
    var a = e.target;
    var p = a.retrieve('popover');
    if (!p) return;
    p.setStyle('background-color', '#333');
    p.morph({
        width: '0px',
        paddingLeft: '0px'
    });
    setTimeout(function () {
        a.setStyle('overflow', 'hidden');
    }, 200);
}

})(adminifier);
<|endoftext|>


<commit_before>/*** MQTT Z-Way odule *******************************************
 Version: 1.0.0
 -----------------------------------------------------------------------------
 Author: David Uebelacker <david@uebelacker.ch>
 ******************************************************************************/

function ZWayMqttBridge(id, controller) {
    ZWayMqttBridge.super_.call(this, id, controller);
}

inherits(ZWayMqttBridge, AutomationModule);

_module = ZWayMqttBridge;

ZWayMqttBridge.prototype.init = function (config) {
    ZWayMqttBridge.super_.prototype.init.call(this, config);

    var self = this;

    this.reconnect = function () {
        self.connected = false;
        self.mqttBridge = null;
        console.log('Will try to reconnect to Mqtt Bridge in 10 seconds ...');
        setTimeout(function () {
            console.log('Will try to reconnect to Mqtt Bridge ...');
            self.connect();
        }, 10000);
    };

    this.connect = function () {
        console.log('Connecting to Mqtt Bridge ....');

        this.mqttBridge = new sockets.tcp();

        this.mqttBridge.onrecv = function (data) {
            console.log('Mqtt Bridge server:' + String.fromCharCode.apply(null, new Uint16Array(data)));
            self.connected = true;
        };

        this.mqttBridge.onclose = function () {
            console.log('Mqtt Bridge websocket was closed!');
            self.reconnect();
        };

        if (this.mqttBridge.connect('192.168.0.62', 8080)) {
            setTimeout(function () {
                if (self.mqttBridge && !self.connected) {
                    console.log('Could not connect to Mqtt Bridge after 5 seconds!');
                    self.reconnect();
                }
            }, 5000);
        } else {
            console.log('Could not connect to Mqtt Bridge!');
            self.reconnect();
        }
    };

    this.deviceUpdate = function (device) {
        if (self.mqttBridge) {
            console.log('Mqtt Bridge: Sending update to Client...')

            var message = JSON.stringify(device, null, 4);

            var buf = new ArrayBuffer(message.length*2); // 2 bytes for each char
            var bufView = new Uint16Array(buf);

            for (var i=0; i < message.length; i++) {
                bufView[i] = message.charCodeAt(i);
            }

            self.mqttBridge.send(buf);
        }
    };

    this.connect();
    this.controller.devices.on('change:metrics:level', self.deviceUpdate);
};

<commit_msg>devel<commit_after>/*** MQTT Z-Way odule *******************************************
 Version: 1.0.0
 -----------------------------------------------------------------------------
 Author: David Uebelacker <david@uebelacker.ch>
 ******************************************************************************/

function ZWayMqttBridge(id, controller) {
    ZWayMqttBridge.super_.call(this, id, controller);
}

inherits(ZWayMqttBridge, AutomationModule);

_module = ZWayMqttBridge;

ZWayMqttBridge.prototype.init = function (config) {
    ZWayMqttBridge.super_.prototype.init.call(this, config);

    var self = this;

    this.reconnect = function () {
        self.connected = false;
        self.mqttBridge = null;
        console.log('Will try to reconnect to Mqtt Bridge in 10 seconds ...');
        setTimeout(function () {
            console.log('Will try to reconnect to Mqtt Bridge ...');
            self.connect();
        }, 10000);
    };

    this.connect = function () {
        console.log('Connecting to Mqtt Bridge ....');

        this.mqttBridge = new sockets.tcp();

        this.mqttBridge.onrecv = function (data) {
            console.log('Mqtt Bridge server:' + String.fromCharCode.apply(null, new Uint8Array(data)));
            self.connected = true;
        };

        this.mqttBridge.onclose = function () {
            console.log('Mqtt Bridge websocket was closed!');
            self.reconnect();
        };

        if (this.mqttBridge.connect('192.168.0.62', 8080)) {
            setTimeout(function () {
                if (self.mqttBridge && !self.connected) {
                    console.log('Could not connect to Mqtt Bridge after 5 seconds!');
                    self.reconnect();
                }
            }, 5000);
        } else {
            console.log('Could not connect to Mqtt Bridge!');
            self.reconnect();
        }
    };

    this.deviceUpdate = function (device) {
        if (self.mqttBridge) {
            console.log('Mqtt Bridge: Sending update to Client...')

            var message = JSON.stringify(device, null, 4);

            var buf = new ArrayBuffer(message.length*2); // 2 bytes for each char
            var bufView = new Uint8Array(buf);

            for (var i=0; i < message.length; i++) {
                bufView[i] = message.charCodeAt(i);
            }

            self.mqttBridge.send(buf);
        }
    };

    this.connect();
    this.controller.devices.on('change:metrics:level', self.deviceUpdate);
};

<|endoftext|>


<commit_before>import React from 'react';
import renderer from 'react-test-renderer';
import Anime from './../src/anime.js';

const reactAnimationFrame = (function() {
    var lastTime = 0;
    var vendors = ['ms', 'moz', 'webkit', 'o'];
    for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
        window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
        window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame']
                                   || window[vendors[x]+'CancelRequestAnimationFrame'];
    }

    if (!window.requestAnimationFrame)
        window.requestAnimationFrame = function(callback, element) {
            var currTime = new Date().getTime();
            var timeToCall = Math.max(0, 16 - (currTime - lastTime));
            var id = window.setTimeout(function() { callback(currTime + timeToCall); },
              timeToCall);
            lastTime = currTime + timeToCall;
            return id;
        };

    if (!window.cancelAnimationFrame)
        window.cancelAnimationFrame = function(id) {
            clearTimeout(id);
        };
}());

//snapshot test
it('Anime single child Snapshot', () => {
  const tree = renderer.create(
    <Anime easing="easeOutElastic"
           loop={true}
           duration={1000}
           direction="alternate"
           loop={true}
           delay={(el, index) => index * 240}>

1

2

      </Anime>,
      {
          createNodeMock: (element) => ({nodeType: true})
      }
  );

  console.warn("@@@TREE!!!", tree)

  expect(tree.toJSON()).toMatchSnapshot();
});<commit_msg>Fixed tests<commit_after>import React from 'react';
import renderer from 'react-test-renderer';
import Anime from 'anime.js';

const reactAnimationFrame = (function() {
    var lastTime = 0;
    var vendors = ['ms', 'moz', 'webkit', 'o'];
    for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
        window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
        window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame']
                                   || window[vendors[x]+'CancelRequestAnimationFrame'];
    }

    if (!window.requestAnimationFrame)
        window.requestAnimationFrame = function(callback, element) {
            var currTime = new Date().getTime();
            var timeToCall = Math.max(0, 16 - (currTime - lastTime));
            var id = window.setTimeout(function() { callback(currTime + timeToCall); },
              timeToCall);
            lastTime = currTime + timeToCall;
            return id;
        };

    if (!window.cancelAnimationFrame)
        window.cancelAnimationFrame = function(id) {
            clearTimeout(id);
        };
}());

//snapshot test
it('Anime single child Snapshot', () => {
  const tree = renderer.create(
    <Anime easing="easeOutElastic"
           loop={true}
           duration={1000}
           direction="alternate"
           loop={true}
           delay={(el, index) => index * 240}>

1

2

      </Anime>,
      {
          createNodeMock: (element) => ({nodeType: true})
      }
  );

  console.warn("@@@TREE!!!", tree)

  expect(tree.toJSON()).toMatchSnapshot();
});<|endoftext|>


<commit_before>/*
*   @constructor Menu
*
*   @desc
*       Object that encapsulates data and behavior (via event handlers)
*       of a custom HTML menu component.
*
*   @param menuNode
*       The DOM element node that serves as the menu container.
*       Each child element of menuNode that represents a menuitem
*       must have its role attribute set to 'menuitem'.
*
*   @param menuButton
*       The MenuButton object associated with this menu. See MenuButton.js
*       for its description.
*/
var Menu = function (menuNode, menuButton) {
  // Check whether menuNode is a DOM element
  if (!menuNode instanceof Element)
    throw new TypeError("Menu constructor argument 'menuNode' is not a DOM Element.");

  // Check whether menu has child elements
  if (menuNode.childElementCount === 0)
    throw new Error("Menu constructor argument 'menuNode' has no Element children!")

  this.menuNode = menuNode;
  this.menuButton = menuButton;
  menuNode.tabIndex = -1;

  this.firstItem = null;
  this.lastItem  = null;

  this.keyCode = Object.freeze({
    'TAB'      :  9,
    'RETURN'   : 13,
    'ESC'      : 27,
    'SPACE'    : 32,
    'PAGEUP'   : 33,
    'PAGEDOWN' : 34,
    'END'      : 35,
    'HOME'     : 36,
    'LEFT'     : 37,
    'UP'       : 38,
    'RIGHT'    : 39,
    'DOWN'     : 40
  });
};

/*
*   @method Menu.prototype.init
*
*   @desc
*       Add menuNode event listeners for mouseover and mouseout.
*       Set firstItem and lastItem to corresponding menuitems.
*       For each menuitem: set tabindex and add event listeners
*       for keydown, click, focus and blur events.
*/
Menu.prototype.init = function () {
  var menuitem, that = this;

  this.menuNode.addEventListener('mouseover', function (event) {
    that.handleMouseover(event);
  });

  this.menuNode.addEventListener('mouseout', function (event) {
    that.handleMouseout(event);
  });

  menuitem = this.menuNode.firstElementChild;

  while (menuitem) {
    if (menuitem.getAttribute('role')  === 'menuitem') {
      menuitem.tabIndex = -1;
      if (!this.firstItem) this.firstItem = menuitem;
      this.lastItem = menuitem;

      menuitem.addEventListener('keydown', function (event) {
        that.handleKeydown(event);
      });

      menuitem.addEventListener('click', function (event) {
        that.handleClick(event);
      });

      menuitem.addEventListener('focus', function (event) {
        that.handleFocus(event);
      });

      menuitem.addEventListener('blur', function (event) {
        that.handleBlur(event);
      });
    }
    menuitem = menuitem.nextElementSibling;
  }
};

/* EVENT HANDLERS */

Menu.prototype.handleKeydown = function (event) {
  var tgt = event.currentTarget,
      flag = false;

  switch (event.keyCode) {
    case this.keyCode.SPACE:
    case this.keyCode.RETURN:
      var clickEvent = new MouseEvent('click', {
        'view': window,
        'bubbles': true,
        'cancelable': true
      });
      tgt.dispatchEvent(clickEvent);
      // Call to this.close was removed because it duplicates
      // the same call made by the click handler.
      flag = true;
      break;

    case this.keyCode.ESC:
      this.setFocusToButton();
      this.close(true);
      flag = true;
      break;

    case this.keyCode.UP:
      this.setFocusToPreviousItem(tgt);
      flag = true;
      break;

    case this.keyCode.DOWN:
      this.setFocusToNextItem(tgt);
      flag = true;
      break;

    case this.keyCode.HOME:
    case this.keyCode.PAGEUP:
      this.setFocusToFirstItem();
      flag = true;
      break;

    case this.keyCode.END:
    case this.keyCode.PAGEDOWN:
      this.setFocusToLastItem();
      flag = true;
      break;

    case this.keyCode.TAB:
      this.setFocusToButton();
      this.close(true);
      break;

    default:
      break;
  }

  if (flag) {
    event.stopPropagation();
    event.preventDefault();
  }
};

Menu.prototype.handleClick = function (event) {
  this.setFocusToButton();
  this.close(true);
};

Menu.prototype.handleFocus = function (event) {
  this.hasFocus = true;
};

Menu.prototype.handleBlur = function (event) {
  var that = this;
  this.hasFocus = false;
  setTimeout(function () { that.close(false) }, 300);
};

Menu.prototype.handleMouseover = function (event) {
  this.hasHover = true;
};

Menu.prototype.handleMouseout = function (event) {
  var that = this;
  this.hasHover = false;
  setTimeout(function () { that.close(false) }, 300);
};

/* ADDITIONAL METHODS */

Menu.prototype.setFocusToButton = function () {
  this.menuButton.buttonNode.focus();
};

Menu.prototype.setFocusToPreviousItem = function (currentItem) {
  var menuitem = currentItem.previousElementSibling;

  while (menuitem) {
    if (menuitem.getAttribute('role')  === 'menuitem') {
      menuitem.focus();
      break;
    }
    menuitem = menuitem.previousElementSibling;
  }

  if (!menuitem && this.lastItem) {
    this.lastItem.focus();
  }
};

Menu.prototype.setFocusToNextItem = function (currentItem) {
  var menuitem = currentItem.nextElementSibling;

  while (menuitem) {
    if (menuitem.getAttribute('role')  === 'menuitem') {
      menuitem.focus();
      break;
    }
    menuitem = menuitem.nextElementSibling;
  }

  if (!menuitem && this.firstItem) {
    this.firstItem.focus();
  }
};

Menu.prototype.setFocusToFirstItem = function () {
  if (this.firstItem) this.firstItem.focus();
};

Menu.prototype.setFocusToLastItem = function () {
  if (this.lastItem) this.lastItem.focus();
};

Menu.prototype.open = function () {
  // get position and bounding rectangle of relNode (e.g. menubutton)
  var pos  = this.getPosition(this.menuButton.buttonNode);
  var rect = this.menuButton.buttonNode.getBoundingClientRect();

  this.menuNode.style.display = 'block';
  this.menuNode.style.position = 'absolute';
  this.menuNode.style.top  = (pos.y + rect.height) + "px";
  this.menuNode.style.left = pos.x + "px"; ;
};

Menu.prototype.close = function (force) {
  if (force || (!this.hasFocus && !this.hasHover && !this.menuButton.hasHover)) {
    this.menuNode.style.display = 'none';
  }
};

Menu.prototype.getPosition = function (element) {
  var x = 0, y = 0;

  while (element) {
    x += (element.offsetLeft - element.scrollLeft + element.clientLeft);
    y += (element.offsetTop - element.scrollTop + element.clientTop);
    element = element.offsetParent;
  }

  return { x: x, y: y };
};
<commit_msg>Update comments<commit_after>/*
*   @constructor Menu
*
*   @desc
*       Object that encapsulates data and behavior (via event handlers)
*       of a custom HTML menu component.
*
*   @param menuNode
*       The DOM element node that serves as the menu container.
*       Each child element of menuNode that represents a menuitem
*       must have its role attribute set to 'menuitem'.
*
*   @param menuButton
*       The MenuButton object associated with this menu. See MenuButton.js
*       for its description.
*/
var Menu = function (menuNode, menuButton) {
  // Check whether menuNode is a DOM element
  if (!menuNode instanceof Element)
    throw new TypeError("Menu constructor argument 'menuNode' is not a DOM Element.");

  // Check whether menu has child elements
  if (menuNode.childElementCount === 0)
    throw new Error("Menu constructor argument 'menuNode' has no Element children!")

  this.menuNode = menuNode;
  this.menuButton = menuButton;
  menuNode.tabIndex = -1;

  this.firstItem = null;
  this.lastItem  = null;

  this.keyCode = Object.freeze({
    'TAB'      :  9,
    'RETURN'   : 13,
    'ESC'      : 27,
    'SPACE'    : 32,
    'PAGEUP'   : 33,
    'PAGEDOWN' : 34,
    'END'      : 35,
    'HOME'     : 36,
    'LEFT'     : 37,
    'UP'       : 38,
    'RIGHT'    : 39,
    'DOWN'     : 40
  });
};

/*
*   @method Menu.prototype.init
*
*   @desc
*       Add menuNode event listeners for mouseover and mouseout.
*       Set firstItem and lastItem to corresponding menuitems.
*       For each menuitem: set tabindex and add event listeners
*       for keydown, click, focus and blur events.
*/
Menu.prototype.init = function () {
  var menuitem, that = this;

  this.menuNode.addEventListener('mouseover', function (event) {
    that.handleMouseover(event);
  });

  this.menuNode.addEventListener('mouseout', function (event) {
    that.handleMouseout(event);
  });

  menuitem = this.menuNode.firstElementChild;

  while (menuitem) {
    if (menuitem.getAttribute('role')  === 'menuitem') {
      menuitem.tabIndex = -1;
      if (!this.firstItem) this.firstItem = menuitem;
      this.lastItem = menuitem;

      menuitem.addEventListener('keydown', function (event) {
        that.handleKeydown(event);
      });

      menuitem.addEventListener('click', function (event) {
        that.handleClick(event);
      });

      menuitem.addEventListener('focus', function (event) {
        that.handleFocus(event);
      });

      menuitem.addEventListener('blur', function (event) {
        that.handleBlur(event);
      });
    }
    menuitem = menuitem.nextElementSibling;
  }
};

/* EVENT HANDLERS FOR MENU ITEMS */

Menu.prototype.handleKeydown = function (event) {
  var tgt = event.currentTarget,
      flag = false;

  switch (event.keyCode) {
    case this.keyCode.SPACE:
    case this.keyCode.RETURN:
      var clickEvent = new MouseEvent('click', {
        'view': window,
        'bubbles': true,
        'cancelable': true
      });
      tgt.dispatchEvent(clickEvent);
      // Call to this.close was removed because it duplicates
      // the same call made by the click handler.
      flag = true;
      break;

    case this.keyCode.ESC:
      this.setFocusToButton();
      this.close(true);
      flag = true;
      break;

    case this.keyCode.UP:
      this.setFocusToPreviousItem(tgt);
      flag = true;
      break;

    case this.keyCode.DOWN:
      this.setFocusToNextItem(tgt);
      flag = true;
      break;

    case this.keyCode.HOME:
    case this.keyCode.PAGEUP:
      this.setFocusToFirstItem();
      flag = true;
      break;

    case this.keyCode.END:
    case this.keyCode.PAGEDOWN:
      this.setFocusToLastItem();
      flag = true;
      break;

    case this.keyCode.TAB:
      this.setFocusToButton();
      this.close(true);
      break;

    default:
      break;
  }

  if (flag) {
    event.stopPropagation();
    event.preventDefault();
  }
};

Menu.prototype.handleClick = function (event) {
  this.setFocusToButton();
  this.close(true);
};

Menu.prototype.handleFocus = function (event) {
  this.hasFocus = true;
};

Menu.prototype.handleBlur = function (event) {
  var that = this;
  this.hasFocus = false;
  setTimeout(function () { that.close(false) }, 300);
};

/* EVENT HANDLERS FOR MENU CONTAINER */

Menu.prototype.handleMouseover = function (event) {
  this.hasHover = true;
};

Menu.prototype.handleMouseout = function (event) {
  var that = this;
  this.hasHover = false;
  setTimeout(function () { that.close(false) }, 300);
};

/* ADDITIONAL METHODS */

Menu.prototype.setFocusToButton = function () {
  this.menuButton.buttonNode.focus();
};

Menu.prototype.setFocusToPreviousItem = function (currentItem) {
  var menuitem = currentItem.previousElementSibling;

  while (menuitem) {
    if (menuitem.getAttribute('role')  === 'menuitem') {
      menuitem.focus();
      break;
    }
    menuitem = menuitem.previousElementSibling;
  }

  if (!menuitem && this.lastItem) {
    this.lastItem.focus();
  }
};

Menu.prototype.setFocusToNextItem = function (currentItem) {
  var menuitem = currentItem.nextElementSibling;

  while (menuitem) {
    if (menuitem.getAttribute('role')  === 'menuitem') {
      menuitem.focus();
      break;
    }
    menuitem = menuitem.nextElementSibling;
  }

  if (!menuitem && this.firstItem) {
    this.firstItem.focus();
  }
};

Menu.prototype.setFocusToFirstItem = function () {
  if (this.firstItem) this.firstItem.focus();
};

Menu.prototype.setFocusToLastItem = function () {
  if (this.lastItem) this.lastItem.focus();
};

Menu.prototype.open = function () {
  // get position and bounding rectangle of relNode (e.g. menubutton)
  var pos  = this.getPosition(this.menuButton.buttonNode);
  var rect = this.menuButton.buttonNode.getBoundingClientRect();

  this.menuNode.style.display = 'block';
  this.menuNode.style.position = 'absolute';
  this.menuNode.style.top  = (pos.y + rect.height) + "px";
  this.menuNode.style.left = pos.x + "px"; ;
};

Menu.prototype.close = function (force) {
  if (force || (!this.hasFocus && !this.hasHover && !this.menuButton.hasHover)) {
    this.menuNode.style.display = 'none';
  }
};

Menu.prototype.getPosition = function (element) {
  var x = 0, y = 0;

  while (element) {
    x += (element.offsetLeft - element.scrollLeft + element.clientLeft);
    y += (element.offsetTop - element.scrollTop + element.clientTop);
    element = element.offsetParent;
  }

  return { x: x, y: y };
};
<|endoftext|>


<commit_before>const parse = require("../index");

describe("diff parser", function() {
  it("should parse null", () => {
    expect(parse(null).length).toBe(0);
  });

  it("should parse empty string", () => {
    expect(parse("").length).toBe(0);
  });

  it("should parse whitespace", () => {
    expect(parse(" ").length).toBe(0);
  });

  it("should parse simple git-like diff", function() {
    const diff = `\
diff --git a/file b/file
index 123..456 789
--- a/file
+++ b/file
@@ -1,2 +1,2 @@
- line1
+ line2\
`;
    const files = parse(diff);
    expect(files.length).toBe(1);
    const file = files[0];
    expect(file.from).toBe("file");
    expect(file.to).toBe("file");
    expect(file.chunks.length).toBe(1);
    const chunk = file.chunks[0];
    expect(chunk.content).toBe("@@ -1,2 +1,2 @@");
    expect(chunk.changes.length).toBe(2);
    expect(chunk.changes[0].content).toBe("- line1");
    expect(chunk.changes[1].content).toBe("+ line2");
  });

  it("should parse simple git-like diff with file enclosed by double-quote", function() {
    const diff = `\
diff --git "a/file1" "b/file2"
similarity index 100%
rename from "file1"
rename to "file2"\
`;
    const files = parse(diff);
    expect(files.length).toBe(1);
    const file = files[0];
    expect(file.from).toBe("file1");
    expect(file.to).toBe("file2");
    expect(file.chunks.length).toBe(0);
  });

  it("should parse diff with new file mode line", function() {
    const diff = `\
diff --git a/test b/test
new file mode 100644
index 0000000..db81be4
--- /dev/null
+++ b/test
@@ -0,0 +1,2 @@
+line1
+line2\
`;
    const files = parse(diff);
    expect(files.length).toBe(1);
    const file = files[0];
    expect(file.new).toBeTruthy();
    expect(file.from).toBe("/dev/null");
    expect(file.to).toBe("test");
    expect(file.chunks[0].content).toBe("@@ -0,0 +1,2 @@");
    expect(file.chunks[0].changes.length).toBe(2);
    expect(file.chunks[0].changes[0].content).toBe("+line1");
    expect(file.chunks[0].changes[1].content).toBe("+line2");
  });

  it("should parse diff with deleted file mode line", function() {
    const diff = `\
diff --git a/test b/test
deleted file mode 100644
index db81be4..0000000
--- b/test
+++ /dev/null
@@ -1,2 +0,0 @@
-line1
-line2\
`;
    const files = parse(diff);
    expect(files.length).toBe(1);
    const file = files[0];
    expect(file.deleted).toBeTruthy();
    expect(file.from).toBe("test");
    expect(file.to).toBe("/dev/null");
    expect(file.chunks[0].content).toBe("@@ -1,2 +0,0 @@");
    expect(file.chunks[0].changes.length).toBe(2);
    expect(file.chunks[0].changes[0].content).toBe("-line1");
    expect(file.chunks[0].changes[1].content).toBe("-line2");
  });

  it("should parse diff with single line files", function() {
    const diff = `\
diff --git a/file1 b/file1
deleted file mode 100644
index db81be4..0000000
--- b/file1
+++ /dev/null
@@ -1 +0,0 @@
-line1
diff --git a/file2 b/file2
new file mode 100644
index 0000000..db81be4
--- /dev/null
+++ b/file2
@@ -0,0 +1 @@
+line1\
`;
    const files = parse(diff);
    expect(files.length).toBe(2);
    let file = files[0];
    expect(file.deleted).toBeTruthy();
    expect(file.from).toBe("file1");
    expect(file.to).toBe("/dev/null");
    expect(file.chunks[0].content).toBe("@@ -1 +0,0 @@");
    expect(file.chunks[0].changes.length).toBe(1);
    expect(file.chunks[0].changes[0].content).toBe("-line1");
    expect(file.chunks[0].changes[0].type).toBe("del");
    file = files[1];
    expect(file.new).toBeTruthy();
    expect(file.from).toBe("/dev/null");
    expect(file.to).toBe("file2");
    expect(file.chunks[0].content).toBe("@@ -0,0 +1 @@");
    expect(file.chunks[0].oldStart).toBe(0);
    expect(file.chunks[0].oldLines).toBe(0);
    expect(file.chunks[0].newStart).toBe(1);
    expect(file.chunks[0].newLines).toBe(1);
    expect(file.chunks[0].changes.length).toBe(1);
    expect(file.chunks[0].changes[0].content).toBe("+line1");
    expect(file.chunks[0].changes[0].type).toBe("add");
  });

  it("should parse multiple files in diff", function() {
    const diff = `\
diff --git a/file1 b/file1
index 123..456 789
--- a/file1
+++ b/file1
@@ -1,2 +1,2 @@
- line1
+ line2
diff --git a/file2 b/file2
index 123..456 789
--- a/file2
+++ b/file2
@@ -1,3 +1,3 @@
- line1
+ line2\
`;
    const files = parse(diff);
    expect(files.length).toBe(2);
    let file = files[0];
    expect(file.from).toBe("file1");
    expect(file.to).toBe("file1");
    expect(file.chunks[0].content).toBe("@@ -1,2 +1,2 @@");
    expect(file.chunks[0].changes.length).toBe(2);
    expect(file.chunks[0].changes[0].content).toBe("- line1");
    expect(file.chunks[0].changes[1].content).toBe("+ line2");
    file = files[1];
    expect(file.from).toBe("file2");
    expect(file.to).toBe("file2");
    expect(file.chunks[0].content).toBe("@@ -1,3 +1,3 @@");
    expect(file.chunks[0].changes.length).toBe(2);
    expect(file.chunks[0].changes[0].content).toBe("- line1");
    expect(file.chunks[0].changes[1].content).toBe("+ line2");
  });

  it("should parse diff with EOF flag", function() {
    const diff = `\
diff --git a/file1 b/file1
index 123..456 789
--- a/file1
+++ b/file1
@@ -1,2 +1,2 @@
- line1
+ line2
\\ No newline at end of file\
`;
    const files = parse(diff);
    expect(files.length).toBe(1);
    const file = files[0];
    expect(file.from).toBe("file1");
    expect(file.to).toBe("file1");
    const chunk = file.chunks[0];
    expect(chunk.content).toBe("@@ -1,2 +1,2 @@");
    expect(chunk.changes.length).toBe(3);
    expect(chunk.changes[0].content).toBe("- line1");
    expect(chunk.changes[1].content).toBe("+ line2");
    expect(chunk.changes[2].type).toBe("add");
    expect(chunk.changes[2].content).toBe("\\ No newline at end of file");
  });

  it("should parse gnu sample diff", function() {
    const diff = `\
--- lao	2002-02-21 23:30:39.942229878 -0800
+++ tzu	2002-02-21 23:30:50.442260588 -0800
@@ -1,7 +1,6 @@
-The Way that can be told of is not the eternal Way;
-The name that can be named is not the eternal name.
 The Nameless is the origin of Heaven and Earth;
-The Named is the mother of all things.
+The named is the mother of all things.
+
 Therefore let there always be non-being,
	so we may see their subtlety,
And let there always be being,
@@ -9,3 +8,6 @@
 The two are the same,
 But after they are produced,
	they have different names.
+They both may be called deep and profound.
+Deeper and more profound,
+The door of all subtleties!\
`;
    const files = parse(diff);
    expect(files.length).toBe(1);
    const file = files[0];
    expect(file.from).toBe("lao");
    expect(file.to).toBe("tzu");
    expect(file.chunks.length).toBe(2);
    const chunk0 = file.chunks[0];
    expect(chunk0.oldStart).toBe(1);
    expect(chunk0.oldLines).toBe(7);
    expect(chunk0.newStart).toBe(1);
    expect(chunk0.newLines).toBe(6);
    const chunk1 = file.chunks[1];
    expect(chunk1.oldStart).toBe(9);
    expect(chunk1.oldLines).toBe(3);
    expect(chunk1.newStart).toBe(8);
    expect(chunk1.newLines).toBe(6);
  });

  it("should parse hg diff output", function() {
    const diff = `\
diff -r 514fc757521e lib/parsers.coffee
--- a/lib/parsers.coffee	Thu Jul 09 00:56:36 2015 +0200
+++ b/lib/parsers.coffee	Fri Jul 10 16:23:43 2015 +0200
@@ -43,6 +43,9 @@
             files[file] = { added: added, deleted: deleted }
         files

+    diff: (out) ->
+        files = {}
+
 module.exports = Parsers

 module.exports.version = (out) ->\
`;
    const files = parse(diff);
    expect(files.length).toBe(1);
    const file = files[0];
    expect(file.chunks[0].content).toBe("@@ -43,6 +43,9 @@");
    expect(file.from).toBe("lib/parsers.coffee");
    expect(file.to).toBe("lib/parsers.coffee");
  });

  it("should parse svn diff output", function() {
    const diff = `\
Index: new.txt
===================================================================
--- new.txt	(revision 0)
+++ new.txt	(working copy)
@@ -0,0 +1 @@
+test
Index: text.txt
===================================================================
--- text.txt	(revision 6)
+++ text.txt	(working copy)
@@ -1,7 +1,5 @@
-This part of the
-document has stayed the
-same from version to
-version.  It shouldn't
+This is an important
+notice! It shouldn't
 be shown if it doesn't
 change.  Otherwise, that
 would not be helping to\
`;
    const files = parse(diff);
    expect(files.length).toBe(2);
    const file = files[0];
    expect(file.from).toBe("new.txt");
    expect(file.to).toBe("new.txt");
    expect(file.chunks[0].changes.length).toBe(1);
  });

  it("should parse file names for n new empty file", function() {
    const diff = `\
diff --git a/newFile.txt b/newFile.txt
new file mode 100644
index 0000000..e6a2e28\
`;
    const files = parse(diff);
    expect(files.length).toBe(1);
    const file = files[0];
    expect(file.from).toBe("/dev/null");
    expect(file.to).toBe("newFile.txt");
  });

  it("should parse file names for a deleted file", function() {
    const diff = `\
diff --git a/deletedFile.txt b/deletedFile.txt
deleted file mode 100644
index e6a2e28..0000000\
`;
    const files = parse(diff);
    expect(files.length).toBe(1);
    const file = files[0];
    expect(file.from).toBe("deletedFile.txt");
    expect(file.to).toBe("/dev/null");
  });

  it("should parse rename diff with space in path with no changes", function() {
    const diff = `\
diff --git a/My Folder/File b/My Folder/a/File
similarity index 100%
rename from a/My Folder/File
rename to My Folder/a/File\
`;
    const files = parse(diff);
    expect(files.length).toBe(1);
    const file = files[0];
    expect(file.from).toBe("My Folder/File");
    expect(file.to).toBe("My Folder/a/File");
    expect(file.chunks.length).toBe(0);
  });

  it("should parse rename diff with space in path with changes", function() {
    const diff = `\
diff --git a/My Folder/File b/My Folder/a/File
similarity index 100%
rename from a/My Folder/File
rename to My Folder/a/File
@@ -1,2 +1,2 @@
- line1
+ line2\
`;
    const files = parse(diff);
    expect(files.length).toBe(1);
    const file = files[0];
    expect(file.from).toBe("My Folder/File");
    expect(file.to).toBe("My Folder/a/File");
    expect(file.chunks.length).toBe(1);
    const chunk = file.chunks[0];
    expect(chunk.content).toBe("@@ -1,2 +1,2 @@");
    expect(chunk.changes.length).toBe(2);
    expect(chunk.changes[0].content).toBe("- line1");
    expect(chunk.changes[1].content).toBe("+ line2");
  });
});
<commit_msg>Add test pattern for #23<commit_after>const parse = require("../index");

describe("diff parser", function() {
  it("should parse null", () => {
    expect(parse(null).length).toBe(0);
  });

  it("should parse empty string", () => {
    expect(parse("").length).toBe(0);
  });

  it("should parse whitespace", () => {
    expect(parse(" ").length).toBe(0);
  });

  it("should parse simple git-like diff", function() {
    const diff = `\
diff --git a/file b/file
index 123..456 789
--- a/file
+++ b/file
@@ -1,2 +1,2 @@
- line1
+ line2\
`;
    const files = parse(diff);
    expect(files.length).toBe(1);
    const file = files[0];
    expect(file.from).toBe("file");
    expect(file.to).toBe("file");
    expect(file.chunks.length).toBe(1);
    const chunk = file.chunks[0];
    expect(chunk.content).toBe("@@ -1,2 +1,2 @@");
    expect(chunk.changes.length).toBe(2);
    expect(chunk.changes[0].content).toBe("- line1");
    expect(chunk.changes[1].content).toBe("+ line2");
  });

  it("should parse simple git-like diff with file enclosed by double-quote", function() {
    const diff = `\
diff --git "a/file1" "b/file2"
similarity index 100%
rename from "file1"
rename to "file2"\
`;
    const files = parse(diff);
    expect(files.length).toBe(1);
    const file = files[0];
    expect(file.from).toBe("file1");
    expect(file.to).toBe("file2");
    expect(file.chunks.length).toBe(0);
  });

  it('should parse file names for changed binaries with spaces in their names', function() {
    const diff = `\
diff --git a/Artsy_Tests/ReferenceImages/ARTopMenuViewControllerSpec/selects 'home' by default as ipad@2x.png b/Artsy_Tests/ReferenceImages/ARTopMenuViewControllerSpec/selects 'home' by default as ipad@2x.png
index fc72ba34b..ec373e9a4 100644
Binary files a/Artsy_Tests/ReferenceImages/ARTopMenuViewControllerSpec/selects 'home' by default as ipad@2x.png and b/Artsy_Tests/ReferenceImages/ARTopMenuViewControllerSpec/selects 'home' by default as ipad@2x.png differ\
`;
    const files = parse(diff);
    expect(files.length).toBe(1)
    const file = files[0]
    expect(file.from).toBe("Artsy_Tests/ReferenceImages/ARTopMenuViewControllerSpec/selects 'home' by default as ipad@2x.png")
    expect(file.to).toBe("Artsy_Tests/ReferenceImages/ARTopMenuViewControllerSpec/selects 'home' by default as ipad@2x.png")
  });

  it("should parse diff with new file mode line", function() {
    const diff = `\
diff --git a/test b/test
new file mode 100644
index 0000000..db81be4
--- /dev/null
+++ b/test
@@ -0,0 +1,2 @@
+line1
+line2\
`;
    const files = parse(diff);
    expect(files.length).toBe(1);
    const file = files[0];
    expect(file.new).toBeTruthy();
    expect(file.from).toBe("/dev/null");
    expect(file.to).toBe("test");
    expect(file.chunks[0].content).toBe("@@ -0,0 +1,2 @@");
    expect(file.chunks[0].changes.length).toBe(2);
    expect(file.chunks[0].changes[0].content).toBe("+line1");
    expect(file.chunks[0].changes[1].content).toBe("+line2");
  });

  it("should parse diff with deleted file mode line", function() {
    const diff = `\
diff --git a/test b/test
deleted file mode 100644
index db81be4..0000000
--- b/test
+++ /dev/null
@@ -1,2 +0,0 @@
-line1
-line2\
`;
    const files = parse(diff);
    expect(files.length).toBe(1);
    const file = files[0];
    expect(file.deleted).toBeTruthy();
    expect(file.from).toBe("test");
    expect(file.to).toBe("/dev/null");
    expect(file.chunks[0].content).toBe("@@ -1,2 +0,0 @@");
    expect(file.chunks[0].changes.length).toBe(2);
    expect(file.chunks[0].changes[0].content).toBe("-line1");
    expect(file.chunks[0].changes[1].content).toBe("-line2");
  });

  it("should parse diff with single line files", function() {
    const diff = `\
diff --git a/file1 b/file1
deleted file mode 100644
index db81be4..0000000
--- b/file1
+++ /dev/null
@@ -1 +0,0 @@
-line1
diff --git a/file2 b/file2
new file mode 100644
index 0000000..db81be4
--- /dev/null
+++ b/file2
@@ -0,0 +1 @@
+line1\
`;
    const files = parse(diff);
    expect(files.length).toBe(2);
    let file = files[0];
    expect(file.deleted).toBeTruthy();
    expect(file.from).toBe("file1");
    expect(file.to).toBe("/dev/null");
    expect(file.chunks[0].content).toBe("@@ -1 +0,0 @@");
    expect(file.chunks[0].changes.length).toBe(1);
    expect(file.chunks[0].changes[0].content).toBe("-line1");
    expect(file.chunks[0].changes[0].type).toBe("del");
    file = files[1];
    expect(file.new).toBeTruthy();
    expect(file.from).toBe("/dev/null");
    expect(file.to).toBe("file2");
    expect(file.chunks[0].content).toBe("@@ -0,0 +1 @@");
    expect(file.chunks[0].oldStart).toBe(0);
    expect(file.chunks[0].oldLines).toBe(0);
    expect(file.chunks[0].newStart).toBe(1);
    expect(file.chunks[0].newLines).toBe(1);
    expect(file.chunks[0].changes.length).toBe(1);
    expect(file.chunks[0].changes[0].content).toBe("+line1");
    expect(file.chunks[0].changes[0].type).toBe("add");
  });

  it("should parse multiple files in diff", function() {
    const diff = `\
diff --git a/file1 b/file1
index 123..456 789
--- a/file1
+++ b/file1
@@ -1,2 +1,2 @@
- line1
+ line2
diff --git a/file2 b/file2
index 123..456 789
--- a/file2
+++ b/file2
@@ -1,3 +1,3 @@
- line1
+ line2\
`;
    const files = parse(diff);
    expect(files.length).toBe(2);
    let file = files[0];
    expect(file.from).toBe("file1");
    expect(file.to).toBe("file1");
    expect(file.chunks[0].content).toBe("@@ -1,2 +1,2 @@");
    expect(file.chunks[0].changes.length).toBe(2);
    expect(file.chunks[0].changes[0].content).toBe("- line1");
    expect(file.chunks[0].changes[1].content).toBe("+ line2");
    file = files[1];
    expect(file.from).toBe("file2");
    expect(file.to).toBe("file2");
    expect(file.chunks[0].content).toBe("@@ -1,3 +1,3 @@");
    expect(file.chunks[0].changes.length).toBe(2);
    expect(file.chunks[0].changes[0].content).toBe("- line1");
    expect(file.chunks[0].changes[1].content).toBe("+ line2");
  });

  it("should parse diff with EOF flag", function() {
    const diff = `\
diff --git a/file1 b/file1
index 123..456 789
--- a/file1
+++ b/file1
@@ -1,2 +1,2 @@
- line1
+ line2
\\ No newline at end of file\
`;
    const files = parse(diff);
    expect(files.length).toBe(1);
    const file = files[0];
    expect(file.from).toBe("file1");
    expect(file.to).toBe("file1");
    const chunk = file.chunks[0];
    expect(chunk.content).toBe("@@ -1,2 +1,2 @@");
    expect(chunk.changes.length).toBe(3);
    expect(chunk.changes[0].content).toBe("- line1");
    expect(chunk.changes[1].content).toBe("+ line2");
    expect(chunk.changes[2].type).toBe("add");
    expect(chunk.changes[2].content).toBe("\\ No newline at end of file");
  });

  it("should parse gnu sample diff", function() {
    const diff = `\
--- lao	2002-02-21 23:30:39.942229878 -0800
+++ tzu	2002-02-21 23:30:50.442260588 -0800
@@ -1,7 +1,6 @@
-The Way that can be told of is not the eternal Way;
-The name that can be named is not the eternal name.
 The Nameless is the origin of Heaven and Earth;
-The Named is the mother of all things.
+The named is the mother of all things.
+
 Therefore let there always be non-being,
	so we may see their subtlety,
And let there always be being,
@@ -9,3 +8,6 @@
 The two are the same,
 But after they are produced,
	they have different names.
+They both may be called deep and profound.
+Deeper and more profound,
+The door of all subtleties!\
`;
    const files = parse(diff);
    expect(files.length).toBe(1);
    const file = files[0];
    expect(file.from).toBe("lao");
    expect(file.to).toBe("tzu");
    expect(file.chunks.length).toBe(2);
    const chunk0 = file.chunks[0];
    expect(chunk0.oldStart).toBe(1);
    expect(chunk0.oldLines).toBe(7);
    expect(chunk0.newStart).toBe(1);
    expect(chunk0.newLines).toBe(6);
    const chunk1 = file.chunks[1];
    expect(chunk1.oldStart).toBe(9);
    expect(chunk1.oldLines).toBe(3);
    expect(chunk1.newStart).toBe(8);
    expect(chunk1.newLines).toBe(6);
  });

  it("should parse hg diff output", function() {
    const diff = `\
diff -r 514fc757521e lib/parsers.coffee
--- a/lib/parsers.coffee	Thu Jul 09 00:56:36 2015 +0200
+++ b/lib/parsers.coffee	Fri Jul 10 16:23:43 2015 +0200
@@ -43,6 +43,9 @@
             files[file] = { added: added, deleted: deleted }
         files

+    diff: (out) ->
+        files = {}
+
 module.exports = Parsers

 module.exports.version = (out) ->\
`;
    const files = parse(diff);
    expect(files.length).toBe(1);
    const file = files[0];
    expect(file.chunks[0].content).toBe("@@ -43,6 +43,9 @@");
    expect(file.from).toBe("lib/parsers.coffee");
    expect(file.to).toBe("lib/parsers.coffee");
  });

  it("should parse svn diff output", function() {
    const diff = `\
Index: new.txt
===================================================================
--- new.txt	(revision 0)
+++ new.txt	(working copy)
@@ -0,0 +1 @@
+test
Index: text.txt
===================================================================
--- text.txt	(revision 6)
+++ text.txt	(working copy)
@@ -1,7 +1,5 @@
-This part of the
-document has stayed the
-same from version to
-version.  It shouldn't
+This is an important
+notice! It shouldn't
 be shown if it doesn't
 change.  Otherwise, that
 would not be helping to\
`;
    const files = parse(diff);
    expect(files.length).toBe(2);
    const file = files[0];
    expect(file.from).toBe("new.txt");
    expect(file.to).toBe("new.txt");
    expect(file.chunks[0].changes.length).toBe(1);
  });

  it("should parse file names for n new empty file", function() {
    const diff = `\
diff --git a/newFile.txt b/newFile.txt
new file mode 100644
index 0000000..e6a2e28\
`;
    const files = parse(diff);
    expect(files.length).toBe(1);
    const file = files[0];
    expect(file.from).toBe("/dev/null");
    expect(file.to).toBe("newFile.txt");
  });

  it("should parse file names for a deleted file", function() {
    const diff = `\
diff --git a/deletedFile.txt b/deletedFile.txt
deleted file mode 100644
index e6a2e28..0000000\
`;
    const files = parse(diff);
    expect(files.length).toBe(1);
    const file = files[0];
    expect(file.from).toBe("deletedFile.txt");
    expect(file.to).toBe("/dev/null");
  });

  it("should parse rename diff with space in path with no changes", function() {
    const diff = `\
diff --git a/My Folder/File b/My Folder/a/File
similarity index 100%
rename from a/My Folder/File
rename to My Folder/a/File\
`;
    const files = parse(diff);
    expect(files.length).toBe(1);
    const file = files[0];
    expect(file.from).toBe("My Folder/File");
    expect(file.to).toBe("My Folder/a/File");
    expect(file.chunks.length).toBe(0);
  });

  it("should parse rename diff with space in path with changes", function() {
    const diff = `\
diff --git a/My Folder/File b/My Folder/a/File
similarity index 100%
rename from a/My Folder/File
rename to My Folder/a/File
@@ -1,2 +1,2 @@
- line1
+ line2\
`;
    const files = parse(diff);
    expect(files.length).toBe(1);
    const file = files[0];
    expect(file.from).toBe("My Folder/File");
    expect(file.to).toBe("My Folder/a/File");
    expect(file.chunks.length).toBe(1);
    const chunk = file.chunks[0];
    expect(chunk.content).toBe("@@ -1,2 +1,2 @@");
    expect(chunk.changes.length).toBe(2);
    expect(chunk.changes[0].content).toBe("- line1");
    expect(chunk.changes[1].content).toBe("+ line2");
  });
});
<|endoftext|>


<commit_before>/* global document, window UMS_CONFIG */
import React from 'react';
import ReactDOM from 'react-dom';
import { Router, hashHistory } from 'react-router';
import { Forms, UMS, Provider as CoreProvider, Core } from 'oicr-ui-core';

if (window.SEARCH_CONFIG) Search.setConfig(window.SEARCH_CONFIG);

// Load store.
const store = require('../site/store').default;

// Get User Session, Invoke once
UMS.getUserInfo()(store.dispatch);

const client = Core.initApolloClient(true, store);

// Forms
const targetForms = document.getElementById('app-forms');
if (targetForms) {
    ReactDOM.render(
        <CoreProvider store={store} client={client}>
            <Router history={hashHistory}>
                <Forms.BaseRoutes store={store} client={client}/>
            </Router>
        </CoreProvider>,
        targetForms,
    );
}

// Forms
const targetEmbedForms = document.getElementById('app-forms-embed');
if (targetEmbedForms) {
    ReactDOM.render(
        <CoreProvider store={store} client={client}>
            <Router history={hashHistory}>
                <Forms.EmbedFormRoutes client={client} />
            </Router>
        </CoreProvider>,
        targetEmbedForms,
    );
}

// Forms
const targetFormVerify = document.getElementById('app-forms-verify');
if (targetFormVerify) {
    ReactDOM.render(
        <CoreProvider store={store} client={client}>
            <Router history={hashHistory}>
                <Forms.VerificationRoutes client={client} />
            </Router>
        </CoreProvider>,
        targetFormVerify,
    );
}

// Forms
// Logic to embed non-iframe worm.
// const targetEmbedCustomForms = document.getElementsByClassName('app-forms-embed-custom');
// if (targetEmbedCustomForms.length) {
//     for (var i = 0; i < targetEmbedCustomForms.length; i++) {
//         ReactDOM.render(
//             <CoreProvider store={store}>
//                 <Forms.Components.RenderForm
//                     params={{
//                         nid: targetEmbedCustomForms[i].getAttribute('data-formid'),
//                         lang: targetEmbedCustomForms[i].getAttribute('data-lang'),
//                     }}
//                 />
//             </CoreProvider>,
//             targetEmbedCustomForms[i],
//         );
//     }
// }
<commit_msg>Update _forms.js<commit_after>/* global document, window UMS_CONFIG */
import React from 'react';
import ReactDOM from 'react-dom';
import { Router, hashHistory } from 'react-router';
import { Forms, UMS, Provider as CoreProvider, Core, Search } from 'oicr-ui-core';

if (window.SEARCH_CONFIG) Search.setConfig(window.SEARCH_CONFIG);

// Load store.
const store = require('../site/store').default;

// Get User Session, Invoke once
UMS.getUserInfo()(store.dispatch);

const client = Core.initApolloClient(true, store);

// Forms
const targetForms = document.getElementById('app-forms');
if (targetForms) {
    ReactDOM.render(
        <CoreProvider store={store} client={client}>
            <Router history={hashHistory}>
                <Forms.BaseRoutes store={store} client={client}/>
            </Router>
        </CoreProvider>,
        targetForms,
    );
}

// Forms
const targetEmbedForms = document.getElementById('app-forms-embed');
if (targetEmbedForms) {
    ReactDOM.render(
        <CoreProvider store={store} client={client}>
            <Router history={hashHistory}>
                <Forms.EmbedFormRoutes client={client} />
            </Router>
        </CoreProvider>,
        targetEmbedForms,
    );
}

// Forms
const targetFormVerify = document.getElementById('app-forms-verify');
if (targetFormVerify) {
    ReactDOM.render(
        <CoreProvider store={store} client={client}>
            <Router history={hashHistory}>
                <Forms.VerificationRoutes client={client} />
            </Router>
        </CoreProvider>,
        targetFormVerify,
    );
}

// Forms
// Logic to embed non-iframe worm.
// const targetEmbedCustomForms = document.getElementsByClassName('app-forms-embed-custom');
// if (targetEmbedCustomForms.length) {
//     for (var i = 0; i < targetEmbedCustomForms.length; i++) {
//         ReactDOM.render(
//             <CoreProvider store={store}>
//                 <Forms.Components.RenderForm
//                     params={{
//                         nid: targetEmbedCustomForms[i].getAttribute('data-formid'),
//                         lang: targetEmbedCustomForms[i].getAttribute('data-lang'),
//                     }}
//                 />
//             </CoreProvider>,
//             targetEmbedCustomForms[i],
//         );
//     }
// }
<|endoftext|>


<commit_before>var page=$("#page_name").attr('data-page');
twttr.anywhere(function (T) {
	if(T.isConnected()){
		show_dropdown(T);
		var user_name=T.currentUser.data('screen_name');
		$("#upload_file_btn").live("click", function(){
		var d=new Date();
		d=d.toISOString();
		var tags=$("#upload_message").val().split(" ");
		var act_tags="", k=0;
		for(var j=0;j<tags.length;j++){
			if(tags[j].indexOf('#') == 0){
				act_tags=act_tags+" "+tags[j];
				act_tags=act_tags.replace(/[`~!@#$%^&*()_|+\-=?;:'",.<>\{\}\[\]\\\/]/gi, '');
				k++;
			}
		}
		act_tags=act_tags.substring(1,act_tags.length);
		var uid=$.couch.newUUID();
		uid="mytweet_"+uid;
		var doc={
			"_id": uid,
			"uploaded_by": user_name,
			"gravatar_url": "http://api.twitter.com/1/users/profile_image/"+user_name,
			"uploader_msg": $("#upload_message").val(),
			"created_at": d,
			"tags": act_tags.split(" ")
		};
		$.couch.db($db).saveDoc(doc,{
			success: function(data){
				var id=data.id;
				var stat=data.ok;
				if(stat){
					$("#uploadModal").modal('hide');
				}
			},
			error: function(data){
				console.log(data);
			}
		});
		return false;
	});

	$("#discuss_btn").live("click",function(){
		var dt=$.trim($("#discuss_title").val());
		var dm=$.trim($("#discuss_message").val());
		if(dt=='' || dm==''){
			if(dt==''){
				$("#discuss_title").focus();
			}
			else if(dm==''){
				$("#discuss_message").focus();
			}
			else{

			}
		}
		else{
			var d=new Date();
			d=d.toISOString();
			var uid=$.couch.newUUID();
			uid="discuss_"+uid;
			var doc={
				"_id": uid,
				"title": dt,
				"author": user_name,
				"content": dm ,
				"date": d,
				"author_pic": "http://api.twitter.com/1/users/profile_image/"+user_name,
				"type": "discussion"
			};
			$.couch.db($db).saveDoc(doc,{
			success: function(data){
				var id=data.id;
				var stat=data.ok;
				if(stat){
					$("#discussModal").modal('hide');
				}
			},
			error: function(data){
				console.log(data);
			}
		});
		}
		return false;
	});

	$("#upload_next_btn").live("click",function(){
		var ftitle=$.trim($("#file_title").val());
		var fdesc=$.trim($("#file_description").val());
		if(ftitle=='' || fdesc==''){
			if(ftitle==''){
				$("#file_title").focus();
			}
			else if(fdesc==''){
				$("#file_description").focus();
			}
			else{

			}
			return;
		}
		var uid=$.couch.newUUID();
		var my_rev;
		uid="up_file_"+uid;
		var d=new Date();
		d=d.toISOString();
		var doc={
			"_id": uid,
			"author": user_name,
			"title": ftitle,
			"description": fdesc,
			"type": "file",
			"author_pic": "http://api.twitter.com/1/users/profile_image/"+user_name,
			"date": d
		};
		$.couch.db($db).saveDoc(doc,{
			success: function(data){
				my_rev=data.rev;
				$("#first_upload_body").hide();
				$("#second_upload_body").html("<form class='form form-horizontal' id='attachment_form' name='attachment_form' content-type='multipart/form-data'>

<input class='span' id='_attachments' name='_attachments' type='file'>
<input type='hidden' name='_id' value='"+uid+"'><input type='hidden' name='_rev' value='"+my_rev+"'>

<input type='submit' class='btn btn-success' value='Upload »' id='file_btn'>

</form>").hide().fadeIn(500);
				$("#upload_modal_footer").hide();
			},
			error: function(data){
				console.log(data);
			}
		});
	});

	$("#attachment_form").live("submit",function(e) { // invoke callback on submit
  e.preventDefault();
  var data = {};
  $.each($("form :input").serializeArray(), function(i, field) {
    data[field.name] = field.value;
  });
  $("form :file").each(function() {
    data[this.name] = this.value; // file inputs need special handling
  });
  if (!data._attachments || data._attachments.length == 0) {
    alert("Please select a file to upload.");
    return;
  }
  $("#second_upload_body").prepend("").hide().show();
  $("#file_btn").attr("disabled","disabled");
  $(this).ajaxSubmit({
    url:  "../../"+data._id,
    success: function(resp) {
    	$("#loader").hide();
    	$("#file_btn").attr("disabled",false);
    	$("#uploadFileModal").modal('hide');
    	$("#second_upload_body").hide();
    	$("#file_title").val('');
    	$("#file_description").val('');
    	$("#_attachments").val('');
    	$("#first_upload_body").show();
    	$("#upload_modal_footer").show();
    },
    error: function(err){
    	$("#loader").hide();
    	console.log("id "+data._id);
    	console.log(err);
    }
  });
  return false;
});

	}
	else{
		$("#uploadModal").on("shown",function(){
			$("#upload_file_btn").live("click", function(){
				if(T.isConnected()){

				}else{
					$("#uploadModal").modal('hide');
					$("#messages").html("
×You need to be logged in!
").hide().fadeIn(500);
				}
			});
		});
		$("#discussModal").on("shown",function(){
			$("#discuss_btn").live("click", function(){
				if(T.isConnected()){

				}else{
					$("#discussModal").modal('hide');
					$("#messages").html("
×You need to be logged in!
").hide().fadeIn(500);
				}
			});
		});
		$("#uploadFileModal").on("shown",function(){
			$("#upload_next_btn").live("click", function(){
				if(T.isConnected()){

				}else{
					$("#uploadFileModal").modal('hide');
					$("#messages").html("
×You need to be logged in!
").hide().fadeIn(500);
				}
			});
			$("#attachment_form").live("submit",function() {
				if(T.isConnected()){

				}else{
					$("#uploadFileModal").modal('hide');
					$("#messages").html("
×You need to be logged in!
").hide().fadeIn(500);
				}
			});
		});
		$("#peepin").html('Login »').show();
	}
  $("#login").live("click",function(){
  	if(T.isConnected()){
  		show_dropdown(T);
  	}
  	else{
  		T.signIn();
  	}
  });
  $("#logout").live("click",function(){
  	twttr.anywhere.signOut();
  	window.location=window.location.href;
  });

});

function show_dropdown(T){
		var user=T.currentUser;
		var p=user.data('profile_image_url');
		var a=p.split('_');
		p=a[0]+"_"+a[1]+"_"+"mini.jpeg";
		$("#peepin").html('
 '+user.data("screen_name")+'

Home

Discussions

Files

Log out!

').hide().fadeIn('fast');
		if(page==="index.html"){
			$("#main-menu").hide();
			$("#tweet_div").html('Tweet »').hide().fadeIn(500);
		}
		if(page==="discussion.html"){
			$("#main-menu").hide();
			$("#discuss_btn_div").html('Discuss »').hide().fadeIn(500);
		}
		if(page==="files.html"){
			$("#main-menu").hide();
			$("#upload_btn_div").html('Upload File »').hide().fadeIn(500);
		}
}
<commit_msg>determine extension of the image and concatenate it<commit_after>var page=$("#page_name").attr('data-page');
twttr.anywhere(function (T) {
	if(T.isConnected()){
		show_dropdown(T);
		var user_name=T.currentUser.data('screen_name');
		$("#upload_file_btn").live("click", function(){
		var d=new Date();
		d=d.toISOString();
		var tags=$("#upload_message").val().split(" ");
		var act_tags="", k=0;
		for(var j=0;j<tags.length;j++){
			if(tags[j].indexOf('#') == 0){
				act_tags=act_tags+" "+tags[j];
				act_tags=act_tags.replace(/[`~!@#$%^&*()_|+\-=?;:'",.<>\{\}\[\]\\\/]/gi, '');
				k++;
			}
		}
		act_tags=act_tags.substring(1,act_tags.length);
		var uid=$.couch.newUUID();
		uid="mytweet_"+uid;
		var doc={
			"_id": uid,
			"uploaded_by": user_name,
			"gravatar_url": "http://api.twitter.com/1/users/profile_image/"+user_name,
			"uploader_msg": $("#upload_message").val(),
			"created_at": d,
			"tags": act_tags.split(" ")
		};
		$.couch.db($db).saveDoc(doc,{
			success: function(data){
				var id=data.id;
				var stat=data.ok;
				if(stat){
					$("#uploadModal").modal('hide');
				}
			},
			error: function(data){
				console.log(data);
			}
		});
		return false;
	});

	$("#discuss_btn").live("click",function(){
		var dt=$.trim($("#discuss_title").val());
		var dm=$.trim($("#discuss_message").val());
		if(dt=='' || dm==''){
			if(dt==''){
				$("#discuss_title").focus();
			}
			else if(dm==''){
				$("#discuss_message").focus();
			}
			else{

			}
		}
		else{
			var d=new Date();
			d=d.toISOString();
			var uid=$.couch.newUUID();
			uid="discuss_"+uid;
			var doc={
				"_id": uid,
				"title": dt,
				"author": user_name,
				"content": dm ,
				"date": d,
				"author_pic": "http://api.twitter.com/1/users/profile_image/"+user_name,
				"type": "discussion"
			};
			$.couch.db($db).saveDoc(doc,{
			success: function(data){
				var id=data.id;
				var stat=data.ok;
				if(stat){
					$("#discussModal").modal('hide');
				}
			},
			error: function(data){
				console.log(data);
			}
		});
		}
		return false;
	});

	$("#upload_next_btn").live("click",function(){
		var ftitle=$.trim($("#file_title").val());
		var fdesc=$.trim($("#file_description").val());
		if(ftitle=='' || fdesc==''){
			if(ftitle==''){
				$("#file_title").focus();
			}
			else if(fdesc==''){
				$("#file_description").focus();
			}
			else{

			}
			return;
		}
		var uid=$.couch.newUUID();
		var my_rev;
		uid="up_file_"+uid;
		var d=new Date();
		d=d.toISOString();
		var doc={
			"_id": uid,
			"author": user_name,
			"title": ftitle,
			"description": fdesc,
			"type": "file",
			"author_pic": "http://api.twitter.com/1/users/profile_image/"+user_name,
			"date": d
		};
		$.couch.db($db).saveDoc(doc,{
			success: function(data){
				my_rev=data.rev;
				$("#first_upload_body").hide();
				$("#second_upload_body").html("<form class='form form-horizontal' id='attachment_form' name='attachment_form' content-type='multipart/form-data'>

<input class='span' id='_attachments' name='_attachments' type='file'>
<input type='hidden' name='_id' value='"+uid+"'><input type='hidden' name='_rev' value='"+my_rev+"'>

<input type='submit' class='btn btn-success' value='Upload »' id='file_btn'>

</form>").hide().fadeIn(500);
				$("#upload_modal_footer").hide();
			},
			error: function(data){
				console.log(data);
			}
		});
	});

	$("#attachment_form").live("submit",function(e) { // invoke callback on submit
  e.preventDefault();
  var data = {};
  $.each($("form :input").serializeArray(), function(i, field) {
    data[field.name] = field.value;
  });
  $("form :file").each(function() {
    data[this.name] = this.value; // file inputs need special handling
  });
  if (!data._attachments || data._attachments.length == 0) {
    alert("Please select a file to upload.");
    return;
  }
  $("#second_upload_body").prepend("").hide().show();
  $("#file_btn").attr("disabled","disabled");
  $(this).ajaxSubmit({
    url:  "../../"+data._id,
    success: function(resp) {
    	$("#loader").hide();
    	$("#file_btn").attr("disabled",false);
    	$("#uploadFileModal").modal('hide');
    	$("#second_upload_body").hide();
    	$("#file_title").val('');
    	$("#file_description").val('');
    	$("#_attachments").val('');
    	$("#first_upload_body").show();
    	$("#upload_modal_footer").show();
    },
    error: function(err){
    	$("#loader").hide();
    	console.log("id "+data._id);
    	console.log(err);
    }
  });
  return false;
});

	}
	else{
		$("#uploadModal").on("shown",function(){
			$("#upload_file_btn").live("click", function(){
				if(T.isConnected()){

				}else{
					$("#uploadModal").modal('hide');
					$("#messages").html("
×You need to be logged in!
").hide().fadeIn(500);
				}
			});
		});
		$("#discussModal").on("shown",function(){
			$("#discuss_btn").live("click", function(){
				if(T.isConnected()){

				}else{
					$("#discussModal").modal('hide');
					$("#messages").html("
×You need to be logged in!
").hide().fadeIn(500);
				}
			});
		});
		$("#uploadFileModal").on("shown",function(){
			$("#upload_next_btn").live("click", function(){
				if(T.isConnected()){

				}else{
					$("#uploadFileModal").modal('hide');
					$("#messages").html("
×You need to be logged in!
").hide().fadeIn(500);
				}
			});
			$("#attachment_form").live("submit",function() {
				if(T.isConnected()){

				}else{
					$("#uploadFileModal").modal('hide');
					$("#messages").html("
×You need to be logged in!
").hide().fadeIn(500);
				}
			});
		});
		$("#peepin").html('Login »').show();
	}
  $("#login").live("click",function(){
  	if(T.isConnected()){
  		show_dropdown(T);
  	}
  	else{
  		T.signIn();
  	}
  });
  $("#logout").live("click",function(){
  	twttr.anywhere.signOut();
  	window.location=window.location.href;
  });

});

function show_dropdown(T){
		var user=T.currentUser;
		var p=user.data('profile_image_url');
		var a=p.split('_');
		var ext=a[2].split('.')
		p=a[0]+"_"+a[1]+"_mini."+ext[1];
		$("#peepin").html('
 '+user.data("screen_name")+'

Home

Discussions

Files

Log out!

').hide().fadeIn('fast');
		if(page==="index.html"){
			$("#main-menu").hide();
			$("#tweet_div").html('Tweet »').hide().fadeIn(500);
		}
		if(page==="discussion.html"){
			$("#main-menu").hide();
			$("#discuss_btn_div").html('Discuss »').hide().fadeIn(500);
		}
		if(page==="files.html"){
			$("#main-menu").hide();
			$("#upload_btn_div").html('Upload File »').hide().fadeIn(500);
		}
}
<|endoftext|>