Fix eslint warnings

Since we are about to release it's time to finally fix our linting. This
patch basically runs eslint --fix and does some further manual fixes.
Also it sets up eslint to fail on every warning on order to make
warnings visable in the CI process.

There should no functional change be introduced.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
This commit is contained in:
Sheogorath 2019-05-31 00:27:56 +02:00
parent 3eca0a74ae
commit 4da68597f7
No known key found for this signature in database
GPG key ID: 1F05CC3635CDDFFD
50 changed files with 1055 additions and 1042 deletions

View file

@ -37,7 +37,7 @@ exports.generateAvatarURL = function (name, email = '', big = true) {
let hexDigest = hash.digest('hex') let hexDigest = hash.digest('hex')
if (email !== '' && config.allowGravatar) { if (email !== '' && config.allowGravatar) {
photo = 'https://cdn.libravatar.org/avatar/' + hexDigest; photo = 'https://cdn.libravatar.org/avatar/' + hexDigest
if (big) { if (big) {
photo += '?s=400' photo += '?s=400'
} else { } else {

View file

@ -22,6 +22,7 @@ module.exports = {
}) })
}).catch(function (error) { }).catch(function (error) {
if (error.message === 'SQLITE_ERROR: duplicate column name: shortid' || error.message === "ER_DUP_FIELDNAME: Duplicate column name 'shortid'" || error.message === 'column "shortid" of relation "Notes" already exists') { if (error.message === 'SQLITE_ERROR: duplicate column name: shortid' || error.message === "ER_DUP_FIELDNAME: Duplicate column name 'shortid'" || error.message === 'column "shortid" of relation "Notes" already exists') {
// eslint-disable-next-line no-console
console.log('Migration has already run… ignoring.') console.log('Migration has already run… ignoring.')
} else { } else {
throw error throw error

View file

@ -9,6 +9,7 @@ module.exports = {
}) })
}).catch(function (error) { }).catch(function (error) {
if (error.message === 'SQLITE_ERROR: duplicate column name: lastchangeuserId' || error.message === "ER_DUP_FIELDNAME: Duplicate column name 'lastchangeuserId'" || error.message === 'column "lastchangeuserId" of relation "Notes" already exists') { if (error.message === 'SQLITE_ERROR: duplicate column name: lastchangeuserId' || error.message === "ER_DUP_FIELDNAME: Duplicate column name 'lastchangeuserId'" || error.message === 'column "lastchangeuserId" of relation "Notes" already exists') {
// eslint-disable-next-line no-console
console.log('Migration has already run… ignoring.') console.log('Migration has already run… ignoring.')
} else { } else {
throw error throw error

View file

@ -9,6 +9,7 @@ module.exports = {
}) })
}).catch(function (error) { }).catch(function (error) {
if (error.message === 'SQLITE_ERROR: duplicate column name: alias' || error.message === "ER_DUP_FIELDNAME: Duplicate column name 'alias'" || error.message === 'column "alias" of relation "Notes" already exists') { if (error.message === 'SQLITE_ERROR: duplicate column name: alias' || error.message === "ER_DUP_FIELDNAME: Duplicate column name 'alias'" || error.message === 'column "alias" of relation "Notes" already exists') {
// eslint-disable-next-line no-console
console.log('Migration has already run… ignoring.') console.log('Migration has already run… ignoring.')
} else { } else {
throw error throw error

View file

@ -5,6 +5,7 @@ module.exports = {
return queryInterface.addColumn('Users', 'refreshToken', Sequelize.STRING) return queryInterface.addColumn('Users', 'refreshToken', Sequelize.STRING)
}).catch(function (error) { }).catch(function (error) {
if (error.message === 'SQLITE_ERROR: duplicate column name: accessToken' || error.message === "ER_DUP_FIELDNAME: Duplicate column name 'accessToken'" || error.message === 'column "accessToken" of relation "Users" already exists') { if (error.message === 'SQLITE_ERROR: duplicate column name: accessToken' || error.message === "ER_DUP_FIELDNAME: Duplicate column name 'accessToken'" || error.message === 'column "accessToken" of relation "Users" already exists') {
// eslint-disable-next-line no-console
console.log('Migration has already run… ignoring.') console.log('Migration has already run… ignoring.')
} else { } else {
throw error throw error

View file

@ -17,6 +17,7 @@ module.exports = {
}) })
}).catch(function (error) { }).catch(function (error) {
if (error.message === 'SQLITE_ERROR: duplicate column name: savedAt' | error.message === "ER_DUP_FIELDNAME: Duplicate column name 'savedAt'" || error.message === 'column "savedAt" of relation "Notes" already exists') { if (error.message === 'SQLITE_ERROR: duplicate column name: savedAt' | error.message === "ER_DUP_FIELDNAME: Duplicate column name 'savedAt'" || error.message === 'column "savedAt" of relation "Notes" already exists') {
// eslint-disable-next-line no-console
console.log('Migration has already run… ignoring.') console.log('Migration has already run… ignoring.')
} else { } else {
throw error throw error

View file

@ -18,6 +18,7 @@ module.exports = {
}) })
}).catch(function (error) { }).catch(function (error) {
if (error.message === 'SQLITE_ERROR: duplicate column name: authorship' || error.message === "ER_DUP_FIELDNAME: Duplicate column name 'authorship'" || error.message === 'column "authorship" of relation "Notes" already exists') { if (error.message === 'SQLITE_ERROR: duplicate column name: authorship' || error.message === "ER_DUP_FIELDNAME: Duplicate column name 'authorship'" || error.message === 'column "authorship" of relation "Notes" already exists') {
// eslint-disable-next-line no-console
console.log('Migration has already run… ignoring.') console.log('Migration has already run… ignoring.')
} else { } else {
throw error throw error

View file

@ -3,6 +3,7 @@ module.exports = {
up: function (queryInterface, Sequelize) { up: function (queryInterface, Sequelize) {
return queryInterface.addColumn('Notes', 'deletedAt', Sequelize.DATE).catch(function (error) { return queryInterface.addColumn('Notes', 'deletedAt', Sequelize.DATE).catch(function (error) {
if (error.message === 'SQLITE_ERROR: duplicate column name: deletedAt' || error.message === "ER_DUP_FIELDNAME: Duplicate column name 'deletedAt'" || error.message === 'column "deletedAt" of relation "Notes" already exists') { if (error.message === 'SQLITE_ERROR: duplicate column name: deletedAt' || error.message === "ER_DUP_FIELDNAME: Duplicate column name 'deletedAt'" || error.message === 'column "deletedAt" of relation "Notes" already exists') {
// eslint-disable-next-line no-console
console.log('Migration has already run… ignoring.') console.log('Migration has already run… ignoring.')
} else { } else {
throw error throw error

View file

@ -4,6 +4,7 @@ module.exports = {
return queryInterface.addColumn('Users', 'email', Sequelize.TEXT).then(function () { return queryInterface.addColumn('Users', 'email', Sequelize.TEXT).then(function () {
return queryInterface.addColumn('Users', 'password', Sequelize.TEXT).catch(function (error) { return queryInterface.addColumn('Users', 'password', Sequelize.TEXT).catch(function (error) {
if (error.message === "ER_DUP_FIELDNAME: Duplicate column name 'password'" || error.message === 'column "password" of relation "Users" already exists') { if (error.message === "ER_DUP_FIELDNAME: Duplicate column name 'password'" || error.message === 'column "password" of relation "Users" already exists') {
// eslint-disable-next-line no-console
console.log('Migration has already run… ignoring.') console.log('Migration has already run… ignoring.')
} else { } else {
throw error throw error
@ -11,6 +12,7 @@ module.exports = {
}) })
}).catch(function (error) { }).catch(function (error) {
if (error.message === 'SQLITE_ERROR: duplicate column name: email' || error.message === "ER_DUP_FIELDNAME: Duplicate column name 'email'" || error.message === 'column "email" of relation "Users" already exists') { if (error.message === 'SQLITE_ERROR: duplicate column name: email' || error.message === "ER_DUP_FIELDNAME: Duplicate column name 'email'" || error.message === 'column "email" of relation "Users" already exists') {
// eslint-disable-next-line no-console
console.log('Migration has already run… ignoring.') console.log('Migration has already run… ignoring.')
} else { } else {
throw error throw error

View file

@ -12,7 +12,7 @@ passport.use(new GoogleStrategy({
clientID: config.google.clientID, clientID: config.google.clientID,
clientSecret: config.google.clientSecret, clientSecret: config.google.clientSecret,
callbackURL: config.serverURL + '/auth/google/callback', callbackURL: config.serverURL + '/auth/google/callback',
userProfileURL: "https://www.googleapis.com/oauth2/v3/userinfo" userProfileURL: 'https://www.googleapis.com/oauth2/v3/userinfo'
}, passportGeneralCallback)) }, passportGeneralCallback))
googleAuth.get('/auth/google', function (req, res, next) { googleAuth.get('/auth/google', function (req, res, next) {

View file

@ -2,7 +2,6 @@
const toobusy = require('toobusy-js') const toobusy = require('toobusy-js')
const response = require('../../response') const response = require('../../response')
const config = require('../../config') const config = require('../../config')

View file

@ -6,7 +6,7 @@
"license": "AGPL-3.0", "license": "AGPL-3.0",
"scripts": { "scripts": {
"test": "npm run-script eslint && npm run-script jsonlint && npm run-script mocha-suite", "test": "npm run-script eslint && npm run-script jsonlint && npm run-script mocha-suite",
"eslint": "node_modules/.bin/eslint lib public test app.js", "eslint": "node_modules/.bin/eslint --max-warnings 0 lib public test app.js",
"jsonlint": "find . -not -path './node_modules/*' -type f -name '*.json' -o -type f -name '*.json.example' | while read json; do echo $json ; jq . $json; done", "jsonlint": "find . -not -path './node_modules/*' -type f -name '*.json' -o -type f -name '*.json.example' | while read json; do echo $json ; jq . $json; done",
"mocha-suite": "NODE_ENV=test CMD_DB_URL=\"sqlite::memory:\" mocha --exit", "mocha-suite": "NODE_ENV=test CMD_DB_URL=\"sqlite::memory:\" mocha --exit",
"standard": "echo 'standard is no longer being used, use `npm run eslint` instead!' && exit 1", "standard": "echo 'standard is no longer being used, use `npm run eslint` instead!' && exit 1",

View file

@ -1,11 +1,6 @@
/* eslint-env browser, jquery */ /* eslint-env browser, jquery */
/* global moment, serverurl */ /* global moment, serverurl */
require('./locale')
require('../css/cover.css')
require('../css/site.css')
import { import {
checkIfAuth, checkIfAuth,
clearLoginState, clearLoginState,
@ -32,6 +27,11 @@ import { saveAs } from 'file-saver'
import List from 'list.js' import List from 'list.js'
import S from 'string' import S from 'string'
require('./locale')
require('../css/cover.css')
require('../css/site.css')
const options = { const options = {
valueNames: ['id', 'text', 'timestamp', 'fromNow', 'time', 'tags', 'pinned'], valueNames: ['id', 'text', 'timestamp', 'fromNow', 'time', 'tags', 'pinned'],
item: `<li class="col-xs-12 col-sm-6 col-md-6 col-lg-4"> item: `<li class="col-xs-12 col-sm-6 col-md-6 col-lg-4">

View file

@ -1,6 +1,22 @@
/* eslint-env browser, jquery */ /* eslint-env browser, jquery */
/* eslint no-console: ["error", { allow: ["warn", "error"] }] */
/* global moment, serverurl */ /* global moment, serverurl */
import Prism from 'prismjs'
import hljs from 'highlight.js'
import PDFObject from 'pdfobject'
import S from 'string'
import { saveAs } from 'file-saver'
import escapeHTML from 'escape-html'
import getUIElements from './lib/editor/ui-elements'
import markdownit from 'markdown-it'
import markdownitContainer from 'markdown-it-container'
/* Defined regex markdown it plugins */
import Plugin from 'markdown-it-regexp'
require('prismjs/themes/prism.css') require('prismjs/themes/prism.css')
require('prismjs/components/prism-wiki') require('prismjs/components/prism-wiki')
require('prismjs/components/prism-haskell') require('prismjs/components/prism-haskell')
@ -10,18 +26,9 @@ require('prismjs/components/prism-jsx')
require('prismjs/components/prism-makefile') require('prismjs/components/prism-makefile')
require('prismjs/components/prism-gherkin') require('prismjs/components/prism-gherkin')
import Prism from 'prismjs'
import hljs from 'highlight.js'
import PDFObject from 'pdfobject'
import S from 'string'
import { saveAs } from 'file-saver'
import escapeHTML from 'escape-html'
require('./lib/common/login') require('./lib/common/login')
require('../vendor/md-toc') require('../vendor/md-toc')
var Viz = require('viz.js') var Viz = require('viz.js')
import getUIElements from './lib/editor/ui-elements'
const ui = getUIElements() const ui = getUIElements()
// auto update last change // auto update last change
@ -665,7 +672,6 @@ export function exportToHTML (view) {
dir: (md && md.meta && md.meta.dir) ? `dir="${md.meta.dir}"` : null dir: (md && md.meta && md.meta.dir) ? `dir="${md.meta.dir}"` : null
} }
const html = template(context) const html = template(context)
// console.log(html);
const blob = new Blob([html], { const blob = new Blob([html], {
type: 'text/html;charset=utf-8' type: 'text/html;charset=utf-8'
}) })
@ -935,9 +941,6 @@ function highlightRender (code, lang) {
return result.value return result.value
} }
import markdownit from 'markdown-it'
import markdownitContainer from 'markdown-it-container'
export let md = markdownit('default', { export let md = markdownit('default', {
html: true, html: true,
breaks: true, breaks: true,
@ -1035,9 +1038,6 @@ md.renderer.rules.fence = (tokens, idx, options, env, self) => {
return `<pre><code${self.renderAttrs(token)}>${highlighted}</code></pre>\n` return `<pre><code${self.renderAttrs(token)}>${highlighted}</code></pre>\n`
} }
/* Defined regex markdown it plugins */
import Plugin from 'markdown-it-regexp'
// youtube // youtube
const youtubePlugin = new Plugin( const youtubePlugin = new Plugin(
// regexp to match // regexp to match

View file

@ -1,4 +1,5 @@
/* eslint-env browser, jquery */ /* eslint-env browser, jquery */
/* eslint no-console: ["error", { allow: ["warn", "error", "debug"] }] */
/* global serverurl, moment */ /* global serverurl, moment */
import store from 'store' import store from 'store'

View file

@ -1,16 +1,8 @@
/* eslint-env browser, jquery */ /* eslint-env browser, jquery */
/* eslint no-console: ["error", { allow: ["warn", "error", "debug"] }] */
/* global CodeMirror, Cookies, moment, Spinner, Idle, serverurl, /* global CodeMirror, Cookies, moment, Spinner, Idle, serverurl,
key, Dropbox, ot, hex2rgb, Visibility */ key, Dropbox, ot, hex2rgb, Visibility */
require('../vendor/showup/showup')
require('../css/index.css')
require('../css/extra.css')
require('../css/slide-preview.css')
require('../css/site.css')
require('highlight.js/styles/github-gist.css')
import TurndownService from 'turndown' import TurndownService from 'turndown'
import { saveAs } from 'file-saver' import { saveAs } from 'file-saver'
@ -83,6 +75,15 @@ import getUIElements from './lib/editor/ui-elements'
import modeType from './lib/modeType' import modeType from './lib/modeType'
import appState from './lib/appState' import appState from './lib/appState'
require('../vendor/showup/showup')
require('../css/index.css')
require('../css/extra.css')
require('../css/slide-preview.css')
require('../css/site.css')
require('highlight.js/styles/github-gist.css')
var defaultTextHeight = 20 var defaultTextHeight = 20
var viewportMargin = 20 var viewportMargin = 20
var defaultEditorMode = 'gfm' var defaultEditorMode = 'gfm'
@ -1075,7 +1076,8 @@ ui.modal.revision.on('show.bs.modal', function (e) {
}) })
.fail(function (err) { .fail(function (err) {
if (debug) { if (debug) {
console.log(err) // eslint-disable-next-line no-console
console.debug(err)
} }
}) })
.always(function () { .always(function () {
@ -1185,7 +1187,8 @@ function selectRevision (time) {
}) })
.fail(function (err) { .fail(function (err) {
if (debug) { if (debug) {
console.log(err) // eslint-disable-next-line no-console
console.debug(err)
} }
}) })
.always(function () { .always(function () {
@ -1245,7 +1248,8 @@ ui.modal.snippetImportProjects.change(function () {
}) })
.fail(function (err) { .fail(function (err) {
if (debug) { if (debug) {
console.log(err) // eslint-disable-next-line no-console
console.debug(err)
} }
}) })
.always(function () { .always(function () {
@ -1503,7 +1507,7 @@ function replaceAll (data) {
} }
function importFromUrl (url) { function importFromUrl (url) {
// console.log(url); // console.debug(url);
if (!url) return if (!url) return
if (!isValidURL(url)) { if (!isValidURL(url)) {
showMessageModal('<i class="fa fa-cloud-download"></i> Import from URL', 'Not a valid URL :(', '', '', false) showMessageModal('<i class="fa fa-cloud-download"></i> Import from URL', 'Not a valid URL :(', '', '', false)
@ -1768,7 +1772,7 @@ var authorship = []
var authorMarks = {} // temp variable var authorMarks = {} // temp variable
var addTextMarkers = [] // temp variable var addTextMarkers = [] // temp variable
function updateInfo (data) { function updateInfo (data) {
// console.log(data); // console.debug(data);
if (data.hasOwnProperty('createtime') && window.createtime !== data.createtime) { if (data.hasOwnProperty('createtime') && window.createtime !== data.createtime) {
window.createtime = data.createtime window.createtime = data.createtime
updateLastChange() updateLastChange()
@ -1993,7 +1997,7 @@ editorInstance.on('update', function () {
}) })
}) })
socket.on('check', function (data) { socket.on('check', function (data) {
// console.log(data); // console.debug(data);
updateInfo(data) updateInfo(data)
}) })
socket.on('permission', function (data) { socket.on('permission', function (data) {
@ -2002,7 +2006,7 @@ socket.on('permission', function (data) {
var permission = null var permission = null
socket.on('refresh', function (data) { socket.on('refresh', function (data) {
// console.log(data); // console.debug(data);
editorInstance.config.docmaxlength = data.docmaxlength editorInstance.config.docmaxlength = data.docmaxlength
editor.setOption('maxLength', editorInstance.config.docmaxlength) editor.setOption('maxLength', editorInstance.config.docmaxlength)
updateInfo(data) updateInfo(data)
@ -2817,8 +2821,8 @@ function partialUpdate (src, tar, des) {
var rawSrc = cloneAndRemoveDataAttr(src[i]) var rawSrc = cloneAndRemoveDataAttr(src[i])
var rawTar = cloneAndRemoveDataAttr(tar[i]) var rawTar = cloneAndRemoveDataAttr(tar[i])
if (rawSrc.outerHTML !== rawTar.outerHTML) { if (rawSrc.outerHTML !== rawTar.outerHTML) {
// console.log(rawSrc); // console.debug(rawSrc);
// console.log(rawTar); // console.debug(rawTar);
$(des[i]).replaceWith(src[i]) $(des[i]).replaceWith(src[i])
} }
} }
@ -2881,12 +2885,12 @@ function partialUpdate (src, tar, des) {
var rawTarEnd = cloneAndRemoveDataAttr(tar[tarEnd + 1 + start - i]) var rawTarEnd = cloneAndRemoveDataAttr(tar[tarEnd + 1 + start - i])
if (rawTarStart && rawTarEnd && rawTarStart.outerHTML === rawTarEnd.outerHTML) { overlap++ } else { break } if (rawTarStart && rawTarEnd && rawTarStart.outerHTML === rawTarEnd.outerHTML) { overlap++ } else { break }
} }
if (debug) { console.log('overlap:' + overlap) } if (debug) { console.debug('overlap:' + overlap) }
// show diff content // show diff content
if (debug) { if (debug) {
console.log('start:' + start) console.debug('start:' + start)
console.log('tarEnd:' + tarEnd) console.debug('tarEnd:' + tarEnd)
console.log('srcEnd:' + srcEnd) console.debug('srcEnd:' + srcEnd)
} }
tarEnd += overlap tarEnd += overlap
srcEnd += overlap srcEnd += overlap
@ -2920,15 +2924,15 @@ function partialUpdate (src, tar, des) {
} }
// add elements // add elements
if (debug) { if (debug) {
console.log('ADD ELEMENTS') console.debug('ADD ELEMENTS')
console.log(newElements.join('\n')) console.debug(newElements.join('\n'))
} }
if (des[start]) { $(newElements.join('')).insertBefore(des[start]) } else { $(newElements.join('')).insertAfter(des[start - 1]) } if (des[start]) { $(newElements.join('')).insertBefore(des[start]) } else { $(newElements.join('')).insertAfter(des[start - 1]) }
// remove elements // remove elements
if (debug) { console.log('REMOVE ELEMENTS') } if (debug) { console.debug('REMOVE ELEMENTS') }
for (let j = 0; j < removeElements.length; j++) { for (let j = 0; j < removeElements.length; j++) {
if (debug) { if (debug) {
console.log(removeElements[j].outerHTML) console.debug(removeElements[j].outerHTML)
} }
if (removeElements[j]) { $(removeElements[j]).remove() } if (removeElements[j]) { $(removeElements[j]).remove() }
} }
@ -3043,7 +3047,7 @@ function checkAbove (method) {
text.push(editor.getLine(i)) text.push(editor.getLine(i))
} }
text = text.join('\n') + '\n' + editor.getLine(cursor.line).slice(0, cursor.ch) text = text.join('\n') + '\n' + editor.getLine(cursor.line).slice(0, cursor.ch)
// console.log(text); // console.debug(text);
return method(text) return method(text)
} }
@ -3055,7 +3059,7 @@ function checkBelow (method) {
text.push(editor.getLine(i)) text.push(editor.getLine(i))
} }
text = editor.getLine(cursor.line).slice(cursor.ch) + '\n' + text.join('\n') text = editor.getLine(cursor.line).slice(cursor.ch) + '\n' + text.join('\n')
// console.log(text); // console.debug(text);
return method(text) return method(text)
} }
@ -3160,7 +3164,7 @@ $(editor.getInputField())
text.push(editor.getLine(cursor.line - 1)) text.push(editor.getLine(cursor.line - 1))
text.push(editor.getLine(cursor.line)) text.push(editor.getLine(cursor.line))
text = text.join('\n') text = text.join('\n')
// console.log(text); // console.debug(text);
if (text === '\n```') { editor.doc.cm.execCommand('goLineUp') } if (text === '\n```') { editor.doc.cm.execCommand('goLineUp') }
}, },
context: function (text) { context: function (text) {
@ -3192,7 +3196,7 @@ $(editor.getInputField())
text.push(editor.getLine(cursor.line - 1)) text.push(editor.getLine(cursor.line - 1))
text.push(editor.getLine(cursor.line)) text.push(editor.getLine(cursor.line))
text = text.join('\n') text = text.join('\n')
// console.log(text); // console.debug(text);
if (text === '\n:::') { editor.doc.cm.execCommand('goLineUp') } if (text === '\n:::') { editor.doc.cm.execCommand('goLineUp') }
}, },
context: function (text) { context: function (text) {

View file

@ -1,12 +1,6 @@
/* eslint-env browser, jquery */ /* eslint-env browser, jquery */
/* global refreshView */ /* global refreshView */
require('../css/extra.css')
require('../css/slide-preview.css')
require('../css/site.css')
require('highlight.js/styles/github-gist.css')
import { import {
autoLinkify, autoLinkify,
deduplicatedHeaderId, deduplicatedHeaderId,
@ -24,6 +18,12 @@ import {
import { preventXSS } from './render' import { preventXSS } from './render'
require('../css/extra.css')
require('../css/slide-preview.css')
require('../css/site.css')
require('highlight.js/styles/github-gist.css')
const markdown = $('#doc.markdown-body') const markdown = $('#doc.markdown-body')
const text = markdown.text() const text = markdown.text()
const lastMeta = md.meta const lastMeta = md.meta

View file

@ -1,12 +1,12 @@
/* eslint-env browser, jquery */ /* eslint-env browser, jquery */
/* global serverurl, Reveal, RevealMarkdown */ /* global serverurl, Reveal, RevealMarkdown */
require('../css/extra.css')
require('../css/site.css')
import { preventXSS } from './render' import { preventXSS } from './render'
import { md, updateLastChange, removeDOMEvents, finishView } from './extra' import { md, updateLastChange, removeDOMEvents, finishView } from './extra'
require('../css/extra.css')
require('../css/site.css')
const body = preventXSS($('.slides').text()) const body = preventXSS($('.slides').text())
window.createtime = window.lastchangeui.time.attr('data-createtime') window.createtime = window.lastchangeui.time.attr('data-createtime')