Skip to content

Commit

Permalink
Add Required Permission to CodeQL Workflow (jupyterlab#10138)
Browse files Browse the repository at this point in the history
  • Loading branch information
afshin authored and cameron-toy committed May 28, 2021
1 parent 8dd05b8 commit 834ac93
Show file tree
Hide file tree
Showing 23 changed files with 243 additions and 27 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ on:
schedule:
- cron: '0 8 * * 3'

permissions:
security-events:
write

jobs:
analyze:
name: Analyze
Expand Down
1 change: 1 addition & 0 deletions packages/application/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"@fortawesome/fontawesome-free": "^5.12.0",
"@jupyterlab/apputils": "^3.1.0-alpha.5",
"@jupyterlab/coreutils": "^5.1.0-alpha.5",
"@jupyterlab/docmanager": "^3.1.0-alpha.5",
"@jupyterlab/docregistry": "^3.1.0-alpha.5",
"@jupyterlab/rendermime": "^3.1.0-alpha.5",
"@jupyterlab/rendermime-interfaces": "^3.1.0-alpha.5",
Expand Down
159 changes: 147 additions & 12 deletions packages/application/src/shell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ import {

import { JupyterFrontEnd } from './frontend';

import { isValidFileName } from '@jupyterlab/docmanager';

/**
* The class name added to AppShell instances.
*/
Expand Down Expand Up @@ -324,14 +326,14 @@ export class LabShell extends Widget implements JupyterFrontEnd.IShell {
);

// Setup single-document-mode title bar
const titleWidget = (this._titleWidget = new Widget());
titleWidget.id = 'jp-title-panel-title';
titleWidget.node.appendChild(document.createElement('h1'));
this.add(titleWidget, 'top', { rank: 100 });
const titleWidgetHandler = (this._titleWidgetHandler = new Private.TitleWidgetHandler(
this
));
this.add(titleWidgetHandler.titleWidget, 'top', { rank: 100 });

if (this._dockPanel.mode === 'multiple-document') {
this._topHandler.addWidget(this._menuHandler.panel, 100);
titleWidget.hide();
titleWidgetHandler.hide();
} else {
rootLayout.insertWidget(2, this._menuHandler.panel);
}
Expand Down Expand Up @@ -471,7 +473,7 @@ export class LabShell extends Widget implements JupyterFrontEnd.IShell {
// Adjust menu and title
// this.add(this._menuHandler.panel, 'top', {rank: 100});
(this.layout as BoxLayout).insertWidget(2, this._menuHandler.panel);
this._titleWidget.show();
this._titleWidgetHandler.show();
this._updateTitlePanelTitle();

this._modeChanged.emit(mode);
Expand Down Expand Up @@ -519,7 +521,7 @@ export class LabShell extends Widget implements JupyterFrontEnd.IShell {
// Adjust menu and title
this.add(this._menuHandler.panel, 'top', { rank: 100 });
// this._topHandler.addWidget(this._menuHandler.panel, 100)
this._titleWidget.hide();
this._titleWidgetHandler.hide();

// Emit the mode changed signal
this._modeChanged.emit(mode);
Expand Down Expand Up @@ -695,7 +697,7 @@ export class LabShell extends Widget implements JupyterFrontEnd.IShell {
return;
}
this._layoutDebouncer.dispose();
this._titleWidget.dispose();
this._titleWidgetHandler.dispose();
super.dispose();
}

Expand Down Expand Up @@ -865,9 +867,10 @@ export class LabShell extends Widget implements JupyterFrontEnd.IShell {
*/
private _updateTitlePanelTitle() {
let current = this.currentWidget;
const h1 = this._titleWidget.node.children[0] as HTMLHeadElement;
h1.textContent = current ? current.title.label : '';
h1.title = current ? current.title.caption : '';
const inputElement = this._titleWidgetHandler.titleWidget.node
.children[0] as HTMLInputElement;
inputElement.value = current ? current.title.label : '';
inputElement.title = current ? current.title.caption : '';
}

/**
Expand Down Expand Up @@ -1210,7 +1213,7 @@ export class LabShell extends Widget implements JupyterFrontEnd.IShell {
private _headerPanel: Panel;
private _topHandler: Private.PanelHandler;
private _menuHandler: Private.PanelHandler;
private _titleWidget: Widget;
private _titleWidgetHandler: Private.TitleWidgetHandler;
private _bottomPanel: Panel;
private _mainOptionsCache = new Map<Widget, DocumentRegistry.IOpenOptions>();
private _sideOptionsCache = new Map<Widget, DocumentRegistry.IOpenOptions>();
Expand Down Expand Up @@ -1547,4 +1550,136 @@ namespace Private {
private _stackedPanel: StackedPanel;
private _lastCurrent: Widget | null;
}

export class TitleWidgetHandler {
/**
* Construct a new title widget handler.
*/
constructor(shell: ILabShell) {
this._shell = shell;
const titleWidget = (this._titleWidget = new Widget());
titleWidget.id = 'jp-title-panel-title';
const titleInput = document.createElement('input');
titleInput.type = 'text';
titleInput.addEventListener('keyup', this);
titleInput.addEventListener('click', this);
titleInput.addEventListener('blur', this);

titleWidget.node.appendChild(titleInput);
}

handleEvent(event: Event): void {
switch (event.type) {
case 'keyup':
void this._evtKeyUp(event as KeyboardEvent);
break;
case 'click':
this._evtClick(event as MouseEvent);
break;
case 'blur':
this._selected = false;
break;
}
}

/**
* Handle `keyup` events on the handler.
*/
private async _evtKeyUp(event: KeyboardEvent): Promise<void> {
if (event.key == 'Enter') {
const widget = this._shell.currentWidget;
if (widget instanceof DocumentWidget) {
const oldName = widget.context.path.split('/').pop()!;
const inputElement = this.titleWidget.node
.children[0] as HTMLInputElement;
const newName = inputElement.value;
inputElement.blur();
if (newName !== oldName && isValidFileName(newName)) {
await widget.context.rename(newName);
} else {
inputElement.value = oldName;
}
}
}
}

/**
* Handle `click` events on the handler.
*/
private _evtClick(event: MouseEvent): void {
// only handle primary button clicks
if (event.button !== 0 || this._selected) {
return;
}

const currentWidget = this._shell.currentWidget;
const inputElement = this.titleWidget.node
.children[0] as HTMLInputElement;
if (currentWidget == null || !(currentWidget instanceof DocumentWidget)) {
inputElement.readOnly = true;
return;
} else {
inputElement.removeAttribute('readOnly');
}

event.preventDefault();
event.stopPropagation();

this._selected = true;

const selectEnd = inputElement.value.indexOf('.');
if (selectEnd === -1) {
inputElement.select();
} else {
inputElement.setSelectionRange(0, selectEnd);
}
}

/**
* Get the input element managed by the handler.
*/
get titleWidget(): Widget {
return this._titleWidget;
}

/**
* Dispose of the handler and the resources it holds.
*/
dispose(): void {
if (this.isDisposed) {
return;
}
this._isDisposed = true;
this._titleWidget.node.removeEventListener('keyup', this);
this._titleWidget.node.removeEventListener('click', this);
this._titleWidget.node.removeEventListener('blur', this);
this._titleWidget.dispose();
}

/**
* Hide the title widget.
*/
hide(): void {
this._titleWidget.hide();
}

/**
* Show the title widget.
*/
show(): void {
this._titleWidget.show();
}

/**
* Test whether the handler has been disposed.
*/
get isDisposed(): boolean {
return this._isDisposed;
}

private _titleWidget: Widget;
private _shell: ILabShell;
private _isDisposed: boolean = false;
private _selected: boolean = false;
}
}
1 change: 1 addition & 0 deletions packages/application/style/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@
@import url('~@jupyterlab/ui-components/style/index.css');
@import url('~@jupyterlab/apputils/style/index.css');
@import url('~@jupyterlab/docregistry/style/index.css');
@import url('~@jupyterlab/docmanager/style/index.css');

@import url('./base.css');
1 change: 1 addition & 0 deletions packages/application/style/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ import '@lumino/widgets/style/index.js';
import '@jupyterlab/ui-components/style/index.js';
import '@jupyterlab/apputils/style/index.js';
import '@jupyterlab/docregistry/style/index.js';
import '@jupyterlab/docmanager/style/index.js';

import './base.css';
14 changes: 11 additions & 3 deletions packages/application/style/titlepanel.css
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,19 @@
margin-left: 8px;
}

#jp-title-panel-title h1 {
font-size: 18px;
color: var(--jp-ui-font-color0);
#jp-title-panel-title input {
background: transparent;
margin: 0;
height: 28px;
box-sizing: border-box;
border: none;
font-size: 18px;
font-weight: normal;
font-family: var(--jp-ui-font-family);
line-height: var(--jp-private-title-panel-height);
color: var(--jp-ui-font-color0);
outline: none;
appearance: none;
-webkit-appearance: none;
-moz-appearance: none;
}
2 changes: 1 addition & 1 deletion packages/application/test/shell.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ describe('LabShell', () => {

beforeAll(() => {
console.debug(
'Expecting 5 console errors logged in this suite: "Widgets added to app shell must have unique id property."'
'Expecting 6 console errors logged in this suite: "Widgets added to app shell must have unique id property."'
);
});

Expand Down
3 changes: 3 additions & 0 deletions packages/application/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
{
"path": "../coreutils"
},
{
"path": "../docmanager"
},
{
"path": "../docregistry"
},
Expand Down
6 changes: 6 additions & 0 deletions packages/application/tsconfig.test.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
{
"path": "../coreutils"
},
{
"path": "../docmanager"
},
{
"path": "../docregistry"
},
Expand Down Expand Up @@ -41,6 +44,9 @@
{
"path": "../coreutils"
},
{
"path": "../docmanager"
},
{
"path": "../docregistry"
},
Expand Down
2 changes: 1 addition & 1 deletion packages/docmanager-extension/style/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@
@import url('~@jupyterlab/apputils/style/index.css');
@import url('~@jupyterlab/statusbar/style/index.css');
@import url('~@jupyterlab/docregistry/style/index.css');
@import url('~@jupyterlab/application/style/index.css');
@import url('~@jupyterlab/docmanager/style/index.css');
@import url('~@jupyterlab/application/style/index.css');
@import url('~@jupyterlab/mainmenu/style/index.css');
2 changes: 1 addition & 1 deletion packages/docmanager-extension/style/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ import '@lumino/widgets/style/index.js';
import '@jupyterlab/apputils/style/index.js';
import '@jupyterlab/statusbar/style/index.js';
import '@jupyterlab/docregistry/style/index.js';
import '@jupyterlab/application/style/index.js';
import '@jupyterlab/docmanager/style/index.js';
import '@jupyterlab/application/style/index.js';
import '@jupyterlab/mainmenu/style/index.js';
30 changes: 30 additions & 0 deletions packages/docregistry/src/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,19 @@ export class Context<
}
}

/**
* Rename the document.
*
* @param newName - the new name for the document.
*/
rename(newName: string): Promise<void> {
return this.ready.then(() => {
return this._manager.ready.then(() => {
return this._rename(newName);
});
});
}

/**
* Save the document contents to disk.
*/
Expand Down Expand Up @@ -499,6 +512,23 @@ export class Context<
});
}

/**
* Rename the document.
*
* @param newName - the new name for the document.
*/
private async _rename(newName: string): Promise<void> {
const splitPath = this.path.split('/');
splitPath[splitPath.length - 1] = newName;
const newPath = splitPath.join('/');

await this._manager.contents.rename(this.path, newPath);
await this.sessionContext.session?.setPath(newPath);
await this.sessionContext.session?.setName(newName);

this._pathChanged.emit(this._path);
}

/**
* Save the document contents to disk.
*/
Expand Down
5 changes: 5 additions & 0 deletions packages/docregistry/src/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -901,6 +901,11 @@ export namespace DocumentRegistry {
*/
readonly ready: Promise<void>;

/**
* Rename the document.
*/
rename(newName: string): Promise<void>;

/**
* Save the document contents to disk.
*/
Expand Down
Loading

0 comments on commit 834ac93

Please sign in to comment.