Improvements to Import (#1109)
* Changed URL Regex to make more links importable, also removed need for special text formatting in order to paste or drop new topic labels. (Didn't break TSV import mode) * Removed console logs * add url regex with full documentation * don't eslint 3rd party lib * check for TSV only at start of string * fix a bug with event/e and eslint * handleTEXT => handleText
This commit is contained in:
parent
8c7a657499
commit
a6694a3f72
3 changed files with 155 additions and 14 deletions
|
@ -6,7 +6,6 @@ import _ from 'lodash'
|
|||
import Active from './Active'
|
||||
import AutoLayout from './AutoLayout'
|
||||
import DataModel from './DataModel'
|
||||
import GlobalUI from './GlobalUI'
|
||||
import Map from './Map'
|
||||
import Synapse from './Synapse'
|
||||
import Topic from './Topic'
|
||||
|
@ -389,6 +388,31 @@ const Import = {
|
|||
)
|
||||
},
|
||||
|
||||
handleText: function(text, opts = {}) {
|
||||
let coords = opts.coords
|
||||
if (!coords || coords.x === undefined || coords.y === undefined) {
|
||||
coords = AutoLayout.getNextCoord({ mappings: DataModel.Mappings })
|
||||
}
|
||||
|
||||
const name = text
|
||||
const url = ''
|
||||
const metacode = opts.metacode || 'Wildcard'
|
||||
const importId = opts.importId || null // don't store a cidMapping
|
||||
const permission = opts.permission || null // use default
|
||||
const desc = opts.desc || ''
|
||||
|
||||
Import.createTopicWithParameters(
|
||||
name,
|
||||
metacode,
|
||||
permission,
|
||||
desc,
|
||||
url,
|
||||
coords.x,
|
||||
coords.y,
|
||||
importId
|
||||
)
|
||||
},
|
||||
|
||||
/*
|
||||
* helper functions
|
||||
*/
|
||||
|
|
|
@ -3,12 +3,9 @@
|
|||
import Import from './Import'
|
||||
import Util from './Util'
|
||||
import Visualize from './Visualize'
|
||||
import URL_REGEX from '../patched/regex-weburl'
|
||||
|
||||
const PasteInput = {
|
||||
// thanks to https://github.com/kevva/url-regex
|
||||
// eslint-disable-next-line no-useless-escape
|
||||
URL_REGEX: new RegExp('^(?:(?:(?:[a-z]+:)?//)|www\.)(?:\S+(?::\S*)?@)?(?:localhost|(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(?:\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])){3}|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,}))\.?)(?::\d{2,5})?(?:[/?#][^\s"]*)?$'),
|
||||
|
||||
init: function() {
|
||||
var self = PasteInput
|
||||
|
||||
|
@ -22,19 +19,17 @@ const PasteInput = {
|
|||
e = e || window.event
|
||||
|
||||
// prevent conflict with react-dropzone file uploader
|
||||
if (event.target.id !== 'infovis-canvas') return
|
||||
if (e.target.id !== 'infovis-canvas') return
|
||||
|
||||
e.preventDefault()
|
||||
var coords = Util.pixelsToCoords(Visualize.mGraph, { x: e.clientX, y: e.clientY })
|
||||
if (e.dataTransfer.files.length > 0) {
|
||||
self.handleFile(e.dataTransfer.files[0], coords)
|
||||
}
|
||||
// OMG import bookmarks 😍
|
||||
// OMG import bookmarks 😍 (Or just text :P)
|
||||
if (e.dataTransfer.items && e.dataTransfer.items.length > 0) {
|
||||
e.dataTransfer.items[0].getAsString(function(text) {
|
||||
if (text.match(self.URL_REGEX)) {
|
||||
self.handle(text, coords)
|
||||
}
|
||||
self.handle(text, coords)
|
||||
})
|
||||
}
|
||||
}, false)
|
||||
|
@ -66,15 +61,26 @@ const PasteInput = {
|
|||
handle: function(text, coords = {}) {
|
||||
var self = PasteInput
|
||||
|
||||
if (text.match(self.URL_REGEX)) {
|
||||
if (text.match(URL_REGEX)) {
|
||||
Import.handleURL(text, coords)
|
||||
} else if (text[0] === '{') {
|
||||
Import.handleJSON(text)
|
||||
} else if (text.match(/\t/)) {
|
||||
} else if (text.match(/^[Tt]opics\t/) || text.match(/^[Ss]ynapses\t/)) {
|
||||
Import.handleTSV(text)
|
||||
} else {
|
||||
// just try to see if CSV works
|
||||
Import.handleCSV(text)
|
||||
// Handle as plain text
|
||||
let textItems = text.split('\n')
|
||||
if (textItems.length === 1) {
|
||||
if (textItems[0].trim() !== '') {
|
||||
Import.handleText(textItems[0].trim(), coords)
|
||||
}
|
||||
} else if (window.confirm('Are you sure you want to create ' + textItems.length + ' new topics?')) {
|
||||
textItems.forEach(item => {
|
||||
if (item.trim() !== '') {
|
||||
self.handle(item.trim(), coords)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
111
frontend/src/patched/regex-weburl.js
Normal file
111
frontend/src/patched/regex-weburl.js
Normal file
|
@ -0,0 +1,111 @@
|
|||
/* eslint-disable */
|
||||
// START METAMAPS CODE
|
||||
// From https://gist.github.com/dperini/729294. Retrieved April 11 2017.
|
||||
// Minor modifications made to make it exportable by devvmh.
|
||||
// END METAMAPS CODE
|
||||
//
|
||||
// Regular Expression for URL validation
|
||||
//
|
||||
// Author: Diego Perini
|
||||
// Updated: 2010/12/05
|
||||
// License: MIT
|
||||
//
|
||||
// Copyright (c) 2010-2013 Diego Perini (http://www.iport.it)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
// files (the "Software"), to deal in the Software without
|
||||
// restriction, including without limitation the rights to use,
|
||||
// copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following
|
||||
// conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be
|
||||
// included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// the regular expression composed & commented
|
||||
// could be easily tweaked for RFC compliance,
|
||||
// it was expressly modified to fit & satisfy
|
||||
// these test for an URL shortener:
|
||||
//
|
||||
// http://mathiasbynens.be/demo/url-regex
|
||||
//
|
||||
// Notes on possible differences from a standard/generic validation:
|
||||
//
|
||||
// - utf-8 char class take in consideration the full Unicode range
|
||||
// - TLDs have been made mandatory so single names like "localhost" fails
|
||||
// - protocols have been restricted to ftp, http and https only as requested
|
||||
//
|
||||
// Changes:
|
||||
//
|
||||
// - IP address dotted notation validation, range: 1.0.0.0 - 223.255.255.255
|
||||
// first and last IP address of each class is considered invalid
|
||||
// (since they are broadcast/network addresses)
|
||||
//
|
||||
// - Added exclusion of private, reserved and/or local networks ranges
|
||||
//
|
||||
// - Made starting path slash optional (http://example.com?foo=bar)
|
||||
//
|
||||
// - Allow a dot (.) at the end of hostnames (http://example.com.)
|
||||
//
|
||||
// Compressed one-line versions:
|
||||
//
|
||||
// Javascript version
|
||||
//
|
||||
// /^(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,}))\.?)(?::\d{2,5})?(?:[/?#]\S*)?$/i
|
||||
//
|
||||
// PHP version
|
||||
//
|
||||
// _^(?:(?:https?|ftp)://)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\x{00a1}-\x{ffff}0-9]-*)*[a-z\x{00a1}-\x{ffff}0-9]+)(?:\.(?:[a-z\x{00a1}-\x{ffff}0-9]-*)*[a-z\x{00a1}-\x{ffff}0-9]+)*(?:\.(?:[a-z\x{00a1}-\x{ffff}]{2,}))\.?)(?::\d{2,5})?(?:[/?#]\S*)?$_iuS
|
||||
//
|
||||
// START METAMAPS CODE
|
||||
export default new RegExp(
|
||||
// ORIGINAL CODE
|
||||
// var re_weburl = new RegExp(
|
||||
// END METAMAPS CODE
|
||||
"^" +
|
||||
// protocol identifier
|
||||
"(?:(?:https?|ftp)://)" +
|
||||
// user:pass authentication
|
||||
"(?:\\S+(?::\\S*)?@)?" +
|
||||
"(?:" +
|
||||
// IP address exclusion
|
||||
// private & local networks
|
||||
"(?!(?:10|127)(?:\\.\\d{1,3}){3})" +
|
||||
"(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})" +
|
||||
"(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})" +
|
||||
// IP address dotted notation octets
|
||||
// excludes loopback network 0.0.0.0
|
||||
// excludes reserved space >= 224.0.0.0
|
||||
// excludes network & broacast addresses
|
||||
// (first & last IP address of each class)
|
||||
"(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])" +
|
||||
"(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}" +
|
||||
"(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))" +
|
||||
"|" +
|
||||
// host name
|
||||
"(?:(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)" +
|
||||
// domain name
|
||||
"(?:\\.(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)*" +
|
||||
// TLD identifier
|
||||
"(?:\\.(?:[a-z\\u00a1-\\uffff]{2,}))" +
|
||||
// TLD may end with dot
|
||||
"\\.?" +
|
||||
")" +
|
||||
// port number
|
||||
"(?::\\d{2,5})?" +
|
||||
// resource path
|
||||
"(?:[/?#]\\S*)?" +
|
||||
"$", "i"
|
||||
);
|
||||
/* eslint-enable */
|
Loading…
Reference in a new issue