diff --git a/app/coffeescripts/calendar/sidebar.coffee b/app/coffeescripts/calendar/sidebar.coffee index 9b93b6f02fe..83cc9a0c7fa 100644 --- a/app/coffeescripts/calendar/sidebar.coffee +++ b/app/coffeescripts/calendar/sidebar.coffee @@ -1,5 +1,6 @@ define [ 'jquery' + 'compiled/userSettings' 'jst/calendar/contextList' 'jst/calendar/undatedEvents' 'compiled/calendar/commonEventFactory' @@ -8,8 +9,7 @@ define [ 'compiled/jquery.kylemenu' 'jquery.instructure_misc_helpers' 'vendor/jquery.ba-tinypubsub' - 'vendor/jquery.store' -], ($, contextListTemplate, undatedEventsTemplate, commonEventFactory, EditEventDetailsDialog, EventDataSource) -> +], ($, userSettings, contextListTemplate, undatedEventsTemplate, commonEventFactory, EditEventDetailsDialog, EventDataSource) -> class VisibleContextManager constructor: (contexts, selectedContexts, @$holder) -> @@ -17,11 +17,10 @@ define [ $.parseJSON($.decodeFromHex(location.hash.substring(1))) || {} catch e {} - savedContexts = $.store.userGet('checked_calendar_codes') @contexts = fragmentData.show.split(',') if fragmentData.show - @contexts or= selectedContexts if selectedContexts - @contexts or= savedContexts.split(',') if savedContexts + @contexts or= selectedContexts + @contexts or= userSettings.get('checked_calendar_codes') @contexts or= (c.asset_string for c in contexts[0...10]) @notify() diff --git a/app/coffeescripts/gradebook2/Gradebook.coffee b/app/coffeescripts/gradebook2/Gradebook.coffee index 2732f22c35f..e8aa31caf1a 100644 --- a/app/coffeescripts/gradebook2/Gradebook.coffee +++ b/app/coffeescripts/gradebook2/Gradebook.coffee @@ -5,6 +5,7 @@ define [ 'jquery' 'underscore' 'compiled/grade_calculator' + 'compiled/userSettings' 'vendor/spin' 'compiled/multi_grid' 'compiled/SubmissionDetailsDialog' @@ -24,13 +25,12 @@ define [ 'jquery.instructure_misc_helpers' 'jquery.instructure_misc_plugins' 'vendor/jquery.ba-tinypubsub' - 'vendor/jquery.store' 'jqueryui/mouse' 'jqueryui/position' 'jqueryui/sortable' 'compiled/jquery.kylemenu' 'compiled/jquery/fixDialogButtons' -], (I18n, GRADEBOOK_TRANSLATIONS, $, _, GradeCalculator, Spinner, MultiGrid, SubmissionDetailsDialog, AssignmentGroupWeightsDialog, SubmissionCell, GradebookHeaderMenu, htmlEscape, gradebook_uploads_form, sectionToShowMenuTemplate, columnHeaderTemplate, groupTotalCellTemplate, rowStudentNameTemplate) -> +], (I18n, GRADEBOOK_TRANSLATIONS, $, _, GradeCalculator, userSettings, Spinner, MultiGrid, SubmissionDetailsDialog, AssignmentGroupWeightsDialog, SubmissionCell, GradebookHeaderMenu, htmlEscape, gradebook_uploads_form, sectionToShowMenuTemplate, columnHeaderTemplate, groupTotalCellTemplate, rowStudentNameTemplate) -> class Gradebook columnWidths = @@ -46,14 +46,14 @@ define [ constructor: (@options) -> @chunk_start = 0 - @students = {} - @rows = [] + @students = {} + @rows = [] @studentsPage = 1 - @sortFn = (student) -> student.sortable_name - @assignmentsToHide = ($.store.userGet("hidden_columns_#{@options.context_code}") || '').split(',') - @sectionToShow = Number($.store.userGet("grading_show_only_section#{@options.context_id}")) || undefined - @show_attendance = $.store.userGet("show_attendance_#{@options.context_code}") == 'true' - @include_ungraded_assignments = $.store.userGet("include_ungraded_assignments_#{@options.context_code}") == 'true' + @sortFn = (student) -> student.sortable_name + @assignmentsToHide = userSettings.contextGet('hidden_columns') || [] + @sectionToShow = userSettings.contextGet 'grading_show_only_section' + @show_attendance = userSettings.contextGet 'show_attendance' + @include_ungraded_assignments = userSettings.contextGet 'include_ungraded_assignments' $.subscribe 'assignment_group_weights_changed', @buildRows $.subscribe 'assignment_muting_toggled', @handleAssignmentMutingChange $.subscribe 'submissions_updated', @updateSubmissionsFromExternal @@ -139,13 +139,13 @@ define [ @$columnArrangementTogglers.each -> $(this).closest('li').showIf $(this).data('arrangeColumnsBy') isnt newThingToArrangeBy @_sortColumnsBy = newThingToArrangeBy - $.store[ if newThingToArrangeBy is 'due_date' then 'userSet' else 'userRemove']("sort_grade_colums_by_#{@options.context_id}", newThingToArrangeBy) + userSettings[ if newThingToArrangeBy is 'due_date' then 'contextSet' else 'contextRemove']('sort_grade_colums_by', newThingToArrangeBy) columns = @gradeGrid.getColumns() columns.sort @columnSortFn @gradeGrid.setColumns(columns) @fixColumnReordering() @buildRows() - @_sortColumnsBy ||= $.store.userGet("sort_grade_colums_by_#{@options.context_id}") || 'assignment_group' + @_sortColumnsBy ||= userSettings.contextGet('sort_grade_colums_by') || 'assignment_group' columnSortFn: (a,b) => return -1 if b.type is 'total_grade' @@ -346,7 +346,7 @@ define [ columnDef.minimized = true @$grid.find(".l#{colIndex}").add($columnHeader).addClass('minimized') @assignmentsToHide.push(columnDef.id) - $.store.userSet("hidden_columns_#{@options.context_code}", _.uniq(@assignmentsToHide).join(',')) + userSettings.contextSet('hidden_columns', _.uniq(@assignmentsToHide)) unminimizeColumn: ($columnHeader) => colIndex = $columnHeader.index() @@ -358,7 +358,7 @@ define [ @$grid.find(".l#{colIndex}").add($columnHeader).removeClass('minimized') $columnHeader.find('.slick-column-name').html(columnDef.name) @assignmentsToHide = $.grep @assignmentsToHide, (el) -> el != columnDef.id - $.store.userSet("hidden_columns_#{@options.context_code}", _.uniq(@assignmentsToHide).join(',')) + userSettings.contextSet('hidden_columns', _.uniq(@assignmentsToHide)) hoverMinimizedCell: (event) => $hoveredCell = $(event.currentTarget) @@ -459,7 +459,7 @@ define [ buttonOpts: {icons: {primary: "ui-icon-sections", secondary: "ui-icon-droparrow"}} $sectionToShowMenu.bind 'menuselect', (event, ui) => @sectionToShow = Number($sectionToShowMenu.find('[aria-checked="true"] input[name="section_to_show_radio"]').val()) || undefined - $.store[ if @sectionToShow then 'userSet' else 'userRemove']("grading_show_only_section#{@options.context_id}", @sectionToShow) + userSettings[ if @sectionToShow then 'contextSet' else 'contextRemove']('grading_show_only_section', @sectionToShow) updateSectionBeingShownText() @buildRows() @@ -467,7 +467,7 @@ define [ $.each ['show_attendance', 'include_ungraded_assignments'], (i, setting) => $settingsMenu.find("##{setting}").prop('checked', @[setting]).change (event) => @[setting] = $(event.target).is(':checked') - $.store.userSet "#{setting}_#{@options.context_code}", (''+@[setting]) + userSettings.contextSet setting, @[setting] @gradeGrid.setColumns @getVisibleGradeGridColumns() if setting is 'show_attendance' @buildRows() diff --git a/app/coffeescripts/userSettings.coffee b/app/coffeescripts/userSettings.coffee new file mode 100644 index 00000000000..cc267aaaf98 --- /dev/null +++ b/app/coffeescripts/userSettings.coffee @@ -0,0 +1,39 @@ +# uses the global ENV.current_user_id and ENV.context_asset_string varibles to store things in +# localStorage (safe, since we only support ie8+) keyed to the user (and current context) +# +# DO NOT PUT SENSITIVE DATA HERE +# +# usage: +# +# userSettings.set 'favoriteColor', 'red' +# userSettings.get 'favoriteColor' # => 'red' +# +# # when you are on /courses/1/x +# userSettings.contextSet 'specialIds', [1,2,3] +# userSettings.contextGet 'specialIds' # => [1,2,3] +# # when you are on /groups/1/x +# userSettings.contextGet 'specialIds' # => undefined +# # back on /courses/1/x +# userSettings.contextRemove 'specialIds' + +define [ + 'underscore' + + # used for $.capitalize + 'jquery' + 'jquery.instructure_misc_helpers' +], (_, $) -> + userSettings = {} + + addTokens = (method, tokens...) -> + (key, value) -> + stringifiedValue = JSON.stringify(value) + joinedTokens = _(tokens).map((token) -> ENV[token]).join('_') + res = localStorage["#{method}Item"]("_#{joinedTokens}_#{key}", stringifiedValue) + JSON.parse(res) if res + + for method in ['get', 'set', 'remove'] + userSettings[method] = addTokens(method, 'current_user_id') + userSettings["context#{$.capitalize(method)}"] = addTokens(method, 'current_user_id', 'context_asset_string') + + userSettings \ No newline at end of file diff --git a/config/build.js b/config/build.js index 6c62d23e159..d60bcddd6a6 100644 --- a/config/build.js +++ b/config/build.js @@ -96,7 +96,6 @@ 'translations/scribd', 'i18n!scribd', 'vendor/scribd.view', - 'vendor/jquery.store', 'jquery.dropdownList', 'vendor/jqueryui/progressbar', 'translations/media_comments', diff --git a/public/javascripts/calendar.js b/public/javascripts/calendar.js index f360b913c5e..fb584a2f42e 100644 --- a/public/javascripts/calendar.js +++ b/public/javascripts/calendar.js @@ -20,25 +20,25 @@ define([ 'INST' /* INST */, 'i18n!calendars', 'jquery' /* $ */, + 'compiled/userSettings', 'calendar_move' /* calendarMonths */, 'jqueryui/draggable' /* /\.draggable/ */, 'jquery.ajaxJSON' /* ajaxJSON */, 'jquery.instructure_date_and_time' /* parseDateTime, formatDateTime, parseFromISO, dateString, datepicker, date_field, time_field, datetime_field, /\$\.datetime/ */, 'jquery.instructure_forms' /* formSubmit, fillFormData, getFormData, hideErrors */, 'jqueryui/dialog', - 'jquery.instructure_misc_helpers' /* encodeToHex, decodeFromHex, replaceTags, /\$\.store/ */, + 'jquery.instructure_misc_helpers' /* encodeToHex, decodeFromHex, replaceTags */, 'jquery.instructure_misc_plugins' /* .dim, confirmDelete, fragmentChange, showIf */, 'jquery.keycodes' /* keycodes */, 'jquery.rails_flash_notifications' /* flashMessage */, 'jquery.templateData' /* fillTemplateData, getTemplateData */, 'vendor/date' /* Date.parse */, 'vendor/jquery.scrollTo' /* /\.scrollTo/ */, - 'vendor/jquery.store' /* /\$\.store/ */, 'jqueryui/datepicker' /* /\.datepicker/ */, 'jqueryui/resizable' /* /\.resizable/ */, 'jqueryui/sortable' /* /\.sortable/ */, 'jqueryui/tabs' /* /\.tabs/ */ -], function(INST, I18n, $, calendarMonths) { +], function(INST, I18n, $, userSettings, calendarMonths) { window.calendar = { viewItem: function(context_string, item_id, item_type) { @@ -1205,7 +1205,7 @@ define([ var code = $(this).attr('id').substring(6); only_contexts.push(code); }); - $.store.userSet('checked_calendar_codes', only_contexts.join(",")); + userSettings.set('checked_calendar_codes', only_contexts); } }, 1000); $(".group_reference_checkbox").bind('change click', function() { @@ -1535,16 +1535,15 @@ define([ $(document).triggerHandler('event_tab_select', ui.index); $(ui.panel).find("select.context_id").triggerHandler('change'); }); - var storedCodes = $.store.userGet('checked_calendar_codes'); - if(storedCodes) { - var codes = storedCodes.split(/,/); + var storedCodes = userSettings.get('checked_calendar_codes'); + if (storedCodes) { var found = 0; - for(var idx in codes) { - var $item = $("#group_" + codes[idx]); + for (var idx in storedCodes) { + var $item = $("#group_" + storedCodes[idx]); $item.attr('checked', true); if($item.length > 0) { found++; } } - if(found == 0) { + if (found == 0) { $(".group_reference .group_reference_checkbox:lt(10)").each(function() { $(this).attr('checked', true); }); diff --git a/public/javascripts/gradebooks.js b/public/javascripts/gradebooks.js index 0e081bb4f61..394029f93b7 100644 --- a/public/javascripts/gradebooks.js +++ b/public/javascripts/gradebooks.js @@ -20,16 +20,17 @@ define([ 'INST' /* INST */, 'i18n!gradebook', 'jquery' /* $ */, + 'underscore', + 'compiled/userSettings', 'datagrid', 'compiled/grade_calculator', 'str/htmlEscape', - 'underscore', 'jquery.ajaxJSON' /* ajaxJSONFiles, ajaxJSON */, 'jquery.dropdownList' /* dropdownList */, 'jquery.instructure_date_and_time' /* parseFromISO */, 'jquery.instructure_forms' /* formSubmit, getFormData, formErrors, errorBox */, 'jqueryui/dialog', - 'jquery.instructure_misc_helpers' /* replaceTags, /\$\.size/, /\$\.store/ */, + 'jquery.instructure_misc_helpers' /* replaceTags, /\$\.size/ */, 'jquery.instructure_misc_plugins' /* fragmentChange, showIf */, 'jquery.keycodes' /* keycodes */, 'jquery.loadingImg' /* loadingImg, loadingImage */, @@ -37,10 +38,9 @@ define([ 'message_students' /* messageStudents */, 'vendor/date' /* Date.parse */, 'vendor/jquery.scrollTo' /* /\.scrollTo/ */, - 'vendor/jquery.store' /* /\$\.store/ */, 'jqueryui/position' /* /\.position\(/ */, 'jqueryui/progressbar' /* /\.progressbar/ */ -], function(INST, I18n, $, datagrid, GradeCalculator, htmlEscape, _) { +], function(INST, I18n, $, _, userSettings, datagrid, GradeCalculator, htmlEscape) { var grading_scheme = window.grading_scheme; var readOnlyGradebook = window.readOnlyGradebook; @@ -67,8 +67,8 @@ define([ var possibleSections = {}, $courseSections = $(".outer_student_name .course_section"), contextId = $("#current_context_code").text().split("_")[1], - sectionToShow = $.store.userGet("grading_show_only_section" + contextId); - + sectionToShow = userSettings.contextGet('grading_show_only_section'); + $courseSections.each(function(){ possibleSections[$(this).data('course_section_id')] = $(this).attr('title'); }); @@ -100,7 +100,7 @@ define([ }); if (!atLeastOnePersonExistsInThisSection) { alert(I18n.t('alerts.no_students_in_section', "Could not find any students in that section, falling back to showing all sections.")); - $.store.userRemove("grading_show_only_section"+contextId); + userSettings.contextRemove('grading_show_only_section'); window.location.reload(); } } @@ -820,7 +820,7 @@ define([ object_data.grid = true; $(document).fragmentChange(fragmentCallback); $(document).fragmentChange(); - var columns = $.grep(($.store.userGet('hidden_columns_' + context_code) || '').split(/,/), function(e) { return e; }); + var columns = $.grep((userSettings.contextGet('hidden_columns') || []), function(e) { return e; }); var columns_to_hide = []; if(columns.length) { @@ -828,7 +828,7 @@ define([ columns_to_hide.push(this); }); } - if($.store.userGet('show_attendance_' + context_code) != 'true') { + if (!userSettings.contextGet('show_attendance')) { $(".cell.assignment_name.attendance").each(function() { columns_to_hide.push(this); }); @@ -884,12 +884,14 @@ define([ toggle: function(column, show) { var $cell = datagrid.cells[0 + ',' + column]; var id = $cell.children('.assignment_header').attr('id'); - var columns = $.grep(($.store.userGet('hidden_columns_' + context_code) || '').split(/,/), function(e) { return e && (!show || e != id); }); + var columns = $.grep((userSettings.contextGet('hidden_columns') || []), function(e) { + return e && (!show || e != id); + }); if(!show) { columns.push(id); } columns = $.uniq(columns); - $.store.userSet('hidden_columns_' + context_code, columns.join(',')); + userSettings.contextSet('hidden_columns', columns); } }); }; @@ -1241,7 +1243,7 @@ define([ }; dialogData['buttons'][I18n.t('buttons.change_section', 'Change Section')] = function() { var val = $("#section_to_show_dialog select").val(); - $.store[val == "all" ? 'userRemove' : 'userSet']("grading_show_only_section"+contextId, val); + userSettings[val == "all" ? 'contextRemove' : 'contextSet']('grading_show_only_section', val); window.location.reload(); }; var $dialog = $("#section_to_show_dialog").dialog(dialogData); diff --git a/public/javascripts/instructure.js b/public/javascripts/instructure.js index c41a30de964..cc6c744153f 100644 --- a/public/javascripts/instructure.js +++ b/public/javascripts/instructure.js @@ -22,6 +22,7 @@ define([ 'i18n!instructure', 'jquery' /* $ */, 'underscore', + 'compiled/userSettings', 'str/htmlEscape', 'wikiSidebar', 'instructure_helper', @@ -33,7 +34,7 @@ define([ 'jquery.instructure_date_and_time' /* parseFromISO, dateString */, 'jquery.instructure_forms' /* formSubmit, fillFormData, formErrors */, 'jqueryui/dialog', - 'jquery.instructure_misc_helpers' /* replaceTags, /\$\.store/, youTubeID */, + 'jquery.instructure_misc_helpers' /* replaceTags, youTubeID */, 'jquery.instructure_misc_plugins' /* ifExists, .dim, confirmDelete, showIf, fillWindowWithMe */, 'jquery.keycodes' /* keycodes */, 'jquery.loadingImg' /* loadingImage */, @@ -44,13 +45,12 @@ define([ 'tinymce.editor_box' /* editorBox */, 'vendor/date' /* Date.parse */, 'vendor/jquery.ba-tinypubsub' /* /\.publish\(/ */, - 'vendor/jquery.store' /* /\$\.store/ */, 'jqueryui/accordion' /* /\.accordion\(/ */, 'jqueryui/resizable' /* /\.resizable/ */, 'jqueryui/sortable' /* /\.sortable/ */, 'jqueryui/tabs' /* /\.tabs/ */, 'vendor/scribd.view' /* scribd */ -], function(ENV, INST, I18n, $, _, htmlEscape, wikiSidebar) { +], function(ENV, INST, I18n, $, _, userSettings, htmlEscape, wikiSidebar) { // see: https://github.com/rails/jquery-ujs/blob/master/src/rails.js#L80 var CSRFProtection = function(xhr) { @@ -926,7 +926,7 @@ define([ var pathname = window.location.pathname; $(".close_wizard_link").click(function(event) { event.preventDefault(); - $.store.userSet('hide_wizard_' + pathname, true); + userSettings.set('hide_wizard_' + pathname, true); $wizard_box.slideUp('fast', function() { $(".wizard_popup_link").slideDown('fast'); setWizardSpacerBoxDispay('hide'); @@ -979,7 +979,7 @@ define([ $details.hide().fadeIn('fast'); }); setTimeout(function() { - if(!$.store.userGet('hide_wizard_' + pathname)) { + if(!userSettings.get('hide_wizard_' + pathname)) { $(".wizard_popup_link.auto_open:first").click(); } }, 500); diff --git a/public/javascripts/jquery.instructure_misc_helpers.js b/public/javascripts/jquery.instructure_misc_helpers.js index 4ab03e70d1d..5d67e1d0780 100644 --- a/public/javascripts/jquery.instructure_misc_helpers.js +++ b/public/javascripts/jquery.instructure_misc_helpers.js @@ -25,8 +25,7 @@ define([ 'jquery.ajaxJSON' /* ajaxJSON */, 'jquery.instructure_forms' /* formSuggestion */, 'jqueryui/dialog', - 'vendor/jquery.scrollTo' /* /\.scrollTo/ */, - 'vendor/jquery.store' /* /\$\.store/ */ + 'vendor/jquery.scrollTo' /* /\.scrollTo/ */ ], function(INST, I18n, $, _, htmlEscape) { // Return the first value which passes a truth test @@ -478,26 +477,6 @@ define([ return string.charAt(0).toUpperCase() + string.substring(1).toLowerCase(); }; - var storage_user_id; - function getUser() { - if ( !storage_user_id ) { - storage_user_id = $.trim($("#identity .user_id").text()); - } - return storage_user_id; - }; - - $.store.userGet = function(key) { - return $.store.get("_" + getUser() + "_" + key); - }; - - $.store.userSet = function(key, value) { - return $.store.set("_" + getUser() + "_" + key, value); - }; - - $.store.userRemove = function(key, value) { - return $.store.remove("_" + getUser() + "_" + key, value); - }; - INST.youTubeRegEx = /^https?:\/\/(www\.youtube\.com\/watch.*v(=|\/)|youtu\.be\/)([^&#]*)/; $.youTubeID = function(path) { var match = path.match(INST.youTubeRegEx); diff --git a/public/javascripts/speed_grader.js b/public/javascripts/speed_grader.js index 2a4a11e63b6..543ada0bc07 100644 --- a/public/javascripts/speed_grader.js +++ b/public/javascripts/speed_grader.js @@ -20,6 +20,7 @@ define([ 'INST' /* INST */, 'i18n!gradebook', 'jquery' /* $ */, + 'compiled/userSettings', 'str/htmlEscape', 'rubric_assessment', 'jst/_turnitinInfo', @@ -30,7 +31,7 @@ define([ 'jquery.doc_previews' /* loadDocPreview */, 'jquery.instructure_date_and_time' /* parseFromISO */, 'jqueryui/dialog', - 'jquery.instructure_misc_helpers' /* replaceTags, /\$\.store/ */, + 'jquery.instructure_misc_helpers' /* replaceTags */, 'jquery.instructure_misc_plugins' /* confirmDelete, showIf, hasScrollbar */, 'jquery.keycodes' /* keycodes */, 'jquery.loadingImg' /* loadingImg, loadingImage */, @@ -42,11 +43,10 @@ define([ 'vendor/jquery.getScrollbarWidth' /* getScrollbarWidth */, 'vendor/jquery.scrollTo' /* /\.scrollTo/ */, 'vendor/jquery.spin' /* /\.spin/ */, - 'vendor/jquery.store' /* /\$\.store/ */, 'vendor/scribd.view' /* scribd */, 'vendor/spin' /* new Spinner */, 'vendor/ui.selectmenu' /* /\.selectmenu/ */ -], function(INST, I18n, $, htmlEscape, rubricAssessment, turnitinInfoTemplate, turnitinScoreTemplate) { +], function(INST, I18n, $, userSettings, htmlEscape, rubricAssessment, turnitinInfoTemplate, turnitinScoreTemplate) { // fire off the request to get the jsonData window.jsonData = {}; @@ -152,10 +152,10 @@ define([ return rubricAssessment.user_id === student.id; }); }); - + // handle showing students only in a certain section. - // the sectionToShow will be remembered for a given user in a given browser across all assignments in this course - sectionToShow = Number($.store.userGet("grading_show_only_section"+jsonData.context_id)); + // the sectionToShow will be remembered for a given user in a given browser across all assignments in this course + sectionToShow = userSettings.contextGet('grading_show_only_section'); if (sectionToShow) { var tempArray = $.grep(jsonData.studentsWithSubmissions, function(student, i){ return $.inArray(sectionToShow, student.section_ids) != -1; @@ -164,7 +164,7 @@ define([ jsonData.studentsWithSubmissions = tempArray; } else { alert(I18n.t('alerts.no_students_in_section', "Could not find any students in that section, falling back to showing all sections.")); - $.store.userRemove("grading_show_only_section"+jsonData.context_id); + userSettings.contextRemove('grading_show_only_section'); window.location.reload(); } } @@ -172,7 +172,7 @@ define([ //by defaut the list is sorted alphbetically by student last name so we dont have to do any more work here, // if the cookie to sort it by submitted_at is set we need to sort by submitted_at. var hideStudentNames; - if ($.store.userGet("eg_hide_student_names") == "true") { + if (userSettings.get("eg_hide_student_names")) { hideStudentNames = true; } if(hideStudentNames) { @@ -180,12 +180,12 @@ define([ return ((a && a.submission && a.submission.id) || Number.MAX_VALUE) - ((b && b.submission && b.submission.id) || Number.MAX_VALUE); }); - } else if ($.store.userGet("eg_sort_by") == "submitted_at") { + } else if (userSettings.get("eg_sort_by") == "submitted_at") { jsonData.studentsWithSubmissions.sort(function(a,b){ return ((a && a.submission && a.submission.submitted_at && $.parseFromISO(a.submission.submitted_at).timestamp) || Number.MAX_VALUE) - ((b && b.submission && b.submission.submitted_at && $.parseFromISO(b.submission.submitted_at).timestamp) || Number.MAX_VALUE); - }); - } else if ($.store.userGet("eg_sort_by") == "submission_status") { + }); + } else if (userSettings.get("eg_sort_by") == "submission_status") { jsonData.studentsWithSubmissions.sort(function(a,b) { var states = { "not_graded": 1, @@ -225,8 +225,8 @@ define([ function initDropdown(){ var hideStudentNames; - - if ($.store.userGet("eg_hide_student_names") == "true" || window.anonymousAssignment) { + + if (userSettings.get("eg_hide_student_names") || window.anonymousAssignment) { hideStudentNames = true; } $("#hide_student_names").attr('checked', hideStudentNames); @@ -277,7 +277,7 @@ define([ .hide() .menu() .delegate('a', 'click mousedown', function(){ - $.store[$(this).data('section-id') == 'all' ? 'userRemove' : 'userSet']("grading_show_only_section"+jsonData.context_id, $(this).data('section-id')); + userSettings[$(this).data('section-id') == 'all' ? 'contextRemove' : 'contextSet']('grading_show_only_section', $(this).data('section-id')); window.location.reload(); }); @@ -381,8 +381,8 @@ define([ }, submitForm: function(e){ - $.store.userSet('eg_sort_by', $('#eg_sort_by').val()); - $.store.userSet('eg_hide_student_names', $("#hide_student_names").prop('checked').toString()); + userSettings.set('eg_sort_by', $('#eg_sort_by').val()); + userSettings.set('eg_hide_student_names', $("#hide_student_names").prop('checked').toString()); $(e.target).find(".submit_button").attr('disabled', true).text(I18n.t('buttons.saving_settings', "Saving Settings...")); window.location.reload(); return false; @@ -846,7 +846,7 @@ define([ initKeyCodes(); $window.bind('hashchange', EG.handleFragmentChange); - $('#eg_sort_by').val($.store.userGet('eg_sort_by')); + $('#eg_sort_by').val(userSettings.get('eg_sort_by')); $('#submit_same_score').click(function(e) { EG.handleGradeSubmit(); e.preventDefault(); diff --git a/public/javascripts/vendor/jquery.store.js b/public/javascripts/vendor/jquery.store.js deleted file mode 100644 index d5612633413..00000000000 --- a/public/javascripts/vendor/jquery.store.js +++ /dev/null @@ -1,111 +0,0 @@ -/* Copyright (c) 2010 Marcus Westin - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -define(['jquery'], function($) { - $.store = (function(){ - var api = {}, - win = window, - doc = win.document, - localStorageName = 'localStorage', - globalStorageName = 'globalStorage', - storage, - rInvalidIeChars = /(\s|\/)/g; - - api.set = function(key, value) {}; - api.get = function(key) {}; - api.remove = function(key) {}; - api.clear = function() {}; - api.transact = function(key, transactionFn) { - var val = api.get(key); - if (typeof val == 'undefined') { val = {}; } - transactionFn(val); - api.set(key, val); - }; - - api.serialize = function(value) { - return JSON.stringify(value); - }; - api.deserialize = function(value) { - if (typeof value != 'string') { return undefined; } - return JSON.parse(value); - }; - - if (localStorageName in win && win[localStorageName]) { - storage = win[localStorageName]; - api.set = function(key, val) { storage.setItem(key, api.serialize(val)); } - api.get = function(key) { return api.deserialize(storage.getItem(key)); } - api.remove = function(key) { storage.removeItem(key); } - api.clear = function() { storage.clear(); } - - } else if (globalStorageName in win && win[globalStorageName]) { - storage = win[globalStorageName][win.location.hostname]; - api.set = function(key, val) { storage[key] = api.serialize(val); } - api.get = function(key) { return api.deserialize(storage[key] && storage[key].value); } - api.remove = function(key) { delete storage[key]; } - api.clear = function() { for (var key in storage ) { delete storage[key]; } } - - } else if (doc.documentElement.addBehavior) { - var storage = doc.createElement('div'); - function withIEStorage(storeFunction) { - return function() { - var args = Array.prototype.slice.call(arguments, 0); - args.unshift(storage); - // See http://msdn.microsoft.com/en-us/library/ms531081(v=VS.85).aspx - // and http://msdn.microsoft.com/en-us/library/ms531424(v=VS.85).aspx - - // workaroud for an IE bug that does not allow slashes or whitespace in userData keys - if (args[1] && args[1].match && args[1].match(rInvalidIeChars)) { - // get rid of whitespace and invalid charicters - args[1] = args[1].replace(rInvalidIeChars, ''); - } - - doc.body.appendChild(storage); - storage.addBehavior('#default#userData'); - storage.load(localStorageName); - var result = storeFunction.apply(api, args); - doc.body.removeChild(storage); - return result; - } - } - api.set = withIEStorage(function(storage, key, val) { - storage.setAttribute(key, api.serialize(val)); - storage.save(localStorageName); - }) - api.get = withIEStorage(function(storage, key) { - return api.deserialize(storage.getAttribute(key)); - }) - api.remove = withIEStorage(function(storage, key) { - storage.removeAttribute(key); - storage.save(localStorageName); - }) - api.clear = withIEStorage(function(storage) { - var attributes = storage.XMLDocument.documentElement.attributes; - storage.load(localStorageName); - for (var i=0, attr; attr = attributes[i]; i++) { - storage.removeAttribute(attr.name); - } - storage.save(localStorageName); - }) - } - - return api; - })(); -}); diff --git a/spec/coffeescripts/userSettingsSpec.coffee b/spec/coffeescripts/userSettingsSpec.coffee new file mode 100644 index 00000000000..9f024b8000d --- /dev/null +++ b/spec/coffeescripts/userSettingsSpec.coffee @@ -0,0 +1,49 @@ + +require [ + 'compiled/userSettings' +], (userSettings)-> + + globalObj = this + + module 'UserSettings', + + setup: -> + @_ENV = globalObj.ENV + globalObj.ENV = + current_user_id: 1 + context_asset_string: 'course_1' + + teardown: -> + globalObj.ENV = @_ENV + + test '`get` should return what was `set`', -> + userSettings.set('foo', 'bar') + equal userSettings.get('foo'), 'bar' + + test 'it should strigify/parse JSON', -> + testObject = + foo: [1, 2, 3] + bar: 'true' + baz: true + userSettings.set('foo', testObject) + deepEqual userSettings.get('foo'), testObject + + test 'it should store different things for different users', -> + userSettings.set('foo', 1) + + ENV.current_user_id = 2 + userSettings.set('foo', 2) + equal userSettings.get('foo'), 2 + + ENV.current_user_id = 1 + equal userSettings.get('foo'), 1 + + test 'it should store different things for different contexts', -> + userSettings.contextSet('foo', 1) + + ENV.context_asset_string = 'course_2' + userSettings.contextSet('foo', 2) + equal userSettings.contextGet('foo'), 2 + + ENV.context_asset_string = 'course_1' + equal userSettings.contextGet('foo'), 1 \ No newline at end of file diff --git a/spec/selenium/courses_spec.rb b/spec/selenium/courses_spec.rb index 1749e29cca7..352e3bcb50a 100644 --- a/spec/selenium/courses_spec.rb +++ b/spec/selenium/courses_spec.rb @@ -26,7 +26,7 @@ describe "courses" do wizard_box.displayed?.should be_false # un-remember the setting - driver.execute_script "$.store.clear()" + driver.execute_script "localStorage.clear()" end it "should open and close wizard after initial close" do diff --git a/spec/selenium/gradebook2_grade_edit_spec.rb b/spec/selenium/gradebook2_grade_edit_spec.rb index 7ff61398db8..4664caf293c 100644 --- a/spec/selenium/gradebook2_grade_edit_spec.rb +++ b/spec/selenium/gradebook2_grade_edit_spec.rb @@ -75,7 +75,7 @@ describe "edititing grades" do # NOTE: gradebook1 does not handle 'remembering' the `include_ungraded_assignments` setting # clear our saved settings - driver.execute_script '$.store.clear();' + driver.execute_script 'localStorage.clear();' end it "should validate initial grade totals are correct" do diff --git a/spec/selenium/jquery_store_spec.rb b/spec/selenium/jquery_store_spec.rb deleted file mode 100644 index f58fa418f0b..00000000000 --- a/spec/selenium/jquery_store_spec.rb +++ /dev/null @@ -1,19 +0,0 @@ -require File.expand_path(File.dirname(__FILE__) + "/common") - -describe "jQuery.store" do - it_should_behave_like "in-process server selenium tests" - - it "should handle slashes in the key" do - get "/" - driver.execute_script(" - $.store.set('foo/bar/baz', true); - return $.store.get('foo/bar/baz');").should be_true - end - - it "should persist across page loads" do - get "/" - driver.execute_script("$.store.set('somethingIWantToStore', true)") - get '/' - driver.execute_script("return $.store.get('somethingIWantToStore');").should be_true - end -end