commit
b2316c6ca2
@ -567,6 +567,7 @@ public abstract class AbstractLesson extends Screen implements Comparable<Object
|
|||||||
link.append(getScreenId());
|
link.append(getScreenId());
|
||||||
link.append("/");
|
link.append("/");
|
||||||
link.append(getCategory().getRanking());
|
link.append(getCategory().getRanking());
|
||||||
|
|
||||||
return link.toString();
|
return link.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@ public class LessonMenuService extends BaseService {
|
|||||||
LessonMenuItem stageItem = new LessonMenuItem();
|
LessonMenuItem stageItem = new LessonMenuItem();
|
||||||
stageItem.setName("Stage " + stageIdx + ": " + stage);
|
stageItem.setName("Stage " + stageIdx + ": " + stage);
|
||||||
// build the link for the stage
|
// build the link for the stage
|
||||||
String stageLink = lessonLink + "&stage=" + stageIdx;
|
String stageLink = lessonLink + "/" + stageIdx;
|
||||||
stageItem.setLink(stageLink);
|
stageItem.setLink(stageLink);
|
||||||
stageItem.setType(LessonMenuItemType.STAGE);
|
stageItem.setType(LessonMenuItemType.STAGE);
|
||||||
if (rla.isStageComplete(ws, stage)) {
|
if (rla.isStageComplete(ws, stage)) {
|
||||||
|
@ -851,7 +851,7 @@ cookie-container {
|
|||||||
color: #e84c3d;
|
color: #e84c3d;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar ul span.lesson-complete {
|
#menu-container ul span.lesson-complete {
|
||||||
float: right;
|
float: right;
|
||||||
margin-left: -5px;
|
margin-left: -5px;
|
||||||
/*margin-right: 5px;*/
|
/*margin-right: 5px;*/
|
||||||
@ -859,11 +859,15 @@ cookie-container {
|
|||||||
display:inline-block;
|
display:inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
#menu-container ul li.selected {
|
#menu-container ul li.selected, #menu-container li a.selected {
|
||||||
background-color: #555;
|
background-color: #555;
|
||||||
}
|
}
|
||||||
|
|
||||||
#menu-container ul li.selected a.selected {
|
#menu-container ul li.stage {
|
||||||
|
padding-left:3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#menu-container li.selected, #menu-container a.selected {
|
||||||
color:white;
|
color:white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,13 +39,13 @@ define(['jquery',
|
|||||||
this.start = function() {
|
this.start = function() {
|
||||||
this.listenTo(this.lessonContent,'contentLoaded',this.onContentLoaded);
|
this.listenTo(this.lessonContent,'contentLoaded',this.onContentLoaded);
|
||||||
};
|
};
|
||||||
|
|
||||||
//load View, which can pull data
|
//load View, which can pull data
|
||||||
this.loadLesson = function(scr,menu) {
|
this.loadLesson = function(scr,menu,stage) {
|
||||||
this.helpsLoaded = {};
|
this.helpsLoaded = {};
|
||||||
this.lessonContent.loadData({
|
this.lessonContent.loadData({
|
||||||
'screen': encodeURIComponent(scr),
|
'screen': scr,
|
||||||
'menu': encodeURIComponent(menu),
|
'menu': menu,
|
||||||
|
'stage': stage
|
||||||
});
|
});
|
||||||
this.planView = {};
|
this.planView = {};
|
||||||
this.solutionView = {};
|
this.solutionView = {};
|
||||||
@ -77,20 +77,24 @@ define(['jquery',
|
|||||||
//
|
//
|
||||||
this.cookieView = new CookieView();
|
this.cookieView = new CookieView();
|
||||||
// parameter model & view
|
// parameter model & view
|
||||||
//TODO: instantiate model with values at once (not sure why was not working before)
|
//TODO: instantiate model with values (not sure why was not working before)
|
||||||
var paramModel = new ParamModel({
|
var paramModel = new ParamModel({
|
||||||
});
|
});
|
||||||
paramModel.set('screenParam',this.lessonContent.get('screenParam'));
|
paramModel.set('screenParam',this.lessonContent.get('screenParam'));
|
||||||
paramModel.set('menuParam',this.lessonContent.get('menuParam'));
|
paramModel.set('menuParam',this.lessonContent.get('menuParam'));
|
||||||
|
paramModel.set('stageParam',this.lessonContent.get('stageParam'));
|
||||||
this.paramView = new ParamView({model:paramModel});
|
this.paramView = new ParamView({model:paramModel});
|
||||||
|
|
||||||
this.hideShowHelps(null);
|
this.hideShowHelps(null);
|
||||||
|
this.trigger('menu:reload');
|
||||||
};
|
};
|
||||||
|
|
||||||
this.areHelpsReady = function (curHelp) {
|
this.areHelpsReady = function (curHelp) {
|
||||||
|
//TODO: significantly refactor (remove) this once LessonInfoService can be used to support lazy loading
|
||||||
this.addCurHelpState(curHelp);
|
this.addCurHelpState(curHelp);
|
||||||
// check if all are ready
|
// check if all are ready
|
||||||
if (this.helpsLoaded['hints'] && this.helpsLoaded['plan'] && this.helpsLoaded['solution'] && this.helpsLoaded['source'] && !this.helpControlsView) {
|
if (this.helpsLoaded['hints'] && this.helpsLoaded['plan'] && this.helpsLoaded['solution'] && this.helpsLoaded['source'] && !this.helpControlsView) {
|
||||||
//
|
|
||||||
this.helpControlsView = new HelpControlsView({
|
this.helpControlsView = new HelpControlsView({
|
||||||
hasPlan:(this.planView.model.get('content') !== null),
|
hasPlan:(this.planView.model.get('content') !== null),
|
||||||
hasSolution:(this.solutionView.model.get('content') !== null),
|
hasSolution:(this.solutionView.model.get('content') !== null),
|
||||||
@ -98,7 +102,7 @@ define(['jquery',
|
|||||||
hasHints:(this.lessonHintView.collection.length > 0),
|
hasHints:(this.lessonHintView.collection.length > 0),
|
||||||
});
|
});
|
||||||
this.helpControlsView.render();
|
this.helpControlsView.render();
|
||||||
//
|
|
||||||
this.listenTo(this.helpControlsView,'plan:show',this.hideShowHelps);
|
this.listenTo(this.helpControlsView,'plan:show',this.hideShowHelps);
|
||||||
this.listenTo(this.helpControlsView,'solution:show',this.hideShowHelps);
|
this.listenTo(this.helpControlsView,'solution:show',this.hideShowHelps);
|
||||||
this.listenTo(this.helpControlsView,'hints:show',this.onShowHints)
|
this.listenTo(this.helpControlsView,'hints:show',this.onShowHints)
|
||||||
|
@ -1,5 +1,12 @@
|
|||||||
define(['jquery','underscore','backbone','goatApp/view/MenuView'],
|
define(['jquery',
|
||||||
function($,_,Backbone,MenuView) {
|
'underscore',
|
||||||
|
'backbone',
|
||||||
|
'goatApp/view/MenuView'
|
||||||
|
],
|
||||||
|
function($,
|
||||||
|
_,
|
||||||
|
Backbone,
|
||||||
|
MenuView) {
|
||||||
Controller = function(options){
|
Controller = function(options){
|
||||||
_.extend(Controller.prototype,Backbone.Events);
|
_.extend(Controller.prototype,Backbone.Events);
|
||||||
options = options || {};
|
options = options || {};
|
||||||
@ -10,8 +17,8 @@ define(['jquery','underscore','backbone','goatApp/view/MenuView'],
|
|||||||
this.listenTo(this.menuView,'lesson:click',this.renderTitle);
|
this.listenTo(this.menuView,'lesson:click',this.renderTitle);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.updateMenu = function(curLesson) {
|
this.updateMenu = function(){
|
||||||
|
this.menuView.updateMenu();
|
||||||
},
|
},
|
||||||
|
|
||||||
//TODO: move title rendering into lessonContent/View pipeline once data can support it
|
//TODO: move title rendering into lessonContent/View pipeline once data can support it
|
||||||
@ -19,6 +26,7 @@ define(['jquery','underscore','backbone','goatApp/view/MenuView'],
|
|||||||
this.titleView.render(title);
|
this.titleView.render(title);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return Controller;
|
return Controller;
|
||||||
|
@ -16,13 +16,14 @@ define(['jquery',
|
|||||||
initialize: function (options) {
|
initialize: function (options) {
|
||||||
this.screenParam = null;
|
this.screenParam = null;
|
||||||
this.menuParam = null;
|
this.menuParam = null;
|
||||||
|
this.stageParam = null;
|
||||||
this.baseUrlRoot = 'attack?Screen=';
|
this.baseUrlRoot = 'attack?Screen=';
|
||||||
},
|
},
|
||||||
loadData: function(options) {
|
loadData: function(options) {
|
||||||
this.urlRoot = this.baseUrlRoot +options.screen + '&menu=' + options.menu;
|
this.urlRoot = this.baseUrlRoot +options.screen + '&menu=' + options.menu + '&stage=' + options.stage;
|
||||||
this.set('menuParam',options.menu);
|
this.set('menuParam',options.menu);
|
||||||
this.set('screenParam',options.screen);
|
this.set('screenParam',options.screen);
|
||||||
|
this.set('stageParam',options.stage)
|
||||||
var self=this;
|
var self=this;
|
||||||
this.fetch().then(function(data) {
|
this.fetch().then(function(data) {
|
||||||
self.setContent(data);
|
self.setContent(data);
|
||||||
|
@ -9,13 +9,21 @@ define(['jquery',
|
|||||||
url:'service/lessonmenu.mvc',
|
url:'service/lessonmenu.mvc',
|
||||||
initialize: function () {
|
initialize: function () {
|
||||||
var self = this;
|
var self = this;
|
||||||
this.fetch().then(function (data) {
|
this.fetch();
|
||||||
this.models = data;
|
|
||||||
self.onDataLoaded();
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
onDataLoaded: function() {
|
onDataLoaded: function() {
|
||||||
this.trigger('menuData:loaded');
|
this.trigger('menuData:loaded');
|
||||||
|
},
|
||||||
|
|
||||||
|
fetch: function() {
|
||||||
|
var self=this;
|
||||||
|
Backbone.Collection.prototype.fetch.apply(this,arguments).then(
|
||||||
|
function(data) {
|
||||||
|
this.models = data;
|
||||||
|
self.onDataLoaded();
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
@ -30,28 +30,3 @@ var menuData = Backbone.Model.extend({
|
|||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/*
|
|
||||||
var menuData = Backbone.Model.extend({
|
|
||||||
urlRoot:'/webgoat/service/lessonmenu.mvc',
|
|
||||||
defaults: {
|
|
||||||
items:null,
|
|
||||||
selectedItem:null
|
|
||||||
},
|
|
||||||
initialize: function () {
|
|
||||||
var self = this;
|
|
||||||
this.fetch().then(function(menuItems){
|
|
||||||
menuItems = goatUtils.enhanceMenuData(menuItems,this.selectedItem);
|
|
||||||
self.items = menuItems;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
update: function() {
|
|
||||||
var self = this;
|
|
||||||
this.fetch().then(function(data) {
|
|
||||||
self.items = data;
|
|
||||||
self.render(0);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
*/
|
|
@ -16,7 +16,7 @@ define(['jquery',
|
|||||||
routes: {
|
routes: {
|
||||||
//#....
|
//#....
|
||||||
'welcome':'welcomeRoute',
|
'welcome':'welcomeRoute',
|
||||||
'attack/:scr/:menu':'attackRoute' //
|
'attack/:scr/:menu(/:stage)':'attackRoute' //
|
||||||
},
|
},
|
||||||
|
|
||||||
lessonController: new LessonController({
|
lessonController: new LessonController({
|
||||||
@ -33,8 +33,8 @@ define(['jquery',
|
|||||||
this.lessonController.start();
|
this.lessonController.start();
|
||||||
this.menuController.initMenu();
|
this.menuController.initMenu();
|
||||||
|
|
||||||
goatRouter.on('route:attackRoute', function(scr,menu) {
|
goatRouter.on('route:attackRoute', function(scr,menu,stage) {
|
||||||
this.lessonController.loadLesson(scr,menu);
|
this.lessonController.loadLesson(scr,menu,stage);
|
||||||
this.menuController.updateMenu(scr,menu);
|
this.menuController.updateMenu(scr,menu);
|
||||||
//update menu
|
//update menu
|
||||||
});
|
});
|
||||||
@ -43,11 +43,11 @@ define(['jquery',
|
|||||||
});
|
});
|
||||||
|
|
||||||
Backbone.history.start();
|
Backbone.history.start();
|
||||||
this.listenTo(this.menuController, 'menu:reload',this.reloadMenu)
|
this.listenTo(this.lessonController, 'menu:reload',this.reloadMenu)
|
||||||
},
|
},
|
||||||
|
|
||||||
reloadMenu: function (curLesson) {
|
reloadMenu: function (curLesson) {
|
||||||
this.menuController.updateMenu(curLesson);
|
this.menuController.updateMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -17,10 +17,11 @@ define(['jquery',
|
|||||||
initialize: function() {
|
initialize: function() {
|
||||||
this.collection = new MenuCollection();
|
this.collection = new MenuCollection();
|
||||||
this.listenTo(this.collection,'menuData:loaded',this.render);
|
this.listenTo(this.collection,'menuData:loaded',this.render);
|
||||||
this.listenTo(this,'menu:click',this.accordionMenu);
|
// this.listenTo(this,'menu:click',this.accordionMenu);
|
||||||
|
this.curLessonLinkId = '';
|
||||||
},
|
},
|
||||||
// rendering top level menu
|
// rendering top level menu
|
||||||
render: function (model){
|
render: function (){
|
||||||
//for now, just brute force
|
//for now, just brute force
|
||||||
//TODO: refactor into sub-views/components
|
//TODO: refactor into sub-views/components
|
||||||
var items, catItems, stages;
|
var items, catItems, stages;
|
||||||
@ -47,11 +48,14 @@ define(['jquery',
|
|||||||
if (lessons) {
|
if (lessons) {
|
||||||
var categoryLessonList = $('<ul>',{class:'slideDown lessonsAndStages',id:catId}); //keepOpen
|
var categoryLessonList = $('<ul>',{class:'slideDown lessonsAndStages',id:catId}); //keepOpen
|
||||||
for (var j=0; j < lessons.length;j++) {
|
for (var j=0; j < lessons.length;j++) {
|
||||||
var lessonItem = $('<li>');
|
var lessonItem = $('<li>',{class:'lesson'});
|
||||||
lessonName = lessons[j].name;
|
var lessonName = lessons[j].name;
|
||||||
|
var lessonId = GoatUtils.makeId(lessonName);
|
||||||
var lessonLink = $('<a>',{href:lessons[j].link,text:lessonName,id:lessonName});
|
if (this.curLessonLinkId === lessonId) {
|
||||||
lessonLink.click(_.bind(this.titleRender,this,lessonName));
|
lessonItem.addClass('selected');
|
||||||
|
}
|
||||||
|
var lessonLink = $('<a>',{href:lessons[j].link,text:lessonName,id:lessonId});
|
||||||
|
lessonLink.click(_.bind(this.onLessonClick,this,lessonName));
|
||||||
lessonItem.append(lessonLink);
|
lessonItem.append(lessonLink);
|
||||||
//check for lab/stages
|
//check for lab/stages
|
||||||
categoryLessonList.append(lessonItem);
|
categoryLessonList.append(lessonItem);
|
||||||
@ -60,13 +64,18 @@ define(['jquery',
|
|||||||
}
|
}
|
||||||
var stages = lessons[j].children;
|
var stages = lessons[j].children;
|
||||||
for (k=0; k < stages.length; k++) {
|
for (k=0; k < stages.length; k++) {
|
||||||
|
var stageItem = $('<li>',{class:'stage'});
|
||||||
var stageName = stages[k].name;
|
var stageName = stages[k].name;
|
||||||
var stageLink = $('<a>',{href:stages[k].link,text:stageName,id:GoatUtils.makeId(stageName)});
|
var stageId = GoatUtils.makeId(stageName);
|
||||||
var stageSpan = $('<span>');
|
if (this.curLessonLinkId === stageId) {
|
||||||
stageSpan.append(stageLink);
|
stageItem.addClass('selected');
|
||||||
categoryLessonList.append(stageSpan);
|
}
|
||||||
|
var stageLink = $('<a>',{href:stages[k].link,text:stageName,id:stageId});
|
||||||
|
stageLink.click(_.bind(this.onLessonClick,this,stageName));
|
||||||
|
stageItem.append(stageLink);
|
||||||
|
categoryLessonList.append(stageItem);
|
||||||
if (stages[k].complete) {
|
if (stages[k].complete) {
|
||||||
stageSpan.append($('<span>',{class:'glyphicon glyphicon-check lesson-complete'}));
|
stageItem.append($('<span>',{class:'glyphicon glyphicon-check lesson-complete'}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -75,15 +84,26 @@ define(['jquery',
|
|||||||
|
|
||||||
menuUl.append(category);
|
menuUl.append(category);
|
||||||
}
|
}
|
||||||
this.$el.append(menuUl);
|
this.$el.html(menuUl);
|
||||||
//if we need to keep a menu open
|
//if we need to keep a menu open
|
||||||
if (this.openMenu) {
|
if (this.openMenu) {
|
||||||
this.accordionMenu(this.openMenu);
|
$('#'+this.openMenu).show();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
titleRender: function (title) {
|
updateMenu: function() {
|
||||||
this.trigger('lesson:click',title);
|
//for now ...
|
||||||
|
this.collection.fetch();
|
||||||
|
},
|
||||||
|
|
||||||
|
onLessonClick: function (title) {
|
||||||
|
var oldLinkId = GoatUtils.makeId(this.curLessonLinkId);
|
||||||
|
$('#'+oldLinkId).removeClass('selected');
|
||||||
|
//update
|
||||||
|
this.curLessonLinkId = GoatUtils.makeId(title);
|
||||||
|
var newLinkId = GoatUtils.makeId(this.curLessonLinkId)
|
||||||
|
$('#'+newLinkId).addClass('selected');
|
||||||
|
this.trigger('lesson:click', title); // will cause menu reload
|
||||||
},
|
},
|
||||||
|
|
||||||
expandCategory: function (id) {
|
expandCategory: function (id) {
|
||||||
@ -94,6 +114,7 @@ define(['jquery',
|
|||||||
|
|
||||||
accordionMenu: function(id) {
|
accordionMenu: function(id) {
|
||||||
if (this.openMenu !== id) {
|
if (this.openMenu !== id) {
|
||||||
|
this.$el.find('#' + this.openMenu).slideUp(200);
|
||||||
this.$el.find('#' + id).slideDown(300);
|
this.$el.find('#' + id).slideDown(300);
|
||||||
this.openMenu = id;
|
this.openMenu = id;
|
||||||
} else { //it's open
|
} else { //it's open
|
||||||
|
@ -22,8 +22,9 @@ function($,
|
|||||||
var paramsTable = $('<table>',{'class':'param-table table-striped table-nonfluid'});
|
var paramsTable = $('<table>',{'class':'param-table table-striped table-nonfluid'});
|
||||||
var self = this;
|
var self = this;
|
||||||
_.each(this.model.keys(), function(attribute) {
|
_.each(this.model.keys(), function(attribute) {
|
||||||
|
var attributeLabel = attribute.replace(/Param/,'');
|
||||||
var newRow = $('<tr>');
|
var newRow = $('<tr>');
|
||||||
newRow.append($('<th>',{text:_.escape(attribute)}))
|
newRow.append($('<th>',{text:_.escape(attributeLabel)}))
|
||||||
newRow.append($('<td>',{text:_.escape(self.model.get(attribute))}));
|
newRow.append($('<td>',{text:_.escape(self.model.get(attribute))}));
|
||||||
paramsTable.append(newRow);
|
paramsTable.append(newRow);
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user