All Downloads are FREE. Search and download functionalities are using the official Maven repository.

web.script.plugin.js Maven / Gradle / Ivy

There is a newer version: 4.9.2
Show newest version
dm4c.add_plugin("de.deepamehta.topicmaps", function() {

    dm4c.load_script("/de.deepamehta.topicmaps/script/plugin_model.js")
    dm4c.load_script("/de.deepamehta.topicmaps/script/plugin_view.js")
    dm4c.load_script("/de.deepamehta.topicmaps/script/topicmap_viewmodel.js")

    var model = new TopicmapsPluginModel()
    var view = new TopicmapsPluginView({
        get_topicmap:               model.get_topicmap,
        get_topicmap_renderer:      model.get_current_topicmap_renderer,
        get_topicmap_topics:        model.get_topicmap_topics,
        iterate_topicmap_renderers: model.iterate_topicmap_renderers,
        select_topicmap: select_topicmap,
        create_topicmap: create_topicmap
    })

    var self = this



    // === REST Client Extension ===

    dm4c.restc.create_topicmap = function(name, topicmap_renderer_uri, private) {
        var params = this.queryParams({
            name:         name,
            renderer_uri: topicmap_renderer_uri,
            private:      private,
        })
        return this.request("POST", "/topicmap" + params)
    }

    /**
     * @param   include_childs (boolean)    Optional: if true the topics contained in the returned topicmap will
     *                                      include their child topics. Default is false.
     */
    dm4c.restc.get_topicmap = function(topicmap_id, include_childs) {
        var params = this.queryParams({include_childs: include_childs})
        return this.request("GET", "/topicmap/" + topicmap_id + params)
    }
    dm4c.restc.add_topic_to_topicmap = function(topicmap_id, topic_id, view_props) {
        this.request("POST", "/topicmap/" + topicmap_id + "/topic/" + topic_id, view_props)
    }
    dm4c.restc.add_association_to_topicmap = function(topicmap_id, assoc_id) {
        this.request("POST", "/topicmap/" + topicmap_id + "/association/" + assoc_id)
    }
    dm4c.restc.set_view_properties = function(topicmap_id, topic_id, view_props) {
        this.request("PUT", "/topicmap/" + topicmap_id + "/topic/" + topic_id, view_props)
    }
    dm4c.restc.set_topic_position = function(topicmap_id, topic_id, x, y) {
        this.request("PUT", "/topicmap/" + topicmap_id + "/topic/" + topic_id + "/" + x + "/" + y)
    }
    dm4c.restc.set_topic_visibility = function(topicmap_id, topic_id, visibility) {
        this.request("PUT", "/topicmap/" + topicmap_id + "/topic/" + topic_id + "/" + visibility)
    }
    dm4c.restc.remove_association_from_topicmap = function(topicmap_id, assoc_id) {
        this.request("DELETE", "/topicmap/" + topicmap_id + "/association/" + assoc_id)
    }
    dm4c.restc.set_cluster_position = function(topicmap_id, cluster_coords) {
        this.request("PUT", "/topicmap/" + topicmap_id, cluster_coords)
    }
    dm4c.restc.set_topicmap_translation = function(topicmap_id, trans_x, trans_y) {
        this.request("PUT", "/topicmap/" + topicmap_id + "/translation/" + trans_x + "/" + trans_y)
    }



    // === Webclient Listeners ===

    /**
     * Registers the installed topicmap renderers.
     * Tries to obtain a valid topicmap ID from browser URL or cookie.
     *
     * Note: plugins are supposed to register their view customizers and viewmodel customizers at init(2) stage.
     * Registering the topicmap renderers at init(1) stage ensures they are available for being customized.
     */
    dm4c.add_listener("init", function() {
        model.init()
    })

    /**
     * Displays the initial topicmap.
     *
     * Note: the Workspaces plugin initializes at init(2) stage. Initializing the topicmaps model at init(3) stage
     * ensures the workspace widget is already added to the toolbar and a selected workspace is already known.
     *
     * Note: plugins are supposed to register their view customizers and viewmodel customizers at init(2) stage.
     * Displaying the initial topicmap at init(3) stage ensures all customizers are registered already.
     */
    dm4c.add_listener("init_3", function() {
        // init model
        model.init_2()
        // init view
        view.create_topicmap_widget()
        view.display_topicmap()                  // ### FIXME: rethink about history update
    })

    /**
     * @param   topic   a Topic object
     */
    dm4c.add_listener("post_update_topic", function(topic) {
        // update the topicmap menu
        if (topic.type_uri == "dm4.topicmaps.topicmap") {
            // update model
            model.fetch_topicmap_topics()
            // update view
            view.refresh_topicmap_menu()
        }
    })

    dm4c.add_listener("pre_push_history", function(history_entry) {
        var topicmap_id = model.get_topicmap().get_id()
        history_entry.state.topicmap_id = topicmap_id
        history_entry.url = "/topicmap/" + topicmap_id + history_entry.url
    })

    dm4c.add_listener("pre_pop_history", function(state) {
        if (state.topicmap_id != model.get_topicmap().get_id()) {
            // switch topicmap
            self.select_topicmap(state.topicmap_id, true)       // no_history_update=true
            return false
        } else if (!state.topic_id) {
            // topicmap not changed and no topic in popstate
            dm4c.do_reset_selection(true)                       // no_history_update=true
            return false
        }
    })

    dm4c.add_listener("pre_draw_canvas", function(ctx) {
        // update view
        //
        // Note: topicmap is undefined if canvas draw() is performed before the Topicmaps plugin is initialized.
        var topicmap = model.get_topicmap()
        topicmap && topicmap.draw_background(ctx)
    })



    // === Workspace Listeners ===

    dm4c.add_listener("post_select_workspace", function(workspace_id) {
        // update model
        model.select_topicmap_for_workspace(workspace_id)
        // update view
        view.refresh_topicmap_menu()
        view.display_topicmap()
    })



    // === Access Control Listeners ===

    dm4c.add_listener("logged_in", function(username) {
        // 1) update model
        //
        // Note: a user can have private topicmaps in several workspaces.
        // So, when the authority changes the topicmap topics for ALL workspaces must be invalidated.
        model.clear_topicmap_topics()
        // Note: when the authority changes the contents of ALL topicmaps in ALL workspaces are affected.
        // So, the entire topicmap cache must be invalidated.
        model.clear_topicmap_cache()
        //
        // Note: when logging in the user always stays in the selected workspace.
        // The workspace is never programmatically switched in response to a login.
        // So, we refetch the topicmap topics for the CURRENT workspace.
        model.fetch_topicmap_topics()
        // Note: when logging in the user always stays in the selected topicmap.
        // The topicmap is never programmatically switched in response to a login.
        // So, we reload the CURRENT topicmap.
        model.reload_topicmap()
        //
        // 2) update view
        view.refresh_topicmap_menu()
        view.display_topicmap()
    })

    dm4c.add_listener("authority_decreased", function() {
        // Note: a user can have private topicmaps in several workspaces.
        // So, when the authority changes the topicmap topics for ALL workspaces must be invalidated.
        model.clear_topicmap_topics()
        // Note: when the authority changes the contents of ALL topicmaps in ALL workspaces are affected.
        // So, the entire topicmap cache must be invalidated.
        model.clear_topicmap_cache()
        //
        // Note: when the authority decreases the workspace and/or the topicmap may switch programmatically.
        // The topicmap menu and the topicmap is refreshed by the "post_select_workspace" listener (above)
    })



    // ------------------------------------------------------------------------------------------------------ Public API

    /**
     * @return  The selected topicmap
     */
    this.get_topicmap = function() {
        return model.get_topicmap()
    }

    this.iterate_topicmaps = function(visitor_func) {
        model.iterate_topicmap_cache(visitor_func)
    }

    this.get_topicmap_renderer = function(renderer_uri) {
        return model.get_topicmap_renderer(renderer_uri)
    }

    /**
     * Selects a topicmap programmatically.
     * The respective item from the topicmap menu is selected and the topicmap is displayed.
     *
     * @param   no_history_update   Optional: boolean.
     */
    this.select_topicmap = function(topicmap_id, no_history_update) {
        // update model + view
        select_topicmap(topicmap_id, no_history_update)
        // update view
        view.refresh_menu_item()
    }

    // ---

    /**
     * Creates a topicmap with the given name, puts it in the topicmap menu, and displays the topicmap.
     *
     * @param   topicmap_renderer_uri   Optional: the topicmap renderer to attach to the topicmap.
     *                                  Default is "dm4.webclient.default_topicmap_renderer".
     *
     * @return  the topicmap topic.
     */
    this.create_topicmap = function(name, topicmap_renderer_uri, private) {
        return create_topicmap(name, topicmap_renderer_uri, private)
    }

    /**
     * Puts a new topicmap in the topicmap menu, selects and displays it.
     * Plugins call this method when they have created a topicmap (at server-side) and now want display it.
     */
    this.add_topicmap = function(topicmap_id) {
        add_topicmap(topicmap_id)
    }

    /**
     * Deletes a topicmap in the DB and updates the client model and view.
     * 

* It is not a requirement that the topicmap is assigned to the workspace which is currently selected. *

* Note: the model/view update is not performed in a "post_delete_topic" listener. It would get in the way with * the delete-workspace action. While the model/view update requests would be sent to objects already deleted in * the DB. ### TODO: explain better. Which requests are sent? Could we use the "pre_delete_topic" listener? *

* (called from Webclient's default_plugin.js) */ this.delete_topicmap = function(topicmap_id) { console.log("delete_topicmap(" + topicmap_id + ")") // Note: the workspace must be determined *before* the topicmap is deleted from DB var workspace_id = get_workspace_id_of_topicmap(topicmap_id) // 1) update DB dm4c.do_delete_topic(topicmap_id) // 2) update model var is_current_topicmap = model.delete_topicmap(topicmap_id, workspace_id) // 3) update view if (workspace_id == model.get_selected_workspace_id()) { view.refresh_topicmap_menu() if (is_current_topicmap) { view.display_topicmap() } } } // --- this._get_initial_topicmap_id = function() { return model._get_initial_topicmap_id() } this._drop_initial_state = function() { return model._drop_initial_state() } // ----------------------------------------------------------------------------------------------- Private Functions // ************************* // *** Controller Helper *** // ************************* /** * Updates the model to reflect the given topicmap is now selected, and displays it. *

* Prerequisite: the topicmap menu already shows the selected topicmap. * * @param no_history_update Optional: boolean. */ function select_topicmap(topicmap_id, no_history_update) { // update model model.set_selected_topicmap(topicmap_id) // update view view.display_topicmap(no_history_update) } /** * Creates a topicmap with the given name, puts it in the topicmap menu, and displays it. * * @param topicmap_renderer_uri Optional: the topicmap renderer to attach to the topicmap. * Default is "dm4.webclient.default_topicmap_renderer". * * @return the topicmap topic. */ function create_topicmap(name, topicmap_renderer_uri, private) { // update DB var topicmap_topic = create_topicmap_topic(name, topicmap_renderer_uri, private) // update model + view add_topicmap(topicmap_topic.id) // return topicmap_topic } /** * ### TODO: drop this (copy in plugin.js) * * Creates an empty topicmap (a topic of type "Topicmap") in the DB. * * @param name The name of the topicmap * @param topicmap_renderer_uri Optional: the topicmap renderer to attach to the topicmap. * Default is "dm4.webclient.default_topicmap_renderer". * * @return The created Topicmap topic. */ function create_topicmap_topic(name, topicmap_renderer_uri, private) { return dm4c.restc.create_topicmap(name, topicmap_renderer_uri || "dm4.webclient.default_topicmap_renderer", private) } /** * Puts a new topicmap in the topicmap menu, selects and displays it. * This is called when a new topicmap is created at server-side and now should be displayed. */ function add_topicmap(topicmap_id) { // update model model.fetch_topicmap_topics() model.set_selected_topicmap(topicmap_id) // update view view.refresh_topicmap_menu() view.display_topicmap() } // --- function get_workspace_id_of_topicmap(topicmap_id) { var workspace = dm4c.restc.get_assigned_workspace(topicmap_id) if (!workspace) { throw "TopicmapsPluginError: topicmap " + topicmap_id + " is not assigned to any workspace" } return workspace.id } }) // Enable debugging for dynamically loaded scripts: //# sourceURL=topicmaps_plugin.js





© 2015 - 2024 Weber Informatics LLC | Privacy Policy