Skip to content
2 changes: 1 addition & 1 deletion ipywidgets/_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
__protocol_version__ = '2.0.0'
__jupyter_widgets_base_version__ = '1.0.0'
__jupyter_widgets_output_version__ = '1.0.0'
__jupyter_widgets_controls_version__ = '1.1.0'
__jupyter_widgets_controls_version__ = '1.2.0'

# A compatible @jupyter-widgets/html-manager npm package semver range
__html_manager_version__ = '^0.11.0'
2 changes: 1 addition & 1 deletion packages/controls/src/version.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@
* implements.
*/
export
const JUPYTER_CONTROLS_VERSION = '1.1.0';
const JUPYTER_CONTROLS_VERSION = '1.2.0';
15 changes: 15 additions & 0 deletions packages/jupyterlab-manager/src/manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ import {
DocumentRegistry
} from '@jupyterlab/docregistry';

import {
valid
} from 'semver';

import {
SemVerCache
} from './semvercache';
Expand Down Expand Up @@ -167,6 +171,17 @@ class WidgetManager extends ManagerBase<Widget> implements IDisposable {
* Load a class and return a promise to the loaded object.
*/
protected loadClass(className: string, moduleName: string, moduleVersion: string): Promise<typeof WidgetModel | typeof WidgetView> {

// Special-case the Jupyter base and controls packages. If we have just a
// plain version, with no indication of the compatible range, prepend a ^ to
// get all compatible versions. We may eventually apply this logic to all
// widget modules. See issues #2006 and #2017 for more discussion.
if ((moduleName === "@jupyter-widgets/base"
|| moduleName === "@jupyter-widgets/controls")
&& valid(moduleVersion)) {
moduleVersion = `^${moduleVersion}`;
}

let mod = this._registry.get(moduleName, moduleVersion);
if (!mod) {
return Promise.reject(`Module ${moduleName}, semver range ${moduleVersion} is not registered as a widget module`);
Expand Down
21 changes: 1 addition & 20 deletions packages/jupyterlab-manager/src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,29 +109,10 @@ function activateWidgetExtension(app: JupyterLab): base.IJupyterWidgetRegistry {
StyleView: base.StyleView
}
});
extension.registerWidget({
name: '@jupyter-widgets/controls',
version: JUPYTER_CONTROLS_VERSION,
exports: () => {
return new Promise((resolve, reject) => {
(require as any).ensure(['@jupyter-widgets/controls'], (require: NodeRequire) => {
resolve(require('@jupyter-widgets/controls'));
},
(err: any) => {
reject(err);
},
'@jupyter-widgets/controls'
);
});
}
});

// Until we do automatic semver matching (for example, converting a request
// for 1.0.0 to ^1.0.0), we register the controls under both the current
// version (above) and older versions it can handle.
extension.registerWidget({
name: '@jupyter-widgets/controls',
version: '1.0.0',
version: JUPYTER_CONTROLS_VERSION,
exports: () => {
return new Promise((resolve, reject) => {
(require as any).ensure(['@jupyter-widgets/controls'], (require: NodeRequire) => {
Expand Down
4 changes: 3 additions & 1 deletion packages/jupyterlab-manager/src/semvercache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ class SemVerCache<T> {
}
if (!(version in this._cache[key])) {
this._cache[key][version] = object;
} else {
throw `Version ${version} of key ${key} already registered.`;
}
}

Expand All @@ -29,4 +31,4 @@ class SemVerCache<T> {
}

private _cache: { [key: string]: {[version: string]: T} } = Object.create(null);
}
}
Loading