From b210bddba6f65b0352cd2f097d91a39913e5488c Mon Sep 17 00:00:00 2001 From: whytheplatypus Date: Sat, 9 Jun 2012 11:14:51 -0400 Subject: [PATCH] =?UTF-8?q?documentation=20start=E2=80=A6.=20and=20testing?= =?UTF-8?q?=20the=20dev=20branch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- htdocs/js/apps/LibraryBrowser/docs/docco.css | 186 +++++ .../LibraryBrowser/docs/library_browser.html | 446 ++++++++++ htdocs/js/lib/webwork/out/api.js | 17 + .../webwork/out/assets/css/external-small.png | Bin 0 -> 491 bytes htdocs/js/lib/webwork/out/assets/css/logo.png | Bin 0 -> 6308 bytes htdocs/js/lib/webwork/out/assets/css/main.css | 782 ++++++++++++++++++ htdocs/js/lib/webwork/out/assets/favicon.png | Bin 0 -> 740 bytes .../js/lib/webwork/out/assets/img/spinner.gif | Bin 0 -> 2685 bytes htdocs/js/lib/webwork/out/assets/index.html | 10 + .../lib/webwork/out/assets/js/api-filter.js | 52 ++ .../js/lib/webwork/out/assets/js/api-list.js | 251 ++++++ .../lib/webwork/out/assets/js/api-search.js | 98 +++ .../js/lib/webwork/out/assets/js/apidocs.js | 351 ++++++++ htdocs/js/lib/webwork/out/assets/js/tabs.js | 38 + .../lib/webwork/out/assets/js/yui-prettify.js | 17 + .../out/assets/vendor/prettify/CHANGES.html | 130 +++ .../out/assets/vendor/prettify/COPYING | 202 +++++ .../out/assets/vendor/prettify/README.html | 203 +++++ .../assets/vendor/prettify/prettify-min.css | 1 + .../assets/vendor/prettify/prettify-min.js | 35 + htdocs/js/lib/webwork/out/classes/index.html | 10 + .../js/lib/webwork/out/classes/webwork.html | 509 ++++++++++++ htdocs/js/lib/webwork/out/data.json | 222 +++++ .../js/lib/webwork/out/files/WeBWorK.js.html | 371 +++++++++ htdocs/js/lib/webwork/out/files/index.html | 10 + .../webwork/out/files/teacher_Library.js.html | 192 +++++ .../webwork/out/files/teacher_Problem.js.html | 204 +++++ .../lib/webwork/out/files/teacher_Set.js.html | 129 +++ htdocs/js/lib/webwork/out/index.html | 124 +++ .../js/lib/webwork/out/modules/WeBWorK.html | 147 ++++ htdocs/js/lib/webwork/out/modules/index.html | 10 + lib/WeBWorK/Constants.pm | 2 +- 32 files changed, 4748 insertions(+), 1 deletion(-) create mode 100644 htdocs/js/apps/LibraryBrowser/docs/docco.css create mode 100644 htdocs/js/apps/LibraryBrowser/docs/library_browser.html create mode 100644 htdocs/js/lib/webwork/out/api.js create mode 100644 htdocs/js/lib/webwork/out/assets/css/external-small.png create mode 100644 htdocs/js/lib/webwork/out/assets/css/logo.png create mode 100644 htdocs/js/lib/webwork/out/assets/css/main.css create mode 100644 htdocs/js/lib/webwork/out/assets/favicon.png create mode 100644 htdocs/js/lib/webwork/out/assets/img/spinner.gif create mode 100644 htdocs/js/lib/webwork/out/assets/index.html create mode 100644 htdocs/js/lib/webwork/out/assets/js/api-filter.js create mode 100644 htdocs/js/lib/webwork/out/assets/js/api-list.js create mode 100644 htdocs/js/lib/webwork/out/assets/js/api-search.js create mode 100644 htdocs/js/lib/webwork/out/assets/js/apidocs.js create mode 100644 htdocs/js/lib/webwork/out/assets/js/tabs.js create mode 100644 htdocs/js/lib/webwork/out/assets/js/yui-prettify.js create mode 100644 htdocs/js/lib/webwork/out/assets/vendor/prettify/CHANGES.html create mode 100644 htdocs/js/lib/webwork/out/assets/vendor/prettify/COPYING create mode 100644 htdocs/js/lib/webwork/out/assets/vendor/prettify/README.html create mode 100644 htdocs/js/lib/webwork/out/assets/vendor/prettify/prettify-min.css create mode 100644 htdocs/js/lib/webwork/out/assets/vendor/prettify/prettify-min.js create mode 100644 htdocs/js/lib/webwork/out/classes/index.html create mode 100644 htdocs/js/lib/webwork/out/classes/webwork.html create mode 100644 htdocs/js/lib/webwork/out/data.json create mode 100644 htdocs/js/lib/webwork/out/files/WeBWorK.js.html create mode 100644 htdocs/js/lib/webwork/out/files/index.html create mode 100644 htdocs/js/lib/webwork/out/files/teacher_Library.js.html create mode 100644 htdocs/js/lib/webwork/out/files/teacher_Problem.js.html create mode 100644 htdocs/js/lib/webwork/out/files/teacher_Set.js.html create mode 100644 htdocs/js/lib/webwork/out/index.html create mode 100644 htdocs/js/lib/webwork/out/modules/WeBWorK.html create mode 100644 htdocs/js/lib/webwork/out/modules/index.html diff --git a/htdocs/js/apps/LibraryBrowser/docs/docco.css b/htdocs/js/apps/LibraryBrowser/docs/docco.css new file mode 100644 index 000000000..5aa0a8d73 --- /dev/null +++ b/htdocs/js/apps/LibraryBrowser/docs/docco.css @@ -0,0 +1,186 @@ +/*--------------------- Layout and Typography ----------------------------*/ +body { + font-family: 'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif; + font-size: 15px; + line-height: 22px; + color: #252519; + margin: 0; padding: 0; +} +a { + color: #261a3b; +} + a:visited { + color: #261a3b; + } +p { + margin: 0 0 15px 0; +} +h1, h2, h3, h4, h5, h6 { + margin: 0px 0 15px 0; +} + h1 { + margin-top: 40px; + } +#container { + position: relative; +} +#background { + position: fixed; + top: 0; left: 525px; right: 0; bottom: 0; + background: #f5f5ff; + border-left: 1px solid #e5e5ee; + z-index: -1; +} +#jump_to, #jump_page { + background: white; + -webkit-box-shadow: 0 0 25px #777; -moz-box-shadow: 0 0 25px #777; + -webkit-border-bottom-left-radius: 5px; -moz-border-radius-bottomleft: 5px; + font: 10px Arial; + text-transform: uppercase; + cursor: pointer; + text-align: right; +} +#jump_to, #jump_wrapper { + position: fixed; + right: 0; top: 0; + padding: 5px 10px; +} + #jump_wrapper { + padding: 0; + display: none; + } + #jump_to:hover #jump_wrapper { + display: block; + } + #jump_page { + padding: 5px 0 3px; + margin: 0 0 25px 25px; + } + #jump_page .source { + display: block; + padding: 5px 10px; + text-decoration: none; + border-top: 1px solid #eee; + } + #jump_page .source:hover { + background: #f5f5ff; + } + #jump_page .source:first-child { + } +table td { + border: 0; + outline: 0; +} + td.docs, th.docs { + max-width: 450px; + min-width: 450px; + min-height: 5px; + padding: 10px 25px 1px 50px; + overflow-x: hidden; + vertical-align: top; + text-align: left; + } + .docs pre { + margin: 15px 0 15px; + padding-left: 15px; + } + .docs p tt, .docs p code { + background: #f8f8ff; + border: 1px solid #dedede; + font-size: 12px; + padding: 0 0.2em; + } + .pilwrap { + position: relative; + } + .pilcrow { + font: 12px Arial; + text-decoration: none; + color: #454545; + position: absolute; + top: 3px; left: -20px; + padding: 1px 2px; + opacity: 0; + -webkit-transition: opacity 0.2s linear; + } + td.docs:hover .pilcrow { + opacity: 1; + } + td.code, th.code { + padding: 14px 15px 16px 25px; + width: 100%; + vertical-align: top; + background: #f5f5ff; + border-left: 1px solid #e5e5ee; + } + pre, tt, code { + font-size: 12px; line-height: 18px; + font-family: Monaco, Consolas, "Lucida Console", monospace; + margin: 0; padding: 0; + } + + +/*---------------------- Syntax Highlighting -----------------------------*/ +td.linenos { background-color: #f0f0f0; padding-right: 10px; } +span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; } +body .hll { background-color: #ffffcc } +body .c { color: #408080; font-style: italic } /* Comment */ +body .err { border: 1px solid #FF0000 } /* Error */ +body .k { color: #954121 } /* Keyword */ +body .o { color: #666666 } /* Operator */ +body .cm { color: #408080; font-style: italic } /* Comment.Multiline */ +body .cp { color: #BC7A00 } /* Comment.Preproc */ +body .c1 { color: #408080; font-style: italic } /* Comment.Single */ +body .cs { color: #408080; font-style: italic } /* Comment.Special */ +body .gd { color: #A00000 } /* Generic.Deleted */ +body .ge { font-style: italic } /* Generic.Emph */ +body .gr { color: #FF0000 } /* Generic.Error */ +body .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +body .gi { color: #00A000 } /* Generic.Inserted */ +body .go { color: #808080 } /* Generic.Output */ +body .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +body .gs { font-weight: bold } /* Generic.Strong */ +body .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +body .gt { color: #0040D0 } /* Generic.Traceback */ +body .kc { color: #954121 } /* Keyword.Constant */ +body .kd { color: #954121; font-weight: bold } /* Keyword.Declaration */ +body .kn { color: #954121; font-weight: bold } /* Keyword.Namespace */ +body .kp { color: #954121 } /* Keyword.Pseudo */ +body .kr { color: #954121; font-weight: bold } /* Keyword.Reserved */ +body .kt { color: #B00040 } /* Keyword.Type */ +body .m { color: #666666 } /* Literal.Number */ +body .s { color: #219161 } /* Literal.String */ +body .na { color: #7D9029 } /* Name.Attribute */ +body .nb { color: #954121 } /* Name.Builtin */ +body .nc { color: #0000FF; font-weight: bold } /* Name.Class */ +body .no { color: #880000 } /* Name.Constant */ +body .nd { color: #AA22FF } /* Name.Decorator */ +body .ni { color: #999999; font-weight: bold } /* Name.Entity */ +body .ne { color: #D2413A; font-weight: bold } /* Name.Exception */ +body .nf { color: #0000FF } /* Name.Function */ +body .nl { color: #A0A000 } /* Name.Label */ +body .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ +body .nt { color: #954121; font-weight: bold } /* Name.Tag */ +body .nv { color: #19469D } /* Name.Variable */ +body .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ +body .w { color: #bbbbbb } /* Text.Whitespace */ +body .mf { color: #666666 } /* Literal.Number.Float */ +body .mh { color: #666666 } /* Literal.Number.Hex */ +body .mi { color: #666666 } /* Literal.Number.Integer */ +body .mo { color: #666666 } /* Literal.Number.Oct */ +body .sb { color: #219161 } /* Literal.String.Backtick */ +body .sc { color: #219161 } /* Literal.String.Char */ +body .sd { color: #219161; font-style: italic } /* Literal.String.Doc */ +body .s2 { color: #219161 } /* Literal.String.Double */ +body .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */ +body .sh { color: #219161 } /* Literal.String.Heredoc */ +body .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */ +body .sx { color: #954121 } /* Literal.String.Other */ +body .sr { color: #BB6688 } /* Literal.String.Regex */ +body .s1 { color: #219161 } /* Literal.String.Single */ +body .ss { color: #19469D } /* Literal.String.Symbol */ +body .bp { color: #954121 } /* Name.Builtin.Pseudo */ +body .vc { color: #19469D } /* Name.Variable.Class */ +body .vg { color: #19469D } /* Name.Variable.Global */ +body .vi { color: #19469D } /* Name.Variable.Instance */ +body .il { color: #666666 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/htdocs/js/apps/LibraryBrowser/docs/library_browser.html b/htdocs/js/apps/LibraryBrowser/docs/library_browser.html new file mode 100644 index 000000000..ca7430fb9 --- /dev/null +++ b/htdocs/js/apps/LibraryBrowser/docs/library_browser.html @@ -0,0 +1,446 @@ + library_browser.js

library_browser.js

Library Browser 3

+ +

This is the current iteration of the library browser for webwork. +It's built out of models contained in the webwork.* framework that +you can find in the js/lib/webwork folder.

+ +

The idea was to use this as a proof of concept of how to write single page +webapps for webwork out of a general client side framework quickly, easily +and in a way that's maintainable.

+ +

The javascript framework is currently written with extensibility in mind. +So base models in the webwork.js file are added too and additional models are +provided for different situations. For instance since library browser is used +by teachers we include the files in the teacher subdirectory and add in features +like adding and remove problems from a sets ProblemList and browsing a Library.

Start things off by wrapping everything in jquery so it will load after the dom is ready.

$(function () {

Since many of the views we'll define will all want to post alerts and messages to the same place +we define a global template and alert function for them.

    var alert_template = _.template('<div class="alert <%= classes %> fade in"><a class="close" data-dismiss="alert" href="#">×</a><%= message %></div>');

set up alerts to close

    $().alert();
+
+    var alert = function(message, classes){
+        $('#messages').html(alert_template({message: message, classes: classes}));
+        setTimeout(function(){$(".alert").alert('close')}, 5000);
+    };

The problem View

A view defined for the browser app for the webwork Problem model. +There's no reason this same view couldn't be used in other pages almost as is.

    var ProblemView = Backbone.View.extend({

We want the problem to render in a li since it will be included in a list

        tagName:"li",

Add the 'problem' class to every problem

        className: "problem",

This is the template for a problem, the html is defined in SetMaker3.pm

        template: _.template($('#problem-template').html()),

Register events that a problem's view should listen for, +in this case it removes the problem if the button with class 'remove' is clicked.

        events:{
+            "click .remove": 'clear'
+        },

In most model views initialize is used to set up listeners +on the views model.

        initialize:function () {
+            this.model.on('change:data', this.render, this);
+            if(!this.options.remove_display){
+                this.options.remove_display = "block";
+            }
+            this.model.on('destroy', this.remove, this);
+        },
+
+        render:function () {
+            var problem = this.model;
+            var self = this;
+
+            if(problem.get('data')){
+                var jsonInfo = this.model.toJSON();
+                _.extend(jsonInfo, self.options);
+                this.$el.html(this.template(jsonInfo));
+            } else {
+                this.$el.html('<img src="/webwork2_files/images/ajax-loader.gif" alt="loading"/>');
+                problem.render();
+            }
+
+            this.el.setAttribute('data-path', problem.get('path'));
+            this.el.id = this.model.cid;
+            this.$el.draggable({
+                helper:'clone',
+                revert:true,
+                handle:'.problem',
+                appendTo:'body',
+                cursorAt:{
+                    top:0,
+                    left:0
+                },
+                opacity:0.35
+            });
+
+
+            return this;
+        },
+
+        clear: function(){
+            this.model.collection.remove(this.model);
+            this.model.clear();
+        }
+    });

The library View

    var LibraryView = Backbone.View.extend({
+        template:_.template($('#Library-template').html()),
+
+        events:{
+            "click .next_group": "loadNextGroup"
+        },
+
+        initialize: function(){
+            var self = this;
+            this.group_size = 25;
+            this.model.get('problems').on('reset', this.render, this);
+            this.model.get('problems').on('syncing', function(value){
+                if(value){
+                    $("[href=#"+self.model.get('name')+"]").addClass("syncing");
+                } else {
+                    $("[href=#"+self.model.get('name')+"]").removeClass("syncing");
+                }
+            }, this);
+            this.model.get('problems').on('alert', function(message){alert(message);});
+
+            if(!(this.model.get('problems').length > 0)){
+                this.model.get('problems').fetch();
+            }
+        },
+
+        render: function(){
+
+            var self = this;
+
+            if ($('#problems_container #' + this.model.get('name')).length == 0) {
+                $('#problems_container').tabs('add', "#"+this.model.get('name'), this.model.get('name') + " (" + this.model.get('problems').length + ")"); //could move to an after?
+                this.setElement(document.getElementById(this.model.get('name')));
+            } else {

select

                $('#problems_container').tabs('select', this.model.get('name'));
+                $("[href=#"+this.model.get('name')+"]").html(this.model.get('name') + " (" + this.model.get('problems').length + ")");
+            }
+
+            if(self.model.get('problems').syncing){
+                $("[href=#"+self.model.get('name')+"]").addClass("syncing");
+            }
+
+            this.$el.addClass("library_tab");
+            this.startIndex = 0;
+
+            var jsonInfo = this.model.toJSON();
+            jsonInfo['group_size'] = this.group_size;
+
+            jsonInfo['enough_problems'] = (this.model.get('problems').length > this.startIndex)? "block" : "none";
+
+            this.$el.html(this.template(jsonInfo));
+
+            this.loadNextGroup();
+
+            return this;
+        },

Define a new function loadNextGroup so that we can just load a few problems at once, +otherwise things get unwieldy :P

        loadNextGroup: function(){
+            console.log("load more");
+            console.log(this.startIndex);
+            console.log(this.group_size);
+
+            var problems = this.model.get('problems');
+            console.log(problems.length);
+            for(var i = 0; i < this.group_size && this.startIndex < problems.length; i++, this.startIndex++){
+                console.log("adding a problem");
+                var problem = problems.at(this.startIndex);
+                var view = new ProblemView({model: problem, remove_display: "none"});
+                this.$(".list").append(view.render().el);
+            }
+
+            if(!(this.model.get('problems').length > this.startIndex)){
+                this.$(".next_group").css('display', "none");
+            }
+        }
+
+    });
+
+    var LibraryListView = Backbone.View.extend({
+        tagName:'span',
+        template:_.template($('#LibraryList-template').html()),
+
+        events: {

'change .list': 'lib_selected'

        },
+
+        initialize:function () {
+            var self = this;
+            this.model.on("reset", this.render, this);
+            this.model.on("add", this.addOne, this);
+            this.model.on('alert', function(message){alert(message);}, this);
+            this.model.on('syncing', function(value){
+                if(value){
+                    self.$el.addClass("syncing white");
+                } else {
+                    self.$el.removeClass("syncing white");
+                }
+            }, this);

not the strongest solution but it will do

            if(!(this.model.length > 0)){
+                this.model.fetch();
+            }
+        },
+
+        render:function () {
+
+            var self = this;
+            if(self.model.syncing){
+                self.$el.addClass("syncing white");
+            }
+            this.$el.html(this.template({name: this.options.name}));
+            self.$("."+this.options.name+".list").on('change', function(event){self.lib_selected(event)});
+            this.addAll();
+            return this;
+        },
+
+        addOne: function(lib){
+            var self = this;
+            var option = document.createElement("option")
+            option.value = lib.cid;
+            option.innerHTML = lib.get('name');
+            this.$('.'+this.options.name + '.list').append(option);//what's the null?
+        },
+
+        addAll: function(){
+            var self = this;
+            if(this.model.length > 0){

should show number of problems in the bar

                this.model.each(function(lib){self.addOne(lib)});
+            } else {
+                this.$('.'+this.options.name+".list").css("display", "none");
+            }
+        },
+
+        lib_selected:function (event) {
+            var self = this;
+            self.$el.removeClass("syncing white");
+            var selectedLib = this.model.getByCid(event.target.value);
+            if(selectedLib){
+                var view = new LibraryListView({model:selectedLib.get('children'), name: selectedLib.cid});
+                this.$('.'+this.options.name+".children").html(view.render().el);
+                libToLoad = selectedLib;
+            }
+        }
+
+    });

The main Set view

    var SetView = Backbone.View.extend({
+        template:_.template($('#set-template').html()),
+        events:{
+        },
+
+        initialize:function () {
+            var self = this;
+            this.model.get('problems').on('add', function(model){self.addOne(model)}, this);
+            this.model.get('problems').on('reset', function(){self.addAll();}, this);
+            this.model.get('problems').on('all', function(){
+                $("[href=#"+self.model.get('name')+"]").html(self.model.get('name') + " (" + self.model.get('problems').length + ")");
+            }, this);
+            this.model.get('problems').on('alert', function(message){alert(message);});
+
+            this.model.get('problems').on('syncing', function(value){
+                if(value){
+                    $("[href=#"+self.model.get('name')+"]").addClass("syncing");
+                } else {
+                    $("[href=#"+self.model.get('name')+"]").removeClass("syncing");
+                }
+            }, this);
+
+        },
+
+        render:function () {
+
+            var self = this;
+            if ($('#problems_container #' + this.model.get('name')).length == 0) {
+                $('#problems_container').tabs('add', "#"+this.model.get('name'), this.model.get('name') + " (" + this.model.get('problems').length + ")"); //could move to an after?
+                this.setElement(document.getElementById(this.model.get('name')));
+            }
+
+            this.$el.html(self.template(self.model.toJSON()));
+
+            if(self.model.get('problems').syncing){
+                $("[href=#"+self.model.get('name')+"]").addClass("syncing");
+            }
+
+            this.$('.list').sortable({
+                axis:'y',
+                start:function (event, ui) {

self.previousOrder = $(this).sortable('toArray');

                },
+                update:function (event, ui) {

self.reorderProblems($(this).sortable('toArray'));

                    var newOrder = self.$('.list').sortable('toArray');
+                    for(var i = 0; i < newOrder.length; i++){
+                        var problem = self.model.get('problems').getByCid(newOrder[i]);
+                        if(problem){
+                            problem.set('place', i);
+                        }
+                    }
+
+                    self.model.get('problems').reorder();
+                }
+            });
+
+            this.addAll();
+            return this;
+        },
+
+        addOne: function(problem){
+            var view = new ProblemView({model:problem});
+            var rendered_problem = view.render().el;
+            this.$(".list").append(rendered_problem);
+            this.$('.list').sortable('refresh');
+
+        },
+
+        addAll: function(){
+            var self = this;
+            this.model.get('problems').each(function(model){self.addOne(model)});
+        }
+    });

The Set view for the setlists

    var SetNameView = Backbone.View.extend({
+        tagName:"li",
+        template:_.template($('#setName-template').html()),
+
+        events:{
+            'click':'view'
+        },
+
+        initialize:function () {
+            this.bigView = false;
+            var self = this;
+            this.model.get('problems').on('all', function(){self.render()}, this);
+            this.model.get('problems').on('alert', function(message){alert(message);});
+            this.model.on('highlight', function(){self.$el.addClass("contains_problem")});
+        },
+
+        render:function () {
+            var self = this;
+
+            self.$el.html(self.template({name: self.model.get('name'), problem_count: self.model.get('problems').length}));
+            self.$el.droppable({
+                tolerance:'pointer',
+
+                hoverClass:'drophover',
+
+                drop:function (event, ui) {

var newProblem = new webwork.Problem({path:ui.draggable.attr("data-path")});

                    self.model.get("problems").add({path:ui.draggable.attr("data-path")});
+                }
+            });
+
+            return this;
+        },
+
+        view:function () {
+            console.log("clicked " + this.model.get('name'));
+            if ($('#problems_container #' + this.model.get('name')).length > 0) {
+                $('#problems_container').tabs('select', this.model.get('name'));
+            } else {
+                console.log("rendering the set");
+                var view = new SetView({model:this.model});

$('#problems_container').append(view.render().el);

                view.render();
+            }

render the full tab thing, or switch to it

        }
+    });

The SetList view

    var SetListView = Backbone.View.extend({
+        tagName:"ul",
+        template:_.template($('#setList-template').html()),
+        className:"nav nav-list",
+
+        initialize:function () {
+            var self = this;
+            this.model.bind('add', function(model){self.addOne(model);}, this);
+            this.model.bind('reset', function(){self.addAll()}, this);

this.model.bind('all', this.render, this);

            if(!(this.model.length > 0)){
+                this.model.fetch();
+            }
+        },
+
+        render:function () {
+            var self = this;
+
+            self.$el.html(self.template());
+
+            return this;
+        },
+
+        addOne:function (added_set) {
+            var view = new SetNameView({model: added_set});
+            this.$el.append(view.render().el);
+        },
+
+        addAll:function () {
+            var self = this;
+            this.model.each(function(model){self.addOne(model)});
+        }
+        /*
+         startCreate: function(){
+         this.$("#dialog").dialog('open');
+         }
+         */
+    });

This is global in order not to confuse the poor select boxes.. +They can never tell who went last :)

    var libToLoad = false;
+    $("#load_problems").on("click", function(event){
+        if(libToLoad){
+            var view = new LibraryView({model: libToLoad});
+            view.render();
+
+        }
+    });

The APP!! yay!!

    var LibraryBrowser = Backbone.View.extend({
+        el:$('#app_box'),
+
+        events:{
+            "click #undo_button":"undo",
+            "click #redo_button":"redo",
+            "hover .problem": "highlightSets",
+            "click #create_set": "createHomeworkSet"
+        },
+
+        initialize:function () {
+            var self = this;

Some default ajax stuff we can keep it or not

            $(document).ajaxError(function(e, jqxhr, settings, exception) {
+                alert(exception, "alert-error");
+            });

get usernames and keys from hidden variables and set up webwork object:

            var myUser = document.getElementById("hidden_user").value;
+            var mySessionKey = document.getElementById("hidden_key").value;
+            var myCourseID = document.getElementById("hidden_courseID").value;

check to make sure that our credentials are available.

            if (myUser && mySessionKey && myCourseID) {
+                webwork.requestObject.user = myUser;
+                webwork.requestObject.session_key = mySessionKey;
+                webwork.requestObject.courseID = myCourseID;
+            } else {
+                alert("missing hidden credentials: user "
+                    + myUser + " session_key " + mySessionKey
+                    + " courseID" + myCourseID, "alert-error");
+            }

Set up the tabbed set lists and libraries:

            $("#problems_container").tabs(
+                {
+                    closable:true,
+                    add:function (event, ui) {

document.getElementById("librarylink").removeChild(document.getElementById("librarylink").lastChild);

                        console.log("adding a tab");
+                        $('#problems_container').tabs('select', '#' + ui.panel.id);
+                        $(".ww_selected").removeClass("ww_selected");// probably reduntant but I want to make sure nothing stays selected
+                    },
+                    create:function (event, ui) {

document.getElementById("librarylink").removeChild(document.getElementById("librarylink").lastChild);

                        $(".ww_selected").removeClass("ww_selected");
+                    },
+                    select:function (event, ui) {
+                        $(".ww_selected").removeClass("ww_selected");
+                    },
+                    remove:function (event, ui) {

document.getElementById("librarylink").removeChild(document.getElementById("librarylink").lastChild);

                        $(".ww_selected").removeClass("ww_selected");
+                    }
+            });

set up our models

            this.homeworkSets = new webwork.SetList;
+            this.cardCatalog = new webwork.LibraryList;
+            this.cardCatalog.defaultRequestObject.xml_command = "listLibraries"
+
+            this.render();
+        },
+
+        createHomeworkSet: function(){
+            if(this.$("#dialog_text").val()){
+                this.homeworkSets.create({name: this.$("#dialog_text").val()});
+            }
+            this.$("#dialog_text").val('');
+        },
+
+        highlightSets: function(event) {
+            switch(event.type){
+                case "mouseenter":

console.log(this.getAttribute("data-path"));

                    var problemPath = event.currentTarget.getAttribute("data-path");
+
+                    this.homeworkSets.each(function(set){
+                        if(set.get('problems').find(function(problem){return problem.get('path') == problemPath})){
+                            set.trigger('highlight');
+                        }
+                    });
+                    break;
+                default:
+                    $(".contains_problem").removeClass("contains_problem");
+                    break;
+            }
+
+        },
+
+        render: function(){
+            var homeworkSetsView = new SetListView({model: this.homeworkSets});
+            this.$("#homework_sets_container").append(homeworkSetsView.render().el);
+
+            var cardCatalogView = new LibraryListView({model: this.cardCatalog, name: "root"});
+            this.$("#CardCatalog").append(cardCatalogView.render().el);
+        },
+
+        undo:function () {

pop the stack and call the function, that's it

            var undoFunc = undo_stack.pop();
+            undoing = true;
+            undoFunc();
+        },
+
+        redo:function () {
+            var redoFunc = redo_stack.pop();
+            redoFunc();
+        }
+    });

instantiate an instance of our app.

    var App = new LibraryBrowser;
+
+});
+
+
\ No newline at end of file diff --git a/htdocs/js/lib/webwork/out/api.js b/htdocs/js/lib/webwork/out/api.js new file mode 100644 index 000000000..6c3b5a906 --- /dev/null +++ b/htdocs/js/lib/webwork/out/api.js @@ -0,0 +1,17 @@ +YUI.add("yuidoc-meta", function(Y) { + Y.YUIDoc = { meta: { + "classes": [ + "webwork" + ], + "modules": [ + "WeBWorK" + ], + "allModules": [ + { + "displayName": "WeBWorK", + "name": "WeBWorK", + "description": "The WeBWorK javascript framework" + } + ] +} }; +}); \ No newline at end of file diff --git a/htdocs/js/lib/webwork/out/assets/css/external-small.png b/htdocs/js/lib/webwork/out/assets/css/external-small.png new file mode 100644 index 0000000000000000000000000000000000000000..759a1cdcb5b1697e5be290d98b830e279cd71f3c GIT binary patch literal 491 zcmVDs{zR1^XE?tfB*h@ASKHAa7wwn{MEbP z7_^nS7{V*>+A}bS;P%45fB%Ai|Neasi2rl3{=EO;!w318%8Ovl7jArHc=P5Brfr~D z0AYimtss2w$hlYlfd>7*aO3TNzw875LBK0xAD9Np|A(oEVYnB*eE9~V6wP%78SXuL z&#-X)Er#`zY#Ce)^8hM>B_8 literal 0 HcmV?d00001 diff --git a/htdocs/js/lib/webwork/out/assets/css/logo.png b/htdocs/js/lib/webwork/out/assets/css/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..609b336c7cc5ef0c787a0068d221d9b8d69b1241 GIT binary patch literal 6308 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 a0R{k+kX}`<%LV)Z0000