mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2024-11-25 19:26:31 -05:00
Merge pull request #825 from SISheogorath/remove/GoogleDrive
Removing google drive integration
This commit is contained in:
commit
42b0965550
11 changed files with 3 additions and 516 deletions
|
@ -272,7 +272,7 @@ There are some config settings you need to change in the files below.
|
|||
| ------- | --------- | ----------- |
|
||||
| facebook, twitter, github, gitlab, mattermost, dropbox, google, ldap, saml | environment variables or `config.json` | for signin |
|
||||
| imgur, s3, minio | environment variables or `config.json` | for image upload |
|
||||
| google drive(`google/apiKey`, `google/clientID`), dropbox(`dropbox/appKey`) | `config.json` | for export and import |
|
||||
| dropbox(`dropbox/appKey`) | `config.json` | for export and import |
|
||||
|
||||
## Third-party integration OAuth callback URLs
|
||||
|
||||
|
|
2
app.js
2
app.js
|
@ -33,8 +33,6 @@ var data = {
|
|||
urlpath: config.urlPath,
|
||||
debug: config.debug,
|
||||
version: config.version,
|
||||
GOOGLE_API_KEY: config.google.clientSecret,
|
||||
GOOGLE_CLIENT_ID: config.google.clientID,
|
||||
DROPBOX_APP_KEY: config.dropbox.appKey,
|
||||
allowedUploadMimeTypes: config.allowedUploadMimeTypes
|
||||
}
|
||||
|
|
4
app.json
4
app.json
|
@ -136,10 +136,6 @@
|
|||
"description": "Google API client secret",
|
||||
"required": false
|
||||
},
|
||||
"HMD_GOOGLE_API_KEY": {
|
||||
"description": "Google API key (for import/export)",
|
||||
"required": false
|
||||
},
|
||||
"HMD_IMGUR_CLIENTID": {
|
||||
"description": "Imgur API client id",
|
||||
"required": false
|
||||
|
|
|
@ -1,118 +0,0 @@
|
|||
/** !
|
||||
* Google Drive File Picker Example
|
||||
* By Daniel Lo Nigro (http://dan.cx/)
|
||||
*/
|
||||
(function () {
|
||||
/**
|
||||
* Initialise a Google Driver file picker
|
||||
*/
|
||||
var FilePicker = window.FilePicker = function (options) {
|
||||
// Config
|
||||
this.apiKey = options.apiKey
|
||||
this.clientId = options.clientId
|
||||
|
||||
// Elements
|
||||
this.buttonEl = options.buttonEl
|
||||
|
||||
// Events
|
||||
this.onSelect = options.onSelect
|
||||
this.buttonEl.on('click', this.open.bind(this))
|
||||
|
||||
// Disable the button until the API loads, as it won't work properly until then.
|
||||
this.buttonEl.prop('disabled', true)
|
||||
|
||||
// Load the drive API
|
||||
window.gapi.client.setApiKey(this.apiKey)
|
||||
window.gapi.client.load('drive', 'v2', this._driveApiLoaded.bind(this))
|
||||
window.google.load('picker', '1', { callback: this._pickerApiLoaded.bind(this) })
|
||||
}
|
||||
|
||||
FilePicker.prototype = {
|
||||
/**
|
||||
* Open the file picker.
|
||||
*/
|
||||
open: function () {
|
||||
// Check if the user has already authenticated
|
||||
var token = window.gapi.auth.getToken()
|
||||
if (token) {
|
||||
this._showPicker()
|
||||
} else {
|
||||
// The user has not yet authenticated with Google
|
||||
// We need to do the authentication before displaying the Drive picker.
|
||||
this._doAuth(false, function () { this._showPicker() }.bind(this))
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Show the file picker once authentication has been done.
|
||||
* @private
|
||||
*/
|
||||
_showPicker: function () {
|
||||
var accessToken = window.gapi.auth.getToken().access_token
|
||||
var view = new window.google.picker.DocsView()
|
||||
view.setMimeTypes('text/markdown,text/html')
|
||||
view.setIncludeFolders(true)
|
||||
view.setOwnedByMe(true)
|
||||
this.picker = new window.google.picker.PickerBuilder()
|
||||
.enableFeature(window.google.picker.Feature.NAV_HIDDEN)
|
||||
.addView(view)
|
||||
.setAppId(this.clientId)
|
||||
.setOAuthToken(accessToken)
|
||||
.setCallback(this._pickerCallback.bind(this))
|
||||
.build()
|
||||
.setVisible(true)
|
||||
},
|
||||
|
||||
/**
|
||||
* Called when a file has been selected in the Google Drive file picker.
|
||||
* @private
|
||||
*/
|
||||
_pickerCallback: function (data) {
|
||||
if (data[window.google.picker.Response.ACTION] === window.google.picker.Action.PICKED) {
|
||||
var file = data[window.google.picker.Response.DOCUMENTS][0]
|
||||
var id = file[window.google.picker.Document.ID]
|
||||
var request = window.gapi.client.drive.files.get({
|
||||
fileId: id
|
||||
})
|
||||
request.execute(this._fileGetCallback.bind(this))
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Called when file details have been retrieved from Google Drive.
|
||||
* @private
|
||||
*/
|
||||
_fileGetCallback: function (file) {
|
||||
if (this.onSelect) {
|
||||
this.onSelect(file)
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Called when the Google Drive file picker API has finished loading.
|
||||
* @private
|
||||
*/
|
||||
_pickerApiLoaded: function () {
|
||||
this.buttonEl.prop('disabled', false)
|
||||
},
|
||||
|
||||
/**
|
||||
* Called when the Google Drive API has finished loading.
|
||||
* @private
|
||||
*/
|
||||
_driveApiLoaded: function () {
|
||||
this._doAuth(true)
|
||||
},
|
||||
|
||||
/**
|
||||
* Authenticate with Google Drive via the Google JavaScript API.
|
||||
* @private
|
||||
*/
|
||||
_doAuth: function (immediate, callback) {
|
||||
window.gapi.auth.authorize({
|
||||
client_id: this.clientId,
|
||||
scope: 'https://www.googleapis.com/auth/drive.readonly',
|
||||
immediate: immediate
|
||||
}, callback || function () {})
|
||||
}
|
||||
}
|
||||
}())
|
|
@ -1,267 +0,0 @@
|
|||
/* eslint-env browser, jquery */
|
||||
/**
|
||||
* Helper for implementing retries with backoff. Initial retry
|
||||
* delay is 1 second, increasing by 2x (+jitter) for subsequent retries
|
||||
*
|
||||
* @constructor
|
||||
*/
|
||||
var RetryHandler = function () {
|
||||
this.interval = 1000 // Start at one second
|
||||
this.maxInterval = 60 * 1000 // Don't wait longer than a minute
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke the function after waiting
|
||||
*
|
||||
* @param {function} fn Function to invoke
|
||||
*/
|
||||
RetryHandler.prototype.retry = function (fn) {
|
||||
setTimeout(fn, this.interval)
|
||||
this.interval = this.nextInterval_()
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the counter (e.g. after successful request.)
|
||||
*/
|
||||
RetryHandler.prototype.reset = function () {
|
||||
this.interval = 1000
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the next wait time.
|
||||
* @return {number} Next wait interval, in milliseconds
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
RetryHandler.prototype.nextInterval_ = function () {
|
||||
var interval = this.interval * 2 + this.getRandomInt_(0, 1000)
|
||||
return Math.min(interval, this.maxInterval)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random int in the range of min to max. Used to add jitter to wait times.
|
||||
*
|
||||
* @param {number} min Lower bounds
|
||||
* @param {number} max Upper bounds
|
||||
* @private
|
||||
*/
|
||||
RetryHandler.prototype.getRandomInt_ = function (min, max) {
|
||||
return Math.floor(Math.random() * (max - min + 1) + min)
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper class for resumable uploads using XHR/CORS. Can upload any Blob-like item, whether
|
||||
* files or in-memory constructs.
|
||||
*
|
||||
* @example
|
||||
* var content = new Blob(["Hello world"], {"type": "text/plain"});
|
||||
* var uploader = new MediaUploader({
|
||||
* file: content,
|
||||
* token: accessToken,
|
||||
* onComplete: function(data) { ... }
|
||||
* onError: function(data) { ... }
|
||||
* });
|
||||
* uploader.upload();
|
||||
*
|
||||
* @constructor
|
||||
* @param {object} options Hash of options
|
||||
* @param {string} options.token Access token
|
||||
* @param {blob} options.file Blob-like item to upload
|
||||
* @param {string} [options.fileId] ID of file if replacing
|
||||
* @param {object} [options.params] Additional query parameters
|
||||
* @param {string} [options.contentType] Content-type, if overriding the type of the blob.
|
||||
* @param {object} [options.metadata] File metadata
|
||||
* @param {function} [options.onComplete] Callback for when upload is complete
|
||||
* @param {function} [options.onProgress] Callback for status for the in-progress upload
|
||||
* @param {function} [options.onError] Callback if upload fails
|
||||
*/
|
||||
var MediaUploader = function (options) {
|
||||
var noop = function () {}
|
||||
this.file = options.file
|
||||
this.contentType = options.contentType || this.file.type || 'application/octet-stream'
|
||||
this.metadata = options.metadata || {
|
||||
'title': this.file.name,
|
||||
'mimeType': this.contentType
|
||||
}
|
||||
this.token = options.token
|
||||
this.onComplete = options.onComplete || noop
|
||||
this.onProgress = options.onProgress || noop
|
||||
this.onError = options.onError || noop
|
||||
this.offset = options.offset || 0
|
||||
this.chunkSize = options.chunkSize || 0
|
||||
this.retryHandler = new RetryHandler()
|
||||
|
||||
this.url = options.url
|
||||
if (!this.url) {
|
||||
var params = options.params || {}
|
||||
params.uploadType = 'resumable'
|
||||
this.url = this.buildUrl_(options.fileId, params, options.baseUrl)
|
||||
}
|
||||
this.httpMethod = options.fileId ? 'PUT' : 'POST'
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiate the upload.
|
||||
*/
|
||||
MediaUploader.prototype.upload = function () {
|
||||
var xhr = new XMLHttpRequest()
|
||||
|
||||
xhr.open(this.httpMethod, this.url, true)
|
||||
xhr.setRequestHeader('Authorization', 'Bearer ' + this.token)
|
||||
xhr.setRequestHeader('Content-Type', 'application/json')
|
||||
xhr.setRequestHeader('X-Upload-Content-Length', this.file.size)
|
||||
xhr.setRequestHeader('X-Upload-Content-Type', this.contentType)
|
||||
|
||||
xhr.onload = function (e) {
|
||||
if (e.target.status < 400) {
|
||||
var location = e.target.getResponseHeader('Location')
|
||||
this.url = location
|
||||
this.sendFile_()
|
||||
} else {
|
||||
this.onUploadError_(e)
|
||||
}
|
||||
}.bind(this)
|
||||
xhr.onerror = this.onUploadError_.bind(this)
|
||||
xhr.send(JSON.stringify(this.metadata))
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the actual file content.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
MediaUploader.prototype.sendFile_ = function () {
|
||||
var content = this.file
|
||||
var end = this.file.size
|
||||
|
||||
if (this.offset || this.chunkSize) {
|
||||
// Only bother to slice the file if we're either resuming or uploading in chunks
|
||||
if (this.chunkSize) {
|
||||
end = Math.min(this.offset + this.chunkSize, this.file.size)
|
||||
}
|
||||
content = content.slice(this.offset, end)
|
||||
}
|
||||
|
||||
var xhr = new XMLHttpRequest()
|
||||
xhr.open('PUT', this.url, true)
|
||||
xhr.setRequestHeader('Content-Type', this.contentType)
|
||||
xhr.setRequestHeader('Content-Range', 'bytes ' + this.offset + '-' + (end - 1) + '/' + this.file.size)
|
||||
xhr.setRequestHeader('X-Upload-Content-Type', this.file.type)
|
||||
if (xhr.upload) {
|
||||
xhr.upload.addEventListener('progress', this.onProgress)
|
||||
}
|
||||
xhr.onload = this.onContentUploadSuccess_.bind(this)
|
||||
xhr.onerror = this.onContentUploadError_.bind(this)
|
||||
xhr.send(content)
|
||||
}
|
||||
|
||||
/**
|
||||
* Query for the state of the file for resumption.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
MediaUploader.prototype.resume_ = function () {
|
||||
var xhr = new XMLHttpRequest()
|
||||
xhr.open('PUT', this.url, true)
|
||||
xhr.setRequestHeader('Content-Range', 'bytes */' + this.file.size)
|
||||
xhr.setRequestHeader('X-Upload-Content-Type', this.file.type)
|
||||
if (xhr.upload) {
|
||||
xhr.upload.addEventListener('progress', this.onProgress)
|
||||
}
|
||||
xhr.onload = this.onContentUploadSuccess_.bind(this)
|
||||
xhr.onerror = this.onContentUploadError_.bind(this)
|
||||
xhr.send()
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the last saved range if available in the request.
|
||||
*
|
||||
* @param {XMLHttpRequest} xhr Request object
|
||||
*/
|
||||
MediaUploader.prototype.extractRange_ = function (xhr) {
|
||||
var range = xhr.getResponseHeader('Range')
|
||||
if (range) {
|
||||
this.offset = parseInt(range.match(/\d+/g).pop(), 10) + 1
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle successful responses for uploads. Depending on the context,
|
||||
* may continue with uploading the next chunk of the file or, if complete,
|
||||
* invokes the caller's callback.
|
||||
*
|
||||
* @private
|
||||
* @param {object} e XHR event
|
||||
*/
|
||||
MediaUploader.prototype.onContentUploadSuccess_ = function (e) {
|
||||
if (e.target.status === 200 || e.target.status === 201) {
|
||||
this.onComplete(e.target.response)
|
||||
} else if (e.target.status === 308) {
|
||||
this.extractRange_(e.target)
|
||||
this.retryHandler.reset()
|
||||
this.sendFile_()
|
||||
} else {
|
||||
this.onContentUploadError_(e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles errors for uploads. Either retries or aborts depending
|
||||
* on the error.
|
||||
*
|
||||
* @private
|
||||
* @param {object} e XHR event
|
||||
*/
|
||||
MediaUploader.prototype.onContentUploadError_ = function (e) {
|
||||
if (e.target.status && e.target.status < 500) {
|
||||
this.onError(e.target.response)
|
||||
} else {
|
||||
this.retryHandler.retry(this.resume_.bind(this))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles errors for the initial request.
|
||||
*
|
||||
* @private
|
||||
* @param {object} e XHR event
|
||||
*/
|
||||
MediaUploader.prototype.onUploadError_ = function (e) {
|
||||
this.onError(e.target.response) // TODO - Retries for initial upload
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a query string from a hash/object
|
||||
*
|
||||
* @private
|
||||
* @param {object} [params] Key/value pairs for query string
|
||||
* @return {string} query string
|
||||
*/
|
||||
MediaUploader.prototype.buildQuery_ = function (params) {
|
||||
params = params || {}
|
||||
return Object.keys(params).map(function (key) {
|
||||
return encodeURIComponent(key) + '=' + encodeURIComponent(params[key])
|
||||
}).join('&')
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the drive upload URL
|
||||
*
|
||||
* @private
|
||||
* @param {string} [id] File ID if replacing
|
||||
* @param {object} [params] Query parameters
|
||||
* @return {string} URL
|
||||
*/
|
||||
MediaUploader.prototype.buildUrl_ = function (id, params, baseUrl) {
|
||||
var url = baseUrl || 'https://www.googleapis.com/upload/drive/v2/files/'
|
||||
if (id) {
|
||||
url += id
|
||||
}
|
||||
var query = this.buildQuery_(params)
|
||||
if (query) {
|
||||
url += '?' + query
|
||||
}
|
||||
return url
|
||||
}
|
||||
|
||||
window.MediaUploader = MediaUploader
|
|
@ -30,8 +30,6 @@ import {
|
|||
import {
|
||||
debug,
|
||||
DROPBOX_APP_KEY,
|
||||
GOOGLE_API_KEY,
|
||||
GOOGLE_CLIENT_ID,
|
||||
noteid,
|
||||
noteurl,
|
||||
urlpath,
|
||||
|
@ -908,29 +906,6 @@ if (DROPBOX_APP_KEY) {
|
|||
ui.toolbar.export.dropbox.hide()
|
||||
}
|
||||
|
||||
// check if google api key and client id are set and load scripts
|
||||
if (GOOGLE_API_KEY && GOOGLE_CLIENT_ID) {
|
||||
$('<script>')
|
||||
.attr('type', 'text/javascript')
|
||||
.attr('src', 'https://www.google.com/jsapi?callback=onGoogleAPILoaded')
|
||||
.prop('async', true)
|
||||
.prop('defer', true)
|
||||
.appendTo('body')
|
||||
} else {
|
||||
ui.toolbar.import.googleDrive.hide()
|
||||
ui.toolbar.export.googleDrive.hide()
|
||||
}
|
||||
|
||||
function onGoogleAPILoaded () {
|
||||
$('<script>')
|
||||
.attr('type', 'text/javascript')
|
||||
.attr('src', 'https://apis.google.com/js/client:plusone.js?onload=onGoogleClientLoaded')
|
||||
.prop('async', true)
|
||||
.prop('defer', true)
|
||||
.appendTo('body')
|
||||
}
|
||||
window.onGoogleAPILoaded = onGoogleAPILoaded
|
||||
|
||||
// button actions
|
||||
// share
|
||||
ui.toolbar.publish.attr('href', noteurl + '/publish')
|
||||
|
@ -979,53 +954,6 @@ ui.toolbar.export.dropbox.click(function () {
|
|||
}
|
||||
Dropbox.save(options)
|
||||
})
|
||||
function uploadToGoogleDrive (accessToken) {
|
||||
ui.spinner.show()
|
||||
var filename = renderFilename(ui.area.markdown) + '.md'
|
||||
var markdown = editor.getValue()
|
||||
var blob = new Blob([markdown], {
|
||||
type: 'text/markdown;charset=utf-8'
|
||||
})
|
||||
blob.name = filename
|
||||
var uploader = new MediaUploader({
|
||||
file: blob,
|
||||
token: accessToken,
|
||||
onComplete: function (data) {
|
||||
data = JSON.parse(data)
|
||||
showMessageModal('<i class="fa fa-cloud-upload"></i> Export to Google Drive', 'Export Complete!', data.alternateLink, 'Click here to view your file', true)
|
||||
ui.spinner.hide()
|
||||
},
|
||||
onError: function (data) {
|
||||
showMessageModal('<i class="fa fa-cloud-upload"></i> Export to Google Drive', 'Export Error :(', '', data, false)
|
||||
ui.spinner.hide()
|
||||
}
|
||||
})
|
||||
uploader.upload()
|
||||
}
|
||||
function googleApiAuth (immediate, callback) {
|
||||
gapi.auth.authorize(
|
||||
{
|
||||
'client_id': GOOGLE_CLIENT_ID,
|
||||
'scope': 'https://www.googleapis.com/auth/drive.file',
|
||||
'immediate': immediate
|
||||
}, callback || function () { })
|
||||
}
|
||||
function onGoogleClientLoaded () {
|
||||
googleApiAuth(true)
|
||||
buildImportFromGoogleDrive()
|
||||
}
|
||||
window.onGoogleClientLoaded = onGoogleClientLoaded
|
||||
// export to google drive
|
||||
ui.toolbar.export.googleDrive.click(function (e) {
|
||||
var token = gapi.auth.getToken()
|
||||
if (token) {
|
||||
uploadToGoogleDrive(token.access_token)
|
||||
} else {
|
||||
googleApiAuth(false, function (result) {
|
||||
uploadToGoogleDrive(result.access_token)
|
||||
})
|
||||
}
|
||||
})
|
||||
// export to gist
|
||||
ui.toolbar.export.gist.attr('href', noteurl + '/gist')
|
||||
// export to snippet
|
||||
|
@ -1075,38 +1003,6 @@ ui.toolbar.import.dropbox.click(function () {
|
|||
}
|
||||
Dropbox.choose(options)
|
||||
})
|
||||
// import from google drive
|
||||
function buildImportFromGoogleDrive () {
|
||||
/* eslint-disable no-unused-vars */
|
||||
let picker = new FilePicker({
|
||||
apiKey: GOOGLE_API_KEY,
|
||||
clientId: GOOGLE_CLIENT_ID,
|
||||
buttonEl: ui.toolbar.import.googleDrive,
|
||||
onSelect: function (file) {
|
||||
if (file.downloadUrl) {
|
||||
ui.spinner.show()
|
||||
var accessToken = gapi.auth.getToken().access_token
|
||||
$.ajax({
|
||||
type: 'GET',
|
||||
beforeSend: function (request) {
|
||||
request.setRequestHeader('Authorization', 'Bearer ' + accessToken)
|
||||
},
|
||||
url: file.downloadUrl,
|
||||
success: function (data) {
|
||||
if (file.fileExtension === 'html') { parseToEditor(data) } else { replaceAll(data) }
|
||||
},
|
||||
error: function (data) {
|
||||
showMessageModal('<i class="fa fa-cloud-download"></i> Import from Google Drive', 'Import failed :(', '', data, false)
|
||||
},
|
||||
complete: function () {
|
||||
ui.spinner.hide()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
/* eslint-enable no-unused-vars */
|
||||
}
|
||||
// import from gist
|
||||
ui.toolbar.import.gist.click(function () {
|
||||
// na
|
||||
|
|
|
@ -5,6 +5,4 @@ window.version = '<%- version %>'
|
|||
|
||||
window.allowedUploadMimeTypes = <%- JSON.stringify(allowedUploadMimeTypes) %>
|
||||
|
||||
window.GOOGLE_API_KEY = '<%- GOOGLE_API_KEY %>'
|
||||
window.GOOGLE_CLIENT_ID = '<%- GOOGLE_CLIENT_ID %>'
|
||||
window.DROPBOX_APP_KEY = '<%- DROPBOX_APP_KEY %>'
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
export const GOOGLE_API_KEY = window.GOOGLE_API_KEY || ''
|
||||
export const GOOGLE_CLIENT_ID = window.GOOGLE_CLIENT_ID || ''
|
||||
export const DROPBOX_APP_KEY = window.DROPBOX_APP_KEY || ''
|
||||
|
||||
export const domain = window.domain || '' // domain name
|
||||
|
|
|
@ -22,13 +22,11 @@ export const getUIElements = () => ({
|
|||
},
|
||||
export: {
|
||||
dropbox: $('.ui-save-dropbox'),
|
||||
googleDrive: $('.ui-save-google-drive'),
|
||||
gist: $('.ui-save-gist'),
|
||||
snippet: $('.ui-save-snippet')
|
||||
},
|
||||
import: {
|
||||
dropbox: $('.ui-import-dropbox'),
|
||||
googleDrive: $('.ui-import-google-drive'),
|
||||
gist: $('.ui-import-gist'),
|
||||
snippet: $('.ui-import-snippet'),
|
||||
clipboard: $('.ui-import-clipboard')
|
||||
|
|
|
@ -32,13 +32,11 @@
|
|||
</li>
|
||||
<li role="presentation"><a role="menuitem" class="ui-extra-slide" tabindex="-1" href="#" target="_blank"><i class="fa fa-tv fa-fw"></i> <%= __('Slide Mode') %></a>
|
||||
</li>
|
||||
<% if((typeof github !== 'undefined' && github) || (typeof dropbox !== 'undefined' && dropbox) || (typeof google !== 'undefined' && google) || (typeof gitlab !== 'undefined' && gitlab && (!gitlab.scope || gitlab.scope === 'api'))) { %>
|
||||
<% if((typeof github !== 'undefined' && github) || (typeof dropbox !== 'undefined' && dropbox) || (typeof gitlab !== 'undefined' && gitlab && (!gitlab.scope || gitlab.scope === 'api'))) { %>
|
||||
<li class="divider"></li>
|
||||
<li class="dropdown-header"><%= __('Export') %></li>
|
||||
<li role="presentation"><a role="menuitem" class="ui-save-dropbox" tabindex="-1" href="#" target="_self"><i class="fa fa-dropbox fa-fw"></i> Dropbox</a>
|
||||
</li>
|
||||
<li role="presentation"><a role="menuitem" class="ui-save-google-drive" tabindex="-1" href="#" target="_self"><i class="fa fa-cloud-upload fa-fw"></i> Google Drive</a>
|
||||
</li>
|
||||
<% if(typeof github !== 'undefined' && github) { %>
|
||||
<li role="presentation"><a role="menuitem" class="ui-save-gist" tabindex="-1" href="#" target="_blank"><i class="fa fa-github fa-fw"></i> Gist</a>
|
||||
</li>
|
||||
|
@ -52,8 +50,6 @@
|
|||
<li class="dropdown-header"><%= __('Import') %></li>
|
||||
<li role="presentation"><a role="menuitem" class="ui-import-dropbox" tabindex="-1" href="#" target="_self"><i class="fa fa-dropbox fa-fw"></i> Dropbox</a>
|
||||
</li>
|
||||
<li role="presentation"><a role="menuitem" class="ui-import-google-drive" tabindex="-1" href="#" target="_self"><i class="fa fa-cloud-download fa-fw"></i> Google Drive</a>
|
||||
</li>
|
||||
<li role="presentation"><a role="menuitem" class="ui-import-gist" href="#" data-toggle="modal" data-target="#gistImportModal"><i class="fa fa-github fa-fw"></i> Gist</a>
|
||||
</li>
|
||||
<% if(typeof gitlab !== 'undefined' && gitlab && (!gitlab.scope || gitlab.scope === 'api')) { %>
|
||||
|
@ -138,13 +134,11 @@
|
|||
</li>
|
||||
<li role="presentation"><a role="menuitem" class="ui-extra-slide" tabindex="-1" href="#" target="_blank"><i class="fa fa-tv fa-fw"></i> <%= __('Slide Mode') %></a>
|
||||
</li>
|
||||
<% if((typeof github !== 'undefined' && github) || (typeof dropbox !== 'undefined' && dropbox) || (typeof google !== 'undefined' && google) || (typeof gitlab !== 'undefined' && gitlab && (!gitlab.scope || gitlab.scope === 'api'))) { %>
|
||||
<% if((typeof github !== 'undefined' && github) || (typeof dropbox !== 'undefined' && dropbox) || (typeof gitlab !== 'undefined' && gitlab && (!gitlab.scope || gitlab.scope === 'api'))) { %>
|
||||
<li class="divider"></li>
|
||||
<li class="dropdown-header"><%= __('Export') %></li>
|
||||
<li role="presentation"><a role="menuitem" class="ui-save-dropbox" tabindex="-1" href="#" target="_self"><i class="fa fa-dropbox fa-fw"></i> Dropbox</a>
|
||||
</li>
|
||||
<li role="presentation"><a role="menuitem" class="ui-save-google-drive" tabindex="-1" href="#" target="_self"><i class="fa fa-cloud-upload fa-fw"></i> Google Drive</a>
|
||||
</li>
|
||||
<% if(typeof github !== 'undefined' && github) { %>
|
||||
<li role="presentation"><a role="menuitem" class="ui-save-gist" tabindex="-1" href="#" target="_blank"><i class="fa fa-github fa-fw"></i> Gist</a>
|
||||
</li>
|
||||
|
@ -158,8 +152,6 @@
|
|||
<li class="dropdown-header"><%= __('Import') %></li>
|
||||
<li role="presentation"><a role="menuitem" class="ui-import-dropbox" tabindex="-1" href="#" target="_self"><i class="fa fa-dropbox fa-fw"></i> Dropbox</a>
|
||||
</li>
|
||||
<li role="presentation"><a role="menuitem" class="ui-import-google-drive" tabindex="-1" href="#" target="_self"><i class="fa fa-cloud-download fa-fw"></i> Google Drive</a>
|
||||
</li>
|
||||
<li role="presentation"><a role="menuitem" class="ui-import-gist" href="#" data-toggle="modal" data-target="#gistImportModal"><i class="fa fa-github fa-fw"></i> Gist</a>
|
||||
</li>
|
||||
<% if(typeof gitlab !== 'undefined' && gitlab && (!gitlab.scope || gitlab.scope === 'api')) { %>
|
||||
|
|
|
@ -208,8 +208,6 @@ module.exports = {
|
|||
'flowchart.js',
|
||||
'js-sequence-diagrams',
|
||||
'expose?RevealMarkdown!reveal-markdown',
|
||||
path.join(__dirname, 'public/js/google-drive-upload.js'),
|
||||
path.join(__dirname, 'public/js/google-drive-picker.js'),
|
||||
path.join(__dirname, 'public/js/index.js')
|
||||
],
|
||||
'index-styles': [
|
||||
|
@ -266,8 +264,6 @@ module.exports = {
|
|||
'script!abcjs',
|
||||
'expose?io!socket.io-client',
|
||||
'expose?RevealMarkdown!reveal-markdown',
|
||||
path.join(__dirname, 'public/js/google-drive-upload.js'),
|
||||
path.join(__dirname, 'public/js/google-drive-picker.js'),
|
||||
path.join(__dirname, 'public/js/index.js')
|
||||
],
|
||||
pretty: [
|
||||
|
|
Loading…
Reference in a new issue