<commit_before>/*
 * Copyright (C) 2012, OpenGroove, Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *  1. Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

var screenshotSenderLocalFile = {
    saveImage: function(message, filename, callbackDataURL) {
        var URL = window.URL || window.webkitURL || undefined;
        var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder ||
                          undefined;

        function getBlobFromDataURL(url) {
            var re = /^data:([^,;]+)((?:;[^;,]*)*),([^\n]*)/;
            var match = re.exec(url);
            if (!match) {
                return;
            }
            var mimetype = match[1].toLowerCase();
            var attrs = match[2].substring(1);
            var body = match[3];
            $.each(attrs.split(/;/), function(idx, val) {
                switch (val) {
                case 'base64':
                    body = atob(body);
                    break;
                }
            });
            var length = body.length;
            var buffer = new Uint8Array(length);
            for (var i = 0; i < length; i++) {
                buffer[i] = body.charCodeAt(i);
            }
            var builder = new BlobBuilder();
            builder.append(buffer.buffer);
            return builder.getBlob(mimetype);
        }

        callbackDataURL(function(uri) {
            var blob = getBlobFromDataURL(uri);
            var href = URL.createObjectURL(blob);
            try {
                var anchor = document.createElement('a');
                anchor.href = href;
                anchor.setAttribute('download', filename);
                anchor.click();
            }
            finally {
                setTimeout(function() { URL.revokeObjectURL(href) },
                           600 * 1000);
            }
        });
    }
}
<commit_msg>Fixed warnings with `BlobBuilder` and `Uint8Array.buffer`<commit_after>/*
 * Copyright (C) 2012, OpenGroove, Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *  1. Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

var screenshotSenderLocalFile = {
    saveImage: function(message, filename, callbackDataURL) {
        function getBlobFromDataURL(url) {
            var re = /^data:([^,;]+)((?:;[^;,]*)*),([^\n]*)/;
            var match = re.exec(url);
            if (!match) {
                return;
            }
            var mimetype = match[1].toLowerCase();
            var attrs = match[2].substring(1);
            var body = match[3];
            $.each(attrs.split(/;/), function(idx, val) {
                switch (val) {
                case 'base64':
                    body = atob(body);
                    break;
                }
            });
            var length = body.length;
            var out = new Uint8Array(length);
            for (var i = 0; i < length; i++) {
                out[i] = body.charCodeAt(i);
            }
            try {
                return new Blob([out], {type: mimetype});
            }
            catch (e) {
                // try to use BlobBuilder....
            }
            var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder;
            var builder = new BlobBuilder();
            builder.append(out.buffer);
            return builder.getBlob(mimetype);
        }

        callbackDataURL(function(uri) {
            var URL = window.URL || window.webkitURL || undefined;
            var blob = getBlobFromDataURL(uri);
            var href = URL.createObjectURL(blob);
            try {
                var anchor = document.createElement('a');
                anchor.href = href;
                anchor.setAttribute('download', filename);
                anchor.click();
            }
            finally {
                setTimeout(function() { URL.revokeObjectURL(href) },
                           600 * 1000);
            }
        });
    }
}
<|endoftext|>


<commit_before>/*
 * Copyright 2009 Kantega AS
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * This script expects the following properties to be set:
 * * debug
 * * contextPath
 * * contentRequestHandler
 * * thisId
 */

/********************************************************************************
 * Common OpenAksess functions. Declares the global namespace for all objects.
 *
 * Used both in standard admin context and by MiniAksess.
 ********************************************************************************/

var openaksess =  {
    // All Javascript objects should use this namespace
};

openaksess.common = {
    columnize : function() {
        var columnized = $(".columnized");
        openaksess.common.debug("openaksess.common(): Number of elements found to columnize: " + columnized.size());
        if (columnized.size() > 0) {
            var columncount = 1;
            var classes = columnized.attr("class").split(" ");
            for (var i = 0; i < classes.length; i++) {
                var c = classes[i];
                if (c.indexOf("columnCount") > -1) {
                    columncount = parseInt(c.substring("columnCount".length, c.length));
                }
            }
            openaksess.common.debug("openaksess.common(): Column count: " + columncount);
            columnized.makeacolumnlists({cols:columncount,colWidth:0,equalHeight:false,startN:1});
        }
    },

    /**
     * Returns the value of a query string parameter
     *
     * @param paramName Query parameter name
     * @param queryString The total query string
     */
    getQueryParam : function(paramName, queryString) {
        var val = null;
        var inx = queryString.indexOf(paramName + "=");
        if (inx != -1) {
            val = queryString.substring(inx + paramName.length + 1, queryString.length);
            if (val.indexOf("&") != -1) {
                val = val.substring(0, val.indexOf("&"));
            }
        }
        return val;
    },

    /**
     * Returns the uri for a content with a given associationId
     *
     * @param associationId
     */
    getContentUrlFromAssociationId : function(associationId) {
        var url = properties.contextPath + "/" + properties.contentRequestHandler + "?" + properties.thisId + "=" + associationId;
        openaksess.common.debug("openaksess.common.getContentUrlFromAssociationId(): associationId: " + associationId + ", returns: " + url);
        return url;
    },

    /**
     * Prints a debug message to Firebug's debug console.
     *
     * @param msg Debug message. Convention: 'functionName(): value'
     */
    debug : function (msg) {
        var debugEnabled = properties.debug;
        if (debugEnabled && $.browser.mozilla && typeof console != 'undefined') {
            var now = new Date();
            console.log(now.getHours()+":"+now.getMinutes()+":"+now.getSeconds()+now.getMilliseconds()+ " - " + msg);
        }
    },

    isPopup : function() {
        return window.parent != window || window.name == 'openAksessPopup';
    },

    /**
     * Responsible for drawing pop-ups and modals.
     */
    modalWindow : function() {

        var $content = '';
        var $overlay = $("<div/>").css({
                    position : 'absolute',
                    background : '#ffffff',
                    opacity: '0'
                })
                .attr("id", "Contentoverlay");
        var $iframe = $('<iframe id="externalSite" frameborder="0" src="" />');

        var config = {
            title: 'OpenAksess',
            titlebar: true,
            resizable: true,
            modal: true,
            iframe: false,
            closeOnEscape: true,
            height: 400,
            width: 600,
            horizontalPadding: 0,
            verticalPadding: 0,
            open: function(){
                $(window).trigger("resize");
            },
            autoResize: true,
            autoOpen: true,
            close: function() {
                openaksess.common.debug("openaksess.common.modalWindow.close()");
                $(this).remove();
            },
            overlay: {
                opacity: 0.2,
                background: "black"
            }
        };

        config.resizeStart = function(){
            openaksess.common.debug("openaksess.common.modalWindow.resizeStart()");
            if (config.iframe) {
                openaksess.common.debug("openaksess.common.modalWindow.resizeStart(): Has iframe. Adding overlay");
                var height = $iframe.height();
                var width = $iframe.width();
                $overlay.css({height : height + "px", width : width + "px"});
                $iframe.before($overlay);
            }
        };
        config.resize = function() {
            if (config.iframe) {
                var height = $iframe.height();
                var width = $iframe.width();
                $overlay.css({height : height + "px", width : width + "px"});
            }
        };

        config.resizeStop = function(){
            if (config.iframe) {
                $overlay.remove();
            }
        };

        return {
            /**
             * Opens a modal with the desired properties.
             *
             * @param additionalConfig
             */
            open : function(additionalConfig){
                openaksess.common.debug("openaksess.common.modalWindow.open(): additionalConfig: " + additionalConfig);

                if (additionalConfig && typeof(additionalConfig) == 'object') {
                    openaksess.common.debug("openaksess.common.modalWindow.open(): Extending default config with user supplied config.");
                    $.extend(config, additionalConfig);
                }

                if (!config.position) {
                    config.position = [(($(window).width()-config.width)/2),(($(window).height()-config.height)/2)];
                }

                if (config.iframe) {
                    var href = config.href;
                    if (config.href.indexOf("?") == -1) {
                        href = href + "?";
                    } else {
                        href = href + "&";
                    }
                    href = href + "dummy=" + new Date().getTime();
                    $content = $iframe.attr("src", href);
                } else {
                    $content = $("<div/>").load(config.href);
                }

                openaksess.common.debug("openaksess.common.modalWindow.open(): Opening modal window.");

                $content.dialog(config);

                if (config.iframe) {
                    $content.width(config.width - config.horizontalPadding).height(config.height - config.verticalPadding);
                }

                openaksess.common.debug("openaksess.common.modalWindow.open(): Modal window opened.");

            },

            /**
             * Closes the current modal.
             */
            close : function(){
                $content.dialog('close');
            },

            /**
             * Sets the modal window's title (top bar)
             */
            setTitle: function(title) {
                $content.dialog( "option", "title", title );
            }
        };

    }(),

    /**
     * Functionality for dealing with browser cookies.
     */
    cookies : {
        /**
         * Creates a cookie
         * @param name - cookie name
         * @param value - Cookie data
         * @param days - Time to live in days. If omitted, the cookie is killed when the browser session ends.
         */
        create : function (name,value,days) {
            var expires = "";
            if (days) {
                var date = new Date();
                date.setTime(date.getTime()+(days*24*60*60*1000));
                expires = "; expires="+date.toGMTString();
            }

            document.cookie = name+"="+value+expires+"; path=/";
        },

        /**
         * Returns the value of a cookie
         * @param name - cookie name.
         */
        read : function(name) {
            var nameEQ = name + "=";
            var ca = document.cookie.split(';');
            for(var i=0;i < ca.length;i++) {
                var c = ca[i];
                while (c.charAt(0)==' ') c = c.substring(1,c.length);
                if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
            }
            return null;
        },

        /**
         * Deletes a cookie.
         * @param name
         */
        erase : function (name) {
            openaksess.common.cookies.create(name,"",-1);
        }
    },

    /**
     * Triggers an OpenAksess specific event.
     * All events are prefixed with openaksess.[eventname], and
     * may possibly have data associated.
     *
     * If no context is given, the event is bound to the html element.
     *
     * Known openaksess events are:
     * - openaksess.navigatorSelect: When an item in the navigator is selected.
     * - openaksess.navigatorOpen: When a navigator folder is opened.
     * - openaksess.navigatorClose: When a navigator folder is closed.
     *
     * @param eventName - Name of the event to trigger, without prefix
     * @param data - Arbitrary data to send with the event.
     * @param context - The context within which the event is visible, e.g. "body".
     * Must be a jQuery selector string or a jQuery object.
     */
    triggerEvent: function(eventName, data, context){
        if (!context) {
            context = $("html");
        }
        if (!(context instanceof jQuery)) {
            context = $(context);
        }
        context.trigger("openaksess." + eventName, data);
    },

    abbreviate: function(str, maxlen, suffix) {
        if (str.length <= maxlen) {
            return str;
        }
        if (!suffix) {
            suffix = "...";
        }
        return str.substring(0, maxlen) + suffix;
    },

    addTouchScrollToIFrame: function (iFrame, container) {
        if(!navigator.userAgent.match(/iPad|iPhone/i)) {
            return;
        }

        var mouseY = 0;
        var mouseX = 0;

        var iframeBody = $(iFrame).get(0).contentWindow.document.body;

        if (iframeBody) {
            iframeBody.addEventListener('touchstart', function(e) {
                mouseY = e.targetTouches[0].pageY;
                mouseX = e.targetTouches[0].pageX;
            });

            //update scroll position based on initial drag position
            iframeBody.addEventListener('touchmove', function(e) {
                e.preventDefault(); //prevent whole page dragging

                var mask = $(container);
                mask.scrollLeft(mask.scrollLeft() + mouseX-e.targetTouches[0].pageX);
                mask.scrollTop(mask.scrollTop() + mouseY-e.targetTouches[0].pageY);
            });

        }
    }
};

<commit_msg>AP-1761<commit_after>/*
 * Copyright 2009 Kantega AS
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * This script expects the following properties to be set:
 * * debug
 * * contextPath
 * * contentRequestHandler
 * * thisId
 */

/********************************************************************************
 * Common OpenAksess functions. Declares the global namespace for all objects.
 *
 * Used both in standard admin context and by MiniAksess.
 ********************************************************************************/

var openaksess =  {
    // All Javascript objects should use this namespace
};

openaksess.common = {
    columnize : function() {
        var columnized = $(".columnized");
        openaksess.common.debug("openaksess.common(): Number of elements found to columnize: " + columnized.size());
        if (columnized.size() > 0) {
            var columncount = 1;
            var classes = columnized.attr("class").split(" ");
            for (var i = 0; i < classes.length; i++) {
                var c = classes[i];
                if (c.indexOf("columnCount") > -1) {
                    columncount = parseInt(c.substring("columnCount".length, c.length));
                }
            }
            openaksess.common.debug("openaksess.common(): Column count: " + columncount);
            columnized.makeacolumnlists({cols:columncount,colWidth:0,equalHeight:false,startN:1});
        }
    },

    /**
     * Returns the value of a query string parameter
     *
     * @param paramName Query parameter name
     * @param queryString The total query string
     */
    getQueryParam : function(paramName, queryString) {
        var val = null;
        var inx = queryString.indexOf(paramName + "=");
        if (inx != -1) {
            val = queryString.substring(inx + paramName.length + 1, queryString.length);
            if (val.indexOf("&") != -1) {
                val = val.substring(0, val.indexOf("&"));
            }
        }
        return val;
    },

    /**
     * Returns the uri for a content with a given associationId
     *
     * @param associationId
     */
    getContentUrlFromAssociationId : function(associationId) {
        var url = properties.contextPath + "/" + properties.contentRequestHandler + "?" + properties.thisId + "=" + associationId;
        openaksess.common.debug("openaksess.common.getContentUrlFromAssociationId(): associationId: " + associationId + ", returns: " + url);
        return url;
    },

    /**
     * Prints a debug message to Firebug's debug console.
     *
     * @param msg Debug message. Convention: 'functionName(): value'
     */
    debug : function (msg) {
        var debugEnabled = properties.debug;
        if (debugEnabled && typeof console != 'undefined') {
            var now = new Date();
            console.log(now.getHours()+":"+now.getMinutes()+":"+now.getSeconds()+now.getMilliseconds()+ " - " + msg);
        }
    },

    isPopup : function() {
        return window.parent != window || window.name == 'openAksessPopup';
    },

    /**
     * Responsible for drawing pop-ups and modals.
     */
    modalWindow : function() {

        var $content = '';
        var $overlay = $("<div/>").css({
                    position : 'absolute',
                    background : '#ffffff',
                    opacity: '0'
                })
                .attr("id", "Contentoverlay");
        var $iframe = $('<iframe id="externalSite" frameborder="0" src="" />');

        var config = {
            title: 'OpenAksess',
            titlebar: true,
            resizable: true,
            modal: true,
            iframe: false,
            closeOnEscape: true,
            height: 400,
            width: 600,
            horizontalPadding: 0,
            verticalPadding: 0,
            open: function(){
                $(window).trigger("resize");
            },
            autoResize: true,
            autoOpen: true,
            close: function() {
                openaksess.common.debug("openaksess.common.modalWindow.close()");
                $(this).remove();
            },
            overlay: {
                opacity: 0.2,
                background: "black"
            }
        };

        config.resizeStart = function(){
            openaksess.common.debug("openaksess.common.modalWindow.resizeStart()");
            if (config.iframe) {
                openaksess.common.debug("openaksess.common.modalWindow.resizeStart(): Has iframe. Adding overlay");
                var height = $iframe.height();
                var width = $iframe.width();
                $overlay.css({height : height + "px", width : width + "px"});
                $iframe.before($overlay);
            }
        };
        config.resize = function() {
            if (config.iframe) {
                var height = $iframe.height();
                var width = $iframe.width();
                $overlay.css({height : height + "px", width : width + "px"});
            }
        };

        config.resizeStop = function(){
            if (config.iframe) {
                $overlay.remove();
            }
        };

        return {
            /**
             * Opens a modal with the desired properties.
             *
             * @param additionalConfig
             */
            open : function(additionalConfig){
                openaksess.common.debug("openaksess.common.modalWindow.open(): additionalConfig: " + additionalConfig);

                if (additionalConfig && typeof(additionalConfig) == 'object') {
                    openaksess.common.debug("openaksess.common.modalWindow.open(): Extending default config with user supplied config.");
                    $.extend(config, additionalConfig);
                }

                if (!config.position) {
                    config.position = [(($(window).width()-config.width)/2),(($(window).height()-config.height)/2)];
                }

                if (config.iframe) {
                    var href = config.href;
                    if (config.href.indexOf("?") == -1) {
                        href = href + "?";
                    } else {
                        href = href + "&";
                    }
                    href = href + "dummy=" + new Date().getTime();
                    $content = $iframe.attr("src", href);
                } else {
                    $content = $("<div/>").load(config.href);
                }

                openaksess.common.debug("openaksess.common.modalWindow.open(): Opening modal window.");

                $content.dialog(config);

                if (config.iframe) {
                    $content.width(config.width - config.horizontalPadding).height(config.height - config.verticalPadding);
                }

                openaksess.common.debug("openaksess.common.modalWindow.open(): Modal window opened.");

            },

            /**
             * Closes the current modal.
             */
            close : function(){
                $content.dialog('close');
            },

            /**
             * Sets the modal window's title (top bar)
             */
            setTitle: function(title) {
                $content.dialog( "option", "title", title );
            }
        };

    }(),

    /**
     * Functionality for dealing with browser cookies.
     */
    cookies : {
        /**
         * Creates a cookie
         * @param name - cookie name
         * @param value - Cookie data
         * @param days - Time to live in days. If omitted, the cookie is killed when the browser session ends.
         */
        create : function (name,value,days) {
            var expires = "";
            if (days) {
                var date = new Date();
                date.setTime(date.getTime()+(days*24*60*60*1000));
                expires = "; expires="+date.toGMTString();
            }

            document.cookie = name+"="+value+expires+"; path=/";
        },

        /**
         * Returns the value of a cookie
         * @param name - cookie name.
         */
        read : function(name) {
            var nameEQ = name + "=";
            var ca = document.cookie.split(';');
            for(var i=0;i < ca.length;i++) {
                var c = ca[i];
                while (c.charAt(0)==' ') c = c.substring(1,c.length);
                if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
            }
            return null;
        },

        /**
         * Deletes a cookie.
         * @param name
         */
        erase : function (name) {
            openaksess.common.cookies.create(name,"",-1);
        }
    },

    /**
     * Triggers an OpenAksess specific event.
     * All events are prefixed with openaksess.[eventname], and
     * may possibly have data associated.
     *
     * If no context is given, the event is bound to the html element.
     *
     * Known openaksess events are:
     * - openaksess.navigatorSelect: When an item in the navigator is selected.
     * - openaksess.navigatorOpen: When a navigator folder is opened.
     * - openaksess.navigatorClose: When a navigator folder is closed.
     *
     * @param eventName - Name of the event to trigger, without prefix
     * @param data - Arbitrary data to send with the event.
     * @param context - The context within which the event is visible, e.g. "body".
     * Must be a jQuery selector string or a jQuery object.
     */
    triggerEvent: function(eventName, data, context){
        if (!context) {
            context = $("html");
        }
        if (!(context instanceof jQuery)) {
            context = $(context);
        }
        context.trigger("openaksess." + eventName, data);
    },

    abbreviate: function(str, maxlen, suffix) {
        if (str.length <= maxlen) {
            return str;
        }
        if (!suffix) {
            suffix = "...";
        }
        return str.substring(0, maxlen) + suffix;
    },

    addTouchScrollToIFrame: function (iFrame, container) {
        if(!navigator.userAgent.match(/iPad|iPhone/i)) {
            return;
        }

        var mouseY = 0;
        var mouseX = 0;

        var iframeBody = $(iFrame).get(0).contentWindow.document.body;

        if (iframeBody) {
            iframeBody.addEventListener('touchstart', function(e) {
                mouseY = e.targetTouches[0].pageY;
                mouseX = e.targetTouches[0].pageX;
            });

            //update scroll position based on initial drag position
            iframeBody.addEventListener('touchmove', function(e) {
                e.preventDefault(); //prevent whole page dragging

                var mask = $(container);
                mask.scrollLeft(mask.scrollLeft() + mouseX-e.targetTouches[0].pageX);
                mask.scrollTop(mask.scrollTop() + mouseY-e.targetTouches[0].pageY);
            });

        }
    }
};

<|endoftext|>


<commit_before>/**
 *  \details © 2011  Open Ximdex Evolution SL [http://www.ximdex.org]
 *
 *  Ximdex a Semantic Content Management System (CMS)
 *
 *  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.
 *
 *  See the Affero GNU General Public License for more details.
 *  You should have received a copy of the Affero GNU General Public License
 *  version 3 along with Ximdex (see LICENSE file).
 *
 *  If not, visit http://gnu.org/licenses/agpl-3.0.html.
 *
 *  @author Ximdex DevTeam <dev@ximdex.com>
 *  @version $Revision$
 */

X.actionLoaded(function (event, fn, params){

	var extended = {};
	var content = params.context;

	$('document').ready(function() {
		get_frame_list(true);
		periodical_refresh_list(5000);

            $dialog = $('

').dialog({
                  autoOpen: false,
                  modal: true,
                  resizable: false,
                  draggable: false,
                  open: function(event, ui) { jQuery('.ui-dialog-titlebar-close').hide(); }
             });
	});

	function periodical_refresh_list(interval) {
		var t = XimTimer.getInstance();
                t.removeAllObservers();
		t.addObserver(get_frame_list, interval);
		t.start();
	}

	function refresh_frame_list(data, initial_state) {
		var progress_table = [];
		progress_table['In'] = 100;
		progress_table['Pending'] = 0;
		progress_table['Due2In'] = 25;
		progress_table['Due2In_'] = 50;
		progress_table['Due2Out'] = 25;
		progress_table['Due2Out_'] = 50;
		progress_table['Pumped'] = 75;
		$('div#frame_list', content).empty();

		if(data.length == 0) {
			$('div#frame_list', content).append('An no se ha enviado a publicar ningn documento');
			return;
		}

		for (var portal_version in data) {
			if(initial_state) extended[portal_version] = false;
			var acum_progress = 0;
			var nodename = '';
                        var batchid = 0;
                        var batch_state = 'activa';
			var triangle_icon = extended[portal_version] ? 'ui-icon ui-icon-triangle-1-se': 'ui-icon ui-icon-triangle-1-e';

			$('div#frame_list', content).append('

');
			$(data[portal_version]).each(function (key, item) {
                           if(item.Progress == '-1') item.Progress = '0';
                           $('div#frame_list', content).append('

' + get_elapsed(item.PubTime) + ' ' + item.FilePath + '/' + item.FileName  + '

');
                           $('#bar_' + item.IdSync, content).progressbar({value: parseInt(item.Progress)});
                                if(item.Error == 1)
                                    $('#bar_' + item.IdSync, content).css({'background': '#F50202'});
                                acum_progress += parseInt(item.Progress);
 			        nodename = item.NodeName;
                                batchid = item.IdBatch;
                                batch_state = item.BatchState;

			});
			$('#bar_pv_' + portal_version, content).progressbar({value: acum_progress/$(data[portal_version]).length});
			$('#bar_pv_' + portal_version, content).next().append('' + nodename + '');
			$('#bar_pv_' + portal_version, content).next().append(' Esta publicacin est ' + batch_state + ' [' + ((batch_state == 'detenida') ? 'Reanudar' : 'Detener') + ' esta publicacin]');

			if(extended[portal_version] === false) $('.portal_version_' + portal_version, content).hide();

			$('#portal_version_' + portal_version, content).click(function(e) {
				$('.' + $(e.currentTarget).attr('id')).toggle();
				var pv = $(e.currentTarget).attr('id').replace('portal_version_', '');
				$(this).toggleClass('ui-icon ui-icon-triangle-1-e ui-icon ui-icon-triangle-1-se');
				extended[pv] = (extended[pv] === false) ? true : false;
			});
		}

		$dialog.dialog('close');

		$('.batch_toggle', content).click(function(e) {
			get_frame_list(initial_state, parseInt(($(e.target).attr('id')).replace('batchid_', '')));
			$dialog.text("Un momento, por favor...");
			$dialog.dialog('open');
		});

		/*$('.progressbar', content).click(function(e) {
			var id = $(this).attr('id');
			if(id.replace('bar_pv', '') != id) {
				$(this).parent().toggleClass('batch_container_selected');
			}
		});*/

	}

	function get_frame_list(initial_state, batch_id) {
		$.get(params.actionView.url, {method: 'getFrameList', batchid: batch_id}, function(data) {
			if(data) {
				var frame_list = eval("(" + data + ")");
				refresh_frame_list(frame_list, initial_state);
			}
		}.bind(this));
	}

	function get_elapsed(seconds) {
		var secs = parseInt(seconds);
		var mins = parseInt(secs / 60);
		secs = secs - (mins * 60);

		return mins + 'm' + secs + 's';
	}
});

<commit_msg>module is working. Start to migrate to angularjs<commit_after>/**
 *  \details © 2011  Open Ximdex Evolution SL [http://www.ximdex.org]
 *
 *  Ximdex a Semantic Content Management System (CMS)
 *
 *  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.
 *
 *  See the Affero GNU General Public License for more details.
 *  You should have received a copy of the Affero GNU General Public License
 *  version 3 along with Ximdex (see LICENSE file).
 *
 *  If not, visit http://gnu.org/licenses/agpl-3.0.html.
 *
 *  @author Ximdex DevTeam <dev@ximdex.com>
 *  @version $Revision$
 */

        X.actionLoaded(function (event, fn, params) {

            var extended = {};
            var content = params.context;

            $('document').ready(function () {
                get_frame_list(true);
                periodical_refresh_list(5000);

                $dialog = $('

').dialog({
                    autoOpen: false,
                    modal: true,
                    resizable: false,
                    draggable: false,
                    open: function (event, ui) {
                        jQuery('.ui-dialog-titlebar-close').hide();
                    }
                });
            });

            function periodical_refresh_list(interval) {
                var t = XimTimer.getInstance();
                t.removeAllObservers();
                t.addObserver(get_frame_list, interval);
                t.start();
            }

            function refresh_frame_list(data, initial_state) {
                var progress_table = [];
                progress_table['In'] = 100;
                progress_table['Pending'] = 0;
                progress_table['Due2In'] = 25;
                progress_table['Due2In_'] = 50;
                progress_table['Due2Out'] = 25;
                progress_table['Due2Out_'] = 50;
                progress_table['Pumped'] = 75;
                $('div#frame_list', content).empty();

                if (data.length == 0) {
                    $('div#frame_list', content).append('Aún no se ha enviado a publicar ningún documento');
                    return;
                }

                for (var portal_version in data) {
                    if (initial_state)
                        extended[portal_version] = false;
                    var acum_progress = 0;
                    var nodename = '';
                    var batchid = 0;
                    var batch_state = 'activa';
                    var triangle_icon = extended[portal_version] ? 'ui-icon ui-icon-triangle-1-se' : 'ui-icon ui-icon-triangle-1-e';

                    $('div#frame_list', content).append('

');
                    $(data[portal_version]).each(function (k, item) {
                        if (item.Progress === '-1')
                            item.Progress = '0';
                        $('div#frame_list', content).append('

' + get_elapsed(item.PubTime) + ' ' + item.FilePath + '/' + item.FileName + '

');
                        $('#bar_' + item.IdSync, content).progressbar({value: parseInt(item.Progress)});
                        if (item.Error === 1)
                            $('#bar_' + item.IdSync, content).css({'background': '#F50202'});
                        acum_progress += parseInt(item.Progress);
                        nodename = item.NodeName;
                        batchid = item.IdBatch;
                        batch_state = item.BatchState;
                    });
                    $('#bar_pv_' + portal_version, content).progressbar({value: acum_progress / $(data[portal_version]).length});
                    $('#bar_pv_' + portal_version, content).next().append('' + nodename + '');
                    $('#bar_pv_' + portal_version, content).next().append(' Esta publicación está ' + batch_state + ' [' + ((batch_state == 'detenida') ? 'Reanudar' : 'Detener') + ' esta publicación]');

                    if (extended[portal_version] === false)
                        $('.portal_version_' + portal_version, content).hide();

                    $('#portal_version_' + portal_version, content).click(function (e) {
                        $('.' + $(e.currentTarget).attr('id')).toggle();
                        var pv = $(e.currentTarget).attr('id').replace('portal_version_', '');
                        $(this).toggleClass('ui-icon ui-icon-triangle-1-e ui-icon ui-icon-triangle-1-se');
                        extended[pv] = (extended[pv] === false) ? true : false;
                    });
                }

                $dialog.dialog('close');

                $('.batch_toggle', content).click(function (e) {
                    get_frame_list(initial_state, parseInt(($(e.target).attr('id')).replace('batchid_', '')));
                    $dialog.text("Un momento, por favor...");
                    $dialog.dialog('open');
                });

                /*$('.progressbar', content).click(function(e) {
                 var id = $(this).attr('id');
                 if(id.replace('bar_pv', '') != id) {
                 $(this).parent().toggleClass('batch_container_selected');
                 }
                 });*/

            }

            function get_frame_list(initial_state, batch_id) {
                $.getJSON(params.actionView.url, {method: 'getFrameList', batchid: batch_id})
                        .done(function (data) {
                            var total = 0, completed = 0;
                            $.each(data, function (k, arr) {
                                $.each(arr, function (i, frame) {
                                    total++;
                                    if (frame.Progress === '100') {
                                        completed++;
                                    }
                                });
                            });
                            if (completed === total) {
                                var t = XimTimer.getInstance();
                                t.getObserver(get_frame_list);
                                t.stop();
                            }
                            refresh_frame_list(data, initial_state);
                        });
            }

            function get_elapsed(seconds) {
                var secs = parseInt(seconds);
                var mins = parseInt(secs / 60);
                secs = secs - (mins * 60);
                return mins + 'm' + secs + 's';
            }
        });

<|endoftext|>


<commit_before>
var Proteus         = require("proteus"),
    Path            = require("path"),
    nutil           = require("util"),
    taskDescription = "",
    futil,
    sake,
    Task,
    FileTask,
    FileList,
    FileCreateTask
;
//---------------------------------------------------------------------------
// Privates
//---------------------------------------------------------------------------
function defineTask (TaskClass, name, prereqs, action) {
    var task = new TaskClass(name, prereqs, action);

    task.description = taskDescription;
    taskDescription = "";

    return task;
}

function defineTaskSync (TaskClass, name, prereqs, action) {
    if (!action && typeof prereqs === "function") {
        action = prereqs;
        prereqs = null;
    }

    return defineTask(TaskClass, name, prereqs, function (t) {
        var v = action && action(t);
        t.done();
    });
}
//---------------------------------------------------------------------------
// Public/Exports
//---------------------------------------------------------------------------
sake = {
    log: function () {
        var opts = this.options;

        if (!(opts.quiet || opts.silent) || opts.verbose) {
            Proteus.slice(arguments).forEach(function (arg) {
                arg = typeof arg === "string" ?
                    "[" + arg + "]" :
                    nutil.inspect(arg, false, 100);
                process.stderr.write(arg + "\n");
            });
        }
    },

    load: function (filepath) {
        require("sake/vm").run(filepath);
    },

    description: function (txt) {
        taskDescription += txt;
    },

    directory: (function () {

        function mkdirAction (t) {
            if (!Path.existsSync(t.name)) {
                futil.mkdir_p(t.name);
            }
        }

        return function (name) {
            var dirpath = name;

            while (dirpath !== "." && dirpath !== "/") {
                defineTaskSync(FileCreateTask, dirpath, mkdirAction);
                dirpath = Path.dirname(dirpath);
            }

            return Task.get(name);
        };
    }()),

    async: require("async")
};
//---------------------------------------------------------------------------
// Exports
//---------------------------------------------------------------------------
/**
 * Define the exports as a 'getter', and then re-define it as a plain property
 * once everything is all setup and ready to go.
 */
Object.defineProperty(module, "exports", {
    get: function () {
        sake.options = require("sake/options");

        Object.defineProperty(module, "exports", {
            value: sake,
            enumerable: true
        });

        // Require these here to avoid recursive requires
        futil                                   = require("sake/file-utils");
        sake.Task           = Task              = require("sake/task");
        sake.FileTask       = FileTask          = require("sake/file-task");
        sake.FileCreateTask = FileCreateTask    = require("sake/file-create-task");
        sake.FileList       = FileList          = require("sake/file-list");
        // bind our task creation functions
        sake.task           = defineTask.bind(sake, Task);
        sake.taskSync       = defineTaskSync.bind(sake, Task);

        sake.file           = defineTask.bind(sake, FileTask);
        sake.fileSync       = defineTaskSync.bind(sake, FileTask);

        sake.fileCreateSync = defineTaskSync.bind(sake, FileCreateTask);
        sake.fileCreate     = defineTask.bind(sake, FileCreateTask);

        // some other functions that need late binding
        sake.desc = sake.description.bind(sake);
        sake.include = sake.load.bind(sake);

        return sake;
    },
    enumerable: true,
    configurable: true
});
<commit_msg>Must reference the local variable for sake instead of 'this'<commit_after>
var Proteus         = require("proteus"),
    Path            = require("path"),
    nutil           = require("util"),
    taskDescription = "",
    futil,
    sake,
    Task,
    FileTask,
    FileList,
    FileCreateTask
;
//---------------------------------------------------------------------------
// Privates
//---------------------------------------------------------------------------
function defineTask (TaskClass, name, prereqs, action) {
    var task = new TaskClass(name, prereqs, action);

    task.description = taskDescription;
    taskDescription = "";

    return task;
}

function defineTaskSync (TaskClass, name, prereqs, action) {
    if (!action && typeof prereqs === "function") {
        action = prereqs;
        prereqs = null;
    }

    return defineTask(TaskClass, name, prereqs, function (t) {
        var v = action && action(t);
        t.done();
    });
}
//---------------------------------------------------------------------------
// Public/Exports
//---------------------------------------------------------------------------
sake = {
    log: function () {
        var opts = sake.options;

        if (!(opts.quiet || opts.silent) || opts.verbose) {
            Proteus.slice(arguments).forEach(function (arg) {
                arg = typeof arg === "string" ?
                    "[" + arg + "]" :
                    nutil.inspect(arg, false, 100);
                process.stderr.write(arg + "\n");
            });
        }
    },

    load: function (filepath) {
        require("sake/vm").run(filepath);
    },

    description: function (txt) {
        taskDescription += txt;
    },

    directory: (function () {

        function mkdirAction (t) {
            if (!Path.existsSync(t.name)) {
                futil.mkdir_p(t.name);
            }
        }

        return function (name) {
            var dirpath = name;

            while (dirpath !== "." && dirpath !== "/") {
                defineTaskSync(FileCreateTask, dirpath, mkdirAction);
                dirpath = Path.dirname(dirpath);
            }

            return Task.get(name);
        };
    }()),

    async: require("async")
};
//---------------------------------------------------------------------------
// Exports
//---------------------------------------------------------------------------
/**
 * Define the exports as a 'getter', and then re-define it as a plain property
 * once everything is all setup and ready to go.
 */
Object.defineProperty(module, "exports", {
    get: function () {
        sake.options = require("sake/options");

        Object.defineProperty(module, "exports", {
            value: sake,
            enumerable: true
        });

        // Require these here to avoid recursive requires
        futil                                   = require("sake/file-utils");
        sake.Task           = Task              = require("sake/task");
        sake.FileTask       = FileTask          = require("sake/file-task");
        sake.FileCreateTask = FileCreateTask    = require("sake/file-create-task");
        sake.FileList       = FileList          = require("sake/file-list");
        // bind our task creation functions
        sake.task           = defineTask.bind(sake, Task);
        sake.taskSync       = defineTaskSync.bind(sake, Task);

        sake.file           = defineTask.bind(sake, FileTask);
        sake.fileSync       = defineTaskSync.bind(sake, FileTask);

        sake.fileCreateSync = defineTaskSync.bind(sake, FileCreateTask);
        sake.fileCreate     = defineTask.bind(sake, FileCreateTask);

        // some other functions that need late binding
        sake.desc = sake.description.bind(sake);
        sake.include = sake.load.bind(sake);

        return sake;
    },
    enumerable: true,
    configurable: true
});
<|endoftext|>


<commit_before>$(document).ready(function() {
    var i = 0;
    var searchvalue = $("#searchvalue").val();
    var nrplaces;
    $('.right-container').scroll(function() {
        if ($(this)[0].scrollHeight - $(this).scrollTop() == $(this).outerHeight()) {
            i++;
            $.ajax({
                url: "morePlacesRequest",
                type: "POST",
                data: 'pag=' + i + '&searchval=' + searchvalue,
                success: function(data) {
                    if (data) {
                        $('#gif-loader').hide();
                        $('.restaurant-list').append(data);
                        nrplaces = $("#nrplaces").val();
                    }
                },
                beforeSend: function() {
                    $('#gif-loader').show();
                },
                complete: function() {
                    $('#gif-loader').hide();
                }
            });
        }
    });
    $(".restaurant-list").on('click','.it',function(){
        param = $(this).attr('href');
        event.preventDefault();
        $(this).addClass('active').siblings().removeClass('active');
        $.ajax({
            url: param,
            type: "GET",
            success: function(data) {
                if (data) {
                    $('.left-container').html(data);
                    refreshMap();
                }
            }
        });
        return false;
        event.preventDefault();
    });
    var refreshMap = function(){
        var toAddrLatLng = $("#lat").val() + " " + $("#lng").val();
        var fromAddr = $("#fromAddress").val();
        //alert(fromAddr);
        var toAddr = $("#toAddress").val();
        //alert(toAddrLatLng);
        if ("" !== toAddr) {
            initialize(fromAddr, toAddrLatLng, $("#lat").val(), $("#lng").val());
        } else {
            initialize(fromAddr, toAddrLatLng, $("#lat").val(), $("#lng").val());
        }
    }
});<commit_msg>fixed sidebar click event for firefox<commit_after>$(document).ready(function() {
    var i = 0;
    var searchvalue = $("#searchvalue").val();
    var nrplaces;
    $('.right-container').scroll(function() {
        if ($(this)[0].scrollHeight - $(this).scrollTop() == $(this).outerHeight()) {
            i++;
            $.ajax({
                url: "morePlacesRequest",
                type: "POST",
                data: 'pag=' + i + '&searchval=' + searchvalue,
                success: function(data) {
                    if (data) {
                        $('#gif-loader').hide();
                        $('.restaurant-list').append(data);
                        nrplaces = $("#nrplaces").val();
                    }
                },
                beforeSend: function() {
                    $('#gif-loader').show();
                },
                complete: function() {
                    $('#gif-loader').hide();
                }
            });
        }
    });
    $(".restaurant-list").on('click','.it',function(event){
        param = $(this).attr('href');
        event.preventDefault();
        $(this).addClass('active').siblings().removeClass('active');
        $.ajax({
            url: param,
            type: "GET",
            success: function(data) {
                if (data) {
                    $('.left-container').html(data);
                    refreshMap();
                }
            }
        });
        return false;
        event.preventDefault();
    });
    var refreshMap = function(){
        var toAddrLatLng = $("#lat").val() + " " + $("#lng").val();
        var fromAddr = $("#fromAddress").val();
        //alert(fromAddr);
        var toAddr = $("#toAddress").val();
        //alert(toAddrLatLng);
        if ("" !== toAddr) {
            initialize(fromAddr, toAddrLatLng, $("#lat").val(), $("#lng").val());
        } else {
            initialize(fromAddr, toAddrLatLng, $("#lat").val(), $("#lng").val());
        }
    }
});<|endoftext|>


<commit_before>appendStyle(zJS.Utils.getUrl('css/ikaeasy.css?version=2.0.0.91'));//@todo change with update
//appendStyle(zJS.Utils.getUrl('css/ikalogs.css?version=2.0.0.91'));//@todo add if with settings
appendStyle('/skin/compiled-' + zJS.Utils.getServerDomain() + '-island.css');
console.log("append");
function appendScript(src) {
    $('head').append('<script type="text/javascript" src="' + src + '"></script>');
}

function appendStyle(src) {
    $('head').append('<link href="' + src + '"  rel="stylesheet" type="text/css" />');
}

function getiUrlImage(url) {
    return chrome.extension.getURL('images/' + url);
}

function createDynamic(title, content) {
    return zJS.Utils.createDynamic(title, content);
}

function getServerDomain() {
    return zJS.Utils.getServerDomain();
}

function askms(params, handler) {
    zJS.Utils.askms(params, handler || false);
}

function getJSON(url, callback) {
    $.ajax({
        url: url,
        async: true,
        dataType: "json",
        error: callback,
        success: callback
    });
}

function postJSON(url, data, callback) {
    $.ajax({
        url: url,
        data: data,
        async: true,
        type: "POST",
        error: callback || false,
        success: callback || false,
        dataType: "json"
    });
}

Array.prototype.removeEl = function() {
    var what, a = arguments, L = a.length, ax;
    while (L && this.length) {
        what = a[--L];
        while ((ax = this.indexOf(what)) !== -1) {
            this.splice(ax, 1);
        }
    }
    return this;
};

function containsObject(obj, list) {
    var i;
    for (i = 0; i < list.length; i++) {
        if (list[i] === obj) {
            return true;
        }
    }

    return false;
}<commit_msg>Update init.js<commit_after>appendStyle(zJS.Utils.getUrl('css/ikaeasy.css?version=2.0.0.91'));//@todo change with update
//appendStyle(zJS.Utils.getUrl('css/ikalogs.css?version=2.0.0.91'));//@todo add if with settings
appendStyle('/skin/compiled-' + zJS.Utils.getServerDomain() + '-island.css');
console.log("append");
function appendScript(src) {
    $('head').append('<script type="text/javascript" src="' + src + '"></script>');
}

function appendStyle(src) {
    $('head').append('<link href="' + src + '"  rel="stylesheet" type="text/css" />');
}

function getiUrlImage(url) {
    return chrome.extension.getURL('images/' + url);
}

function createDynamic(title, content) {
    return zJS.Utils.createDynamic(title, content);
}

function getServerDomain() {
    return zJS.Utils.getServerDomain();
}

function askms(params, handler) {
    zJS.Utils.askms(params, handler || false);
}

function getJSON(url, callback) {
    $.ajax({
        url: url,
        async: true,
        xhrFields: { withCredentials: true },
        dataType: "json",
        error: callback,
        success: callback
    });
}

function postJSON(url, data, callback) {
    $.ajax({
        url: url,
        data: data,
        async: true,
        xhrFields: { withCredentials: true },
        type: "POST",
        error: callback || false,
        success: callback || false,
        dataType: "json"
    });
}

Array.prototype.removeEl = function() {
    var what, a = arguments, L = a.length, ax;
    while (L && this.length) {
        what = a[--L];
        while ((ax = this.indexOf(what)) !== -1) {
            this.splice(ax, 1);
        }
    }
    return this;
};

function containsObject(obj, list) {
    var i;
    for (i = 0; i < list.length; i++) {
        if (list[i] === obj) {
            return true;
        }
    }

    return false;
}
<|endoftext|>


<commit_before>'use strict';

// TODO : add a mopidy service designed for angular, to avoid ugly $scope.$apply()...
angular.module('partyApp', [])
  .controller('MainController', function($scope) {

  // Scope variables

  $scope.message = [];
  $scope.tracks  = [];
	$scope.tltrack = [];
  $scope.loading = true;
  $scope.ready   = false;
  $scope.currentState = {
    paused : false,
    length : 0,
    track  : {
      length : 0,
      name   : 'Nothing playing, add some songs to get the party going!'
    }
  };

  // Initialize

  var mopidy = new Mopidy({
    'callingConvention' : 'by-position-or-by-name'
  });

  // Adding listenners

  mopidy.on('state:online', function () {
    mopidy.playback
    .getCurrentTrack()
    .then(function(track){
      if(track)
        $scope.currentState.track = track;
      return mopidy.playback.getState();
    })
    .then(function(state){
      $scope.currentState.paused = (state === 'paused');
      return mopidy.tracklist.getLength();
    })
    .then(function(length){
      $scope.currentState.length = length;
    })
    .done(function(){
      $scope.ready   = true;
      $scope.loading = false;
      $scope.$apply();
    });
  });
  mopidy.on('event:playbackStateChanged', function(event){
    $scope.currentState.paused = (event.new_state === 'paused');
    $scope.$apply();
  });
  mopidy.on('event:trackPlaybackStarted', function(event){
    $scope.currentState.track = event.tl_track.track;
    $scope.$apply();
  });
  mopidy.on('event:tracklistChanged', function(){
    mopidy.tracklist.getLength().done(function(length){
      $scope.currentState.length = length;
      $scope.$apply();
    });
  });

  $scope.printDuration = function(track){

    if(!track.length)
      return '';

    var _sum = parseInt(track.length / 1000);
    var _min = parseInt(_sum / 60);
    var _sec = _sum % 60;

    return '(' + _min + ':' + (_sec < 10 ? '0' + _sec : _sec) + ')' ;
  };

  $scope.togglePause = function(){
    var _fn = $scope.currentState.paused ? mopidy.playback.resume : mopidy.playback.pause;
    _fn().done();
  };

  $scope.search = function(){

    if(!$scope.searchField)
      return;

    $scope.message = [];
    $scope.loading = true;

    mopidy.library.search({
      'any' : [$scope.searchField]
    }).done(function(res){

      $scope.loading = false;
      $scope.tracks  = [];

      var _index = 0;
      var _found = true;
      while(_found){
        _found = false;
        for(var i = 0; i < res.length; i++){
          if(res[i].tracks && res[i].tracks[_index]){
            $scope.tracks.push(res[i].tracks[_index]);
            _found = true;
            mopidy.tracklist.filter({'uri': [res[i].tracks[_index].uri]}).done(function(matches){
    if (matches.length) {
      for (var i = 0; i < $scope.tracks.length; i++)
      {
        if ($scope.tracks[i].uri == matches[0].track.uri)
          $scope.tracks[i].disabled = true;
      }
      $scope.$apply();
    }
      });
          }
        }
        _index++;
      }

      $scope.$apply();
    });
  };

  $scope.addTrack = function(track){

    track.disabled = true;

    mopidy.tracklist
    .index()
    .then(function(index){
      return mopidy.tracklist.add({uris: [track.uri]});
    })
    .then(function(){
      // Notify user
      $scope.message = ['success', 'Next track: ' + track.name];
      $scope.$apply();
      return mopidy.tracklist.setConsume([true]);
    })
    .then(function(){
      return mopidy.playback.getState();
    })
    .then(function(state){
      // Get current state
      if(state !== 'stopped')
        return;
      // If stopped, start music NOW!
      return mopidy.playback.play();
    })
    .catch(function(){
      track.disabled = false;
      $scope.message = ['error', 'Unable to add track, please try again...'];
      $scope.$apply();
    })
    .done();
  };

  $scope.nextTrack = function(){
    var xmlHttp = new XMLHttpRequest();
    xmlHttp.open( "GET", "/party/vote", false ); // false for synchronous request
    xmlHttp.send( null );
    $scope.message = ['success', xmlHttp.responseText];
    $scope.$apply();
  };
});
<commit_msg>Update controller.js<commit_after>'use strict';

// TODO : add a mopidy service designed for angular, to avoid ugly $scope.$apply()...
angular.module('partyApp', [])
  .controller('MainController', function($scope) {

  // Scope variables

  $scope.message = [];
  $scope.tracks  = [];
  $scope.tltrack = "Aucune musique dans la playlist";
  $scope.loading = true;
  $scope.ready   = false;
  $scope.currentState = {
    paused : false,
    length : 0,
    track  : {
      length : 0,
      name   : 'Nothing playing, add some songs to get the party going!'
    }
  };

  // Initialize

  var mopidy = new Mopidy({
    'callingConvention' : 'by-position-or-by-name'
  });

  // Adding listenners

  mopidy.on('state:online', function () {
    mopidy.playback
    .getCurrentTrack()
    .then(function(track){
      if(track)
        $scope.currentState.track = track;
      return mopidy.playback.getState();
    })
    .then(function(state){
      $scope.currentState.paused = (state === 'paused');
      return mopidy.tracklist.getLength();
    })
    .then(function(length){
      $scope.currentState.length = length;
    })
    .done(function(){
      $scope.ready   = true;
      $scope.loading = false;
      $scope.$apply();
    });
  });
  mopidy.on('event:playbackStateChanged', function(event){
    $scope.currentState.paused = (event.new_state === 'paused');
    $scope.$apply();
  });
  mopidy.on('event:trackPlaybackStarted', function(event){
    $scope.currentState.track = event.tl_track.track;
    $scope.$apply();
  });
  mopidy.on('event:tracklistChanged', function(){
    mopidy.tracklist.getLength().done(function(length){
      $scope.currentState.length = length;
      $scope.$apply();
    });
  });

  $scope.printDuration = function(track){

    if(!track.length)
      return '';

    var _sum = parseInt(track.length / 1000);
    var _min = parseInt(_sum / 60);
    var _sec = _sum % 60;

    return '(' + _min + ':' + (_sec < 10 ? '0' + _sec : _sec) + ')' ;
  };

  $scope.togglePause = function(){
    var _fn = $scope.currentState.paused ? mopidy.playback.resume : mopidy.playback.pause;
    _fn().done();
  };

  $scope.search = function(){

    if(!$scope.searchField)
      return;

    $scope.message = [];
    $scope.loading = true;

    mopidy.library.search({
      'any' : [$scope.searchField]
    }).done(function(res){

      $scope.loading = false;
      $scope.tracks  = [];

      var _index = 0;
      var _found = true;
      while(_found){
        _found = false;
        for(var i = 0; i < res.length; i++){
          if(res[i].tracks && res[i].tracks[_index]){
            $scope.tracks.push(res[i].tracks[_index]);
            _found = true;
            mopidy.tracklist.filter({'uri': [res[i].tracks[_index].uri]}).done(function(matches){
    if (matches.length) {
      for (var i = 0; i < $scope.tracks.length; i++)
      {
        if ($scope.tracks[i].uri == matches[0].track.uri)
          $scope.tracks[i].disabled = true;
      }
      $scope.$apply();
    }
      });
          }
        }
        _index++;
      }

      $scope.$apply();
    });
  };

  $scope.addTrack = function(track){

    track.disabled = true;

    mopidy.tracklist
    .index()
    .then(function(index){
      return mopidy.tracklist.add({uris: [track.uri]});
    })
    .then(function(){
      // Notify user
      $scope.message = ['success', 'Next track: ' + track.name];
      $scope.$apply();
      return mopidy.tracklist.setConsume([true]);
    })
    .then(function(){
      return mopidy.playback.getState();
    })
    .then(function(state){
      // Get current state
      if(state !== 'stopped')
        return;
      // If stopped, start music NOW!
      return mopidy.playback.play();
    })
    .catch(function(){
      track.disabled = false;
      $scope.message = ['error', 'Unable to add track, please try again...'];
      $scope.$apply();
    })
    .done();
  };

  $scope.nextTrack = function(){
    var xmlHttp = new XMLHttpRequest();
    xmlHttp.open( "GET", "/party/vote", false ); // false for synchronous request
    xmlHttp.send( null );
    $scope.message = ['success', xmlHttp.responseText];
    $scope.$apply();
  };
});
<|endoftext|>


<commit_before>'use strict';

// TODO : add a mopidy service designed for angular, to avoid ugly $scope.$apply()...
angular.module('partyApp', [])
  .controller('MainController', function($scope) {

  // Scope variables

  $scope.message = [];
  $scope.tracks  = [];
  $scope.tltracks = ["Aucune musique dans la playlist"];
	$scope.timevote = 30;
  $scope.loading = true;
  $scope.ready   = false;
	$scope.trackvote = false;
  $scope.currentState = {
    paused : false,
    length : 0,
    track  : {
      length : 0,
      name   : 'Aucune musique dans la playlist, recherchez et ajoutez en !'
    }
  };
  // Initialize

  var mopidy = new Mopidy({
    'callingConvention' : 'by-position-or-by-name'
  });

  // Adding listenners

  mopidy.on('state:online', function () {

		mopidy.playback.getCurrentTrack()
    .then(function(track){
      if(track)
        $scope.currentState.track = track;
      return mopidy.playback.getState();
    })
    .then(function(state){
      $scope.currentState.paused = (state === 'paused');
      return mopidy.tracklist.getLength();
    })
    .then(function(length){
      $scope.currentState.length = length;
    })
    .done(function(){
      $scope.ready   = true;
      $scope.loading = false;
      $scope.$apply();
    });

		mopidy.tracklist.getTracks()
			.done(function(tltrack){
	    var keys = Object.keys(tltrack);
			var tracks = [];
			for (var i = 0, len = keys.length; i < len; i++) {
				tracks.push(tltrack[i]["name"]);
				$scope.tltracks = tracks;
			}
			$scope.$apply()
		});

  });
  mopidy.on('event:playbackStateChanged', function(event){
    $scope.currentState.paused = (event.new_state === 'paused');
    $scope.$apply();
  });
  mopidy.on('event:trackPlaybackStarted', function(event){
    $scope.currentState.track = event.tl_track.track;
    $scope.$apply();
  });
  mopidy.on('event:tracklistChanged', function(){
    mopidy.tracklist.getTracks()
			.done(function(tltrack){
			var keys = Object.keys(tltrack);
			var tracks = [];
			var tlenght = 	[];
			for (var i = 0, len = keys.length; i < len; i++) {
				tracks.push(tltrack[i]["name"]);
				tlenght.push(tltrack[i]["lenght"])
				$scope.tltracks = tracks;
			}
			$scope.$apply()
		});
	});

	function trackName(tlname) {
		return tlname.album.name === name;
	}

  $scope.printDuration = function(track){

    if(!track.length)
      return '';

    var _sum = parseInt(track.length / 1000);
    var _min = parseInt(_sum / 60);
    var _sec = _sum % 60;

    return '(' + _min + ':' + (_sec < 10 ? '0' + _sec : _sec) + ')' ;
  };

  $scope.togglePause = function(){
    var _fn = $scope.currentState.paused ? mopidy.playback.resume : mopidy.playback.pause;
    _fn().done();
  };

  $scope.search = function(){

    if(!$scope.searchField)
      return;

    $scope.message = [];
    $scope.loading = true;

    mopidy.library.search({
      'any' : [$scope.searchField]
    }).done(function(res){

      $scope.loading = false;
      $scope.tracks  = [];

      var _index = 0;
      var _found = true;
      while(_found){
        _found = false;
        for(var i = 0; i < res.length; i++){
          if(res[i].tracks && res[i].tracks[_index]){
            $scope.tracks.push(res[i].tracks[_index]);
            _found = true;
            mopidy.tracklist.filter({'uri': [res[i].tracks[_index].uri]}).done(function(matches){
    if (matches.length) {
      for (var i = 0; i < $scope.tracks.length; i++)
      {
        if ($scope.tracks[i].uri == matches[0].track.uri)
          $scope.tracks[i].disabled = true;
      }
      $scope.$apply();
    }
      });
          }
        }
        _index++;
      }

      $scope.$apply();
    });
  };

  $scope.addTrack = function(track){

    track.disabled = true;

    mopidy.tracklist
    .index()
    .then(function(index){
      return mopidy.tracklist.add({uris: [track.uri]});
    })
    .then(function(){
      // Notify user
      $scope.message = ['success', track.name + " à été ajouté à la playlist"];
      $scope.$apply();
      return mopidy.tracklist.setConsume([true]);
    })
    .then(function(){
      return mopidy.playback.getState();
    })
    .then(function(state){
      // Get current state
      if(state !== 'stopped')
        return;
      // If stopped, start music NOW!
      return mopidy.playback.play();
    })
    .catch(function(){
      track.disabled = false;
      $scope.message = ['error', "Impossible d'ajouter la musique, réessayez..."];
      $scope.$apply();
    })
    .done();
  };

  $scope.nextTrack = function(){
    var xmlHttp = new XMLHttpRequest();
    xmlHttp.open( "GET", "/party/vote", false ); // false for synchronous request
    xmlHttp.send( null );
    $scope.message = ['success', xmlHttp.responseText];
    $scope.$apply();
  };

$scope.notifyMe = function notifyMe() {

	// Voyons si le navigateur supporte les notifications
  if (!("Notification" in window)) {
    alert("Ce navigateur ne supporte pas les notifications desktop");
  }

  // Voyons si l'utilisateur est OK pour recevoir des notifications
  else if (Notification.permission === "granted") {
    // Si c'est ok, créons une notification
    var text = "Votez pour enlever une musique";
		var notification = new Notification("Vote en cours !", {body: text});
		window.navigator.vibrate(500);
  }

  // Sinon, nous avons besoin de la permission de l'utilisateur
  // Note : Chrome n'implémente pas la propriété statique permission
  // Donc, nous devons vérifier s'il n'y a pas 'denied' à la place de 'default'
  else if (Notification.permission !== 'denied') {
    Notification.requestPermission(function (permission) {

      // Quelque soit la réponse de l'utilisateur, nous nous assurons de stocker cette information
      if(!('permission' in Notification)) {
        Notification.permission = permission;
      }

      // Si l'utilisateur est OK, on crée une notification
      if (permission === "granted") {
				var text = "Votez pour enlever une musique";
				var notification = new Notification("Vote en cours !", {body: text});
				window.navigator.vibrate(500);
      }
    });
  }

	var i = 30;

var counterBack = setInterval(function(){
  i--;
  if (i > 0){
    $('.progress-bar').css('width', i*3 +'%');
		$scope.timevote = i;
		$scope.$apply()
  } else {
    clearInterval(counterBack);
  }

}, 1000);
  // Comme ça, si l'utlisateur a refusé toute notification, et que vous respectez ce choix,
  // il n'y a pas besoin de l'ennuyer à nouveau.
$scope.trackvote = true;
}

});
<commit_msg>Update controller.js<commit_after>'use strict';

// TODO : add a mopidy service designed for angular, to avoid ugly $scope.$apply()...
angular.module('partyApp', [])
  .controller('MainController', function($scope) {

  // Scope variables

  $scope.message = [];
  $scope.tracks  = [];
  $scope.tltracks = ["Aucune musique dans la playlist"];
	$scope.timevote = 30;
  $scope.loading = true;
  $scope.ready   = false;
	$scope.trackvote = false;
  $scope.currentState = {
    paused : false,
    length : 0,
    track  : {
      length : 0,
      name   : 'Aucune musique dans la playlist, recherchez et ajoutez en !'
    }
  };
  // Initialize

  var mopidy = new Mopidy({
    'callingConvention' : 'by-position-or-by-name'
  });

  // Adding listenners

  mopidy.on('state:online', function () {

		mopidy.playback.getCurrentTrack()
    .then(function(track){
      if(track)
        $scope.currentState.track = track;
      return mopidy.playback.getState();
    })
    .then(function(state){
      $scope.currentState.paused = (state === 'paused');
      return mopidy.tracklist.getLength();
    })
    .then(function(length){
      $scope.currentState.length = length;
    })
    .done(function(){
      $scope.ready   = true;
      $scope.loading = false;
      $scope.$apply();
    });

		mopidy.tracklist.getTracks()
			.done(function(tltrack){
	    var keys = Object.keys(tltrack);
			var tracks = [];
			for (var i = 0, len = keys.length; i < len; i++) {
				tracks.push(tltrack[i]["name"]);
				$scope.tltracks = tracks;
			}
			$scope.$apply()
		});

  });
  mopidy.on('event:playbackStateChanged', function(event){
    $scope.currentState.paused = (event.new_state === 'paused');
    $scope.$apply();
  });
  mopidy.on('event:trackPlaybackStarted', function(event){
    $scope.currentState.track = event.tl_track.track;
    $scope.$apply();
  });
  mopidy.on('event:tracklistChanged', function(){
    mopidy.tracklist.getTracks()
			.done(function(tltrack){
			var keys = Object.keys(tltrack);
			var tracks = [];
			var tlenght = 	[];
			for (var i = 0, len = keys.length; i < len; i++) {
				tracks.push(tltrack[i]["name"]);
				tlenght.push(tltrack[i]["lenght"])
				$scope.tltracks = tracks;
			}
			$scope.$apply()
		});
	});

	function trackName(tlname) {
		return tlname.album.name === name;
	}

  $scope.printDuration = function(track){

    if(!track.length)
      return '';

    var _sum = parseInt(track.length / 1000);
    var _min = parseInt(_sum / 60);
    var _sec = _sum % 60;

    return '(' + _min + ':' + (_sec < 10 ? '0' + _sec : _sec) + ')' ;
  };

  $scope.togglePause = function(){
    var _fn = $scope.currentState.paused ? mopidy.playback.resume : mopidy.playback.pause;
    _fn().done();
  };

  $scope.search = function(){

    if(!$scope.searchField)
      return;

    $scope.message = [];
    $scope.loading = true;

    mopidy.library.search({
      'any' : [$scope.searchField]
    }).done(function(res){

      $scope.loading = false;
      $scope.tracks  = [];

      var _index = 0;
      var _found = true;
      while(_found){
        _found = false;
        for(var i = 0; i < res.length; i++){
          if(res[i].tracks && res[i].tracks[_index]){
            $scope.tracks.push(res[i].tracks[_index]);
            _found = true;
            mopidy.tracklist.filter({'uri': [res[i].tracks[_index].uri]}).done(function(matches){
    if (matches.length) {
      for (var i = 0; i < $scope.tracks.length; i++)
      {
        if ($scope.tracks[i].uri == matches[0].track.uri)
          $scope.tracks[i].disabled = true;
      }
      $scope.$apply();
    }
      });
          }
        }
        _index++;
      }

      $scope.$apply();
    });
  };

  $scope.addTrack = function(track){

    track.disabled = true;

    mopidy.tracklist
    .index()
    .then(function(index){
      return mopidy.tracklist.add({uris: [track.uri]});
    })
    .then(function(){
      // Notify user
      $scope.message = ['success', track.name + " à été ajouté à la playlist"];
      $scope.$apply();
      return mopidy.tracklist.setConsume([true]);
    })
    .then(function(){
      return mopidy.playback.getState();
    })
    .then(function(state){
      // Get current state
      if(state !== 'stopped')
        return;
      // If stopped, start music NOW!
      return mopidy.playback.play();
    })
    .catch(function(){
      track.disabled = false;
      $scope.message = ['error', "Impossible d'ajouter la musique, réessayez..."];
      $scope.$apply();
    })
    .done();
  };

  $scope.nextTrack = function(){
    var xmlHttp = new XMLHttpRequest();
    xmlHttp.open( "GET", "/party/vote", false ); // false for synchronous request
    xmlHttp.send( null );
    $scope.message = ['success', xmlHttp.responseText];
    $scope.$apply();
  };

$scope.notifyMe = function notifyMe() {

	// Voyons si le navigateur supporte les notifications
  if (!("Notification" in window)) {
    alert("Ce navigateur ne supporte pas les notifications desktop");
  }

  // Voyons si l'utilisateur est OK pour recevoir des notifications
  else if (Notification.permission === "granted") {
    // Si c'est ok, créons une notification
    var text = "Votez pour enlever une musique";
		var notification = new Notification("Vote en cours !", {body: text});
		window.navigator.vibrate(500);
  }

  // Sinon, nous avons besoin de la permission de l'utilisateur
  // Note : Chrome n'implémente pas la propriété statique permission
  // Donc, nous devons vérifier s'il n'y a pas 'denied' à la place de 'default'
  else if (Notification.permission !== 'denied') {
    Notification.requestPermission(function (permission) {

      // Quelque soit la réponse de l'utilisateur, nous nous assurons de stocker cette information
      if(!('permission' in Notification)) {
        Notification.permission = permission;
      }

      // Si l'utilisateur est OK, on crée une notification
      if (permission === "granted") {
				var text = "Votez pour enlever une musique";
				var notification = new Notification("Vote en cours !", {body: text});
				window.navigator.vibrate(500);
      }
    });
  }

	var i = 30;
	var counterBack = setInterval(function(){
		i--;
		if (i >= 0){
			$('.progress-bar').css('width', i*3+6 +'%');
			$scope.timevote = i;
			$scope.$apply()
		}
		else{
			clearInterval(counterBack);
		}
	}, 1000);

$scope.trackvote = true;
}

});
<|endoftext|>


<commit_before>var Node = require("../node.js").Node;

function Converter() {
}

Converter.prototype = {
  exportOptions: {
    headerOffset: 1,
    exportFromLineNumber: false,
    suppressSubScriptHandling: false,
    suppressAutoLink: false
  },

  untitled: "Untitled",
  result: null,

  // TODO: Manage TODO lists

  initialize: function (orgDocument, exportOptions) {
    this.orgDocument = orgDocument;
    this.documentOptions = orgDocument.options || {};
    this.exportOptions = exportOptions || {};

    this.headers = [];
    this.headerOffset =
      typeof this.exportOptions.headerOffset === "number" ? this.exportOptions.headerOffset : 1;
    this.sectionNumbers = [0];
  },

  createTocItem: function (headerNode, parentTocs) {
      var childTocs = [];
      childTocs.parent = parentTocs;
      var tocItem = { headerNode: headerNode, childTocs: childTocs };
      return tocItem;
  },

  computeToc: function (exportTocLevel) {
    if (typeof exportTocLevel !== "number")
      exportTocLevel = Infinity;

    var toc = [];
    toc.parent = null;

    var previousLevel = 1;
    var currentTocs = toc;  // first

    for (var i = 0; i < this.headers.length; ++i) {
      var headerNode = this.headers[i];

      if (headerNode.level > exportTocLevel)
        continue;

      var levelDiff = headerNode.level - previousLevel;
      if (levelDiff > 0) {
        for (var j = 0; j < levelDiff; ++j) {
          if (currentTocs.length === 0) {
            // Create a dummy tocItem
            var dummyHeader = Node.createHeader([], {
              level: previousLevel + j
            });
            dummyHeader.sectionNumberText = "";
            currentTocs.push(this.createTocItem(dummyHeader, currentTocs));
          }
          currentTocs = currentTocs[currentTocs.length - 1].childTocs;
        }
      } else if (levelDiff < 0) {
        levelDiff = -levelDiff;
        for (var k = 0; k < levelDiff; ++k) {
          currentTocs = currentTocs.parent;
        }
      }

      currentTocs.push(this.createTocItem(headerNode, currentTocs));

      previousLevel = headerNode.level;
    }

    return toc;
  },

  convertNode: function (node, recordHeader) {
    var childText = node.children ? this.convertNodes(node.children, recordHeader) : "";
    var text;

    var auxData = this.computeAuxDataForNode(node);

    switch (node.type) {
    case Node.types.header:
      // Parse task status
      var taskStatus = null;
      if (childText.indexOf("TODO ") === 0)
        taskStatus = "todo";
      else if (childText.indexOf("DONE ") === 0)
        taskStatus = "done";

      // Compute section number
      var sectionNumberText = null;
      if (recordHeader) {
        var thisHeaderLevel = node.level;
        var previousHeaderLevel = this.sectionNumbers.length;
        if (thisHeaderLevel > previousHeaderLevel) {
          // Fill missing section number
          var levelDiff = thisHeaderLevel - previousHeaderLevel;
          for (var j = 0; j < levelDiff; ++j) {
            this.sectionNumbers[thisHeaderLevel - 1 - j] = 0; // Extend
          }
        } else if (thisHeaderLevel < previousHeaderLevel) {
          this.sectionNumbers.length = thisHeaderLevel; // Collapse
        }
        this.sectionNumbers[thisHeaderLevel - 1]++;
        sectionNumberText = this.sectionNumbers.join(".");
        node.sectionNumberText = sectionNumberText; // Can be used in ToC
      }

      text = this.convertHeader(node, childText, auxData,
                                taskStatus, sectionNumberText);

      if (recordHeader)
        this.headers.push(node);
      break;
    case Node.types.orderedList:
      text = this.convertOrderedList(node, childText, auxData);
      break;
    case Node.types.unorderedList:
      text = this.convertUnorderedList(node, childText, auxData);
      break;
    case Node.types.definitionList:
      text = this.convertDefinitionList(node, childText, auxData);
      break;
    case Node.types.listElement:
      if (node.isDefinitionList) {
        var termText = this.convertNodes(node.term, recordHeader);
        text = this.convertDefinitionItem(node, childText, auxData,
                                          termText, childText);
      } else {
        text = this.convertListItem(node, childText, auxData);
      }
      break;
    case Node.types.paragraph:
      text = this.convertParagraph(node, childText, auxData);
      break;
    case Node.types.preformatted:
      text = this.convertPreformatted(node, childText, auxData);
      break;
    case Node.types.table:
      text = this.convertTable(node, childText, auxData);
      break;
    case Node.types.tableRow:
      text = this.convertTableRow(node, childText, auxData);
      break;
    case Node.types.tableCell:
      if (node.isHeader)
        text = this.convertTableHeader(node, childText, auxData);
      else
        text = this.convertTableCell(node, childText, auxData);
      break;
    case Node.types.horizontalRule:
      text = this.convertHorizontalRule(node, childText, auxData);
      break;
      // ============================================================ //
      // Inline
      // ============================================================ //
    case Node.types.inlineContainer:
      text = this.convertInlineContainer(node, childText, auxData);
      break;
    case Node.types.bold:
      text = this.convertBold(node, childText, auxData);
      break;
    case Node.types.italic:
      text = this.convertItalic(node, childText, auxData);
      break;
    case Node.types.underline:
      text = this.convertUnderline(node, childText, auxData);
      break;
    case Node.types.code:
      text = this.convertCode(node, childText, auxData);
      break;
    case Node.types.dashed:
      text = this.convertDashed(node, childText, auxData);
      break;
    case Node.types.link:
      text = this.convertLink(node, childText, auxData);
      break;
    case Node.types.directive:
      switch (node.directiveName) {
      case "quote":
        text = this.convertQuote(node, childText, auxData);
        break;
      case "example":
        text = this.convertExample(node, childText, auxData);
        break;
      case "src":
        text = this.convertSrc(node, childText, auxData);
        break;
      default:
        text = childText;
      }
      break;
    default:
      var baseText = null;
      if (node.type === Node.types.text) {
        baseText = node.value;
      } else if (typeof node === "string") {
        baseText = node;
      } else {
        throw "Unknown node type: " + node.type;
      }
      text = this.convertText(baseText);
      break;
    }

    if (typeof this.postProcess === "function") {
      text = this.postProcess(node, text);
    }

    return text;
  },

  convertText: function (text) {
    var escapedText = this.escapeSpecialChars(text);
    if (!this.exportOptions.suppressSubScriptHandling)
      escapedText = this.makeSubscripts(escapedText);
    if (!this.exportOptions.suppressAutoLink)
      escapedText = this.linkURL(escapedText);
    return escapedText;
  },

  convertNodes: function (nodes, recordHeader) {
    return nodes.map(function (node) {
      return this.convertNode(node, recordHeader);
    }, this).join("");
  },

  getNodeTextContent: function (node) {
    if (node.type === Node.types.text)
      return this.escapeSpecialChars(node.value);
    else
      return node.children ? node.children.map(this.getNodeTextContent, this).join("") : "";
  },

  // @Override
  escapeSpecialChars: function (text) {
    throw "Implement escapeSpecialChars";
  },

  // http://daringfireball.net/2010/07/improved_regex_for_matching_urls
  urlPattern: /\b(?:https?:\/\/|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’])/i,

  // @Override
  linkURL: function (text) {
    var self = this;
    return text.replace(this.urlPattern, function (matched) {
      if (matched.indexOf("://") < 0)
        matched = "http://" + matched;
      return self.makeLink(matched);
    });
  },

  makeLink: function (url) {
    throw "Implement makeLink";
  },

  makeSubscripts: function (text) {
    if (this.documentOptions["^"] === "{}")
      return text.replace(/\b([^_ \t]*)_{([^}]*)}/g,
                          this.makeSubscript);
    else if (this.documentOptions["^"])
      return text.replace(/\b([^_ \t]*)_([^_]*)\b/g,
                          this.makeSubscript);
    else
      return text;
  },

  makeSubscript: function (match, body, subscript) {
    throw "Implement makeSubscript";
  },

  imageExtensionPattern: new RegExp("(" + [
    "bmp", "png", "jpeg", "jpg", "gif", "tiff",
    "tif", "xbm", "xpm", "pbm", "pgm", "ppm"
  ].join("|") + ")$")
};

if (typeof exports !== "undefined")
  exports.Converter = Converter;
<commit_msg>Allow images' extensions in capital<commit_after>var Node = require("../node.js").Node;

function Converter() {
}

Converter.prototype = {
  exportOptions: {
    headerOffset: 1,
    exportFromLineNumber: false,
    suppressSubScriptHandling: false,
    suppressAutoLink: false
  },

  untitled: "Untitled",
  result: null,

  // TODO: Manage TODO lists

  initialize: function (orgDocument, exportOptions) {
    this.orgDocument = orgDocument;
    this.documentOptions = orgDocument.options || {};
    this.exportOptions = exportOptions || {};

    this.headers = [];
    this.headerOffset =
      typeof this.exportOptions.headerOffset === "number" ? this.exportOptions.headerOffset : 1;
    this.sectionNumbers = [0];
  },

  createTocItem: function (headerNode, parentTocs) {
      var childTocs = [];
      childTocs.parent = parentTocs;
      var tocItem = { headerNode: headerNode, childTocs: childTocs };
      return tocItem;
  },

  computeToc: function (exportTocLevel) {
    if (typeof exportTocLevel !== "number")
      exportTocLevel = Infinity;

    var toc = [];
    toc.parent = null;

    var previousLevel = 1;
    var currentTocs = toc;  // first

    for (var i = 0; i < this.headers.length; ++i) {
      var headerNode = this.headers[i];

      if (headerNode.level > exportTocLevel)
        continue;

      var levelDiff = headerNode.level - previousLevel;
      if (levelDiff > 0) {
        for (var j = 0; j < levelDiff; ++j) {
          if (currentTocs.length === 0) {
            // Create a dummy tocItem
            var dummyHeader = Node.createHeader([], {
              level: previousLevel + j
            });
            dummyHeader.sectionNumberText = "";
            currentTocs.push(this.createTocItem(dummyHeader, currentTocs));
          }
          currentTocs = currentTocs[currentTocs.length - 1].childTocs;
        }
      } else if (levelDiff < 0) {
        levelDiff = -levelDiff;
        for (var k = 0; k < levelDiff; ++k) {
          currentTocs = currentTocs.parent;
        }
      }

      currentTocs.push(this.createTocItem(headerNode, currentTocs));

      previousLevel = headerNode.level;
    }

    return toc;
  },

  convertNode: function (node, recordHeader) {
    var childText = node.children ? this.convertNodes(node.children, recordHeader) : "";
    var text;

    var auxData = this.computeAuxDataForNode(node);

    switch (node.type) {
    case Node.types.header:
      // Parse task status
      var taskStatus = null;
      if (childText.indexOf("TODO ") === 0)
        taskStatus = "todo";
      else if (childText.indexOf("DONE ") === 0)
        taskStatus = "done";

      // Compute section number
      var sectionNumberText = null;
      if (recordHeader) {
        var thisHeaderLevel = node.level;
        var previousHeaderLevel = this.sectionNumbers.length;
        if (thisHeaderLevel > previousHeaderLevel) {
          // Fill missing section number
          var levelDiff = thisHeaderLevel - previousHeaderLevel;
          for (var j = 0; j < levelDiff; ++j) {
            this.sectionNumbers[thisHeaderLevel - 1 - j] = 0; // Extend
          }
        } else if (thisHeaderLevel < previousHeaderLevel) {
          this.sectionNumbers.length = thisHeaderLevel; // Collapse
        }
        this.sectionNumbers[thisHeaderLevel - 1]++;
        sectionNumberText = this.sectionNumbers.join(".");
        node.sectionNumberText = sectionNumberText; // Can be used in ToC
      }

      text = this.convertHeader(node, childText, auxData,
                                taskStatus, sectionNumberText);

      if (recordHeader)
        this.headers.push(node);
      break;
    case Node.types.orderedList:
      text = this.convertOrderedList(node, childText, auxData);
      break;
    case Node.types.unorderedList:
      text = this.convertUnorderedList(node, childText, auxData);
      break;
    case Node.types.definitionList:
      text = this.convertDefinitionList(node, childText, auxData);
      break;
    case Node.types.listElement:
      if (node.isDefinitionList) {
        var termText = this.convertNodes(node.term, recordHeader);
        text = this.convertDefinitionItem(node, childText, auxData,
                                          termText, childText);
      } else {
        text = this.convertListItem(node, childText, auxData);
      }
      break;
    case Node.types.paragraph:
      text = this.convertParagraph(node, childText, auxData);
      break;
    case Node.types.preformatted:
      text = this.convertPreformatted(node, childText, auxData);
      break;
    case Node.types.table:
      text = this.convertTable(node, childText, auxData);
      break;
    case Node.types.tableRow:
      text = this.convertTableRow(node, childText, auxData);
      break;
    case Node.types.tableCell:
      if (node.isHeader)
        text = this.convertTableHeader(node, childText, auxData);
      else
        text = this.convertTableCell(node, childText, auxData);
      break;
    case Node.types.horizontalRule:
      text = this.convertHorizontalRule(node, childText, auxData);
      break;
      // ============================================================ //
      // Inline
      // ============================================================ //
    case Node.types.inlineContainer:
      text = this.convertInlineContainer(node, childText, auxData);
      break;
    case Node.types.bold:
      text = this.convertBold(node, childText, auxData);
      break;
    case Node.types.italic:
      text = this.convertItalic(node, childText, auxData);
      break;
    case Node.types.underline:
      text = this.convertUnderline(node, childText, auxData);
      break;
    case Node.types.code:
      text = this.convertCode(node, childText, auxData);
      break;
    case Node.types.dashed:
      text = this.convertDashed(node, childText, auxData);
      break;
    case Node.types.link:
      text = this.convertLink(node, childText, auxData);
      break;
    case Node.types.directive:
      switch (node.directiveName) {
      case "quote":
        text = this.convertQuote(node, childText, auxData);
        break;
      case "example":
        text = this.convertExample(node, childText, auxData);
        break;
      case "src":
        text = this.convertSrc(node, childText, auxData);
        break;
      default:
        text = childText;
      }
      break;
    default:
      var baseText = null;
      if (node.type === Node.types.text) {
        baseText = node.value;
      } else if (typeof node === "string") {
        baseText = node;
      } else {
        throw "Unknown node type: " + node.type;
      }
      text = this.convertText(baseText);
      break;
    }

    if (typeof this.postProcess === "function") {
      text = this.postProcess(node, text);
    }

    return text;
  },

  convertText: function (text) {
    var escapedText = this.escapeSpecialChars(text);
    if (!this.exportOptions.suppressSubScriptHandling)
      escapedText = this.makeSubscripts(escapedText);
    if (!this.exportOptions.suppressAutoLink)
      escapedText = this.linkURL(escapedText);
    return escapedText;
  },

  convertNodes: function (nodes, recordHeader) {
    return nodes.map(function (node) {
      return this.convertNode(node, recordHeader);
    }, this).join("");
  },

  getNodeTextContent: function (node) {
    if (node.type === Node.types.text)
      return this.escapeSpecialChars(node.value);
    else
      return node.children ? node.children.map(this.getNodeTextContent, this).join("") : "";
  },

  // @Override
  escapeSpecialChars: function (text) {
    throw "Implement escapeSpecialChars";
  },

  // http://daringfireball.net/2010/07/improved_regex_for_matching_urls
  urlPattern: /\b(?:https?:\/\/|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’])/i,

  // @Override
  linkURL: function (text) {
    var self = this;
    return text.replace(this.urlPattern, function (matched) {
      if (matched.indexOf("://") < 0)
        matched = "http://" + matched;
      return self.makeLink(matched);
    });
  },

  makeLink: function (url) {
    throw "Implement makeLink";
  },

  makeSubscripts: function (text) {
    if (this.documentOptions["^"] === "{}")
      return text.replace(/\b([^_ \t]*)_{([^}]*)}/g,
                          this.makeSubscript);
    else if (this.documentOptions["^"])
      return text.replace(/\b([^_ \t]*)_([^_]*)\b/g,
                          this.makeSubscript);
    else
      return text;
  },

  makeSubscript: function (match, body, subscript) {
    throw "Implement makeSubscript";
  },

  imageExtensionPattern: new RegExp("(" + [
    "bmp", "png", "jpeg", "jpg", "gif", "tiff",
    "tif", "xbm", "xpm", "pbm", "pgm", "ppm"
  ].join("|") + ")$", "i")
};

if (typeof exports !== "undefined")
  exports.Converter = Converter;
<|endoftext|>