commit
21674d31ac
|
@ -1,13 +1,12 @@
|
||||||
This folder contains the h5p general library. The files within this folder are not specific to any framework.
|
This folder contains the h5p general library. The files within this folder are not specific to any framework.
|
||||||
|
|
||||||
Any interaction with LMS, CMS or other frameworks is done through interfaces. Plattforms needs to implement
|
Any interaction with LMS, CMS or other frameworks is done through interfaces. Plattforms needs to implement
|
||||||
the following interfaces in order for the h5p libraries to work:
|
the H5PFrameworkInterface(in h5p.classes.php) and also do the following:
|
||||||
|
|
||||||
- TODO: Fill in here
|
|
||||||
|
|
||||||
In addition frameworks need to do the following:
|
|
||||||
|
|
||||||
- Provide a form for uploading h5p packages.
|
- Provide a form for uploading h5p packages.
|
||||||
- Place the uploaded h5p packages in a temporary directory
|
- Place the uploaded h5p packages in a temporary directory
|
||||||
|
+++
|
||||||
|
|
||||||
See existing implementations for details. For instance the Drupal h5p module located on drupal.org/project/h5p
|
See existing implementations for details. For instance the Drupal h5p module located on drupal.org/project/h5p
|
||||||
|
|
||||||
|
We will make available documentations and tutorials for creating platform integrations in the future
|
||||||
|
|
|
@ -93,6 +93,7 @@ class H5PDevelopment {
|
||||||
// TODO: Should we remove libraries without files? Not really needed, but must be cleaned up some time, right?
|
// TODO: Should we remove libraries without files? Not really needed, but must be cleaned up some time, right?
|
||||||
|
|
||||||
// Go trough libraries and insert dependencies. Missing deps. will just be ignored and not available. (I guess?!)
|
// Go trough libraries and insert dependencies. Missing deps. will just be ignored and not available. (I guess?!)
|
||||||
|
$this->h5pF->lockDependencyStorage();
|
||||||
foreach ($this->libraries as $library) {
|
foreach ($this->libraries as $library) {
|
||||||
$this->h5pF->deleteLibraryDependencies($library['libraryId']);
|
$this->h5pF->deleteLibraryDependencies($library['libraryId']);
|
||||||
// This isn't optimal, but without it we would get duplicate warnings.
|
// This isn't optimal, but without it we would get duplicate warnings.
|
||||||
|
@ -104,6 +105,7 @@ class H5PDevelopment {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
$this->h5pF->unlockDependencyStorage();
|
||||||
// TODO: Deps must be inserted into h5p_nodes_libraries as well... ? But only if they are used?!
|
// TODO: Deps must be inserted into h5p_nodes_libraries as well... ? But only if they are used?!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
350
h5p.classes.php
350
h5p.classes.php
|
@ -4,6 +4,33 @@
|
||||||
*/
|
*/
|
||||||
interface H5PFrameworkInterface {
|
interface H5PFrameworkInterface {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns info for the current platform
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
* An associative array containing:
|
||||||
|
* - name: The name of the plattform, for instance "Wordpress"
|
||||||
|
* - version: The version of the pattform, for instance "4.0"
|
||||||
|
* - h5pVersion: The version of the H5P plugin/module
|
||||||
|
*/
|
||||||
|
public function getPlatformInfo();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches a file from a remote server using HTTP GET
|
||||||
|
*
|
||||||
|
* @param $url
|
||||||
|
* @return string The content (response body). NULL if something went wrong
|
||||||
|
*/
|
||||||
|
public function fetchExternalData($url);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the tutorial URL for a library. All versions of the library is set
|
||||||
|
*
|
||||||
|
* @param string $machineName
|
||||||
|
* @param string $tutorialUrl
|
||||||
|
*/
|
||||||
|
public function setLibraryTutorialUrl($machineName, $tutorialUrl);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show the user an error message
|
* Show the user an error message
|
||||||
*
|
*
|
||||||
|
@ -33,59 +60,82 @@ interface H5PFrameworkInterface {
|
||||||
* - @variable: escape plain text to HTML
|
* - @variable: escape plain text to HTML
|
||||||
* - %variable: escape text and theme as a placeholder for user-submitted
|
* - %variable: escape text and theme as a placeholder for user-submitted
|
||||||
* content
|
* content
|
||||||
* @return string Translated string
|
* @return string
|
||||||
|
* Translated string
|
||||||
*/
|
*/
|
||||||
public function t($message, $replacements = array());
|
public function t($message, $replacements = array());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the Path to the last uploaded h5p
|
* Get the Path to the last uploaded h5p
|
||||||
*
|
*
|
||||||
* @return string Path to the folder where the last uploaded h5p for this session is located.
|
* @return string
|
||||||
|
* Path to the folder where the last uploaded h5p for this session is located.
|
||||||
*/
|
*/
|
||||||
public function getUploadedH5pFolderPath();
|
public function getUploadedH5pFolderPath();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string Path to the folder where all h5p files are stored
|
* @return string
|
||||||
|
* Path to the folder where all h5p files are stored
|
||||||
*/
|
*/
|
||||||
public function getH5pPath();
|
public function getH5pPath();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the path to the last uploaded h5p file
|
* Get the path to the last uploaded h5p file
|
||||||
*
|
*
|
||||||
* @return string Path to the last uploaded h5p
|
* @return string
|
||||||
|
* Path to the last uploaded h5p
|
||||||
*/
|
*/
|
||||||
public function getUploadedH5pPath();
|
public function getUploadedH5pPath();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the list of the current installed libraries
|
* Get a list of the current installed libraries
|
||||||
*
|
*
|
||||||
* @return array Associative array containg one item per machine name. This item contains an array of libraries.
|
* @return array
|
||||||
|
* Associative array containg one entry per machine name.
|
||||||
|
* For each machineName there is a list of libraries(with different versions)
|
||||||
*/
|
*/
|
||||||
public function loadLibraries();
|
public function loadLibraries();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saving the unsupported library list
|
* Saving the unsupported library list
|
||||||
*
|
*
|
||||||
* @param array A list of unsupported libraries
|
* @param array
|
||||||
|
* A list of unsupported libraries. Each list entry contains:
|
||||||
|
* - name: MachineName for the library
|
||||||
|
* - downloadUrl: URL to a location a new version of the library may be downloaded from
|
||||||
|
* - currentVersion: The unsupported version of the library installed on the system.
|
||||||
|
* This is an associative array containing:
|
||||||
|
* - major: The major version of the library
|
||||||
|
* - minor: The minor version of the library
|
||||||
|
* - patch: The patch version of the library
|
||||||
*/
|
*/
|
||||||
public function setUnsupportedLibraries($libraries);
|
public function setUnsupportedLibraries($libraries);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns unsupported libraries
|
* Returns unsupported libraries
|
||||||
*
|
*
|
||||||
* @return array A list of the unsupported libraries
|
* @return array
|
||||||
|
* A list of unsupported libraries. Each entry contains an associative array with:
|
||||||
|
* - name: MachineName for the library
|
||||||
|
* - downloadUrl: URL to a location a new version of the library may be downloaded from
|
||||||
|
* - currentVersion: The unsupported version of the library installed on the system.
|
||||||
|
* This is an associative array containing:
|
||||||
|
* - major: The major version of the library
|
||||||
|
* - minor: The minor version of the library
|
||||||
|
* - patch: The patch version of the library
|
||||||
*/
|
*/
|
||||||
public function getUnsupportedLibraries();
|
public function getUnsupportedLibraries();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the URL to the library admin page
|
* Returns the URL to the library admin page
|
||||||
*
|
*
|
||||||
* @return string URL to admin page
|
* @return string
|
||||||
|
* URL to admin page
|
||||||
*/
|
*/
|
||||||
public function getAdminUrl();
|
public function getAdminUrl();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get id to an excisting library
|
* Get id to an existing library
|
||||||
*
|
*
|
||||||
* @param string $machineName
|
* @param string $machineName
|
||||||
* The librarys machine name
|
* The librarys machine name
|
||||||
|
@ -104,8 +154,12 @@ interface H5PFrameworkInterface {
|
||||||
* The default extension list is part of h5p, but admins should be allowed to modify it
|
* The default extension list is part of h5p, but admins should be allowed to modify it
|
||||||
*
|
*
|
||||||
* @param boolean $isLibrary
|
* @param boolean $isLibrary
|
||||||
|
* TRUE if this is the whitelist for a library. FALSE if it is the whitelist
|
||||||
|
* for the content folder we are getting
|
||||||
* @param string $defaultContentWhitelist
|
* @param string $defaultContentWhitelist
|
||||||
|
* A string of file extensions separated by whitespace
|
||||||
* @param string $defaultLibraryWhitelist
|
* @param string $defaultLibraryWhitelist
|
||||||
|
* A string of file extensions separated by whitespace
|
||||||
*/
|
*/
|
||||||
public function getWhitelist($isLibrary, $defaultContentWhitelist, $defaultLibraryWhitelist);
|
public function getWhitelist($isLibrary, $defaultContentWhitelist, $defaultLibraryWhitelist);
|
||||||
|
|
||||||
|
@ -113,9 +167,13 @@ interface H5PFrameworkInterface {
|
||||||
* Is the library a patched version of an existing library?
|
* Is the library a patched version of an existing library?
|
||||||
*
|
*
|
||||||
* @param object $library
|
* @param object $library
|
||||||
* The library data for a library we are checking
|
* An associateve array containing:
|
||||||
|
* - machineName: The library machineName
|
||||||
|
* - majorVersion: The librarys majorVersion
|
||||||
|
* - minorVersion: The librarys minorVersion
|
||||||
|
* - patchVersion: The librarys patchVersion
|
||||||
* @return boolean
|
* @return boolean
|
||||||
* TRUE if the library is a patched version of an excisting library
|
* TRUE if the library is a patched version of an existing library
|
||||||
* FALSE otherwise
|
* FALSE otherwise
|
||||||
*/
|
*/
|
||||||
public function isPatchedLibrary($library);
|
public function isPatchedLibrary($library);
|
||||||
|
@ -144,23 +202,53 @@ interface H5PFrameworkInterface {
|
||||||
* Also fills in the libraryId in the libraryData object if the object is new
|
* Also fills in the libraryId in the libraryData object if the object is new
|
||||||
*
|
*
|
||||||
* @param object $libraryData
|
* @param object $libraryData
|
||||||
* Object holding the information that is to be stored
|
* Associative array containing:
|
||||||
|
* - libraryId: The id of the library if it is an existing library.
|
||||||
|
* - title: The library's name
|
||||||
|
* - machineName: The library machineName
|
||||||
|
* - majorVersion: The library's majorVersion
|
||||||
|
* - minorVersion: The library's minorVersion
|
||||||
|
* - patchVersion: The library's patchVersion
|
||||||
|
* - runnable: 1 if the library is a content type, 0 otherwise
|
||||||
|
* - fullscreen(optional): 1 if the library supports fullscreen, 0 otherwise
|
||||||
|
* - embedTypes(optional): list of supported embed types
|
||||||
|
* - preloadedJs(optional): list of associative arrays containing:
|
||||||
|
* - path: path to a js file relative to the library root folder
|
||||||
|
* - preloadedCss(optional): list of associative arrays containing:
|
||||||
|
* - path: path to css file relative to the library root folder
|
||||||
|
* - dropLibraryCss(optional): list of associative arrays containing:
|
||||||
|
* - machineName: machine name for the librarys that are to drop their css
|
||||||
|
* - semantics(optional): Json describing the content structure for the library
|
||||||
|
* - language(optional): associative array containing:
|
||||||
|
* - languageCode: Translation in json format
|
||||||
*/
|
*/
|
||||||
public function saveLibraryData(&$libraryData, $new = TRUE);
|
public function saveLibraryData(&$libraryData, $new = TRUE);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Insert new content.
|
* Insert new content.
|
||||||
*
|
*
|
||||||
* @param object $content
|
* @param array $content
|
||||||
|
* An associative array containing:
|
||||||
|
* - id: The content id
|
||||||
|
* - params: The content in json format
|
||||||
|
* - library: An associative array containing:
|
||||||
|
* - libraryId: The id of the main library for this content
|
||||||
* @param int $contentMainId
|
* @param int $contentMainId
|
||||||
|
* Main id for the content if this is a system that supports versioning
|
||||||
*/
|
*/
|
||||||
public function insertContent($content, $contentMainId = NULL);
|
public function insertContent($content, $contentMainId = NULL);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update old content.
|
* Update old content.
|
||||||
*
|
*
|
||||||
* @param object $content
|
* @param array $content
|
||||||
|
* An associative array containing:
|
||||||
|
* - id: The content id
|
||||||
|
* - params: The content in json format
|
||||||
|
* - library: An associative array containing:
|
||||||
|
* - libraryId: The id of the main library for this content
|
||||||
* @param int $contentMainId
|
* @param int $contentMainId
|
||||||
|
* Main id for the content if this is a system that supports versioning
|
||||||
*/
|
*/
|
||||||
public function updateContent($content, $contentMainId = NULL);
|
public function updateContent($content, $contentMainId = NULL);
|
||||||
|
|
||||||
|
@ -170,21 +258,27 @@ interface H5PFrameworkInterface {
|
||||||
* @param int $libraryId
|
* @param int $libraryId
|
||||||
* Library Id for the library we're saving dependencies for
|
* Library Id for the library we're saving dependencies for
|
||||||
* @param array $dependencies
|
* @param array $dependencies
|
||||||
* List of dependencies in the format used in library.json
|
* List of dependencies as associative arrays containing:
|
||||||
|
* - machineName: The library machineName
|
||||||
|
* - majorVersion: The library's majorVersion
|
||||||
|
* - minorVersion: The library's minorVersion
|
||||||
* @param string $dependency_type
|
* @param string $dependency_type
|
||||||
* What type of dependency this is, for instance it might be an editor dependency
|
* What type of dependency this is, the following values are allowed:
|
||||||
|
* - editor
|
||||||
|
* - preloaded
|
||||||
|
* - dynamic
|
||||||
*/
|
*/
|
||||||
public function saveLibraryDependencies($libraryId, $dependencies, $dependency_type);
|
public function saveLibraryDependencies($libraryId, $dependencies, $dependency_type);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copies library usage
|
* Give an H5P the same library dependencies as a given H5P
|
||||||
*
|
*
|
||||||
* @param int $contentId
|
* @param int $contentId
|
||||||
* Framework specific id identifying the content
|
* Id identifying the content
|
||||||
* @param int $copyFromId
|
* @param int $copyFromId
|
||||||
* Framework specific id identifying the content to be copied
|
* Id identifying the content to be copied
|
||||||
* @param int $contentMainId
|
* @param int $contentMainId
|
||||||
* Framework specific main id for the content, typically used in frameworks
|
* Main id for the content, typically used in frameworks
|
||||||
* That supports versioning. (In this case the content id will typically be
|
* That supports versioning. (In this case the content id will typically be
|
||||||
* the version id, and the contentMainId will be the frameworks content id
|
* the version id, and the contentMainId will be the frameworks content id
|
||||||
*/
|
*/
|
||||||
|
@ -194,7 +288,7 @@ interface H5PFrameworkInterface {
|
||||||
* Deletes content data
|
* Deletes content data
|
||||||
*
|
*
|
||||||
* @param int $contentId
|
* @param int $contentId
|
||||||
* Framework specific id identifying the content
|
* Id identifying the content
|
||||||
*/
|
*/
|
||||||
public function deleteContentData($contentId);
|
public function deleteContentData($contentId);
|
||||||
|
|
||||||
|
@ -210,11 +304,17 @@ interface H5PFrameworkInterface {
|
||||||
* Saves what libraries the content uses
|
* Saves what libraries the content uses
|
||||||
*
|
*
|
||||||
* @param int $contentId
|
* @param int $contentId
|
||||||
* Framework specific id identifying the content
|
* Id identifying the content
|
||||||
* @param array $librariesInUse
|
* @param array $librariesInUse
|
||||||
* List of libraries the content uses. Libraries consist of arrays with:
|
* List of libraries the content uses. Libraries consist of associative arrays with:
|
||||||
* - libraryId stored in $librariesInUse[<place>]['library']['libraryId']
|
* - library: Associative array containing:
|
||||||
* - libraryId stored in $librariesInUse[<place>]['preloaded']
|
* - dropLibraryCss(optional): commasepareted list of machineNames
|
||||||
|
* - machineName: Machine name for the library
|
||||||
|
* - libraryId: Id of the library
|
||||||
|
* - type: The dependency type. Allowed values:
|
||||||
|
* - editor
|
||||||
|
* - dynamic
|
||||||
|
* - preloaded
|
||||||
*/
|
*/
|
||||||
public function saveLibraryUsage($contentId, $librariesInUse);
|
public function saveLibraryUsage($contentId, $librariesInUse);
|
||||||
|
|
||||||
|
@ -222,9 +322,12 @@ interface H5PFrameworkInterface {
|
||||||
* Get number of content/nodes using a library, and the number of
|
* Get number of content/nodes using a library, and the number of
|
||||||
* dependencies to other libraries
|
* dependencies to other libraries
|
||||||
*
|
*
|
||||||
* @param int $library_id
|
* @param int $libraryId
|
||||||
* @return array The array contains two elements, keyed by 'content' and 'libraries'.
|
* Library identifier
|
||||||
* Each element contains a number
|
* @return array
|
||||||
|
* Associative array containing:
|
||||||
|
* - content: Number of content using the library
|
||||||
|
* - libraries: Number of libraries depending on the library
|
||||||
*/
|
*/
|
||||||
public function getLibraryUsage($libraryId);
|
public function getLibraryUsage($libraryId);
|
||||||
|
|
||||||
|
@ -232,71 +335,151 @@ interface H5PFrameworkInterface {
|
||||||
* Loads a library
|
* Loads a library
|
||||||
*
|
*
|
||||||
* @param string $machineName
|
* @param string $machineName
|
||||||
|
* The library's machine name
|
||||||
* @param int $majorVersion
|
* @param int $majorVersion
|
||||||
|
* The library's major version
|
||||||
* @param int $minorVersion
|
* @param int $minorVersion
|
||||||
|
* The library's minor version
|
||||||
* @return array|FALSE
|
* @return array|FALSE
|
||||||
* Array representing the library with dependency descriptions
|
* FALSE if the library doesn't exist.
|
||||||
* FALSE if the library doesn't exist
|
* Otherwise an associative array containing:
|
||||||
|
* - libraryId: The id of the library if it is an existing library.
|
||||||
|
* - title: The library's name
|
||||||
|
* - machineName: The library machineName
|
||||||
|
* - majorVersion: The library's majorVersion
|
||||||
|
* - minorVersion: The library's minorVersion
|
||||||
|
* - patchVersion: The library's patchVersion
|
||||||
|
* - runnable: 1 if the library is a content type, 0 otherwise
|
||||||
|
* - fullscreen(optional): 1 if the library supports fullscreen, 0 otherwise
|
||||||
|
* - embedTypes(optional): list of supported embed types
|
||||||
|
* - preloadedJs(optional): comma separated string with js file paths
|
||||||
|
* - preloadedCss(optional): comma separated sting with css file paths
|
||||||
|
* - dropLibraryCss(optional): list of associative arrays containing:
|
||||||
|
* - machineName: machine name for the librarys that are to drop their css
|
||||||
|
* - semantics(optional): Json describing the content structure for the library
|
||||||
|
* - preloadedDependencies(optional): list of associative arrays containing:
|
||||||
|
* - machineName: Machine name for a library this library is depending on
|
||||||
|
* - majorVersion: Major version for a library this library is depending on
|
||||||
|
* - minorVersion: Minor for a library this library is depending on
|
||||||
|
* - dynamicDependencies(optional): list of associative arrays containing:
|
||||||
|
* - machineName: Machine name for a library this library is depending on
|
||||||
|
* - majorVersion: Major version for a library this library is depending on
|
||||||
|
* - minorVersion: Minor for a library this library is depending on
|
||||||
|
* - editorDependencies(optional): list of associative arrays containing:
|
||||||
|
* - machineName: Machine name for a library this library is depending on
|
||||||
|
* - majorVersion: Major version for a library this library is depending on
|
||||||
|
* - minorVersion: Minor for a library this library is depending on
|
||||||
*/
|
*/
|
||||||
public function loadLibrary($machineName, $majorVersion, $minorVersion);
|
public function loadLibrary($machineName, $majorVersion, $minorVersion);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads library semantics.
|
* Loads library semantics.
|
||||||
*
|
*
|
||||||
* @param string $name library identifier.
|
* @param string $machineName
|
||||||
* @param int $majorVersion library identifier.
|
* Machine name for the library
|
||||||
* @param int $minorVersion library identifier.
|
* @param int $majorVersion
|
||||||
* @return string semantics.
|
* The library's major version
|
||||||
|
* @param int $minorVersion
|
||||||
|
* The library's minor version
|
||||||
|
* @return string
|
||||||
|
* The library's semantics as json
|
||||||
*/
|
*/
|
||||||
public function loadLibrarySemantics($name, $majorVersion, $minorVersion);
|
public function loadLibrarySemantics($machineName, $majorVersion, $minorVersion);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes it possible to alter the semantics, adding custom fields, etc.
|
* Makes it possible to alter the semantics, adding custom fields, etc.
|
||||||
*
|
*
|
||||||
* @param array $semantics
|
* @param array $semantics
|
||||||
* @param string $name library identifier.
|
* Associative array representing the semantics
|
||||||
* @param int $majorVersion library identifier.
|
* @param string $machineName
|
||||||
* @param int $minorVersion library identifier.
|
* The library's machine name
|
||||||
|
* @param int $majorVersion
|
||||||
|
* The library's major version
|
||||||
|
* @param int $minorVersion
|
||||||
|
* The library's minor version
|
||||||
*/
|
*/
|
||||||
public function alterLibrarySemantics(&$semantics, $name, $majorVersion, $minorVersion);
|
public function alterLibrarySemantics(&$semantics, $machineName, $majorVersion, $minorVersion);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete all dependencies belonging to given library
|
* Delete all dependencies belonging to given library
|
||||||
*
|
*
|
||||||
* @param int $libraryId
|
* @param int $libraryId
|
||||||
* Library Id
|
* Library identifier
|
||||||
*/
|
*/
|
||||||
public function deleteLibraryDependencies($libraryId);
|
public function deleteLibraryDependencies($libraryId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start an atomic operation against the dependency storage
|
||||||
|
*/
|
||||||
|
public function lockDependencyStorage();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops an atomic operation against the dependency storage
|
||||||
|
*/
|
||||||
|
public function unlockDependencyStorage();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete a library from database and file system
|
* Delete a library from database and file system
|
||||||
*
|
*
|
||||||
* @param mixed $library Library
|
* @param stdClass $library
|
||||||
|
* Library object with id, name, major version and minor version.
|
||||||
*/
|
*/
|
||||||
public function deleteLibrary($library);
|
public function deleteLibrary($library);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load content.
|
* Load content.
|
||||||
*
|
*
|
||||||
* @return object Content, null if not found.
|
* @param int $id
|
||||||
|
* Content identifier
|
||||||
|
* @return array
|
||||||
|
* Associative array containing:
|
||||||
|
* - contentId: Identifier for the content
|
||||||
|
* - params: json content as string
|
||||||
|
* - embedType: csv of embed types
|
||||||
|
* - title: The contents title
|
||||||
|
* - language: Language code for the content
|
||||||
|
* - libraryId: Id for the main library
|
||||||
|
* - libraryName: The library machine name
|
||||||
|
* - libraryMajorVersion: The library's majorVersion
|
||||||
|
* - libraryMinorVersion: The library's minorVersion
|
||||||
|
* - libraryEmbedTypes: CSV of the main library's embed types
|
||||||
|
* - libraryFullscreen: 1 if fullscreen is supported. 0 otherwise.
|
||||||
*/
|
*/
|
||||||
public function loadContent($id);
|
public function loadContent($id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load dependencies for the given content of the given type.
|
* Load dependencies for the given content of the given type.
|
||||||
*
|
*
|
||||||
* @param int $id content.
|
* @param int $id
|
||||||
* @param int $type dependency.
|
* Content identifier
|
||||||
|
* @param int $type
|
||||||
|
* Dependency types. Allowed values:
|
||||||
|
* - editor
|
||||||
|
* - preloaded
|
||||||
|
* - dynamic
|
||||||
* @return array
|
* @return array
|
||||||
|
* List of associative arrays containing:
|
||||||
|
* - libraryId: The id of the library if it is an existing library.
|
||||||
|
* - machineName: The library machineName
|
||||||
|
* - majorVersion: The library's majorVersion
|
||||||
|
* - minorVersion: The library's minorVersion
|
||||||
|
* - patchVersion: The library's patchVersion
|
||||||
|
* - preloadedJs(optional): comma separated string with js file paths
|
||||||
|
* - preloadedCss(optional): comma separated sting with css file paths
|
||||||
|
* - dropCss(optional): csv of machine names
|
||||||
*/
|
*/
|
||||||
public function loadContentDependencies($id, $type = NULL);
|
public function loadContentDependencies($id, $type = NULL);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get stored setting.
|
* Get stored setting.
|
||||||
*
|
*
|
||||||
* @param string $name Identifier
|
* @param string $name
|
||||||
* @param string $default Optional
|
* Identifier for the setting
|
||||||
* @return mixed data
|
* @param string $default
|
||||||
|
* Optional default value if settings is not set
|
||||||
|
* @return mixed
|
||||||
|
* Whatever has been stored as the setting
|
||||||
*/
|
*/
|
||||||
public function getOption($name, $default = NULL);
|
public function getOption($name, $default = NULL);
|
||||||
|
|
||||||
|
@ -304,8 +487,10 @@ interface H5PFrameworkInterface {
|
||||||
* Stores the given setting.
|
* Stores the given setting.
|
||||||
* For example when did we last check h5p.org for updates to our libraries.
|
* For example when did we last check h5p.org for updates to our libraries.
|
||||||
*
|
*
|
||||||
* @param string $name Identifier
|
* @param string $name
|
||||||
* @param mixed $value Data limited to 2^32 bytes of data
|
* Identifier for the setting
|
||||||
|
* @param mixed $value Data
|
||||||
|
* Whatever we want to store as the setting
|
||||||
*/
|
*/
|
||||||
public function setOption($name, $value);
|
public function setOption($name, $value);
|
||||||
|
|
||||||
|
@ -337,10 +522,10 @@ interface H5PFrameworkInterface {
|
||||||
/**
|
/**
|
||||||
* Get number of contents using library as main library.
|
* Get number of contents using library as main library.
|
||||||
*
|
*
|
||||||
* @param int $library_id
|
* @param int $libraryId
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
public function getNumContent($library_id);
|
public function getNumContent($libraryId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1090,7 +1275,8 @@ class H5PStorage {
|
||||||
}
|
}
|
||||||
$destination_path = $libraries_path . DIRECTORY_SEPARATOR . H5PCore::libraryToString($library, TRUE);
|
$destination_path = $libraries_path . DIRECTORY_SEPARATOR . H5PCore::libraryToString($library, TRUE);
|
||||||
H5PCore::deleteFileTree($destination_path);
|
H5PCore::deleteFileTree($destination_path);
|
||||||
rename($library['uploadDirectory'], $destination_path);
|
$this->h5pC->copyFileTree($library['uploadDirectory'], $destination_path);
|
||||||
|
H5PCore::deleteFileTree($library['uploadDirectory']);
|
||||||
|
|
||||||
$library_saved = TRUE;
|
$library_saved = TRUE;
|
||||||
}
|
}
|
||||||
|
@ -1120,7 +1306,7 @@ class H5PStorage {
|
||||||
|
|
||||||
// Find out which libraries are used by this package/content
|
// Find out which libraries are used by this package/content
|
||||||
$librariesInUse = array();
|
$librariesInUse = array();
|
||||||
$this->h5pC->findLibraryDependencies($librariesInUse, $this->h5pC->mainJsonData);
|
$nextWeight = $this->h5pC->findLibraryDependencies($librariesInUse, $this->h5pC->mainJsonData);
|
||||||
|
|
||||||
// Save content
|
// Save content
|
||||||
if ($content === NULL) {
|
if ($content === NULL) {
|
||||||
|
@ -1141,7 +1327,8 @@ class H5PStorage {
|
||||||
|
|
||||||
// Move the content folder
|
// Move the content folder
|
||||||
$destination_path = $contents_path . DIRECTORY_SEPARATOR . $contentId;
|
$destination_path = $contents_path . DIRECTORY_SEPARATOR . $contentId;
|
||||||
@rename($current_path, $destination_path);
|
$this->h5pC->copyFileTree($current_path, $destination_path);
|
||||||
|
H5PCore::deleteFileTree($current_path);
|
||||||
|
|
||||||
// Save the content library dependencies
|
// Save the content library dependencies
|
||||||
$this->h5pF->saveLibraryUsage($contentId, $librariesInUse);
|
$this->h5pF->saveLibraryUsage($contentId, $librariesInUse);
|
||||||
|
@ -1259,7 +1446,7 @@ Class H5PExport {
|
||||||
'title' => $content['title'],
|
'title' => $content['title'],
|
||||||
// TODO - stop using 'und', this is not the preferred way.
|
// TODO - stop using 'und', this is not the preferred way.
|
||||||
// Either remove language from the json if not existing, or use "language": null
|
// Either remove language from the json if not existing, or use "language": null
|
||||||
'language' => isset($content['language']) ? $content['language'] : 'und',
|
'language' => (isset($content['language']) && strlen(trim($content['language'])) !== 0) ? $content['language'] : 'und',
|
||||||
'mainLibrary' => $content['library']['name'],
|
'mainLibrary' => $content['library']['name'],
|
||||||
'embedTypes' => $embedTypes,
|
'embedTypes' => $embedTypes,
|
||||||
);
|
);
|
||||||
|
@ -1291,7 +1478,7 @@ Class H5PExport {
|
||||||
|
|
||||||
// Create new zip instance.
|
// Create new zip instance.
|
||||||
$zip = new ZipArchive();
|
$zip = new ZipArchive();
|
||||||
$zip->open($zipPath, ZIPARCHIVE::CREATE);
|
$zip->open($zipPath, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE);
|
||||||
|
|
||||||
// Get all files and folders in $tempPath
|
// Get all files and folders in $tempPath
|
||||||
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($tempPath . DIRECTORY_SEPARATOR));
|
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($tempPath . DIRECTORY_SEPARATOR));
|
||||||
|
@ -1370,6 +1557,8 @@ class H5PCore {
|
||||||
public static $defaultLibraryWhitelistExtras = 'js css';
|
public static $defaultLibraryWhitelistExtras = 'js css';
|
||||||
|
|
||||||
public $librariesJsonData, $contentJsonData, $mainJsonData, $h5pF, $path, $development_mode, $h5pD, $disableFileCheck;
|
public $librariesJsonData, $contentJsonData, $mainJsonData, $h5pF, $path, $development_mode, $h5pD, $disableFileCheck;
|
||||||
|
const SECONDS_IN_WEEK = 604800;
|
||||||
|
|
||||||
private $exportEnabled;
|
private $exportEnabled;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1472,6 +1661,9 @@ class H5PCore {
|
||||||
|
|
||||||
// Update content dependencies.
|
// Update content dependencies.
|
||||||
$content['dependencies'] = $validator->getDependencies();
|
$content['dependencies'] = $validator->getDependencies();
|
||||||
|
|
||||||
|
// Sometimes the parameters are filtered before content has been created
|
||||||
|
if ($content['id']) {
|
||||||
$this->h5pF->deleteLibraryUsage($content['id']);
|
$this->h5pF->deleteLibraryUsage($content['id']);
|
||||||
$this->h5pF->saveLibraryUsage($content['id'], $content['dependencies']);
|
$this->h5pF->saveLibraryUsage($content['id'], $content['dependencies']);
|
||||||
|
|
||||||
|
@ -1485,6 +1677,7 @@ class H5PCore {
|
||||||
|
|
||||||
// Cache.
|
// Cache.
|
||||||
$this->h5pF->setFilteredParameters($content['id'], $params);
|
$this->h5pF->setFilteredParameters($content['id'], $params);
|
||||||
|
}
|
||||||
return $params;
|
return $params;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1645,9 +1838,12 @@ class H5PCore {
|
||||||
*
|
*
|
||||||
* @param array $librariesUsed Flat list of all dependencies.
|
* @param array $librariesUsed Flat list of all dependencies.
|
||||||
* @param array $library To find all dependencies for.
|
* @param array $library To find all dependencies for.
|
||||||
* @param bool $editor Used interally to force all preloaded sub dependencies of an editor dependecy to be editor dependencies.
|
* @param int $nextWeight An integer determining the order of the libraries
|
||||||
|
* when they are loaded
|
||||||
|
* @param bool $editor Used interally to force all preloaded sub dependencies
|
||||||
|
* of an editor dependecy to be editor dependencies.
|
||||||
*/
|
*/
|
||||||
public function findLibraryDependencies(&$dependencies, $library, $editor = FALSE) {
|
public function findLibraryDependencies(&$dependencies, $library, $nextWeight = 1, $editor = FALSE) {
|
||||||
foreach (array('dynamic', 'preloaded', 'editor') as $type) {
|
foreach (array('dynamic', 'preloaded', 'editor') as $type) {
|
||||||
$property = $type . 'Dependencies';
|
$property = $type . 'Dependencies';
|
||||||
if (!isset($library[$property])) {
|
if (!isset($library[$property])) {
|
||||||
|
@ -1671,7 +1867,8 @@ class H5PCore {
|
||||||
'library' => $dependencyLibrary,
|
'library' => $dependencyLibrary,
|
||||||
'type' => $type
|
'type' => $type
|
||||||
);
|
);
|
||||||
$this->findLibraryDependencies($dependencies, $dependencyLibrary, $type === 'editor');
|
$nextWeight = $this->findLibraryDependencies($dependencies, $dependencyLibrary, $nextWeight, $type === 'editor');
|
||||||
|
$dependencies[$dependencyKey]['weight'] = $nextWeight++;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// This site is missing a dependency!
|
// This site is missing a dependency!
|
||||||
|
@ -1679,6 +1876,7 @@ class H5PCore {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return $nextWeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1996,6 +2194,31 @@ class H5PCore {
|
||||||
$html .= '</ul><span><br>These libraries may cause problems on this site. See <a href="http://h5p.org/releases/h5p-core-1.3">here</a> for more info</div>';
|
$html .= '</ul><span><br>These libraries may cause problems on this site. See <a href="http://h5p.org/releases/h5p-core-1.3">here</a> for more info</div>';
|
||||||
return $html;
|
return $html;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch a list of libraries' metadata from h5p.org.
|
||||||
|
* Save URL tutorial to database. Each platform implementation
|
||||||
|
* is responsible for invoking this, eg using cron
|
||||||
|
*/
|
||||||
|
public function fetchLibrariesMetadata($fetchingDisabled = FALSE) {
|
||||||
|
$platformInfo = $this->h5pF->getPlatformInfo();
|
||||||
|
$platformInfo['autoFetchingDisabled'] = $fetchingDisabled;
|
||||||
|
$platformInfo['uuid'] = $this->h5pF->getOption('h5p_site_uuid', '');
|
||||||
|
// Adding random string to GET to be sure nothing is cached
|
||||||
|
$random = substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, 5);
|
||||||
|
$json = $this->h5pF->fetchExternalData('http://h5p.org/libraries-metadata.json?api=1&platform=' . urlencode(json_encode($platformInfo)) . '&x=' . urlencode($random));
|
||||||
|
if ($json !== NULL) {
|
||||||
|
$json = json_decode($json);
|
||||||
|
if (isset($json->libraries)) {
|
||||||
|
foreach ($json->libraries as $machineName => $libInfo) {
|
||||||
|
$this->h5pF->setLibraryTutorialUrl($machineName, $libInfo->tutorialUrl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if($platformInfo['uuid'] === '' && isset($json->uuid)) {
|
||||||
|
$this->h5pF->setOption('h5p_site_uuid', $json->uuid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2004,8 +2227,7 @@ class H5PCore {
|
||||||
class H5PContentValidator {
|
class H5PContentValidator {
|
||||||
public $h5pF;
|
public $h5pF;
|
||||||
public $h5pC;
|
public $h5pC;
|
||||||
private $typeMap;
|
private $typeMap, $libraries, $dependencies, $nextWeight;
|
||||||
private $libraries, $dependencies;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor for the H5PContentValidator
|
* Constructor for the H5PContentValidator
|
||||||
|
@ -2031,6 +2253,7 @@ class H5PContentValidator {
|
||||||
'select' => 'validateSelect',
|
'select' => 'validateSelect',
|
||||||
'library' => 'validateLibrary',
|
'library' => 'validateLibrary',
|
||||||
);
|
);
|
||||||
|
$this->nextWeight = 1;
|
||||||
|
|
||||||
// Keep track of the libraries we load to avoid loading it multiple times.
|
// Keep track of the libraries we load to avoid loading it multiple times.
|
||||||
$this->libraries = array();
|
$this->libraries = array();
|
||||||
|
@ -2418,7 +2641,8 @@ class H5PContentValidator {
|
||||||
'type' => 'preloaded'
|
'type' => 'preloaded'
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->h5pC->findLibraryDependencies($this->dependencies, $library);
|
$this->nextWeight = $this->h5pC->findLibraryDependencies($this->dependencies, $library, $this->nextWeight);
|
||||||
|
$this->dependencies[$depkey]['weight'] = $this->nextWeight++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -37,6 +37,7 @@ var H5PLibraryList= H5PLibraryList || {};
|
||||||
$.each (libraries.listData, function (index, library) {
|
$.each (libraries.listData, function (index, library) {
|
||||||
var $libraryRow = H5PUtils.createTableRow([
|
var $libraryRow = H5PUtils.createTableRow([
|
||||||
library.title,
|
library.title,
|
||||||
|
'<input class="h5p-admin-restricted" type="checkbox"/>',
|
||||||
{
|
{
|
||||||
text: library.numContent,
|
text: library.numContent,
|
||||||
class: 'h5p-admin-center'
|
class: 'h5p-admin-center'
|
||||||
|
@ -56,6 +57,8 @@ var H5PLibraryList= H5PLibraryList || {};
|
||||||
</div>'
|
</div>'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
H5PLibraryList.addRestricted($('.h5p-admin-restricted', $libraryRow), library.restrictedUrl, library.restricted);
|
||||||
|
|
||||||
var hasContent = !(library.numContent === '' || library.numContent === 0);
|
var hasContent = !(library.numContent === '' || library.numContent === 0);
|
||||||
if (library.upgradeUrl === null) {
|
if (library.upgradeUrl === null) {
|
||||||
$('.h5p-admin-upgrade-library', $libraryRow).remove();
|
$('.h5p-admin-upgrade-library', $libraryRow).remove();
|
||||||
|
@ -92,6 +95,34 @@ var H5PLibraryList= H5PLibraryList || {};
|
||||||
return $table;
|
return $table;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
H5PLibraryList.addRestricted = function ($checkbox, url, selected) {
|
||||||
|
if (selected === null) {
|
||||||
|
$checkbox.remove();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$checkbox.change(function () {
|
||||||
|
$checkbox.attr('disabled', true);
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
dataType: 'json',
|
||||||
|
url: url,
|
||||||
|
cache: false
|
||||||
|
}).fail(function () {
|
||||||
|
$checkbox.attr('disabled', false);
|
||||||
|
|
||||||
|
// Reset
|
||||||
|
$checkbox.attr('checked', !$checkbox.is(':checked'));
|
||||||
|
}).done(function (result) {
|
||||||
|
url = result.url;
|
||||||
|
$checkbox.attr('disabled', false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
if (selected) {
|
||||||
|
$checkbox.attr('checked', true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Initialize me:
|
// Initialize me:
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
|
|
64
js/h5p.js
64
js/h5p.js
|
@ -104,7 +104,7 @@ H5P.init = function () {
|
||||||
if (!(contentData.disable & H5P.DISABLE_COPYRIGHT) && instance.getCopyrights !== undefined) {
|
if (!(contentData.disable & H5P.DISABLE_COPYRIGHT) && instance.getCopyrights !== undefined) {
|
||||||
// Add copyrights button
|
// Add copyrights button
|
||||||
H5P.jQuery('<li class="h5p-button h5p-copyrights" role="button" tabindex="1" title="' + H5P.t('copyrightsDescription') + '">' + H5P.t('copyrights') + '</li>').appendTo($actions).click(function () {
|
H5P.jQuery('<li class="h5p-button h5p-copyrights" role="button" tabindex="1" title="' + H5P.t('copyrightsDescription') + '">' + H5P.t('copyrights') + '</li>').appendTo($actions).click(function () {
|
||||||
H5P.openCopyrightsDialog($actions, instance);
|
H5P.openCopyrightsDialog($actions, instance, library.params, contentId);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (!(contentData.disable & H5P.DISABLE_EMBED)) {
|
if (!(contentData.disable & H5P.DISABLE_EMBED)) {
|
||||||
|
@ -529,19 +529,77 @@ H5P.Dialog = function (name, title, content, $element) {
|
||||||
* @param {object} instance to get copyright information from.
|
* @param {object} instance to get copyright information from.
|
||||||
* @returns {undefined}
|
* @returns {undefined}
|
||||||
*/
|
*/
|
||||||
H5P.openCopyrightsDialog = function ($element, instance) {
|
H5P.openCopyrightsDialog = function ($element, instance, parameters, contentId) {
|
||||||
var copyrights = instance.getCopyrights();
|
var copyrights;
|
||||||
|
if (instance.getCopyrights !== undefined) {
|
||||||
|
// Use the instance's own copyright generator
|
||||||
|
copyrights = instance.getCopyrights();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Create a generic flat copyright list
|
||||||
|
copyrights = new H5P.ContentCopyrights();
|
||||||
|
H5P.findCopyrights(copyrights, parameters, contentId);
|
||||||
|
}
|
||||||
|
|
||||||
if (copyrights !== undefined) {
|
if (copyrights !== undefined) {
|
||||||
|
// Convert to string
|
||||||
copyrights = copyrights.toString();
|
copyrights = copyrights.toString();
|
||||||
}
|
}
|
||||||
if (copyrights === undefined || copyrights === '') {
|
if (copyrights === undefined || copyrights === '') {
|
||||||
|
// Use no copyrights default text
|
||||||
copyrights = H5P.t('noCopyrights');
|
copyrights = H5P.t('noCopyrights');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Open dialog with copyright information
|
||||||
var dialog = new H5P.Dialog('copyrights', H5P.t('copyrightInformation'), copyrights, $element);
|
var dialog = new H5P.Dialog('copyrights', H5P.t('copyrightInformation'), copyrights, $element);
|
||||||
dialog.open();
|
dialog.open();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gather a flat list of copyright information from the given parameters.
|
||||||
|
*
|
||||||
|
* @param {H5P.ContentCopyrights} info Used to collect all information in.
|
||||||
|
* @param {(Object|Arrray)} parameters To search for file objects in.
|
||||||
|
* @param {Number} contentId Used to insert thumbnails for images.
|
||||||
|
* @returns {undefined}
|
||||||
|
*/
|
||||||
|
H5P.findCopyrights = function (info, parameters, contentId) {
|
||||||
|
// Cycle through parameters
|
||||||
|
for (var field in parameters) {
|
||||||
|
if (!parameters.hasOwnProperty(field)) {
|
||||||
|
continue; // Do not check
|
||||||
|
}
|
||||||
|
var value = parameters[field];
|
||||||
|
|
||||||
|
if (value instanceof Array) {
|
||||||
|
// Cycle through array
|
||||||
|
H5P.findCopyrights(info, value, contentId);
|
||||||
|
}
|
||||||
|
else if (value instanceof Object) {
|
||||||
|
// Check if object is a file with copyrights
|
||||||
|
if (value.copyright === undefined ||
|
||||||
|
value.copyright.license === undefined ||
|
||||||
|
value.path === undefined ||
|
||||||
|
value.mime === undefined) {
|
||||||
|
|
||||||
|
// Nope, cycle throught object
|
||||||
|
H5P.findCopyrights(info, value, contentId);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Found file, add copyrights
|
||||||
|
var copyrights = new H5P.MediaCopyright(value.copyright);
|
||||||
|
if (value.width !== undefined && value.height !== undefined) {
|
||||||
|
copyrights.setThumbnail(new H5P.Thumbnail(H5P.getPath(value.path, contentId), value.width, value.height));
|
||||||
|
}
|
||||||
|
info.addMedia(copyrights);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display a dialog containing the embed code.
|
* Display a dialog containing the embed code.
|
||||||
*
|
*
|
||||||
|
|
|
@ -237,6 +237,8 @@ div.h5p-fullscreen {
|
||||||
font-size: 1.5em;
|
font-size: 1.5em;
|
||||||
margin: 0.25em 0;
|
margin: 0.25em 0;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
line-height: 1.25em;
|
||||||
|
padding: 0;
|
||||||
}
|
}
|
||||||
.h5p-embed-dialog .h5p-inner {
|
.h5p-embed-dialog .h5p-inner {
|
||||||
width: 50%;
|
width: 50%;
|
||||||
|
|
Loading…
Reference in New Issue