<commit_before>/*global Wirecloud*/

(function () {

    "use strict";

    var anchor_element = document.createElement('a');
    anchor_element.href = Wirecloud.URLs.LOCAL_REPOSITORY;
    var base_url = anchor_element.href;
    if (base_url[base_url.length - 1] !== '/') {
        base_url += '/';
    }
    base_url += 'static/';

    var create_workspace = function create_workspace(autoAction) {
        LayoutManagerFactory.getInstance().changeCurrentView('workspace');
        opManager.addWorkspace('Basic concepts tutorial', {
            allow_renaming: true,
            onSuccess: function () {
                autoAction.nextHandler();
            }
        });
    };

    var build_static_url = function build_static_url(path) {
        return base_url + path;
    };

    var reset_marketplace_view = function reset_marketplace_view(autoAction) {
        if (LayoutManagerFactory.getInstance().viewsByName.marketplace.viewsByName.local != null) {
            LayoutManagerFactory.getInstance().viewsByName.marketplace.changeCurrentMarket('local');
            LayoutManagerFactory.getInstance().viewsByName.marketplace.viewsByName.local.home();
        }

        autoAction.nextHandler();
    };

    var install_flickr = function install_flickr(autoAction) {
        if (!Wirecloud.LocalCatalogue.resourceExistsId('CoNWeT/flickr/2.7')) {
            Wirecloud.LocalCatalogue.addResourceFromURL(build_static_url('tutorial-data/CoNWeT_flickr_2.7.wgt'), {
                packaged: true,
                onSuccess: autoAction.nextHandler.bind(autoAction)
            });
        } else {
            autoAction.nextHandler();
        }
    };

    var install_multimediaViewer = function install_multimediaViewer(autoAction) {
        if (!Wirecloud.LocalCatalogue.resourceExistsId('CoNWeT/multimedia-viewer/1.0.1')) {
            Wirecloud.LocalCatalogue.addResourceFromURL(build_static_url('tutorial-data/CoNWeT_multimedia-viewer_1.0.1.wgt'), {
                packaged: true,
                onSuccess: autoAction.nextHandler.bind(autoAction)
            });
        } else {
            autoAction.nextHandler();
        }
    };

    var install_search = function install_search(autoAction) {
        if (!Wirecloud.LocalCatalogue.resourceExistsId('CoNWeT/search/1.3.1')) {
            Wirecloud.LocalCatalogue.addResourceFromURL(build_static_url('tutorial-data/CoNWeT_search_1.3.1.wgt'), {
                packaged: true,
                onSuccess: autoAction.nextHandler.bind(autoAction)
            });
        } else {
            autoAction.nextHandler();
        }
    };

    var install_youtubeSearch = function install_youtubeSearch(autoAction) {
        if (!Wirecloud.LocalCatalogue.resourceExistsId('CoNWeT/youtube-video-search/2.45.0')) {
            Wirecloud.LocalCatalogue.addResourceFromURL(build_static_url('tutorial-data/CoNWeT_youtube-video-search_2.45.0.wgt'), {
                packaged: true,
                onSuccess: autoAction.nextHandler.bind(autoAction)
            });
        } else {
            autoAction.nextHandler();
        }
    };

    var marketplaceButton = function() {
        return document.getElementById("wirecloud_header").getElementsByClassName('marketplace')[0];
    };

    var ResizeButton = function() {
        return document.getElementsByClassName("rightResizeHandle")[0];
    };

    var widgetHeader = function() {
        return document.getElementsByClassName("widget_menu")[0].getElementsByTagName('span')[0];
    };

    var refreshMarketplace = function refreshMarketplace(autoAction) {
        LayoutManagerFactory.getInstance().viewsByName.marketplace.viewsByName.local.refresh_search_results();
        autoAction.nextHandler();
    };

    var searchAction = function(autoAction, elem) {
        elem.value = "";
        setTimeout(function() {elem.value = 'y'}, 1000);
        setTimeout(function() {elem.value += 'o'}, 1300);
        setTimeout(function() {elem.value += 'u'}, 1600);
        setTimeout(function() {elem.value += 't'}, 1900);
        setTimeout(function() {elem.value += 'u'}, 2200);
        setTimeout(function() {elem.value += 'b'}, 2500);
        setTimeout(function() {elem.value += 'e'}, 2800);
        setTimeout(function() {elem.value += ' '}, 3100);
        setTimeout(function() {elem.value += 's'}, 3400);
        setTimeout(function() {elem.value += 'e'}, 3700);
        setTimeout(function() {elem.value += 'a'}, 4000);
        setTimeout(function() {elem.value += 'r'}, 4300);
        setTimeout(function() {elem.value += 'c'}, 4600);
        setTimeout(function() {
            elem.value += 'h';
            LayoutManagerFactory.getInstance().viewsByName.marketplace.viewsByName.local.viewsByName.search._onSearchInput();
        }, 4900);
        setTimeout(function() {autoAction.nextHandler();}, 6500);
    };

    var searchAction2 = function(autoAction, elem) {
        elem.value = "";
        setTimeout(function() {elem.value = 's'}, 1000);
        setTimeout(function() {elem.value += 'e'}, 1300);
        setTimeout(function() {elem.value += 'a'}, 1600);
        setTimeout(function() {elem.value += 'r'}, 1900);
        setTimeout(function() {elem.value += 'c'}, 2200);
        setTimeout(function() {
            elem.value += 'h';
            LayoutManagerFactory.getInstance().viewsByName.marketplace.viewsByName.local.viewsByName.search._onSearchInput();
        }, 2500);
        setTimeout(function() {autoAction.nextHandler();}, 4100);
    };

    var searchInputMarketplace = function() {
        return LayoutManagerFactory.getInstance().viewsByName.marketplace.alternatives.getCurrentAlternative().viewsByName.search.wrapperElement.getElementsByClassName('simple_search_text')[0];
    };

    var findElementByTextContent = function findElementByTextContent(nodes, text) {
        var i;
        for (i = 0; i < nodes.length; i ++) {
            if (nodes[i].textContent.toLowerCase() == text.toLowerCase()) {
                return nodes[i];
            }
        }
        return null;
    };

    var addbuttonSearch = function() {
        var resources, widget;

        resources = LayoutManagerFactory.getInstance().viewsByName.marketplace.alternatives.getCurrentAlternative().viewsByName.search.wrapperElement.getElementsByClassName('resource_name');
        widget = findElementByTextContent(resources, "Search");
        return widget.parentNode.getElementsByClassName("mainbutton")[0];
    };

    var addbuttonYoutubeSearch = function() {
        var resources, widget;

        resources = LayoutManagerFactory.getInstance().viewsByName.marketplace.alternatives.getCurrentAlternative().viewsByName.search.wrapperElement.getElementsByClassName('resource_name');
        widget = findElementByTextContent(resources, "Youtube Video Search");
        return widget.parentNode.getElementsByClassName("mainbutton")[0];
    };

    var getDocument = function() {
        return document;
    };

    var wiringEditorButton = function() {
        return document.getElementById("wirecloud_header").getElementsByClassName('wiring')[0];
    };

    var get_menubar = function get_menubar() {
        var wiring_editor = document.getElementsByClassName('wiring_editor')[0];
        return wiring_editor.getElementsByClassName('menubar')[0];
    };

    /*
    var getMenuWorkspaceButton = function() {
        return document.getElementById('wirecloud_breadcrum').getElementsByClassName('icon-menu')[0];
    };

    var getAdminButton = function() {
        var header = document.getElementById('wirecloud_header');
        var elements = header.getElementsByClassName('user_menu_wrapper');
        if (elements.length == 0) {
            elements = header.getElementsByClassName('nav pull-right');
        }
        return elements[0];
    };*/

    var get_yvs_mini_widget = function get_yvs_mini_widget() {
        var yvs_id = opManager.activeWorkspace.getIWidgets()[0].id;
        return LayoutManagerFactory.getInstance().viewsByName.wiring.mini_widgets[yvs_id].wrapperElement;
    };

    var deploy_tutorial_menu = function deploy_tutorial_menu(autoAction) {
        var header = document.getElementById('wirecloud_header');
        var button = header.getElementsByClassName('arrow-down-settings')[0];
        button.click();
        autoAction.nextHandler();
    };

    var get_tutorial_menu_item = function get_tutorial_menu_item() {
        var popup_menu = document.getElementsByClassName('popup_menu')[0];
        return findElementByTextContent(popup_menu.getElementsByClassName('menu_item'), 'Tutorials');
    };

    Wirecloud.TutorialCatalogue.add(new Wirecloud.ui.Tutorial(gettext('Basic concepts'), [
            // Editor
            {'type': 'simpleDescription', 'title': gettext('Wirecloud Basic Tutorial'), 'msg': gettext("
Welcome to Wirecloud!!

This tutorial will show you the basic concepts behind Wirecloud.
"), 'elem': null},
            {'type': 'autoAction', 'action': create_workspace},
            {'type': 'simpleDescription', 'title': gettext('Wirecloud Basic Tutorial'), 'msg': gettext("
This is the Editor view. In this view, you can use and modify your workspaces. Currently you are in a newly created workspace: Basic concepts tutorial. This workspace is empty, so the first step is to add widgets from the Wirecloud marketplace.
"), 'elem': null},
            // MarketPlace
            {'type': 'autoAction', 'action': reset_marketplace_view},
            {'type': 'userAction', 'msg': gettext("Click Marketplace"), 'elem': marketplaceButton, 'pos': 'downLeft'},
            {'type': 'simpleDescription', 'title': gettext('Wirecloud Basic Tutorial'), 'msg': gettext('
This is the Marketplace view. In this view you can browse the Mashable Application Components (Widgets, operators and Mashups) that are currently available to you. Also, you can browse external catalogues too.

In next steps we need some widgets, so we are going to install them for you in the catalogue. You can safetly uninstall these widgets after finishing the tutorial.

'), 'elem': null},
            {'type': 'autoAction', 'action': install_flickr},
            {'type': 'autoAction', 'action': install_multimediaViewer},
            {'type': 'autoAction', 'action': install_search},
            {'type': 'autoAction', 'action': install_youtubeSearch},
            {'type': 'autoAction', 'action': refreshMarketplace},
            {'type': 'simpleDescription', 'title': gettext('Wirecloud Basic Tutorial'), 'msg': gettext("
Ok, widgets have been installed successfuly and you can find them in your local catalogue.

Next step is to add the YouTube Video Search widget to the workspace. You can directly select the widget or, alternatively, you can reduce the list using the keyword search feature.
"), 'elem': null},
            {'type': 'autoAction', 'msg': gettext('Typing "youtube search" we can filter widgets that contains in their name or description these words'), 'elem': searchInputMarketplace, 'pos': 'downRight', 'action': searchAction},
            {'type': 'userAction', 'msg': gettext("Once you have the results, you can add the widget. So click Add to workspace"), 'elem': addbuttonYoutubeSearch, 'pos': 'downRight'},
            {'type': 'simpleDescription', 'title': gettext('Wirecloud Basic Tutorial'), 'msg': gettext("
Great! That was easy, wasn't it?.

Let's continue adding the Search widget.
"), 'elem': null},
            {'type': 'userAction', 'msg': gettext("Click Marketplace"), 'elem': marketplaceButton, 'pos': 'downLeft'},
            {'type': 'autoAction', 'msg': gettext('Typing search...'), 'elem': searchInputMarketplace, 'pos': 'downRight', 'action': searchAction2},
            {'type': 'userAction', 'msg': gettext("Click Add to workspace"), 'elem': addbuttonSearch, 'pos': 'downRight'},

            {'type': 'simpleDescription', 'title': gettext('Wirecloud Basic Tutorial'), 'msg': gettext("
One of the main features of Wirecloud is that you can edit your workspaces' layout not only by adding and removing widgets, but also moving and resizing them.
"), 'elem': null},
            {'type': 'userAction', 'msg': gettext("Drag & drop to resize the widget"), 'elem': ResizeButton, 'pos': 'downRight', 'event': 'mouseup', 'eventToDeactivateLayer': 'mousedown'},
            {'type': 'userAction', 'msg': gettext("Drag & drop to move the widget"), 'elem': widgetHeader, 'pos': 'downRight', 'event': 'mouseup', 'eventToDeactivateLayer': 'mousedown', 'elemToApplyNextStepEvent': getDocument},

            //{'type': 'simpleDescription', 'title': gettext('Wirecloud Basic Tutorial'), 'msg': gettext("
Play with the widgets of the wokspace moving, resizing, ... widgets as you like before going into the Wiring view.
"), 'elem': null},
            //{'type': 'userAction', 'msg': gettext("Click Wiring to continue"), 'elem': wiringEditorButton, 'pos': 'downLeft', 'eventToDeactivateLayer': 'mousemove', 'elemToApplyDeactivateLayerEvent': getDocument, 'disableElems': [getMenuWorkspaceButton, getAdminButton]},
            {'type': 'userAction', 'msg': gettext("Click Wiring"), 'elem': wiringEditorButton, 'pos': 'downLeft'},

            // WiringEditor
            {'type': 'simpleDescription', 'title': gettext('Wirecloud Basic Tutorial'), 'msg': gettext("
This is the Wiring view.

Here you can wire widgets and operators toghether turning your workspace into and application mashup.
"), 'elem': null},
            {'type': 'simpleDescription', 'title': gettext('Wirecloud Basic Tutorial'), 'msg': gettext("
In left menu you can find all widgets added into your workspace.
"), 'elem': get_menubar},

            {'type': 'userAction', 'msg': gettext("Drag & drop Youtube Video Search"), 'elem': get_yvs_mini_widget, 'pos': 'downRight', 'event': 'mouseup', 'eventToDeactivateLayer': 'mousedown', 'elemToApplyNextStepEvent': getDocument},

            {'type': 'autoAction', 'action': deploy_tutorial_menu},
            {'type': 'simpleDescription', 'title': gettext('Wirecloud Basic Tutorial'), 'msg': gettext("
This is the end of this tutorial. Remember that you can allways go to the Tutorial menu for others.
"), 'elem': get_tutorial_menu_item},
    ]));

})();
<commit_msg>Basic Concepts tutorial improvements<commit_after>/*global Wirecloud*/

(function () {

    "use strict";

    var anchor_element = document.createElement('a');
    anchor_element.href = Wirecloud.URLs.LOCAL_REPOSITORY;
    var base_url = anchor_element.href;
    if (base_url[base_url.length - 1] !== '/') {
        base_url += '/';
    }
    base_url += 'static/';

    var create_workspace = function create_workspace(autoAction) {
        LayoutManagerFactory.getInstance().changeCurrentView('workspace');
        opManager.addWorkspace('Basic concepts tutorial', {
            allow_renaming: true,
            onSuccess: function () {
                autoAction.nextHandler();
            }
        });
    };

    var build_static_url = function build_static_url(path) {
        return base_url + path;
    };

    var reset_marketplace_view = function reset_marketplace_view(autoAction) {
        if (LayoutManagerFactory.getInstance().viewsByName.marketplace.viewsByName.local != null) {
            LayoutManagerFactory.getInstance().viewsByName.marketplace.changeCurrentMarket('local');
            LayoutManagerFactory.getInstance().viewsByName.marketplace.viewsByName.local.home();
        }

        autoAction.nextHandler();
    };

    var install_flickr = function install_flickr(autoAction) {
        if (!Wirecloud.LocalCatalogue.resourceExistsId('CoNWeT/flickr/2.7')) {
            Wirecloud.LocalCatalogue.addResourceFromURL(build_static_url('tutorial-data/CoNWeT_flickr_2.7.wgt'), {
                packaged: true,
                onSuccess: autoAction.nextHandler.bind(autoAction)
            });
        } else {
            autoAction.nextHandler();
        }
    };

    var install_multimediaViewer = function install_multimediaViewer(autoAction) {
        if (!Wirecloud.LocalCatalogue.resourceExistsId('CoNWeT/multimedia-viewer/1.0.1')) {
            Wirecloud.LocalCatalogue.addResourceFromURL(build_static_url('tutorial-data/CoNWeT_multimedia-viewer_1.0.1.wgt'), {
                packaged: true,
                onSuccess: autoAction.nextHandler.bind(autoAction)
            });
        } else {
            autoAction.nextHandler();
        }
    };

    var install_search = function install_search(autoAction) {
        if (!Wirecloud.LocalCatalogue.resourceExistsId('CoNWeT/search/1.3.1')) {
            Wirecloud.LocalCatalogue.addResourceFromURL(build_static_url('tutorial-data/CoNWeT_search_1.3.1.wgt'), {
                packaged: true,
                onSuccess: autoAction.nextHandler.bind(autoAction)
            });
        } else {
            autoAction.nextHandler();
        }
    };

    var install_youtubeSearch = function install_youtubeSearch(autoAction) {
        if (!Wirecloud.LocalCatalogue.resourceExistsId('CoNWeT/youtube-video-search/2.45.0')) {
            Wirecloud.LocalCatalogue.addResourceFromURL(build_static_url('tutorial-data/CoNWeT_youtube-video-search_2.45.0.wgt'), {
                packaged: true,
                onSuccess: autoAction.nextHandler.bind(autoAction)
            });
        } else {
            autoAction.nextHandler();
        }
    };

    var ResizeButton = function() {
        return document.getElementsByClassName("rightResizeHandle")[0];
    };

    var widgetHeader = function() {
        return document.getElementsByClassName("widget_menu")[0].getElementsByTagName('span')[0];
    };

    var refreshMarketplace = function refreshMarketplace(autoAction) {
        LayoutManagerFactory.getInstance().viewsByName.marketplace.viewsByName.local.refresh_search_results();
        autoAction.nextHandler();
    };

    var searchAction = function(autoAction, elem) {
        elem.value = "";
        setTimeout(function() {elem.value = 'y'}, 1000);
        setTimeout(function() {elem.value += 'o'}, 1300);
        setTimeout(function() {elem.value += 'u'}, 1600);
        setTimeout(function() {elem.value += 't'}, 1900);
        setTimeout(function() {elem.value += 'u'}, 2200);
        setTimeout(function() {elem.value += 'b'}, 2500);
        setTimeout(function() {elem.value += 'e'}, 2800);
        setTimeout(function() {elem.value += ' '}, 3100);
        setTimeout(function() {elem.value += 's'}, 3400);
        setTimeout(function() {elem.value += 'e'}, 3700);
        setTimeout(function() {elem.value += 'a'}, 4000);
        setTimeout(function() {elem.value += 'r'}, 4300);
        setTimeout(function() {elem.value += 'c'}, 4600);
        setTimeout(function() {
            elem.value += 'h';
            LayoutManagerFactory.getInstance().viewsByName.marketplace.viewsByName.local.viewsByName.search._onSearchInput();
        }, 4900);
        setTimeout(function() {autoAction.nextHandler();}, 6500);
    };

    var searchAction2 = function(autoAction, elem) {
        elem.value = "";
        setTimeout(function() {elem.value = 's'}, 1000);
        setTimeout(function() {elem.value += 'e'}, 1300);
        setTimeout(function() {elem.value += 'a'}, 1600);
        setTimeout(function() {elem.value += 'r'}, 1900);
        setTimeout(function() {elem.value += 'c'}, 2200);
        setTimeout(function() {
            elem.value += 'h';
            LayoutManagerFactory.getInstance().viewsByName.marketplace.viewsByName.local.viewsByName.search._onSearchInput();
        }, 2500);
        setTimeout(function() {autoAction.nextHandler();}, 4100);
    };

    var searchInputMarketplace = function() {
        return LayoutManagerFactory.getInstance().viewsByName.marketplace.alternatives.getCurrentAlternative().viewsByName.search.wrapperElement.getElementsByClassName('simple_search_text')[0];
    };

    var findElementByTextContent = function findElementByTextContent(nodes, text) {
        var i;
        for (i = 0; i < nodes.length; i ++) {
            if (nodes[i].textContent.toLowerCase() == text.toLowerCase()) {
                return nodes[i];
            }
        }
        return null;
    };

    var addbuttonSearch = function() {
        var resources, widget;

        resources = LayoutManagerFactory.getInstance().viewsByName.marketplace.alternatives.getCurrentAlternative().viewsByName.search.wrapperElement.getElementsByClassName('resource_name');
        widget = findElementByTextContent(resources, "Search");
        return widget.parentNode.getElementsByClassName("mainbutton")[0];
    };

    var addbuttonYoutubeSearch = function() {
        var resources, widget;

        resources = LayoutManagerFactory.getInstance().viewsByName.marketplace.alternatives.getCurrentAlternative().viewsByName.search.wrapperElement.getElementsByClassName('resource_name');
        widget = findElementByTextContent(resources, "Youtube Video Search");
        return widget.parentNode.getElementsByClassName("mainbutton")[0];
    };

    var getDocument = function() {
        return document;
    };

    var wirecloud_header = function wirecloud_header() {
        return document.getElementById('wirecloud_header');
    };

    var main_view_button = function(view) {
        return document.getElementById("wirecloud_header").getElementsByClassName(view)[0];
    };

    var get_menubar = function get_menubar() {
        var wiring_editor = document.getElementsByClassName('wiring_editor')[0];
        return wiring_editor.getElementsByClassName('menubar')[0];
    };

    var getMenuWorkspaceButton = function() {
        return document.getElementById('wirecloud_breadcrum').getElementsByClassName('icon-menu')[0];
    };

    var getAdminButton = function() {
        var header = document.getElementById('wirecloud_header');
        var elements = header.getElementsByClassName('user_menu_wrapper');
        if (elements.length == 0) {
            elements = header.getElementsByClassName('nav pull-right');
        }
        return elements[0];
    };

    var get_close_buttons = function get_close_buttons() {
        var workspace = document.getElementById('workspace');
        return workspace.getElementsByClassName('icon-remove');
    };

    var get_mini_widget = function get_mini_widget(index) {
        var widget_id = opManager.activeWorkspace.getIWidgets()[index].id;
        return LayoutManagerFactory.getInstance().viewsByName.wiring.mini_widgets[widget_id].wrapperElement;
    };

    var deploy_tutorial_menu = function deploy_tutorial_menu(autoAction) {
        var header = document.getElementById('wirecloud_header');
        var button = header.getElementsByClassName('arrow-down-settings')[0];
        button.click();
        autoAction.nextHandler();
    };

    var get_tutorial_menu_item = function get_tutorial_menu_item() {
        var popup_menu = document.getElementsByClassName('popup_menu')[0];
        return findElementByTextContent(popup_menu.getElementsByClassName('menu_item'), 'Tutorials');
    };

    var get_endpoint = function get_endpoint(index, name) {
        var widget_id = opManager.activeWorkspace.getIWidgets()[index].id;
        var wiringEditor = LayoutManagerFactory.getInstance().viewsByName["wiring"];
        return wiringEditor.iwidgets[widget_id].getAnchor(name).wrapperElement;
    };

    var get_wiring_canvas = function get_wiring_canvas() {
        var wiringEditor = LayoutManagerFactory.getInstance().viewsByName["wiring"];
        return wiringEditor.canvas;
    };

    var input_box_input = function input_box_input() {
        var widget = opManager.activeWorkspace.getIWidgets()[1];
        return new Wirecloud.ui.Tutorial.WidgetElement(widget, widget.content.contentDocument.getElementById('text'));
    };

    Wirecloud.TutorialCatalogue.add(new Wirecloud.ui.Tutorial(gettext('Basic concepts'), [
            // Editor
            {'type': 'simpleDescription', 'title': gettext('Wirecloud Basic Tutorial'), 'msg': gettext("
Welcome to Wirecloud!!

This tutorial will show you the basic concepts behind Wirecloud.
"), 'elem': null},
            {'type': 'autoAction', 'action': create_workspace},
            {'type': 'simpleDescription', 'title': gettext('Wirecloud Basic Tutorial'), 'msg': gettext("
This is the Editor view. In this view, you can use and modify your workspaces. Currently you are in a newly created workspace: Basic concepts tutorial. This workspace is empty, so the first step is to add widgets from the Wirecloud marketplace.
"), 'elem': null},
            // MarketPlace
            {'type': 'autoAction', 'action': reset_marketplace_view},
            {'type': 'userAction', 'msg': gettext("Click Marketplace"), 'elem': main_view_button.bind(null, 'marketplace'), 'pos': 'downLeft'},
            {'type': 'simpleDescription', 'title': gettext('Wirecloud Basic Tutorial'), 'msg': gettext('
This is the Marketplace view. In this view you can browse the Mashable Application Components (Widgets, operators and mashups) that are currently available to you. Also, you can browse external catalogues too.

In next steps we need some widgets, so we are going to install them for you in the catalogue. You can safetly uninstall these widgets after finishing the tutorial.

'), 'elem': null},
            {'type': 'autoAction', 'action': install_flickr},
            {'type': 'autoAction', 'action': install_multimediaViewer},
            {'type': 'autoAction', 'action': install_search},
            {'type': 'autoAction', 'action': install_youtubeSearch},
            {'type': 'autoAction', 'action': refreshMarketplace},
            {'type': 'simpleDescription', 'title': gettext('Wirecloud Basic Tutorial'), 'msg': gettext("
Ok, widgets have been installed successfuly and you can find them in your local catalogue.

Next step is to add the YouTube Video Search widget to the workspace. You can directly select the widget or, alternatively, you can reduce the list using the keyword search feature.
"), 'elem': null},
            {'type': 'autoAction', 'msg': gettext('Typing "youtube search" we can filter widgets that contains in their name or description these words'), 'elem': searchInputMarketplace, 'pos': 'downRight', 'action': searchAction},
            {'type': 'userAction', 'msg': gettext("Once you have the results, you can add the widget. So click Add to workspace"), 'elem': addbuttonYoutubeSearch, 'pos': 'downRight'},
            {'type': 'simpleDescription', 'title': gettext('Wirecloud Basic Tutorial'), 'msg': gettext("
Great! That was easy, wasn't it?.

Let's continue adding the Search widget.
"), 'elem': null},
            {'type': 'userAction', 'msg': gettext("Click Marketplace"), 'elem': main_view_button.bind(null, 'marketplace'), 'pos': 'downLeft'},
            {'type': 'autoAction', 'msg': gettext('Typing search...'), 'elem': searchInputMarketplace, 'pos': 'downRight', 'action': searchAction2},
            {'type': 'userAction', 'msg': gettext("Click Add to workspace"), 'elem': addbuttonSearch, 'pos': 'downRight'},

            {'type': 'simpleDescription', 'title': gettext('Wirecloud Basic Tutorial'), 'msg': gettext("
One of the main features of Wirecloud is that you can edit your workspaces' layout not only by adding and removing widgets, but also moving and resizing them.
"), 'elem': null},
            {'type': 'userAction', 'msg': gettext("Drag & drop to resize the widget"), 'elem': ResizeButton, 'pos': 'downRight', 'event': 'mouseup', 'eventToDeactivateLayer': 'mousedown'},
            {'type': 'userAction', 'msg': gettext("Drag & drop to move the widget"), 'elem': widgetHeader, 'pos': 'downRight', 'event': 'mouseup', 'eventToDeactivateLayer': 'mousedown', 'elemToApplyNextStepEvent': getDocument},

            {'type': 'simpleDescription', 'title': gettext('Wirecloud Basic Tutorial'), 'msg': gettext("
Play with the widgets of the wokspace moving, resizing, ... widgets as you like before going into the Wiring view.
"), 'elem': null},
            {'type': 'userAction', 'msg': gettext("Click Wiring to continue"), 'elem': main_view_button.bind(null, 'wiring'), 'pos': 'downLeft', 'eventToDeactivateLayer': 'mousemove', 'elemToApplyDeactivateLayerEvent': getDocument, 'disableElems': [getMenuWorkspaceButton, getAdminButton, get_close_buttons, main_view_button.bind(null, 'marketplace')]},

            // WiringEditor
            {'type': 'simpleDescription', 'title': gettext('Wirecloud Basic Tutorial'), 'msg': gettext("
This is the Wiring view.

Here you can wire widgets and operators together turning your workspace into and application mashup.
"), 'elem': null},
            {'type': 'simpleDescription', 'title': gettext('Wirecloud Basic Tutorial'), 'msg': gettext("
In left menu you can find all widgets added into your workspace.
"), 'elem': get_menubar},

            {'type': 'userAction', 'msg': gettext("Drag & drop Input Box"), 'elem': get_mini_widget.bind(null, 1), 'pos': 'downRight', 'event': 'mouseup', 'eventToDeactivateLayer': 'mousedown', 'elemToApplyNextStepEvent': getDocument},
            {'type': 'userAction', 'msg': gettext("Drag & drop Youtube Video Search"), 'elem': get_mini_widget.bind(null, 0), 'pos': 'downRight', 'event': 'mouseup', 'eventToDeactivateLayer': 'mousedown', 'elemToApplyNextStepEvent': getDocument},

            {'type': 'userAction', 'msg': gettext("Drag & drop a new connection from Input Box's keyword endpoint ..."),
                'elem': get_endpoint.bind(null, 1, 'keyword'), 'pos': 'downLeft',
                'eventToDeactivateLayer': 'arrowadded', 'elemToApplyDeactivateLayerEvent': get_wiring_canvas,
                'disableElems': [wirecloud_header, get_menubar],
                'nextStepMsg': gettext("... to YouTube Video Search's keyword endpoint"),
                'elemToApplyNextStepEvent': get_endpoint.bind(null, 0, 'keyword'), 'event': 'mouseup', 'second_pos': 'downLeft',
            },
            {'type': 'userAction', 'msg': gettext("Click Editor"), 'elem': main_view_button.bind(null, 'workspace'), 'pos': 'downLeft'},
            {'type': 'userAction', 'msg': gettext("Enter a search keyword and press Enter"), 'elem': input_box_input, 'pos': 'downLeft'},

            {'type': 'autoAction', 'action': deploy_tutorial_menu},
            {'type': 'simpleDescription', 'title': gettext('Wirecloud Basic Tutorial'), 'msg': gettext("
This is the end of this tutorial. Remember that you can always go to the Tutorial menu for others.
"), 'elem': get_tutorial_menu_item},
    ]));

})();
<|endoftext|>


<commit_before>define([ 'exports', 'jquery', 'underscore', 'widgy.backbone', 'shelves/shelves', 'modal/modal',
    'text!./node.html',
    'text!./drop_target.html',
    'text!./popped_out.html',
    'nodes/base',
    'nodes/models'
    ], function(exports, $, _, Backbone, shelves, modal,
      node_view_template,
      drop_target_view_template,
      popped_out_template,
      DraggableView,
      models
      ) {

  var debug = function(where) {
    console.log(where, this, _.rest(arguments));
  };

  /**
   * The NodeView provides an interface to the node.  It will also create a
   * ContentView for the node's content.  Additionally, it will create child
   * NodeViews for all of the nodes in children.
   *
   * Properties:
   *
   * -  `this.model` is the node.
   * -  `this.collection` is the node's children (Also available in
   *    `this.model.children`.)
   * -  `this.app` is the instance of AppView
   */
  var NodeView = DraggableView.extend({
    template: node_view_template,

    events: function() {
      return _.extend({}, DraggableView.prototype.events , {
        'click .delete': 'delete',
        'click .pop_out': 'popOut',
        'click .pop_in': 'closeSubwindow'
      });
    },

    initialize: function() {
      DraggableView.prototype.initialize.apply(this, arguments);

      _.bindAll(this,
        'renderChildren',
        'addChild',
        'addDropTargets',
        'createDropTarget',
        'clearDropTargets',
        'startDrag',
        'stopDrag',
        'stopDragging',
        'dropChildView',
        'receiveChildView',
        'renderContent',
        'resortChildren',
        'popOut',
        'popIn',
        'closeSubwindow'
        );

      this.collection = this.model.children;
      this.drop_targets_list = new Backbone.ViewList();

      this
        .listenTo(this.collection, 'add', this.addChild)
        .listenTo(this.collection, 'reset', this.renderChildren)
        .listenTo(this.collection, 'sort', this.resortChildren);

      this
        .listenTo(this.model, 'remove', this.close);

      this.list = new Backbone.ViewList();
    },

    isRootNode: function() {
      return ! this.parent;
    },

    onClose: function() {
      DraggableView.prototype.onClose.apply(this, arguments);

      if ( this.content_view ) {
        this.content_view.close();
        delete this.content_view;
      }

      this.list.closeAll();
    },

    dontShowChildren: function() {
      return this.model.pop_out === 2 && ! this.isRootNode();
    },

    renderChildren: function() {
      debug.call(this, 'renderChildren');
      if ( this.dontShowChildren() )
        return;

      this.list.closeAll();
      this.collection.each(this.addChild);
      this.resortChildren();
    },

    addChild: function(node, collection, options) {
      if ( this.dontShowChildren() )
        return;

      var node_view = new NodeView({
        model: node,
        parent: this,
        app: this.app
      });

      this
        .listenTo(node_view, 'startDrag', this.startDrag)
        .listenTo(node_view, 'stopDrag', this.stopDrag);

      this.app.node_view_list.push(node_view);
      if ( options && options.index ) {
        this.list.list.splice(options.index, 0, node_view);
      } else {
        this.list.push(node_view);
      }
      this.$children.append(node_view.render().el);
    },

    resortChildren: function() {
      console.log(this.model.__class__, 'resorting children');
      var new_list = [];
      this.collection.each(function(model) {
        var node_view = this.list.findByModel(model);
        this.$children.append(node_view.el);
        new_list.push(node_view);
      }, this);
      this.list.list = new_list;
    },

    'delete': function(event) {
      var spinner = new Backbone.Spinner({el: this.$content.find('.delete')}),
          model = this.model;

      var error = function() {
        spinner.restore();
        modal.raiseError.apply(this, arguments);
      };

      this.model.collection.trigger('destroy_child');
      this.model.destroy({
        wait: true,
        error: error,
        app: this.app
      });
      return false;
    },

    startDrag: function(dragged_view) {
      debug.call(this, 'startDrag', dragged_view);

      if ( ( this.hasShelf() && ! dragged_view.model.id || ! this.model.get('parent_id') )) {
        this.dragged_view = dragged_view;

        var bindToDocument = _.bind(function() {
          $(document)
            .on('mouseup.' + dragged_view.cid, this.stopDragging)
            .on('mousemove.' + dragged_view.cid, dragged_view.followMouse)
            .on('selectstart.' + dragged_view.cid, function(){ return false; })
            // debugging helper
            .one('keypress.' + dragged_view.cid, function(event) {
              if ( event.which === 96 ) {
                $(document)
                  .off('.' + dragged_view.cid)
                  // resume dragging
                  .one('keypress.' + dragged_view.cid, function(event) {
                    if ( event.which === 96 ) bindToDocument();
                  });
              }
            });
        }, this);

        bindToDocument();

        this.addDropTargets(dragged_view);
      } else {
        // propagate event
        this.trigger('startDrag', dragged_view);
      }
    },

    stopDragging: function() {
      var dragged_view = this.dragged_view;
      delete this.dragged_view;

      $(document).off('.' + dragged_view.cid);

      if ( dragged_view.placeholder )
        dragged_view.placeholder.remove();

      this.clearDropTargets();

      dragged_view.stopBeingDragged();

      return dragged_view;
    },

    stopDrag: function(callback) {
      debug.call(this, 'stopDrag', callback);

      if ( this.hasShelf() && this.dragged_view ) {
        callback(this.stopDragging());
      } else {
        // propagate event
        this.trigger('stopDrag', callback);
      }
    },

    getShelf: function() {
      if ( this.model.pop_out == 2 && ! this.isRootNode() )
        return null;
      else if ( this.hasShelf() )
        return this.shelf;
      else
        return this.parent.getShelf();
    },

    // TODO: move these methods to model.
    canAcceptChild: function(view) {
      return ! this.dontShowChildren() && view.canAcceptParent(this);
    },

    canAcceptParent: function(parent) {
      // it is me.
      if ( this === parent )
        return false;

      // it is already my child.
      if ( parent.list.contains(this) )
        return true;

      return this.app.validateRelationship(parent, this.model.content);
    },

    /**
     * `addDropTargets`, `createDropTarget`, `clearDropTargets`, `position`,
     * and `dropChildView` all deal with a possible child NodeView being
     * dragged.  It is confusing that these methods are on the same class that
     * the methods dealing with being dragged around are on, but that's the
     * nature of the beast with recursive nodes.
     */
    addDropTargets: function(view) {
      var $children = this.$children,
          that = this,
          mine = this.list.contains(view);

      // I can't be my own grandfather.
      if (this !== view) {
        this.list.each(function(node_view) {
          node_view.addDropTargets(view);
        });
      }

      if (this.canAcceptChild(view))
      {
        $children.prepend(this.createDropTarget().el);
        this.list.each(function(node_view) {
          var drop_target = that.createDropTarget().$el.insertAfter(node_view.el);

          if ( mine && view == node_view )
            drop_target.hide();
        });
      }
    },

    createDropTarget: function() {
      var drop_target = new DropTargetView();
      drop_target.on('dropped', this.dropChildView);
      this.drop_targets_list.push(drop_target);

      return drop_target.render();
    },

    clearDropTargets: function() {
      this.drop_targets_list.closeAll();

      this.list.each(function(node_view) {
        node_view.clearDropTargets();
      });
    },

    dropChildView: function(drop_target) {
      var index = drop_target.$el.index() / 2,
          dragCallback = _.bind(this.receiveChildView, this, index);

      // We need to stop the drag before finding the right node.
      // `this.app.stopDrag` will clear all of the drop targets, so we need to
      // remove them before we can get elements by index.
      this.stopDrag(dragCallback);
    },

    /**
     * This is the method that is called when the NodeView that is being
     * dragged is dropped on one of my drop targets.
     */
    receiveChildView: function(index, dragged_view) {
      debug('receiveChildView');

      var node = dragged_view.model;

      // It's already mine and it was dragged into its own drop target.
      if ( index === this.collection.indexOf(dragged_view) )
        return;

      // This will return the model that we want at our right or undefined.
      var right = this.collection.at(index);

      // Bail if it didn't move.
      if ( this.model === node.getParent() && right === node )
        return;

      var attributes = {
        parent_id: this.model.id,
        right_id: right ? right.id : null
      };

      this.collection.trigger('receive_child');
      dragged_view.model.save(attributes, {
        success: this.collection.reposition,
        error: modal.raiseError,
        app: this.app
      });
    },

    saveAt: function(attributes, options) {
      this.model.save(attributes, options);
    },

    hasShelf: function() {
      return this.model.shelf || this.isRootNode();
    },

    render: function() {
      debug.call(this, 'render');
      DraggableView.prototype.render.apply(this, arguments);

      this.$children = this.$el.find(' > .widget > .node_children');
      this.$content = this.$el.find(' > .widget > .content ');

      this.renderChildren();

      if ( this.hasShelf() ) {
        this.renderShelf();
      }

      this.model.ready(this.renderContent);

      return this;
    },

    renderContent: function() {
      if ( this.content_view )
        return;

      console.log(this.model.__class__, 'renderContent');

      this.content_view = new this.model.component.View({
        model: this.model.content,
        el: this.$content,
        app: this.app
      });

      this.content_view.render();

      // when we are popped out, we need to remove our own pop out button.
      if ( this.isRootNode() ) {
        this.$content.find('.pop_out').remove();
      }
    },

    renderShelf: function() {
      if (this.shelf)
        return false;

      var shelf = this.shelf = new shelves.ShelfView({
        collection: new shelves.ShelfCollection({
            node: this.model
          }),
        app: this.app
      });

      this.listenTo(shelf, 'startDrag', this.startDrag)
          .listenTo(shelf, 'stopDrag', this.stopDrag);

      // position sticky
      if ( false && this.isRootNode() ) {
        // The shelf needs to be after the children because in state 0 (fixed),
        // the shelf items will be displayed underneath everything else that is
        // after it in HTML.
        this.$children.after(shelf.render().el);

        var state = -1;
        $(window).scroll(_.bind(function() {
          var upper_bound = this.el.offsetTop,
              lower_bound = upper_bound + this.el.offsetHeight - this.shelf.el.offsetHeight;
          if ( window.scrollY < upper_bound && state !== -1) {
            this.shelf.$el.css({
              position: '',
              top: '',
              left: ''
            });
            state = -1;
          }
          if ( window.scrollY > upper_bound && state !== 0) {
            this.shelf.$el.css({
              position: 'fixed',
              // this 80px is to adjust for Mezzanine's fixed header.
              top: 80,
              left: this.shelf.$el.offset().left
            });
            state = 0;
          }
          if ( window.scrollY > lower_bound && state !== 1) {
            this.shelf.$el.css({
              position: 'absolute',
              top: lower_bound - upper_bound,
              left: ''
            });
            state = 1;
          }
        }, this));
      } else {
        this.$children.before(shelf.render().el);
      }
    },

    toJSON: function() {
      var json = this.model.toJSON();
      if ( this.model.content )
        json.content = this.model.content.toJSON();

      return json;
    },

    popOut: function(event) {
      debug.call(this, 'popOut');

      event.preventDefault();
      event.stopPropagation(); // our parent nodes

      this.subwindow = window.open(event.target.href, '', 'height=500,width=800,resizable=yes,scrollbars=yes');
      this.subwindow.widgyCloseCallback = this.popIn;

      // If they leave this page, pop back in.
      $(window).on('unload.widgyPopOut-' + this.cid, this.popIn);

      this.collection.reset();
      this.content_view.close();
      delete this.content_view;
      this.$el.html(this.renderTemplate(popped_out_template, this.toJSON()));
    },

    popIn: function(event) {
      debug.call(this, 'popIn');

      event.preventDefault();
      event.stopPropagation();

      // we're popped in so don't popIn again when we leave this
      // page.
      $(window).off('.widgyPopOut-' + this.cid);

      this.model.fetch({
        app: this.app,
        resort: true,
        success: this.render
      });

      return false;
    },

    closeSubwindow: function() {
      if ( this.subwindow )
        this.subwindow.close();
      return false;
    },

    cssClasses: function() {
      return this.model.css_classes;
    }
  });

  var DropTargetView = Backbone.View.extend({
    tagName: 'li',
    className: 'node_drop_target',
    template: drop_target_view_template,

    triggers: {
      'mouseup': 'dropped'
    },

    events: {
      'mouseenter': 'activate',
      'mouseleave': 'deactivate'
    },

    render: function() {
      Backbone.View.prototype.render.apply(this, arguments);

      // In a perfect world, the CSS pointer-events property would be supported
      // by all browsers and every version of each browser and we would set
      // pointer-events to none for .node.being_dragged.  But even since we
      // can't use that, we are going to use this method to capture all of the
      // events.
      //
      // Above the drop targets, we put an invisible div that has a z-index
      // high enough to be above the dragged_node.  This allows us to catch the
      // pointer events (mouseup, mouseenter, mouseleave) that we need drop
      // targets to receive.
      //
      // Normally I don't like putting CSS in the JavaScript, but this CSS
      // creates functionality and not prettiness, so I have to.
      this.$el.css({
        'position': 'relative'
      });

      var $pointerEventsCatcher = $('<div class="pointer_event_catcher">')
        .css({
          'z-index': 51,
          'opacity': 0,
          'width': '100%',
          'height': '100%',
          'position': 'absolute',
          'top': 0,
          'left': 0
        });
      this.$el.prepend($pointerEventsCatcher);

      return this;
    },

    activate: function(event) {
      this.$el.addClass('active');
    },

    deactivate: function(event) {
      this.$el.removeClass('active');
    }
  });

  return _.extend({}, models, {
    DropTargetView: DropTargetView,
    NodeView: NodeView
  });

});
<commit_msg>use the isRootNode method instead of ! parent_id<commit_after>define([ 'exports', 'jquery', 'underscore', 'widgy.backbone', 'shelves/shelves', 'modal/modal',
    'text!./node.html',
    'text!./drop_target.html',
    'text!./popped_out.html',
    'nodes/base',
    'nodes/models'
    ], function(exports, $, _, Backbone, shelves, modal,
      node_view_template,
      drop_target_view_template,
      popped_out_template,
      DraggableView,
      models
      ) {

  var debug = function(where) {
    console.log(where, this, _.rest(arguments));
  };

  /**
   * The NodeView provides an interface to the node.  It will also create a
   * ContentView for the node's content.  Additionally, it will create child
   * NodeViews for all of the nodes in children.
   *
   * Properties:
   *
   * -  `this.model` is the node.
   * -  `this.collection` is the node's children (Also available in
   *    `this.model.children`.)
   * -  `this.app` is the instance of AppView
   */
  var NodeView = DraggableView.extend({
    template: node_view_template,

    events: function() {
      return _.extend({}, DraggableView.prototype.events , {
        'click .delete': 'delete',
        'click .pop_out': 'popOut',
        'click .pop_in': 'closeSubwindow'
      });
    },

    initialize: function() {
      DraggableView.prototype.initialize.apply(this, arguments);

      _.bindAll(this,
        'renderChildren',
        'addChild',
        'addDropTargets',
        'createDropTarget',
        'clearDropTargets',
        'startDrag',
        'stopDrag',
        'stopDragging',
        'dropChildView',
        'receiveChildView',
        'renderContent',
        'resortChildren',
        'popOut',
        'popIn',
        'closeSubwindow'
        );

      this.collection = this.model.children;
      this.drop_targets_list = new Backbone.ViewList();

      this
        .listenTo(this.collection, 'add', this.addChild)
        .listenTo(this.collection, 'reset', this.renderChildren)
        .listenTo(this.collection, 'sort', this.resortChildren);

      this
        .listenTo(this.model, 'remove', this.close);

      this.list = new Backbone.ViewList();
    },

    isRootNode: function() {
      return ! this.parent;
    },

    onClose: function() {
      DraggableView.prototype.onClose.apply(this, arguments);

      if ( this.content_view ) {
        this.content_view.close();
        delete this.content_view;
      }

      this.list.closeAll();
    },

    dontShowChildren: function() {
      return this.model.pop_out === 2 && ! this.isRootNode();
    },

    renderChildren: function() {
      debug.call(this, 'renderChildren');
      if ( this.dontShowChildren() )
        return;

      this.list.closeAll();
      this.collection.each(this.addChild);
      this.resortChildren();
    },

    addChild: function(node, collection, options) {
      if ( this.dontShowChildren() )
        return;

      var node_view = new NodeView({
        model: node,
        parent: this,
        app: this.app
      });

      this
        .listenTo(node_view, 'startDrag', this.startDrag)
        .listenTo(node_view, 'stopDrag', this.stopDrag);

      this.app.node_view_list.push(node_view);
      if ( options && options.index ) {
        this.list.list.splice(options.index, 0, node_view);
      } else {
        this.list.push(node_view);
      }
      this.$children.append(node_view.render().el);
    },

    resortChildren: function() {
      console.log(this.model.__class__, 'resorting children');
      var new_list = [];
      this.collection.each(function(model) {
        var node_view = this.list.findByModel(model);
        this.$children.append(node_view.el);
        new_list.push(node_view);
      }, this);
      this.list.list = new_list;
    },

    'delete': function(event) {
      var spinner = new Backbone.Spinner({el: this.$content.find('.delete')}),
          model = this.model;

      var error = function() {
        spinner.restore();
        modal.raiseError.apply(this, arguments);
      };

      this.model.collection.trigger('destroy_child');
      this.model.destroy({
        wait: true,
        error: error,
        app: this.app
      });
      return false;
    },

    startDrag: function(dragged_view) {
      debug.call(this, 'startDrag', dragged_view);

      if ( ( this.hasShelf() && ! dragged_view.model.id || this.isRootNode() )) {
        this.dragged_view = dragged_view;

        var bindToDocument = _.bind(function() {
          $(document)
            .on('mouseup.' + dragged_view.cid, this.stopDragging)
            .on('mousemove.' + dragged_view.cid, dragged_view.followMouse)
            .on('selectstart.' + dragged_view.cid, function(){ return false; })
            // debugging helper
            .one('keypress.' + dragged_view.cid, function(event) {
              if ( event.which === 96 ) {
                $(document)
                  .off('.' + dragged_view.cid)
                  // resume dragging
                  .one('keypress.' + dragged_view.cid, function(event) {
                    if ( event.which === 96 ) bindToDocument();
                  });
              }
            });
        }, this);

        bindToDocument();

        this.addDropTargets(dragged_view);
      } else {
        // propagate event
        this.trigger('startDrag', dragged_view);
      }
    },

    stopDragging: function() {
      var dragged_view = this.dragged_view;
      delete this.dragged_view;

      $(document).off('.' + dragged_view.cid);

      if ( dragged_view.placeholder )
        dragged_view.placeholder.remove();

      this.clearDropTargets();

      dragged_view.stopBeingDragged();

      return dragged_view;
    },

    stopDrag: function(callback) {
      debug.call(this, 'stopDrag', callback);

      if ( this.hasShelf() && this.dragged_view ) {
        callback(this.stopDragging());
      } else {
        // propagate event
        this.trigger('stopDrag', callback);
      }
    },

    getShelf: function() {
      if ( this.model.pop_out == 2 && ! this.isRootNode() )
        return null;
      else if ( this.hasShelf() )
        return this.shelf;
      else
        return this.parent.getShelf();
    },

    // TODO: move these methods to model.
    canAcceptChild: function(view) {
      return ! this.dontShowChildren() && view.canAcceptParent(this);
    },

    canAcceptParent: function(parent) {
      // it is me.
      if ( this === parent )
        return false;

      // it is already my child.
      if ( parent.list.contains(this) )
        return true;

      return this.app.validateRelationship(parent, this.model.content);
    },

    /**
     * `addDropTargets`, `createDropTarget`, `clearDropTargets`, `position`,
     * and `dropChildView` all deal with a possible child NodeView being
     * dragged.  It is confusing that these methods are on the same class that
     * the methods dealing with being dragged around are on, but that's the
     * nature of the beast with recursive nodes.
     */
    addDropTargets: function(view) {
      var $children = this.$children,
          that = this,
          mine = this.list.contains(view);

      // I can't be my own grandfather.
      if (this !== view) {
        this.list.each(function(node_view) {
          node_view.addDropTargets(view);
        });
      }

      if (this.canAcceptChild(view))
      {
        $children.prepend(this.createDropTarget().el);
        this.list.each(function(node_view) {
          var drop_target = that.createDropTarget().$el.insertAfter(node_view.el);

          if ( mine && view == node_view )
            drop_target.hide();
        });
      }
    },

    createDropTarget: function() {
      var drop_target = new DropTargetView();
      drop_target.on('dropped', this.dropChildView);
      this.drop_targets_list.push(drop_target);

      return drop_target.render();
    },

    clearDropTargets: function() {
      this.drop_targets_list.closeAll();

      this.list.each(function(node_view) {
        node_view.clearDropTargets();
      });
    },

    dropChildView: function(drop_target) {
      var index = drop_target.$el.index() / 2,
          dragCallback = _.bind(this.receiveChildView, this, index);

      // We need to stop the drag before finding the right node.
      // `this.app.stopDrag` will clear all of the drop targets, so we need to
      // remove them before we can get elements by index.
      this.stopDrag(dragCallback);
    },

    /**
     * This is the method that is called when the NodeView that is being
     * dragged is dropped on one of my drop targets.
     */
    receiveChildView: function(index, dragged_view) {
      debug('receiveChildView');

      var node = dragged_view.model;

      // It's already mine and it was dragged into its own drop target.
      if ( index === this.collection.indexOf(dragged_view) )
        return;

      // This will return the model that we want at our right or undefined.
      var right = this.collection.at(index);

      // Bail if it didn't move.
      if ( this.model === node.getParent() && right === node )
        return;

      var attributes = {
        parent_id: this.model.id,
        right_id: right ? right.id : null
      };

      this.collection.trigger('receive_child');
      dragged_view.model.save(attributes, {
        success: this.collection.reposition,
        error: modal.raiseError,
        app: this.app
      });
    },

    saveAt: function(attributes, options) {
      this.model.save(attributes, options);
    },

    hasShelf: function() {
      return this.model.shelf || this.isRootNode();
    },

    render: function() {
      debug.call(this, 'render');
      DraggableView.prototype.render.apply(this, arguments);

      this.$children = this.$el.find(' > .widget > .node_children');
      this.$content = this.$el.find(' > .widget > .content ');

      this.renderChildren();

      if ( this.hasShelf() ) {
        this.renderShelf();
      }

      this.model.ready(this.renderContent);

      return this;
    },

    renderContent: function() {
      if ( this.content_view )
        return;

      console.log(this.model.__class__, 'renderContent');

      this.content_view = new this.model.component.View({
        model: this.model.content,
        el: this.$content,
        app: this.app
      });

      this.content_view.render();

      // when we are popped out, we need to remove our own pop out button.
      if ( this.isRootNode() ) {
        this.$content.find('.pop_out').remove();
      }
    },

    renderShelf: function() {
      if (this.shelf)
        return false;

      var shelf = this.shelf = new shelves.ShelfView({
        collection: new shelves.ShelfCollection({
            node: this.model
          }),
        app: this.app
      });

      this.listenTo(shelf, 'startDrag', this.startDrag)
          .listenTo(shelf, 'stopDrag', this.stopDrag);

      // position sticky
      if ( false && this.isRootNode() ) {
        // The shelf needs to be after the children because in state 0 (fixed),
        // the shelf items will be displayed underneath everything else that is
        // after it in HTML.
        this.$children.after(shelf.render().el);

        var state = -1;
        $(window).scroll(_.bind(function() {
          var upper_bound = this.el.offsetTop,
              lower_bound = upper_bound + this.el.offsetHeight - this.shelf.el.offsetHeight;
          if ( window.scrollY < upper_bound && state !== -1) {
            this.shelf.$el.css({
              position: '',
              top: '',
              left: ''
            });
            state = -1;
          }
          if ( window.scrollY > upper_bound && state !== 0) {
            this.shelf.$el.css({
              position: 'fixed',
              // this 80px is to adjust for Mezzanine's fixed header.
              top: 80,
              left: this.shelf.$el.offset().left
            });
            state = 0;
          }
          if ( window.scrollY > lower_bound && state !== 1) {
            this.shelf.$el.css({
              position: 'absolute',
              top: lower_bound - upper_bound,
              left: ''
            });
            state = 1;
          }
        }, this));
      } else {
        this.$children.before(shelf.render().el);
      }
    },

    toJSON: function() {
      var json = this.model.toJSON();
      if ( this.model.content )
        json.content = this.model.content.toJSON();

      return json;
    },

    popOut: function(event) {
      debug.call(this, 'popOut');

      event.preventDefault();
      event.stopPropagation(); // our parent nodes

      this.subwindow = window.open(event.target.href, '', 'height=500,width=800,resizable=yes,scrollbars=yes');
      this.subwindow.widgyCloseCallback = this.popIn;

      // If they leave this page, pop back in.
      $(window).on('unload.widgyPopOut-' + this.cid, this.popIn);

      this.collection.reset();
      this.content_view.close();
      delete this.content_view;
      this.$el.html(this.renderTemplate(popped_out_template, this.toJSON()));
    },

    popIn: function(event) {
      debug.call(this, 'popIn');

      event.preventDefault();
      event.stopPropagation();

      // we're popped in so don't popIn again when we leave this
      // page.
      $(window).off('.widgyPopOut-' + this.cid);

      this.model.fetch({
        app: this.app,
        resort: true,
        success: this.render
      });

      return false;
    },

    closeSubwindow: function() {
      if ( this.subwindow )
        this.subwindow.close();
      return false;
    },

    cssClasses: function() {
      return this.model.css_classes;
    }
  });

  var DropTargetView = Backbone.View.extend({
    tagName: 'li',
    className: 'node_drop_target',
    template: drop_target_view_template,

    triggers: {
      'mouseup': 'dropped'
    },

    events: {
      'mouseenter': 'activate',
      'mouseleave': 'deactivate'
    },

    render: function() {
      Backbone.View.prototype.render.apply(this, arguments);

      // In a perfect world, the CSS pointer-events property would be supported
      // by all browsers and every version of each browser and we would set
      // pointer-events to none for .node.being_dragged.  But even since we
      // can't use that, we are going to use this method to capture all of the
      // events.
      //
      // Above the drop targets, we put an invisible div that has a z-index
      // high enough to be above the dragged_node.  This allows us to catch the
      // pointer events (mouseup, mouseenter, mouseleave) that we need drop
      // targets to receive.
      //
      // Normally I don't like putting CSS in the JavaScript, but this CSS
      // creates functionality and not prettiness, so I have to.
      this.$el.css({
        'position': 'relative'
      });

      var $pointerEventsCatcher = $('<div class="pointer_event_catcher">')
        .css({
          'z-index': 51,
          'opacity': 0,
          'width': '100%',
          'height': '100%',
          'position': 'absolute',
          'top': 0,
          'left': 0
        });
      this.$el.prepend($pointerEventsCatcher);

      return this;
    },

    activate: function(event) {
      this.$el.addClass('active');
    },

    deactivate: function(event) {
      this.$el.removeClass('active');
    }
  });

  return _.extend({}, models, {
    DropTargetView: DropTargetView,
    NodeView: NodeView
  });

});
<|endoftext|>


<commit_before>import $ from "jquery";

import render_keyboard_shortcut from "../templates/keyboard_shortcuts.hbs";
import render_markdown_help from "../templates/markdown_help.hbs";
import render_search_operator from "../templates/search_operators.hbs";

import * as browser_history from "./browser_history";
import * as common from "./common";
import * as components from "./components";
import {$t, $t_html} from "./i18n";
import * as keydown_util from "./keydown_util";
import * as markdown from "./markdown";
import * as overlays from "./overlays";
import * as rendered_markdown from "./rendered_markdown";
import * as ui from "./ui";
import {user_settings} from "./user_settings";
import * as util from "./util";

// Make it explicit that our toggler is undefined until
// set_up_toggler is called.
export let toggler;

const markdown_help_rows = [
    {
        markdown: "*italic*",
        usage_html: "(or Ctrl+I)",
    },
    {
        markdown: "**bold**",
        usage_html: "(or Ctrl+B)",
    },
    {
        markdown: "~~strikethrough~~",
    },
    {
        markdown: "[Zulip website](https://zulip.org)",
        usage_html: "(or Ctrl+Shift+L)",
    },
    {
        markdown: `\
* Milk
* Tea
  * Green tea
  * Black tea
  * Oolong tea
* Coffee`,
    },
    {
        markdown: `\
1. Milk
1. Tea
1. Coffee`,
    },
    {
        markdown: ":heart:",
        usage_html:
            '(and many others, from the Noto Project)',
    },
    {
        markdown: "@**Joe Smith**",
        usage_html: "(autocompletes from @joe)",
        output_html: '
@Joe Smith
',
        effect_html: "(notifies Joe Smith)",
    },
    {
        markdown: "@_**Joe Smith**",
        usage_html: "(autocompletes from @_joe)",
        output_html: '
Joe Smith
',
        effect_html: "(links to profile but doesn't notify Joe Smith)",
    },
    {
        markdown: "@**all**",
        effect_html: "(notifies all recipients)",
    },
    {
        markdown: "#**streamName**",
        output_html: "
#streamName
",
        effect_html: "(links to a stream)",
    },
    {
        markdown: "/me is busy working",
        output_html: '
Iago is busy working
',
        usage_html: "(send a status message as user Iago)",
    },
    {
        markdown: "Some inline `code`",
    },
    {
        markdown: `\
\`\`\`
def zulip():
    print "Zulip"
\`\`\``,
    },
    {
        markdown: `\
\`\`\`python
def zulip():
    print "Zulip"
\`\`\``,
        output_html: `\

def zulip():
    print "Zulip"

`,
    },
    {
        note_html: $t_html(
            {
                defaultMessage:
                    "To add syntax highlighting to a multi-line code block, add the language's first <z-link>Pygments short name</z-link> after the first set of back-ticks. You can also make a code block by indenting each line with 4 spaces.",
            },
            {
                "z-link": (content_html) =>
                    `<a target="_blank" rel="noopener noreferrer" href="https://pygments.org/docs/lexers/">${content_html}</a>`,
            },
        ),
    },
    {
        markdown: "> Quoted",
    },
    {
        markdown: `\
\`\`\`quote
Quoted block
\`\`\``,
    },
    {
        markdown: `\
\`\`\`spoiler Always visible heading
This text won't be visible until the user clicks.
\`\`\``,
    },
    {
        markdown: "Some inline math $$ e^{i \\pi} + 1 = 0 $$",
    },
    {
        markdown: `\
\`\`\`math
\\int_{0}^{1} f(x) dx
\`\`\``,
    },
    {
        note_html: $t_html(
            {
                defaultMessage:
                    "You can also make <z-link>tables</z-link> with this <z-link>Markdown-ish table syntax</z-link>.",
            },
            {
                "z-link": (content_html) =>
                    `<a target="_blank" rel="noopener noreferrer" href="https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet#wiki-tables">${content_html}</a>`,
            },
        ),
    },
];

export function set_up_toggler() {
    for (const row of markdown_help_rows) {
        if (row.markdown && !row.output_html) {
            const message = {raw_content: row.markdown};
            markdown.apply_markdown(message);
            row.output_html = util.clean_user_content_links(message.content);
        }
    }

    const $markdown_help = $(render_markdown_help({markdown_help_rows}));
    $markdown_help.find(".rendered_markdown").each(function () {
        rendered_markdown.update_elements($(this));
    });
    $(".informational-overlays .overlay-body").append($markdown_help);

    const $search_operators = $(render_search_operator());
    $(".informational-overlays .overlay-body").append($search_operators);

    const $keyboard_shortcuts = $(render_keyboard_shortcut());
    $(".informational-overlays .overlay-body").append($keyboard_shortcuts);

    const opts = {
        selected: 0,
        child_wants_focus: true,
        values: [
            {label: $t({defaultMessage: "Keyboard shortcuts"}), key: "keyboard-shortcuts"},
            {label: $t({defaultMessage: "Message formatting"}), key: "message-formatting"},
            {label: $t({defaultMessage: "Search operators"}), key: "search-operators"},
        ],
        callback(name, key) {
            $(".overlay-modal").hide();
            $(`#${CSS.escape(key)}`).show();
            ui.get_scroll_element($(`#${CSS.escape(key)}`).find(".modal-body")).trigger("focus");
        },
    };

    toggler = components.toggle(opts);
    const $elem = toggler.get();
    $elem.addClass("large allow-overflow");

    const modals = opts.values.map((item) => {
        const key = item.key; // e.g. message-formatting
        const $modal = $(`#${CSS.escape(key)}`).find(".modal-body");
        return $modal;
    });

    for (const $modal of modals) {
        ui.get_scroll_element($modal).prop("tabindex", 0);
        keydown_util.handle({
            $elem: $modal,
            handlers: {
                ArrowLeft: toggler.maybe_go_left,
                ArrowRight: toggler.maybe_go_right,
            },
        });
    }

    $(".informational-overlays .overlay-tabs").append($elem);

    $("#go-to-default-view-hotkey-help").toggleClass(
        "notdisplayed",
        !user_settings.escape_navigates_to_default_view,
    );
    common.adjust_mac_shortcuts(".hotkeys_table .hotkey kbd");
    common.adjust_mac_shortcuts("#markdown-instructions kbd");
}

export function show(target) {
    if (!toggler) {
        set_up_toggler();
    }

    const $overlay = $(".informational-overlays");

    if (!$overlay.hasClass("show")) {
        overlays.open_overlay({
            name: "informationalOverlays",
            $overlay,
            on_close() {
                browser_history.exit_overlay();
            },
        });
    }

    if (target) {
        toggler.goto(target);
    }
}
<commit_msg>documentation (user): Remove redundant 2nd line from /me documentation.<commit_after>import $ from "jquery";

import render_keyboard_shortcut from "../templates/keyboard_shortcuts.hbs";
import render_markdown_help from "../templates/markdown_help.hbs";
import render_search_operator from "../templates/search_operators.hbs";

import * as browser_history from "./browser_history";
import * as common from "./common";
import * as components from "./components";
import {$t, $t_html} from "./i18n";
import * as keydown_util from "./keydown_util";
import * as markdown from "./markdown";
import * as overlays from "./overlays";
import * as rendered_markdown from "./rendered_markdown";
import * as ui from "./ui";
import {user_settings} from "./user_settings";
import * as util from "./util";

// Make it explicit that our toggler is undefined until
// set_up_toggler is called.
export let toggler;

const markdown_help_rows = [
    {
        markdown: "*italic*",
        usage_html: "(or Ctrl+I)",
    },
    {
        markdown: "**bold**",
        usage_html: "(or Ctrl+B)",
    },
    {
        markdown: "~~strikethrough~~",
    },
    {
        markdown: "[Zulip website](https://zulip.org)",
        usage_html: "(or Ctrl+Shift+L)",
    },
    {
        markdown: `\
* Milk
* Tea
  * Green tea
  * Black tea
  * Oolong tea
* Coffee`,
    },
    {
        markdown: `\
1. Milk
1. Tea
1. Coffee`,
    },
    {
        markdown: ":heart:",
        usage_html:
            '(and many others, from the Noto Project)',
    },
    {
        markdown: "@**Joe Smith**",
        usage_html: "(autocompletes from @joe)",
        output_html: '
@Joe Smith
',
        effect_html: "(notifies Joe Smith)",
    },
    {
        markdown: "@_**Joe Smith**",
        usage_html: "(autocompletes from @_joe)",
        output_html: '
Joe Smith
',
        effect_html: "(links to profile but doesn't notify Joe Smith)",
    },
    {
        markdown: "@**all**",
        effect_html: "(notifies all recipients)",
    },
    {
        markdown: "#**streamName**",
        output_html: "
#streamName
",
        effect_html: "(links to a stream)",
    },
    {
        markdown: "/me is busy working",
        output_html: '
Iago is busy working
',
    },
    {
        markdown: "Some inline `code`",
    },
    {
        markdown: `\
\`\`\`
def zulip():
    print "Zulip"
\`\`\``,
    },
    {
        markdown: `\
\`\`\`python
def zulip():
    print "Zulip"
\`\`\``,
        output_html: `\

def zulip():
    print "Zulip"

`,
    },
    {
        note_html: $t_html(
            {
                defaultMessage:
                    "To add syntax highlighting to a multi-line code block, add the language's first <z-link>Pygments short name</z-link> after the first set of back-ticks. You can also make a code block by indenting each line with 4 spaces.",
            },
            {
                "z-link": (content_html) =>
                    `<a target="_blank" rel="noopener noreferrer" href="https://pygments.org/docs/lexers/">${content_html}</a>`,
            },
        ),
    },
    {
        markdown: "> Quoted",
    },
    {
        markdown: `\
\`\`\`quote
Quoted block
\`\`\``,
    },
    {
        markdown: `\
\`\`\`spoiler Always visible heading
This text won't be visible until the user clicks.
\`\`\``,
    },
    {
        markdown: "Some inline math $$ e^{i \\pi} + 1 = 0 $$",
    },
    {
        markdown: `\
\`\`\`math
\\int_{0}^{1} f(x) dx
\`\`\``,
    },
    {
        note_html: $t_html(
            {
                defaultMessage:
                    "You can also make <z-link>tables</z-link> with this <z-link>Markdown-ish table syntax</z-link>.",
            },
            {
                "z-link": (content_html) =>
                    `<a target="_blank" rel="noopener noreferrer" href="https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet#wiki-tables">${content_html}</a>`,
            },
        ),
    },
];

export function set_up_toggler() {
    for (const row of markdown_help_rows) {
        if (row.markdown && !row.output_html) {
            const message = {raw_content: row.markdown};
            markdown.apply_markdown(message);
            row.output_html = util.clean_user_content_links(message.content);
        }
    }

    const $markdown_help = $(render_markdown_help({markdown_help_rows}));
    $markdown_help.find(".rendered_markdown").each(function () {
        rendered_markdown.update_elements($(this));
    });
    $(".informational-overlays .overlay-body").append($markdown_help);

    const $search_operators = $(render_search_operator());
    $(".informational-overlays .overlay-body").append($search_operators);

    const $keyboard_shortcuts = $(render_keyboard_shortcut());
    $(".informational-overlays .overlay-body").append($keyboard_shortcuts);

    const opts = {
        selected: 0,
        child_wants_focus: true,
        values: [
            {label: $t({defaultMessage: "Keyboard shortcuts"}), key: "keyboard-shortcuts"},
            {label: $t({defaultMessage: "Message formatting"}), key: "message-formatting"},
            {label: $t({defaultMessage: "Search operators"}), key: "search-operators"},
        ],
        callback(name, key) {
            $(".overlay-modal").hide();
            $(`#${CSS.escape(key)}`).show();
            ui.get_scroll_element($(`#${CSS.escape(key)}`).find(".modal-body")).trigger("focus");
        },
    };

    toggler = components.toggle(opts);
    const $elem = toggler.get();
    $elem.addClass("large allow-overflow");

    const modals = opts.values.map((item) => {
        const key = item.key; // e.g. message-formatting
        const $modal = $(`#${CSS.escape(key)}`).find(".modal-body");
        return $modal;
    });

    for (const $modal of modals) {
        ui.get_scroll_element($modal).prop("tabindex", 0);
        keydown_util.handle({
            $elem: $modal,
            handlers: {
                ArrowLeft: toggler.maybe_go_left,
                ArrowRight: toggler.maybe_go_right,
            },
        });
    }

    $(".informational-overlays .overlay-tabs").append($elem);

    $("#go-to-default-view-hotkey-help").toggleClass(
        "notdisplayed",
        !user_settings.escape_navigates_to_default_view,
    );
    common.adjust_mac_shortcuts(".hotkeys_table .hotkey kbd");
    common.adjust_mac_shortcuts("#markdown-instructions kbd");
}

export function show(target) {
    if (!toggler) {
        set_up_toggler();
    }

    const $overlay = $(".informational-overlays");

    if (!$overlay.hasClass("show")) {
        overlays.open_overlay({
            name: "informationalOverlays",
            $overlay,
            on_close() {
                browser_history.exit_overlay();
            },
        });
    }

    if (target) {
        toggler.goto(target);
    }
}
<|endoftext|>


<commit_before>/*
 * Copyright 2013 Mozilla Foundation
 *
 * 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.
 */

var Matrix3DDefinition = (function () {
  return {
    // (v:Vector = null)
    __class__: "flash.geom.Matrix3D",
    initialize: function () {
    },
    __glue__: {
      native: {
        static: {
          interpolate: function interpolate(thisMat, toMat, percent) { // (thisMat:Matrix3D, toMat:Matrix3D, percent:Number) -> Matrix3D
            notImplemented("Matrix3D.interpolate");
          }
        },
        instance: {
          ctor: function ctor(v) { // (v:Vector) -> void
            notImplemented("Matrix3D.ctor");
          },
          clone: function clone() { // (void) -> Matrix3D
            notImplemented("Matrix3D.clone");
          },
          copyToMatrix3D: function copyToMatrix3D(dest) { // (dest:Matrix3D) -> void
            notImplemented("Matrix3D.copyToMatrix3D");
          },
          append: function append(lhs) { // (lhs:Matrix3D) -> void
            notImplemented("Matrix3D.append");
          },
          prepend: function prepend(rhs) { // (rhs:Matrix3D) -> void
            notImplemented("Matrix3D.prepend");
          },
          invert: function invert() { // (void) -> Boolean
            notImplemented("Matrix3D.invert");
          },
          identity: function identity() { // (void) -> void
            notImplemented("Matrix3D.identity");
          },
          decompose: function decompose(orientationStyle) { // (orientationStyle:String = "eulerAngles") -> Vector
            notImplemented("Matrix3D.decompose");
          },
          recompose: function recompose(components, orientationStyle) { // (components:Vector, orientationStyle:String = "eulerAngles") -> Boolean
            notImplemented("Matrix3D.recompose");
          },
          appendTranslation: function appendTranslation(x, y, z) { // (x:Number, y:Number, z:Number) -> void
            notImplemented("Matrix3D.appendTranslation");
          },
          appendRotation: function appendRotation(degrees, axis, pivotPoint) { // (degrees:Number, axis:Vector3D, pivotPoint:Vector3D = null) -> void
            notImplemented("Matrix3D.appendRotation");
          },
          appendScale: function appendScale(xScale, yScale, zScale) { // (xScale:Number, yScale:Number, zScale:Number) -> void
            notImplemented("Matrix3D.appendScale");
          },
          prependTranslation: function prependTranslation(x, y, z) { // (x:Number, y:Number, z:Number) -> void
            notImplemented("Matrix3D.prependTranslation");
          },
          prependRotation: function prependRotation(degrees, axis, pivotPoint) { // (degrees:Number, axis:Vector3D, pivotPoint:Vector3D = null) -> void
            notImplemented("Matrix3D.prependRotation");
          },
          prependScale: function prependScale(xScale, yScale, zScale) { // (xScale:Number, yScale:Number, zScale:Number) -> void
            notImplemented("Matrix3D.prependScale");
          },
          transformVector: function transformVector(v) { // (v:Vector3D) -> Vector3D
            notImplemented("Matrix3D.transformVector");
          },
          deltaTransformVector: function deltaTransformVector(v) { // (v:Vector3D) -> Vector3D
            notImplemented("Matrix3D.deltaTransformVector");
          },
          transformVectors: function transformVectors(vin, vout) { // (vin:Vector, vout:Vector) -> void
            notImplemented("Matrix3D.transformVectors");
          },
          transpose: function transpose() { // (void) -> void
            notImplemented("Matrix3D.transpose");
          },
          pointAt: function pointAt(pos, at, up) { // (pos:Vector3D, at:Vector3D = null, up:Vector3D = null) -> void
            notImplemented("Matrix3D.pointAt");
          },
          interpolateTo: function interpolateTo(toMat, percent) { // (toMat:Matrix3D, percent:Number) -> void
            notImplemented("Matrix3D.interpolateTo");
          },
          copyFrom: function copyFrom(sourceMatrix3D) { // (sourceMatrix3D:Matrix3D) -> void
            notImplemented("Matrix3D.copyFrom");
          },
          copyRawDataTo: function copyRawDataTo(vector, index, transpose) { // (vector:Vector, index:uint = 0, transpose:Boolean = false) -> void
            notImplemented("Matrix3D.copyRawDataTo");
          },
          copyRawDataFrom: function copyRawDataFrom(vector, index, transpose) { // (vector:Vector, index:uint = 0, transpose:Boolean = false) -> void
            notImplemented("Matrix3D.copyRawDataFrom");
          },
          copyRowTo: function copyRowTo(row, vector3D) { // (row:uint, vector3D:Vector3D) -> void
            notImplemented("Matrix3D.copyRowTo");
          },
          copyColumnTo: function copyColumnTo(column, vector3D) { // (column:uint, vector3D:Vector3D) -> void
            notImplemented("Matrix3D.copyColumnTo");
          },
          copyRowFrom: function copyRowFrom(row, vector3D) { // (row:uint, vector3D:Vector3D) -> void
            notImplemented("Matrix3D.copyRowFrom");
          },
          copyColumnFrom: function copyColumnFrom(column, vector3D) { // (column:uint, vector3D:Vector3D) -> void
            notImplemented("Matrix3D.copyColumnFrom");
          },
          rawData: {
            get: function rawData() { // (void) -> Vector
              notImplemented("Matrix3D.rawData");
              return this._rawData;
            },
            set: function rawData(v) { // (v:Vector) -> void
              notImplemented("Matrix3D.rawData");
              this._rawData = v;
            }
          },
          position: {
            get: function position() { // (void) -> Vector3D
              notImplemented("Matrix3D.position");
              return this._position;
            },
            set: function position(pos) { // (pos:Vector3D) -> void
              notImplemented("Matrix3D.position");
              this._position = pos;
            }
          },
          determinant: {
            get: function determinant() { // (void) -> Number
              notImplemented("Matrix3D.determinant");
              return this._determinant;
            }
          }
        }
      },
      script: { Glue.ALL }
    }
  };
}).call(this);
<commit_msg>Type-o.<commit_after>/*
 * Copyright 2013 Mozilla Foundation
 *
 * 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.
 */

var Matrix3DDefinition = (function () {
  return {
    // (v:Vector = null)
    __class__: "flash.geom.Matrix3D",
    initialize: function () {
    },
    __glue__: {
      native: {
        static: {
          interpolate: function interpolate(thisMat, toMat, percent) { // (thisMat:Matrix3D, toMat:Matrix3D, percent:Number) -> Matrix3D
            notImplemented("Matrix3D.interpolate");
          }
        },
        instance: {
          ctor: function ctor(v) { // (v:Vector) -> void
            notImplemented("Matrix3D.ctor");
          },
          clone: function clone() { // (void) -> Matrix3D
            notImplemented("Matrix3D.clone");
          },
          copyToMatrix3D: function copyToMatrix3D(dest) { // (dest:Matrix3D) -> void
            notImplemented("Matrix3D.copyToMatrix3D");
          },
          append: function append(lhs) { // (lhs:Matrix3D) -> void
            notImplemented("Matrix3D.append");
          },
          prepend: function prepend(rhs) { // (rhs:Matrix3D) -> void
            notImplemented("Matrix3D.prepend");
          },
          invert: function invert() { // (void) -> Boolean
            notImplemented("Matrix3D.invert");
          },
          identity: function identity() { // (void) -> void
            notImplemented("Matrix3D.identity");
          },
          decompose: function decompose(orientationStyle) { // (orientationStyle:String = "eulerAngles") -> Vector
            notImplemented("Matrix3D.decompose");
          },
          recompose: function recompose(components, orientationStyle) { // (components:Vector, orientationStyle:String = "eulerAngles") -> Boolean
            notImplemented("Matrix3D.recompose");
          },
          appendTranslation: function appendTranslation(x, y, z) { // (x:Number, y:Number, z:Number) -> void
            notImplemented("Matrix3D.appendTranslation");
          },
          appendRotation: function appendRotation(degrees, axis, pivotPoint) { // (degrees:Number, axis:Vector3D, pivotPoint:Vector3D = null) -> void
            notImplemented("Matrix3D.appendRotation");
          },
          appendScale: function appendScale(xScale, yScale, zScale) { // (xScale:Number, yScale:Number, zScale:Number) -> void
            notImplemented("Matrix3D.appendScale");
          },
          prependTranslation: function prependTranslation(x, y, z) { // (x:Number, y:Number, z:Number) -> void
            notImplemented("Matrix3D.prependTranslation");
          },
          prependRotation: function prependRotation(degrees, axis, pivotPoint) { // (degrees:Number, axis:Vector3D, pivotPoint:Vector3D = null) -> void
            notImplemented("Matrix3D.prependRotation");
          },
          prependScale: function prependScale(xScale, yScale, zScale) { // (xScale:Number, yScale:Number, zScale:Number) -> void
            notImplemented("Matrix3D.prependScale");
          },
          transformVector: function transformVector(v) { // (v:Vector3D) -> Vector3D
            notImplemented("Matrix3D.transformVector");
          },
          deltaTransformVector: function deltaTransformVector(v) { // (v:Vector3D) -> Vector3D
            notImplemented("Matrix3D.deltaTransformVector");
          },
          transformVectors: function transformVectors(vin, vout) { // (vin:Vector, vout:Vector) -> void
            notImplemented("Matrix3D.transformVectors");
          },
          transpose: function transpose() { // (void) -> void
            notImplemented("Matrix3D.transpose");
          },
          pointAt: function pointAt(pos, at, up) { // (pos:Vector3D, at:Vector3D = null, up:Vector3D = null) -> void
            notImplemented("Matrix3D.pointAt");
          },
          interpolateTo: function interpolateTo(toMat, percent) { // (toMat:Matrix3D, percent:Number) -> void
            notImplemented("Matrix3D.interpolateTo");
          },
          copyFrom: function copyFrom(sourceMatrix3D) { // (sourceMatrix3D:Matrix3D) -> void
            notImplemented("Matrix3D.copyFrom");
          },
          copyRawDataTo: function copyRawDataTo(vector, index, transpose) { // (vector:Vector, index:uint = 0, transpose:Boolean = false) -> void
            notImplemented("Matrix3D.copyRawDataTo");
          },
          copyRawDataFrom: function copyRawDataFrom(vector, index, transpose) { // (vector:Vector, index:uint = 0, transpose:Boolean = false) -> void
            notImplemented("Matrix3D.copyRawDataFrom");
          },
          copyRowTo: function copyRowTo(row, vector3D) { // (row:uint, vector3D:Vector3D) -> void
            notImplemented("Matrix3D.copyRowTo");
          },
          copyColumnTo: function copyColumnTo(column, vector3D) { // (column:uint, vector3D:Vector3D) -> void
            notImplemented("Matrix3D.copyColumnTo");
          },
          copyRowFrom: function copyRowFrom(row, vector3D) { // (row:uint, vector3D:Vector3D) -> void
            notImplemented("Matrix3D.copyRowFrom");
          },
          copyColumnFrom: function copyColumnFrom(column, vector3D) { // (column:uint, vector3D:Vector3D) -> void
            notImplemented("Matrix3D.copyColumnFrom");
          },
          rawData: {
            get: function rawData() { // (void) -> Vector
              notImplemented("Matrix3D.rawData");
              return this._rawData;
            },
            set: function rawData(v) { // (v:Vector) -> void
              notImplemented("Matrix3D.rawData");
              this._rawData = v;
            }
          },
          position: {
            get: function position() { // (void) -> Vector3D
              notImplemented("Matrix3D.position");
              return this._position;
            },
            set: function position(pos) { // (pos:Vector3D) -> void
              notImplemented("Matrix3D.position");
              this._position = pos;
            }
          },
          determinant: {
            get: function determinant() { // (void) -> Number
              notImplemented("Matrix3D.determinant");
              return this._determinant;
            }
          }
        }
      },
      script: { instance: Glue.ALL }
    }
  };
}).call(this);
<|endoftext|>


<commit_before>import $ from 'jquery'
import Dropdown from '../../com/dropdown'
import NavTree from '../../com/nav-tree'
import './api.scss'

function getVersion(element) {
  let version = $(element).attr('data-kotlin-version');
  if (version.startsWith("Kotlin ")) {
    version = version.substring("Kotlin ".length)
  }
  return version
}

function updateState(state) {
  localStorage.setItem("apiState", JSON.stringify(state));
  const $platformDependentElements = $('[data-platform]');
  const $versionDependentElements = $('[data-kotlin-version]');
  $versionDependentElements.removeClass('hidden');
  $platformDependentElements.removeClass('hidden');

  if (state.platform.toLowerCase() != 'all') {
    $platformDependentElements.each((ind, element) => {
      const $element = $(element);
      if ($element.attr('data-platform').toLowerCase() == state.platform.toLowerCase()) return;
      $element.addClass('hidden')
    })
  }

  $versionDependentElements.each((ind, element) => {
    const $element = $(element);
    const version = getVersion(element);
    if (version <= state.version) return;
    $element.addClass('hidden')
  })
}

function addSelectToPanel(panelElement, title, config) {
  const selectElement = $(`<div class="api-panel__select"><span class="api-panel__dropdown-title">${title}</span></div>`);
  $(panelElement).append(selectElement);
  new Dropdown(selectElement, config);
}

function initializeSelects() {
  const $breadcrumbs = $('.api-docs-breadcrumbs');
  if ($breadcrumbs.length > 0) {
    $breadcrumbs
      .wrap('

')
      .after('

');
  } else {
    $('.page-content').prepend('

');
  }

  const switchersPanel = $('.api-panel__switchers')[0];

  const state = localStorage.getItem("apiState") ?
    JSON.parse(localStorage.getItem("apiState")) :
    {
      platform: 'all',
      version: '1.2'
    };
  updateState(state);

  addSelectToPanel(switchersPanel, "Platform", {
    items: {
      'all': 'All',
      'jvm': 'JVM',
      'js': 'JS'
    },
    selected: state.platform,
    onSelect: (platform) => {
      state.platform = platform;
      updateState(state)
    }
  });

  addSelectToPanel(switchersPanel, "Version", {
    items: {
      '1.0': '1.0',
      '1.1': '1.1',
      '1.2': '1.2'
    },
    selected: state.version,
    onSelect: (version) => {
      state.version = version;
      updateState(state)
    }
  })
}

function addTag(rowElement, tag) {
  let $tagsElement = $(rowElement).find('.tags');
  if ($tagsElement.length == 0) {
    $tagsElement = $('

');
    $(rowElement).find('td:first').append($tagsElement);
  }
  $tagsElement.append(`<div class="tags__tag">${tag}</div>`)
}

function addTags() {
  $('[data-platform]').each((ind, element) => {
    const platform = element.getAttribute('data-platform');
    addTag(element, platform)
  });

  $('[data-kotlin-version]').each((ind, element) => addTag(element, getVersion(element)));

  $('[data-jre-version]').each((ind, element) => {
    const platform = element.getAttribute('data-jre-version');
    addTag(element, platform)
  });
}

$(document).ready(() => {
  initializeSelects();
  addTags();
  new NavTree(document.querySelector('.js-side-tree-nav'));
});
<commit_msg>Don't save latest version to localStorage.<commit_after>import $ from 'jquery'
import Dropdown from '../../com/dropdown'
import NavTree from '../../com/nav-tree'
import './api.scss'

const DEFAULT_VERSION = '1.2';
const LOCAL_STORAGE_KEY = 'targetApi';

function getVersion(element) {
  let version = $(element).attr('data-kotlin-version');
  if (version.startsWith("Kotlin ")) {
    version = version.substring("Kotlin ".length)
  }
  return version
}

function updateState(state) {
  localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(state));
  const $platformDependentElements = $('[data-platform]');
  const $versionDependentElements = $('[data-kotlin-version]');
  $versionDependentElements.removeClass('hidden');
  $platformDependentElements.removeClass('hidden');

  if (state.platform.toLowerCase() != 'all') {
    $platformDependentElements.each((ind, element) => {
      const $element = $(element);
      if ($element.attr('data-platform').toLowerCase() == state.platform.toLowerCase()) return;
      $element.addClass('hidden')
    })
  }

  $versionDependentElements.each((ind, element) => {
    const $element = $(element);
    const version = getVersion(element);
    if (state.version == null || version <= state.version) return;
    $element.addClass('hidden')
  })
}

function addSelectToPanel(panelElement, title, config) {
  const selectElement = $(`<div class="api-panel__select"><span class="api-panel__dropdown-title">${title}</span></div>`);
  $(panelElement).append(selectElement);
  new Dropdown(selectElement, config);
}

function initializeSelects() {
  const $breadcrumbs = $('.api-docs-breadcrumbs');
  if ($breadcrumbs.length > 0) {
    $breadcrumbs
      .wrap('

')
      .after('

');
  } else {
    $('.page-content').prepend('

');
  }

  const switchersPanel = $('.api-panel__switchers')[0];

  const state = localStorage.getItem(LOCAL_STORAGE_KEY) ?
    JSON.parse(localStorage.getItem(LOCAL_STORAGE_KEY)) :
    {
      platform: 'all'
    };
  updateState(state);

  addSelectToPanel(switchersPanel, "Platform", {
    items: {
      'all': 'All',
      'jvm': 'JVM',
      'js': 'JS'
    },
    selected: state.platform,
    onSelect: (platform) => {
      state.platform = platform;
      updateState(state)
    }
  });

  addSelectToPanel(switchersPanel, "Version", {
    items: {
      '1.0': '1.0',
      '1.1': '1.1',
      '1.2': '1.2'
    },
    selected: state.version != null ? state.version : DEFAULT_VERSION,
    onSelect: (version) => {
      if(version != DEFAULT_VERSION){
        state.version = version;
      } else {
        delete state.version;
      }
      updateState(state)
    }
  })
}

function addTag(rowElement, tag) {
  let $tagsElement = $(rowElement).find('.tags');
  if ($tagsElement.length == 0) {
    $tagsElement = $('

');
    $(rowElement).find('td:first').append($tagsElement);
  }
  $tagsElement.append(`<div class="tags__tag">${tag}</div>`)
}

function addTags() {
  $('[data-platform]').each((ind, element) => {
    const platform = element.getAttribute('data-platform');
    addTag(element, platform)
  });

  $('[data-kotlin-version]').each((ind, element) => addTag(element, getVersion(element)));

  $('[data-jre-version]').each((ind, element) => {
    const platform = element.getAttribute('data-jre-version');
    addTag(element, platform)
  });
}

$(document).ready(() => {
  initializeSelects();
  addTags();
  new NavTree(document.querySelector('.js-side-tree-nav'));
});
<|endoftext|>


<commit_before>//redirecter.js
var qs = require('querystring');

module.exports = function (req, res) {
  var referer = req.headers.referer.split('/')[3] || 'rooster';
  var _data = '';

  req.on('data', function (data) {
    _data += data;
  });

  req.on('end', function () {
    var query = qs.parse(_data);

    if (query && query.search != '') {
      query.search = query.search.trim();

      if (query.search == 'hoewerkt') res.redirect('http://hoewerkt.werkmanrooster.nl');
      res.redirect('/' + referer + '/' + query.search);
    }
  });

}
<commit_msg>Made the user go back to the main page if query is empty.<commit_after>//redirecter.js
var qs = require('querystring');

module.exports = function (req, res) {
  var referer = req.headers.referer.split('/')[3] || 'rooster';
  var _data = '';

  req.on('data', function (data) {
    _data += data;
  });

  req.on('end', function () {
    var query = qs.parse(_data);

    if (query && query.search != '') {
      query.search = query.search.trim();

      if (query.search == 'hoewerkt') res.redirect('http://hoewerkt.werkmanrooster.nl');
      res.redirect('/' + referer + '/' + query.search);
    }
    else {
      res.redirect('/');
    }
  });

}
<|endoftext|>