Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
ee4178e7
Commit
ee4178e7
authored
Jan 20, 2014
by
polesye
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add CookieStorage.
parent
7fa5ae9c
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
370 additions
and
3 deletions
+370
-3
CHANGELOG.rst
+3
-0
common/lib/xmodule/xmodule/js/spec/video/cookie_storage_spec.js
+149
-0
common/lib/xmodule/xmodule/js/spec/video/video_volume_control_spec.js
+3
-2
common/lib/xmodule/xmodule/js/src/video/00_cookie_storage.js
+196
-0
common/lib/xmodule/xmodule/js/src/video/README.rst
+16
-0
common/lib/xmodule/xmodule/video_module.py
+3
-1
No files found.
CHANGELOG.rst
View file @
ee4178e7
...
@@ -5,6 +5,9 @@ These are notable changes in edx-platform. This is a rolling list of changes,
...
@@ -5,6 +5,9 @@ These are notable changes in edx-platform. This is a rolling list of changes,
in roughly chronological order, most recent first. Add your entries at or near
in roughly chronological order, most recent first. Add your entries at or near
the top. Include a label indicating the component affected.
the top. Include a label indicating the component affected.
Blades: Adds CookieStorage utility for video player that provides convenient
way to work with cookies.
Blades: Fix comparison of float numbers. BLD-434.
Blades: Fix comparison of float numbers. BLD-434.
Blades: Allow regexp strings as the correct answer to a string response question. BLD-475.
Blades: Allow regexp strings as the correct answer to a string response question. BLD-475.
...
...
common/lib/xmodule/xmodule/js/spec/video/cookie_storage_spec.js
0 → 100644
View file @
ee4178e7
(
function
(
requirejs
,
require
,
define
)
{
require
(
[
'video/00_cookie_storage.js'
],
function
(
CookieStorage
)
{
describe
(
'CookieStorage'
,
function
()
{
var
mostRecentCall
;
beforeEach
(
function
()
{
mostRecentCall
=
$
.
cookie
.
mostRecentCall
;
});
afterEach
(
function
()
{
CookieStorage
(
'test_storage'
).
clear
();
});
describe
(
'intialize'
,
function
()
{
it
(
'with namespace'
,
function
()
{
var
storage
=
CookieStorage
(
'test_storage'
);
storage
.
setItem
(
'item_1'
,
'value_1'
);
expect
(
mostRecentCall
.
args
[
0
]).
toBe
(
'test_storage'
);
});
it
(
'without namespace'
,
function
()
{
var
storage
=
CookieStorage
();
storage
.
setItem
(
'item_1'
,
'value_1'
);
expect
(
mostRecentCall
.
args
[
0
]).
toBe
(
'cookieStorage'
);
});
});
it
(
'unload'
,
function
()
{
var
expected
=
JSON
.
stringify
({
storage
:
{
'item_2'
:
{
value
:
'value_2'
,
session
:
false
}
},
keys
:
[
'item_2'
]
}),
storage
=
CookieStorage
(
'test_storage'
);
storage
.
setItem
(
'item_1'
,
'value_1'
,
true
);
storage
.
setItem
(
'item_2'
,
'value_2'
);
$
(
window
).
trigger
(
'unload'
);
expect
(
mostRecentCall
.
args
[
1
]).
toBe
(
expected
);
});
describe
(
'methods: '
,
function
()
{
var
data
=
{
storage
:
{
'item_1'
:
{
value
:
'value_1'
,
session
:
false
}
},
keys
:
[
'item_1'
]
},
storage
;
beforeEach
(
function
()
{
$
.
cookie
.
andReturn
(
JSON
.
stringify
(
data
));
storage
=
CookieStorage
(
'test_storage'
);
});
describe
(
'setItem'
,
function
()
{
it
(
'pass correct data'
,
function
()
{
var
expected
=
JSON
.
stringify
({
storage
:
{
'item_1'
:
{
value
:
'value_1'
,
session
:
false
},
'item_2'
:
{
value
:
'value_2'
,
session
:
false
},
'item_3'
:
{
value
:
'value_3'
,
session
:
true
},
},
keys
:
[
'item_1'
,
'item_2'
,
'item_3'
]
});
storage
.
setItem
(
'item_2'
,
'value_2'
);
storage
.
setItem
(
'item_3'
,
'value_3'
,
true
);
expect
(
mostRecentCall
.
args
[
0
]).
toBe
(
'test_storage'
);
expect
(
mostRecentCall
.
args
[
1
]).
toBe
(
expected
);
});
it
(
'pass broken arguments'
,
function
()
{
$
.
cookie
.
reset
();
storage
.
setItem
(
null
,
'value_1'
);
expect
(
$
.
cookie
).
not
.
toHaveBeenCalled
();
});
});
describe
(
'getItem'
,
function
()
{
it
(
'item exist'
,
function
()
{
$
.
each
(
data
[
'storage'
],
function
(
key
,
value
)
{
expect
(
storage
.
getItem
(
key
)).
toBe
(
value
[
'value'
]);
});
});
it
(
'item does not exist'
,
function
()
{
expect
(
storage
.
getItem
(
'nonexistent'
)).
toBe
(
null
);
});
});
describe
(
'removeItem'
,
function
()
{
it
(
'item exist'
,
function
()
{
var
expected
=
JSON
.
stringify
({
storage
:
{},
keys
:
[]
});
storage
.
removeItem
(
'item_1'
);
expect
(
mostRecentCall
.
args
[
1
]).
toBe
(
expected
);
});
it
(
'item does not exist'
,
function
()
{
storage
.
removeItem
(
'nonexistent'
);
expect
(
mostRecentCall
.
args
[
1
]).
toBe
(
JSON
.
stringify
(
data
));
});
});
it
(
'clear'
,
function
()
{
storage
.
clear
();
expect
(
mostRecentCall
.
args
[
1
]).
toBe
(
null
);
});
describe
(
'key'
,
function
()
{
it
(
'key exist'
,
function
()
{
$
.
each
(
data
[
'keys'
],
function
(
index
,
name
)
{
expect
(
storage
.
key
(
index
)).
toBe
(
name
);
});
});
it
(
'key is grater than keys list'
,
function
()
{
expect
(
storage
.
key
(
100
)).
toBe
(
null
);
});
});
});
});
});
}(
RequireJS
.
requirejs
,
RequireJS
.
require
,
RequireJS
.
define
));
common/lib/xmodule/xmodule/js/spec/video/video_volume_control_spec.js
View file @
ee4178e7
...
@@ -22,11 +22,12 @@
...
@@ -22,11 +22,12 @@
describe
(
'constructor'
,
function
()
{
describe
(
'constructor'
,
function
()
{
beforeEach
(
function
()
{
beforeEach
(
function
()
{
spyOn
(
$
.
fn
,
'slider'
).
andCallThrough
();
spyOn
(
$
.
fn
,
'slider'
).
andCallThrough
();
$
.
cookie
.
andReturn
(
'75'
);
initialize
();
initialize
();
});
});
it
(
'initialize currentVolume to
100
'
,
function
()
{
it
(
'initialize currentVolume to
75
'
,
function
()
{
expect
(
state
.
videoVolumeControl
.
currentVolume
).
toEqual
(
1
);
expect
(
state
.
videoVolumeControl
.
currentVolume
).
toEqual
(
75
);
});
});
it
(
'render the volume control'
,
function
()
{
it
(
'render the volume control'
,
function
()
{
...
...
common/lib/xmodule/xmodule/js/src/video/00_cookie_storage.js
0 → 100644
View file @
ee4178e7
(
function
(
requirejs
,
require
,
define
)
{
define
(
'video/00_cookie_storage.js'
,
[],
function
()
{
"use strict"
;
/**
* Provides convenient way to work with cookies.
*
* Maximum 4096 bytes can be stored per namespace.
*
* @TODO: Uses localStorage if available.
*
* @param {string} namespace Namespace that is used to store data.
* @return {object} CookieStorage API.
*/
var
CookieStorage
=
function
(
namespace
)
{
var
Storage
;
/**
* Returns an empty storage with proper data structure.
*
* @private
* @return {object} Empty storage.
*/
var
_getEmptyStorage
=
function
()
{
return
{
storage
:
{},
keys
:
[]
};
};
/**
* Returns the current value associated with the given namespace.
* If data doesn't exist or has data with incorrect interface, it creates
* an empty storage with proper data structure.
*
* @private
* @param {string} namespace Namespace that is used to store data.
* @return {object} Stored data or an empty storage.
*/
var
_getData
=
function
(
namespace
)
{
var
data
;
try
{
data
=
JSON
.
parse
(
$
.
cookie
(
namespace
));
}
catch
(
err
)
{
}
if
(
!
data
||
!
data
[
'storage'
]
||
!
data
[
'keys'
])
{
return
_getEmptyStorage
();
}
return
data
;
};
/**
* Clears cookies that has flag `session` equals true.
*
* @private
*/
var
_clearSession
=
function
()
{
Storage
[
'keys'
]
=
$
.
grep
(
Storage
[
'keys'
],
function
(
key_name
,
index
)
{
if
(
Storage
[
'storage'
][
key_name
][
'session'
])
{
delete
Storage
[
'storage'
][
key_name
];
return
false
;
}
return
true
;
});
$
.
cookie
(
namespace
,
JSON
.
stringify
(
Storage
),
{
expires
:
-
1
,
path
:
'/'
});
};
/**
* Adds new value to the storage or rewrites existent.
*
* @param {string} name Identifier of the data.
* @param {any} value Data to store.
* @param {boolean} useSession Data with this flag will be removed on
* window unload.
*/
var
setItem
=
function
(
name
,
value
,
useSession
)
{
if
(
name
)
{
if
(
$
.
inArray
(
name
,
Storage
[
'keys'
])
===
-
1
)
{
Storage
[
'keys'
].
push
(
name
);
}
Storage
[
'storage'
][
name
]
=
{
value
:
value
,
session
:
useSession
?
true
:
false
};
$
.
cookie
(
namespace
,
JSON
.
stringify
(
Storage
),
{
expires
:
3650
,
path
:
'/'
});
}
};
/**
* Returns the current value associated with the given name.
*
* @param {string} name Identifier of the data.
* @return {any} The current value associated with the given name.
* If the given key does not exist in the list
* associated with the object then this method must return null.
*/
var
getItem
=
function
(
name
)
{
try
{
return
Storage
[
'storage'
][
name
][
'value'
];
}
catch
(
err
)
{
}
return
null
;
};
/**
* Removes the current value associated with the given name.
*
* @param {string} name Identifier of the data.
*/
var
removeItem
=
function
(
name
)
{
delete
Storage
[
'storage'
][
name
];
Storage
[
'keys'
]
=
$
.
grep
(
Storage
[
'keys'
],
function
(
key_name
,
index
)
{
return
name
!==
key_name
;
});
$
.
cookie
(
namespace
,
JSON
.
stringify
(
Storage
),
{
expires
:
3650
,
path
:
'/'
});
};
/**
* Empties the storage.
*
*/
var
clear
=
function
()
{
Storage
=
_getEmptyStorage
();
$
.
cookie
(
namespace
,
null
,
{
expires
:
-
1
,
path
:
'/'
});
};
/**
* Returns the name of the `n`th key in the list.
*
* @param {number} n Index of the key.
* @return {string} Name of the `n`th key in the list.
* If `n` is greater than or equal to the number of key/value pairs
* in the object, then this method must return `null`.
*/
var
key
=
function
(
n
)
{
if
(
n
>=
Storage
[
'keys'
].
length
)
{
return
null
;
}
return
Storage
[
'keys'
][
n
];
};
/**
* Initializes the module: creates a storage with proper namespace, binds
* `unload` event.
*
* @private
*/
(
function
initialize
()
{
if
(
!
namespace
)
{
namespace
=
'cookieStorage'
;
}
Storage
=
_getData
(
namespace
);
$
(
window
).
unload
(
_clearSession
);
}());
return
{
clear
:
clear
,
getItem
:
getItem
,
key
:
key
,
removeItem
:
removeItem
,
setItem
:
setItem
};
};
return
CookieStorage
;
});
}(
RequireJS
.
requirejs
,
RequireJS
.
require
,
RequireJS
.
define
));
common/lib/xmodule/xmodule/js/src/video/README.rst
0 → 100644
View file @
ee4178e7
Video player persists some user preferences between videos and these
preferences are stored on server.
Content for sequential positions is loaded just once on page load and is not
updated when the user navigates between sequential positions. So, we doesn't
have an actual data from server.
To resolve this issue, cookies are used as temporary storage and are removed
on page unload.
How it works:
1) On page load: cookies are empty and player get an actual data from server.
2) When user change some preferences, new value is stored to cookie;
3) If we navigate to another sequential position, video player get an actual data
from cookies.
4) Close the page: `unload` event fires and we clear our cookies and send user
preferences to the server.
common/lib/xmodule/xmodule/video_module.py
View file @
ee4178e7
...
@@ -25,7 +25,6 @@ from xmodule.x_module import XModule
...
@@ -25,7 +25,6 @@ from xmodule.x_module import XModule
from
xmodule.editing_module
import
TabsEditingDescriptor
from
xmodule.editing_module
import
TabsEditingDescriptor
from
xmodule.raw_module
import
EmptyDataRawDescriptor
from
xmodule.raw_module
import
EmptyDataRawDescriptor
from
xmodule.xml_module
import
is_pointer_tag
,
name_to_pathname
,
deserialize_field
from
xmodule.xml_module
import
is_pointer_tag
,
name_to_pathname
,
deserialize_field
from
xmodule.modulestore
import
Location
from
xblock.fields
import
Scope
,
String
,
Boolean
,
List
,
Integer
,
ScopeIds
from
xblock.fields
import
Scope
,
String
,
Boolean
,
List
,
Integer
,
ScopeIds
from
xmodule.fields
import
RelativeTime
from
xmodule.fields
import
RelativeTime
...
@@ -134,8 +133,11 @@ class VideoModule(VideoFields, XModule):
...
@@ -134,8 +133,11 @@ class VideoModule(VideoFields, XModule):
video_time
=
0
video_time
=
0
icon_class
=
'video'
icon_class
=
'video'
# To make sure that js files are called in proper order we use numerical
# index. We do that to avoid issues that occurs in tests.
js
=
{
js
=
{
'js'
:
[
'js'
:
[
resource_string
(
__name__
,
'js/src/video/00_cookie_storage.js'
),
resource_string
(
__name__
,
'js/src/video/00_resizer.js'
),
resource_string
(
__name__
,
'js/src/video/00_resizer.js'
),
resource_string
(
__name__
,
'js/src/video/01_initialize.js'
),
resource_string
(
__name__
,
'js/src/video/01_initialize.js'
),
resource_string
(
__name__
,
'js/src/video/025_focus_grabber.js'
),
resource_string
(
__name__
,
'js/src/video/025_focus_grabber.js'
),
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment