Merge branch 'dev-life'
Conflicts: app/init.go public/js/common-min.js public/js/common.js
This commit is contained in:
app
controllers
AttachController.goAuthController.goBaseController.goBlogController.goFileController.goNoteController.goPreviewController.go
admin
member
db
info
init.golea
release
service
AttachService.goAuthService.goFileService.goGroupService.goNoteContentHistoryService.goShareService.goThemeService.goUserService.go
views
messages
public
admin
js
blog
js
themes
backup
default
archive.htmlcate.htmlcomment.htmlfooter.htmlheader.htmlhighlight.html
images
index.htmlnoise.pngpage.htmlpaging.htmlsearch.htmlsingle.htmlstyle.csstag_posts.htmltags.htmltheme.jsonview.htmlview.jselegant
archive.htmlcate.htmlcomment.htmlfooter.htmlheader.htmlhighlight.html
images
index.htmlpage.htmlpaging.htmlsearch.htmlsingle.htmlstyle.csstag_posts.htmltags.htmltheme.jsonview.htmlview.jsnav_fixed
elegant
css
blog
bootstrap.csscss
index.cssindex.lesstheme
basic.lessdefault.cssdefault.lessmobile.lesssimple.csssimple.lesswritting-overwrite.csswritting-overwrite.lesswritting.css
zTreeStyle
dist
images
slider
js
ZeroClipboard
all.jsapp
attachment_upload-min.jsattachment_upload.jseditor_drop_paste-min.jseditor_drop_paste.jsnote-min.jsnote.jsnotebook-min.jsnotebook.jspage-min.jspage.jsshare-min.jsshare.js
common-min.jscommon.jsfastclick.jsjquery.mobile-1.4.4.min.jsjquery.ztree.all-3.5-min.jsjquery.ztree.all-3.5.jsmain-min.jsmain.jsother.jslibs
MathJax
MathJax.jsfontdata-extra.jsfontdata.jsfontdata-extra.jsfontdata.jsfontdata-extra.jsfontdata.jsfontdata-extra.jsfontdata.jsfontdata-extra.jsfontdata.jsimageFonts.jsjax.js
config
AM_HTMLorMML-full.jsAM_HTMLorMML.jsAccessible-full.jsAccessible.jsMML_HTMLorMML-full.jsMML_HTMLorMML.jsMMLorHTML.jsSafe.jsTeX-AMS_HTML-full.jsTeX-AMS_HTML.jsdefault.js
local
extensions
FontWarnings.js
HTML-CSS
HelpDialog.jsMatchWebFonts.jsMathEvents.jsMathMenu.jsMathZoom.jsSafe.jsTeX
AMScd.jsAMSmath.jsAMSsymbols.jsHTML.jsaction.jsautobold.jsautoload-all.jsbbox.jsbegingroup.jsboldsymbol.jscancel.jscolor.jsenclose.jsextpfeil.jsmathchoice.jsmhchem.jsnewcommand.jsnoErrors.jsnoUndefined.jsunicode.jsverb.js
asciimath2jax.jsjsMath2jax.jstex2jax.jsfonts
HTML-CSS
Asana-Math
woff
AsanaMathJax_Alphabets-Regular.woffAsanaMathJax_Arrows-Regular.woffAsanaMathJax_DoubleStruck-Regular.woffAsanaMathJax_Fraktur-Regular.woffAsanaMathJax_Latin-Regular.woffAsanaMathJax_Main-Regular.woffAsanaMathJax_Marks-Regular.woffAsanaMathJax_Misc-Regular.woffAsanaMathJax_Monospace-Regular.woffAsanaMathJax_NonUnicode-Regular.woffAsanaMathJax_Normal-Regular.woffAsanaMathJax_Operators-Regular.woffAsanaMathJax_SansSerif-Regular.woffAsanaMathJax_Script-Regular.woffAsanaMathJax_Shapes-Regular.woffAsanaMathJax_Size1-Regular.woffAsanaMathJax_Size2-Regular.woffAsanaMathJax_Size3-Regular.woffAsanaMathJax_Size4-Regular.woffAsanaMathJax_Size5-Regular.woffAsanaMathJax_Size6-Regular.woffAsanaMathJax_Symbols-Regular.woffAsanaMathJax_Variants-Regular.woff
Gyre-Pagella
woff
GyrePagellaMathJax_Alphabets-Regular.woffGyrePagellaMathJax_Arrows-Regular.woffGyrePagellaMathJax_DoubleStruck-Regular.woffGyrePagellaMathJax_Fraktur-Regular.woffGyrePagellaMathJax_Latin-Regular.woffGyrePagellaMathJax_Main-Regular.woffGyrePagellaMathJax_Marks-Regular.woffGyrePagellaMathJax_Misc-Regular.woffGyrePagellaMathJax_Monospace-Regular.woffGyrePagellaMathJax_NonUnicode-Regular.woffGyrePagellaMathJax_Normal-Regular.woffGyrePagellaMathJax_Operators-Regular.woffGyrePagellaMathJax_SansSerif-Regular.woffGyrePagellaMathJax_Script-Regular.woffGyrePagellaMathJax_Shapes-Regular.woffGyrePagellaMathJax_Size1-Regular.woffGyrePagellaMathJax_Size2-Regular.woffGyrePagellaMathJax_Size3-Regular.woffGyrePagellaMathJax_Size4-Regular.woffGyrePagellaMathJax_Size5-Regular.woffGyrePagellaMathJax_Size6-Regular.woffGyrePagellaMathJax_Symbols-Regular.woffGyrePagellaMathJax_Variants-Regular.woff
Gyre-Termes
woff
GyreTermesMathJax_Alphabets-Regular.woffGyreTermesMathJax_Arrows-Regular.woffGyreTermesMathJax_DoubleStruck-Regular.woffGyreTermesMathJax_Fraktur-Regular.woffGyreTermesMathJax_Latin-Regular.woffGyreTermesMathJax_Main-Regular.woffGyreTermesMathJax_Marks-Regular.woffGyreTermesMathJax_Misc-Regular.woffGyreTermesMathJax_Monospace-Regular.woffGyreTermesMathJax_NonUnicode-Regular.woffGyreTermesMathJax_Normal-Regular.woffGyreTermesMathJax_Operators-Regular.woffGyreTermesMathJax_SansSerif-Regular.woffGyreTermesMathJax_Script-Regular.woffGyreTermesMathJax_Shapes-Regular.woffGyreTermesMathJax_Size1-Regular.woffGyreTermesMathJax_Size2-Regular.woffGyreTermesMathJax_Size3-Regular.woffGyreTermesMathJax_Size4-Regular.woffGyreTermesMathJax_Size5-Regular.woffGyreTermesMathJax_Size6-Regular.woffGyreTermesMathJax_Symbols-Regular.woffGyreTermesMathJax_Variants-Regular.woff
Latin-Modern
woff
LatinModernMathJax_Alphabets-Regular.woffLatinModernMathJax_Arrows-Regular.woffLatinModernMathJax_DoubleStruck-Regular.woffLatinModernMathJax_Fraktur-Regular.woffLatinModernMathJax_Latin-Regular.woffLatinModernMathJax_Main-Regular.woffLatinModernMathJax_Marks-Regular.woffLatinModernMathJax_Misc-Regular.woffLatinModernMathJax_Monospace-Regular.woffLatinModernMathJax_NonUnicode-Regular.woffLatinModernMathJax_Normal-Regular.woffLatinModernMathJax_Operators-Regular.woffLatinModernMathJax_SansSerif-Regular.woffLatinModernMathJax_Script-Regular.woffLatinModernMathJax_Shapes-Regular.woffLatinModernMathJax_Size1-Regular.woffLatinModernMathJax_Size2-Regular.woffLatinModernMathJax_Size3-Regular.woffLatinModernMathJax_Size4-Regular.woffLatinModernMathJax_Size5-Regular.woffLatinModernMathJax_Size6-Regular.woffLatinModernMathJax_Size7-Regular.woffLatinModernMathJax_Symbols-Regular.woffLatinModernMathJax_Variants-Regular.woff
Neo-Euler
woff
NeoEulerMathJax_Alphabets-Regular.woffNeoEulerMathJax_Arrows-Regular.woffNeoEulerMathJax_Fraktur-Regular.woffNeoEulerMathJax_Main-Regular.woffNeoEulerMathJax_Marks-Regular.woffNeoEulerMathJax_NonUnicode-Regular.woffNeoEulerMathJax_Normal-Regular.woffNeoEulerMathJax_Operators-Regular.woffNeoEulerMathJax_Script-Regular.woffNeoEulerMathJax_Shapes-Regular.woffNeoEulerMathJax_Size1-Regular.woffNeoEulerMathJax_Size2-Regular.woffNeoEulerMathJax_Size3-Regular.woffNeoEulerMathJax_Size4-Regular.woffNeoEulerMathJax_Size5-Regular.woffNeoEulerMathJax_Symbols-Regular.woffNeoEulerMathJax_Variants-Regular.woff
STIX-Web
woff
STIXMathJax_Alphabets-Bold.woffSTIXMathJax_Alphabets-BoldItalic.woffSTIXMathJax_Alphabets-Italic.woffSTIXMathJax_Alphabets-Regular.woffSTIXMathJax_Arrows-Bold.woffSTIXMathJax_Arrows-Regular.woffSTIXMathJax_DoubleStruck-Bold.woffSTIXMathJax_DoubleStruck-BoldItalic.woffSTIXMathJax_DoubleStruck-Italic.woffSTIXMathJax_DoubleStruck-Regular.woffSTIXMathJax_Fraktur-Bold.woffSTIXMathJax_Fraktur-Regular.woffSTIXMathJax_Latin-Bold.woffSTIXMathJax_Latin-BoldItalic.woffSTIXMathJax_Latin-Italic.woffSTIXMathJax_Latin-Regular.woffSTIXMathJax_Main-Bold.woffSTIXMathJax_Main-BoldItalic.woffSTIXMathJax_Main-Italic.woffSTIXMathJax_Main-Regular.woffSTIXMathJax_Marks-Bold.woffSTIXMathJax_Marks-BoldItalic.woffSTIXMathJax_Marks-Italic.woffSTIXMathJax_Marks-Regular.woffSTIXMathJax_Misc-Bold.woffSTIXMathJax_Misc-BoldItalic.woffSTIXMathJax_Misc-Italic.woffSTIXMathJax_Misc-Regular.woffSTIXMathJax_Monospace-Regular.woffSTIXMathJax_Normal-Bold.woffSTIXMathJax_Normal-BoldItalic.woffSTIXMathJax_Normal-Italic.woffSTIXMathJax_Operators-Bold.woffSTIXMathJax_Operators-Regular.woffSTIXMathJax_SansSerif-Bold.woffSTIXMathJax_SansSerif-BoldItalic.woffSTIXMathJax_SansSerif-Italic.woffSTIXMathJax_SansSerif-Regular.woffSTIXMathJax_Script-BoldItalic.woffSTIXMathJax_Script-Italic.woffSTIXMathJax_Script-Regular.woffSTIXMathJax_Shapes-Bold.woffSTIXMathJax_Shapes-BoldItalic.woffSTIXMathJax_Shapes-Regular.woffSTIXMathJax_Size1-Regular.woffSTIXMathJax_Size2-Regular.woffSTIXMathJax_Size3-Regular.woffSTIXMathJax_Size4-Regular.woffSTIXMathJax_Size5-Regular.woffSTIXMathJax_Symbols-Bold.woffSTIXMathJax_Symbols-Regular.woffSTIXMathJax_Variants-Bold.woffSTIXMathJax_Variants-BoldItalic.woffSTIXMathJax_Variants-Italic.woffSTIXMathJax_Variants-Regular.woff
TeX
woff
MathJax_AMS-Regular.woffMathJax_Caligraphic-Bold.woffMathJax_Caligraphic-Regular.woffMathJax_Fraktur-Bold.woffMathJax_Fraktur-Regular.woffMathJax_Main-Bold.woffMathJax_Main-Italic.woffMathJax_Main-Regular.woffMathJax_Math-BoldItalic.woffMathJax_Math-Italic.woffMathJax_Math-Regular.woffMathJax_SansSerif-Bold.woffMathJax_SansSerif-Italic.woffMathJax_SansSerif-Regular.woffMathJax_Script-Regular.woffMathJax_Size1-Regular.woffMathJax_Size2-Regular.woffMathJax_Size3-Regular.woffMathJax_Size4-Regular.woffMathJax_Typewriter-Regular.woff
jax
element
mml
jax.js
optable
Arrows.jsBasicLatin.jsCombDiacritMarks.jsCombDiactForSymbols.jsDingbats.jsGeneralPunctuation.jsGeometricShapes.jsGreekAndCoptic.jsLatin1Supplement.jsLetterlikeSymbols.jsMathOperators.jsMiscMathSymbolsA.jsMiscMathSymbolsB.jsMiscSymbolsAndArrows.jsMiscTechnical.jsSpacingModLetters.jsSuppMathOperators.jsSupplementalArrowsA.jsSupplementalArrowsB.js
input
output
HTML-CSS
autoload
config.jsfonts
Asana-Math
Alphabets
Regular
Arrows
Regular
DoubleStruck
Regular
Fraktur
Regular
Latin
Regular
Main
Regular
Marks
Regular
Misc
Regular
Monospace
Regular
NonUnicode
Regular
Normal
Regular
Operators
Regular
SansSerif
Regular
Script
Regular
Shapes
Regular
Size1
Regular
Size2
Regular
Size3
Regular
Size4
Regular
Size5
Regular
Size6
Regular
Symbols
Regular
Variants
Regular
Gyre-Pagella
Alphabets
Regular
Arrows
Regular
DoubleStruck
Regular
Fraktur
Regular
Latin
Regular
Main
Regular
Marks
Regular
Misc
Regular
Monospace
Regular
NonUnicode
Regular
Normal
Regular
Operators
Regular
SansSerif
Regular
Script
Regular
Shapes
Regular
Size1
Regular
Size2
Regular
Size3
Regular
Size4
Regular
Size5
Regular
Size6
Regular
Symbols
Regular
Variants
Regular
Gyre-Termes
Alphabets
Regular
Arrows
Regular
DoubleStruck
Regular
Fraktur
Regular
Latin
Regular
Main
Regular
Marks
Regular
Misc
Regular
Monospace
Regular
NonUnicode
Regular
Normal
Regular
Operators
Regular
SansSerif
Regular
Script
Regular
Shapes
Regular
Size1
Regular
Size2
Regular
Size3
Regular
Size4
Regular
Size5
Regular
Size6
Regular
Symbols
Regular
Variants
Regular
Latin-Modern
Alphabets
Regular
Arrows
Regular
DoubleStruck
Regular
Fraktur
Regular
Latin
Regular
Main
Regular
Marks
Regular
Misc
Regular
Monospace
Regular
NonUnicode
Regular
Normal
Regular
Operators
Regular
SansSerif
Regular
Script
Regular
Shapes
Regular
Size1
Regular
Size2
Regular
Size3
Regular
Size4
Regular
Size5
Regular
Size6
Regular
Size7
Regular
Symbols
Regular
Variants
Regular
Neo-Euler
Alphabets
Regular
Arrows
Regular
Fraktur
Regular
Main
Regular
Marks
Regular
NonUnicode
Regular
Normal
Regular
Operators
Regular
Script
Regular
Shapes
Regular
Size1
Regular
Size2
Regular
Size3
Regular
Size4
Regular
Size5
Regular
Symbols
Regular
Variants
Regular
STIX-Web
Alphabets
Arrows
DoubleStruck
Fraktur
Latin
Main
Marks
Misc
Monospace
Regular
Normal
Operators
SansSerif
Script
Shapes
Size1
Regular
Size2
Regular
Size3
Regular
Size4
Regular
Size5
Regular
Symbols
Variants
fontdata-extra.jsfontdata.jsSTIX
General
Bold
AlphaPresentForms.jsArrows.jsBBBold.jsBoldFraktur.jsBoxDrawing.jsCombDiacritMarks.jsCombDiactForSymbols.jsControlPictures.jsCurrencySymbols.jsCyrillic.jsEnclosedAlphanum.jsGeneralPunctuation.jsGeometricShapes.jsGreekAndCoptic.jsGreekBold.jsGreekSSBold.jsIPAExtensions.jsLatin1Supplement.jsLatinExtendedA.jsLatinExtendedAdditional.jsLatinExtendedB.jsLatinExtendedD.jsLetterlikeSymbols.jsMain.jsMathBold.jsMathOperators.jsMathSSBold.jsMiscMathSymbolsA.jsMiscMathSymbolsB.jsMiscSymbols.jsMiscTechnical.jsNumberForms.jsPhoneticExtensions.jsSpacingModLetters.jsSuperAndSubscripts.jsSuppMathOperators.js
BoldItalic
AlphaPresentForms.jsBasicLatin.jsBoxDrawing.jsCombDiactForSymbols.jsControlPictures.jsCurrencySymbols.jsCyrillic.jsEnclosedAlphanum.jsGeneralPunctuation.jsGreekAndCoptic.jsGreekBoldItalic.jsGreekSSBoldItalic.jsIPAExtensions.jsLatin1Supplement.jsLatinExtendedA.jsLatinExtendedAdditional.jsLatinExtendedB.jsLetterlikeSymbols.jsMain.jsMathBoldItalic.jsMathBoldScript.jsMathOperators.jsMathSSItalicBold.jsSpacingModLetters.js
Italic
AlphaPresentForms.jsBoxDrawing.jsCombDiactForSymbols.jsControlPictures.jsCurrencySymbols.jsCyrillic.jsEnclosedAlphanum.jsGeneralPunctuation.jsGreekAndCoptic.jsGreekItalic.jsIPAExtensions.jsLatin1Supplement.jsLatinExtendedA.jsLatinExtendedAdditional.jsLatinExtendedB.jsLetterlikeSymbols.jsMain.jsMathItalic.jsMathOperators.jsMathSSItalic.jsMathScript.jsSpacingModLetters.jsij.js
Regular
AlphaPresentForms.jsArrows.jsBBBold.jsBlockElements.jsBoldFraktur.jsBoxDrawing.jsCJK.jsCombDiacritMarks.jsCombDiactForSymbols.jsControlPictures.jsCurrencySymbols.jsCyrillic.jsDingbats.jsEnclosedAlphanum.jsFraktur.jsGeneralPunctuation.jsGeometricShapes.jsGreekAndCoptic.jsGreekBold.jsGreekBoldItalic.jsGreekItalic.jsGreekSSBold.jsGreekSSBoldItalic.jsHiragana.jsIPAExtensions.jsLatin1Supplement.jsLatinExtendedA.jsLatinExtendedAdditional.jsLatinExtendedB.jsLatinExtendedD.jsLetterlikeSymbols.jsMain.jsMathBold.jsMathBoldItalic.jsMathBoldScript.jsMathItalic.jsMathOperators.jsMathSS.jsMathSSBold.jsMathSSItalic.jsMathSSItalicBold.jsMathScript.jsMathTT.jsMiscMathSymbolsA.jsMiscMathSymbolsB.jsMiscSymbols.jsMiscSymbolsAndArrows.jsMiscTechnical.jsNumberForms.jsPhoneticExtensions.jsSpacingModLetters.jsSpecials.jsSuperAndSubscripts.jsSuppMathOperators.jsSupplementalArrowsA.jsSupplementalArrowsB.jsij.js
IntegralsD
IntegralsSm
IntegralsUp
IntegralsUpD
IntegralsUpSm
NonUnicode
Bold
BoldItalic
Italic
Regular
SizeFiveSym
SizeFourSym
SizeOneSym
SizeThreeSym
SizeTwoSym
Variants
fontdata-1.0.jsfontdata-beta.jsfontdata-extra.jsfontdata.jsTeX
AMS
Regular
Arrows.jsBBBold.jsBoxDrawing.jsCombDiacritMarks.jsDingbats.jsEnclosedAlphanum.jsGeneralPunctuation.jsGeometricShapes.jsGreekAndCoptic.jsLatin1Supplement.jsLatinExtendedA.jsLetterlikeSymbols.jsMain.jsMathOperators.jsMiscMathSymbolsB.jsMiscSymbols.jsMiscTechnical.jsPUA.jsSpacingModLetters.jsSuppMathOperators.js
Caligraphic
Fraktur
Greek
Main
Bold
Arrows.jsCombDiacritMarks.jsCombDiactForSymbols.jsGeneralPunctuation.jsGeometricShapes.jsLatin1Supplement.jsLatinExtendedA.jsLatinExtendedB.jsLetterlikeSymbols.jsMain.jsMathOperators.jsMiscMathSymbolsA.jsMiscSymbols.jsMiscTechnical.jsSpacingModLetters.jsSuppMathOperators.jsSupplementalArrowsA.js
Italic
Regular
Math
SansSerif
Bold
Italic
Regular
Script
Regular
Size1
Regular
Size2
Regular
Size3
Regular
Size4
Regular
Typewriter
WinChrome
Regular
WinIE6
fontdata-extra.jsfontdata.jsace
ace.jsext-beautify.jsext-chromevox.jsext-elastic_tabstops_lite.jsext-emmet.jsext-error_marker.jsext-keybinding_menu.jsext-language_tools.jsext-linking.jsext-modelist.jsext-old_ie.jsext-searchbox.jsext-settings_menu.jsext-spellcheck.jsext-split.jsext-static_highlight.jsext-statusbar.jsext-textarea.jsext-themelist.jsext-whitespace.jskeybinding-emacs.jskeybinding-vim.jsmode-abap.jsmode-actionscript.jsmode-ada.jsmode-apache_conf.jsmode-applescript.jsmode-asciidoc.jsmode-assembly_x86.jsmode-autohotkey.jsmode-batchfile.jsmode-c9search.jsmode-c_cpp.jsmode-cirru.jsmode-clojure.jsmode-cobol.jsmode-coffee.jsmode-coldfusion.jsmode-csharp.jsmode-css.jsmode-curly.jsmode-d.jsmode-dart.jsmode-diff.jsmode-django.jsmode-dockerfile.jsmode-dot.jsmode-eiffel.jsmode-ejs.jsmode-erlang.jsmode-forth.jsmode-ftl.jsmode-gcode.jsmode-gherkin.jsmode-gitignore.jsmode-glsl.jsmode-golang.jsmode-groovy.jsmode-haml.jsmode-handlebars.jsmode-haskell.jsmode-haxe.jsmode-html.jsmode-html_ruby.jsmode-ini.jsmode-io.jsmode-jack.jsmode-jade.jsmode-java.jsmode-javascript.jsmode-json.jsmode-jsoniq.jsmode-jsp.jsmode-jsx.jsmode-julia.jsmode-latex.jsmode-less.jsmode-liquid.jsmode-lisp.jsmode-livescript.jsmode-logiql.jsmode-lsl.jsmode-lua.jsmode-luapage.jsmode-lucene.jsmode-makefile.jsmode-markdown.jsmode-matlab.jsmode-mel.jsmode-mushcode.jsmode-mysql.jsmode-nix.jsmode-objectivec.jsmode-ocaml.jsmode-pascal.jsmode-perl.jsmode-pgsql.jsmode-php.jsmode-plain_text.jsmode-powershell.jsmode-praat.jsmode-prolog.jsmode-properties.jsmode-protobuf.jsmode-python.jsmode-r.jsmode-rdoc.jsmode-rhtml.jsmode-ruby.jsmode-rust.jsmode-sass.jsmode-scad.jsmode-scala.jsmode-scheme.jsmode-scss.jsmode-sh.jsmode-sjs.jsmode-smarty.jsmode-snippets.jsmode-soy_template.jsmode-space.jsmode-sql.jsmode-stylus.jsmode-svg.jsmode-tcl.jsmode-tex.jsmode-text.jsmode-textile.jsmode-toml.jsmode-twig.jsmode-typescript.jsmode-vala.jsmode-vbscript.jsmode-velocity.jsmode-verilog.jsmode-vhdl.jsmode-xml.jsmode-xquery.jsmode-yaml.js
snippets
abap.jsactionscript.jsada.jsapache_conf.jsapplescript.jsasciidoc.jsassembly_x86.jsautohotkey.jsbatchfile.jsc9search.jsc_cpp.jscirru.jsclojure.jscobol.jscoffee.jscoldfusion.jscsharp.jscss.jscurly.jsd.jsdart.jsdiff.jsdjango.jsdockerfile.jsdot.jseiffel.jsejs.jserlang.jsforth.jsftl.jsgcode.jsgherkin.jsgitignore.jsglsl.jsgolang.jsgroovy.jshaml.jshandlebars.jshaskell.jshaxe.jshtml.jshtml_ruby.jsini.jsio.jsjack.jsjade.jsjava.jsjavascript.jsjson.jsjsoniq.jsjsp.jsjsx.jsjulia.jslatex.jsless.jsliquid.jslisp.jslivescript.jslogiql.jslsl.jslua.jsluapage.jslucene.jsmakefile.jsmarkdown.jsmatlab.jsmel.jsmushcode.jsmysql.jsnix.jsobjectivec.jsocaml.jspascal.jsperl.jspgsql.jsphp.jsplain_text.jspowershell.jspraat.jsprolog.jsproperties.jsprotobuf.jspython.jsr.jsrdoc.jsrhtml.jsruby.jsrust.jssass.jsscad.jsscala.jsscheme.jsscss.jssh.jssjs.jssmarty.jssnippets.jssoy_template.jsspace.jssql.jsstylus.jssvg.jstcl.jstex.jstext.jstextile.jstoml.jstwig.jstypescript.jsvala.jsvbscript.jsvelocity.jsverilog.jsvhdl.jsxml.jsxquery.jsyaml.js
theme-ambiance.jstheme-chaos.jstheme-chrome.jstheme-clouds.jstheme-clouds_midnight.jstheme-cobalt.jstheme-crimson_editor.jstheme-dawn.jstheme-dreamweaver.jstheme-eclipse.jstheme-github.jstheme-idle_fingers.jstheme-katzenmilch.jstheme-kr.jstheme-kr_theme.jstheme-kuroir.jstheme-merbivore.jstheme-merbivore_soft.jstheme-mono_industrial.jstheme-monokai.jstheme-pastel_on_dark.jstheme-solarized_dark.jstheme-solarized_light.jstheme-terminal.jstheme-textmate.jstheme-tomorrow.jstheme-tomorrow_night.jstheme-tomorrow_night_blue.jstheme-tomorrow_night_bright.jstheme-tomorrow_night_eighties.jstheme-twilight.jstheme-vibrant_ink.jstheme-xcode.jsworker-coffee.jsworker-css.jsworker-html.jsworker-javascript.jsworker-json.jsworker-lua.jsworker-php.jsworker-xquery.jsmdeditor
css
bootstrap-responsive.cssbootstrap.cssindex2.html
smoothness
images
animated-overlay.gifui-bg_flat_0_aaaaaa_40x100.pngui-bg_flat_75_ffffff_40x100.pngui-bg_glass_55_fbf9ee_1x400.pngui-bg_glass_65_ffffff_1x400.pngui-bg_glass_75_dadada_1x400.pngui-bg_glass_75_e6e6e6_1x400.pngui-bg_glass_95_fef1ec_1x400.pngui-bg_highlight-soft_75_cccccc_1x100.pngui-icons_222222_256x240.pngui-icons_2e83ff_256x240.pngui-icons_454545_256x240.pngui-icons_888888_256x240.pngui-icons_cd0a0a_256x240.png
jquery-ui-1.10.2.custom.cssjquery-ui-1.10.2.custom.min.csseditor
editor-min.jseditor.js
google-code-prettify
lang-apollo.jslang-basic.jslang-clj.jslang-css.jslang-dart.jslang-erlang.jslang-go.jslang-hs.jslang-lisp.jslang-llvm.jslang-lua.jslang-matlab.jslang-ml.jslang-mumps.jslang-n.jslang-pascal.jslang-proto.jslang-r.jslang-rd.jslang-scala.jslang-sql.jslang-tcl.jslang-tex.jslang-vb.jslang-vhdl.jslang-wiki.jslang-xq.jslang-yaml.jsmine.cssprettify.cssprettify.jsrun_prettify.js
mdeditor.jsimg
member
css
js
ace
ck
ace-min.jsext-beautify-min.jsext-chromevox-min.jsext-elastic_tabstops_lite-min.jsext-emmet-min.jsext-error_marker-min.jsext-keybinding_menu-min.jsext-language_tools-min.jsext-linking-min.jsext-modelist-min.jsext-old_ie-min.jsext-prompt-min.jsext-searchbox-min.jsext-settings_menu-min.jsext-spellcheck-min.jsext-split-min.jsext-static_highlight-min.jsext-statusbar-min.jsext-textarea-min.jsext-themelist-min.jsext-whitespace-min.jskeybinding-emacs-min.jskeybinding-vim-min.jsmode-abap-min.jsmode-actionscript-min.jsmode-ada-min.jsmode-apache_conf-min.jsmode-applescript-min.jsmode-asciidoc-min.jsmode-assembly_x86-min.jsmode-autohotkey-min.jsmode-batchfile-min.jsmode-c9search-min.jsmode-c_cpp-min.jsmode-cirru-min.jsmode-clojure-min.jsmode-cobol-min.jsmode-coffee-min.jsmode-coldfusion-min.jsmode-csharp-min.jsmode-css-min.jsmode-curly-min.jsmode-d-min.jsmode-dart-min.jsmode-diff-min.jsmode-django-min.jsmode-dockerfile-min.jsmode-dot-min.jsmode-ejs-min.jsmode-erlang-min.jsmode-forth-min.jsmode-ftl-min.jsmode-gherkin-min.jsmode-glsl-min.jsmode-golang-min.jsmode-groovy-min.jsmode-haml-min.jsmode-handlebars-min.jsmode-haskell-min.jsmode-haxe-min.jsmode-html-min.jsmode-html_completions-min.jsmode-html_ruby-min.jsmode-ini-min.jsmode-jack-min.jsmode-jade-min.jsmode-java-min.jsmode-javascript-min.jsmode-json-min.jsmode-jsoniq-min.jsmode-jsp-min.jsmode-jsx-min.jsmode-julia-min.jsmode-latex-min.jsmode-less-min.jsmode-liquid-min.jsmode-lisp-min.jsmode-livescript-min.jsmode-logiql-min.jsmode-lsl-min.jsmode-lua-min.jsmode-luapage-min.jsmode-lucene-min.jsmode-makefile-min.jsmode-markdown-min.jsmode-matlab-min.jsmode-mel-min.jsmode-mushcode-min.jsmode-mushcode_high_rules-min.jsmode-mysql-min.jsmode-nix-min.jsmode-objectivec-min.jsmode-ocaml-min.jsmode-pascal-min.jsmode-perl-min.jsmode-pgsql-min.jsmode-php-min.jsmode-plain_text-min.jsmode-powershell-min.jsmode-prolog-min.jsmode-properties-min.jsmode-protobuf-min.jsmode-python-min.jsmode-r-min.jsmode-rdoc-min.jsmode-rhtml-min.jsmode-ruby-min.jsmode-rust-min.jsmode-sass-min.jsmode-scad-min.jsmode-scala-min.jsmode-scheme-min.jsmode-scss-min.jsmode-sh-min.jsmode-sjs-min.jsmode-smarty-min.jsmode-snippets-min.jsmode-soy_template-min.jsmode-space-min.jsmode-sql-min.jsmode-stylus-min.jsmode-svg-min.jsmode-tcl-min.jsmode-tex-min.jsmode-textile-min.jsmode-toml-min.jsmode-twig-min.jsmode-typescript-min.jsmode-vala-min.jsmode-vbscript-min.jsmode-verilog-min.jsmode-vhdl-min.jsmode-xml-min.jsmode-yaml-min.js
mode-abap.jsmode-actionscript.jsmode-ada.jsmode-apache_conf.jsmode-applescript.jsmode-asciidoc.jsmode-assembly_x86.jsmode-autohotkey.jsmode-batchfile.jsmode-c9search.jsmode-c_cpp.jsmode-cirru.jsmode-clojure.jsmode-cobol.jsmode-coffee.jsmode-coldfusion.jsmode-csharp.jsmode-curly.jsmode-d.jsmode-dart.jsmode-diff.jsmode-django.jsmode-dockerfile.jsmode-dot.jsmode-ejs.jsmode-erlang.jsmode-forth.jsmode-ftl.jsmode-gherkin.jsmode-glsl.jsmode-golang.jsmode-groovy.jsmode-haml.jsmode-handlebars.jsmode-haskell.jsmode-haxe.jsmode-html_completions.jsmode-html_ruby.jsmode-ini.jsmode-jack.jsmode-jade.jsmode-java.jsmode-json.jsmode-jsoniq.jsmode-jsp.jsmode-jsx.jsmode-julia.jsmode-latex.jsmode-liquid.jsmode-lisp.jsmode-livescript.jsmode-logiql.jsmode-lsl.jsmode-lua.jsmode-luapage.jsmode-lucene.jsmode-makefile.jsmode-markdown.jsmode-matlab.jsmode-mel.jsmode-mushcode.jsmode-mushcode_high_rules.jsmode-mysql.jsmode-nix.jsmode-objectivec.jsmode-ocaml.jsmode-pascal.jsmode-perl.jsmode-pgsql.jsmode-php.jsmode-plain_text.jsmode-powershell.jsmode-prolog.jsmode-properties.jsmode-protobuf.jsmode-python.jsmode-r.jsmode-rdoc.jsmode-rhtml.jsmode-ruby.jsmode-rust.jsmode-sass.jsmode-scad.jsmode-scala.jsmode-scheme.jsmode-scss.jsmode-sh.jsmode-sjs.jsmode-smarty.jsmode-snippets.jsmode-soy_template.jsmode-space.jsmode-sql.jsmode-stylus.jsmode-svg.jsmode-tcl.jsmode-tex.jsmode-textile.jsmode-toml.jsmode-twig.jsmode-typescript.jsmode-vala.jsmode-vbscript.jsmode-velocity.jsmode-verilog.jsmode-vhdl.jsmode-xml.jsmode-xquery.jsmode-yaml.jssnippets
abap.jsactionscript.jsada.jsapache_conf.jsapplescript.jsasciidoc.jsassembly_x86.jsautohotkey.jsbatchfile.jsc9search.jsc_cpp.jscirru.js
theme-ambiance.jstheme-chaos.jstheme-chrome.jstheme-cloud9_day.jstheme-cloud9_night.jstheme-cloud9_night_low_color.jstheme-clouds.jstheme-clouds_midnight.jstheme-cobalt.jstheme-crimson_editor.jstheme-dawn.jstheme-dreamweaver.jstheme-eclipse.jstheme-github.jstheme-idle_fingers.jstheme-katzenmilch.jstheme-kr.jstheme-kuroir.jstheme-merbivore.jstheme-merbivore_soft.jstheme-mono_industrial.jstheme-monokai.jstheme-pastel_on_dark.jstheme-solarized_dark.jstheme-solarized_light.jstheme-terminal.jstheme-textmate.jstheme-tomorrow_night.jstheme-tomorrow_night_blue.jstheme-tomorrow_night_bright.jstheme-tomorrow_night_eighties.jstheme-twilight.jstheme-vibrant_ink.jstheme-xcode.jsck
abap-min.jsactionscript-min.jsada-min.jsapache_conf-min.jsapplescript-min.jsasciidoc-min.jsassembly_x86-min.jsautohotkey-min.jsbatchfile-min.jsc9search-min.jsc_cpp-min.jscirru-min.jsclojure-min.jscobol-min.jscoffee-min.jscoldfusion-min.jscsharp-min.jscss-min.jscurly-min.jsd-min.jsdart-min.jsdiff-min.jsdjango-min.jsdockerfile-min.jsdot-min.jsejs-min.jserlang-min.jsforth-min.jsftl-min.jsgherkin-min.jsglsl-min.jsgolang-min.jsgroovy-min.jshaml-min.jshandlebars-min.jshaskell-min.jshaxe-min.jshtml-min.jshtml_completions-min.jshtml_ruby-min.jsini-min.jsjack-min.jsjade-min.jsjava-min.jsjavascript-min.jsjson-min.jsjsoniq-min.jsjsp-min.jsjsx-min.jsjulia-min.jslatex-min.jsless-min.jsliquid-min.jslisp-min.jslivescript-min.jslogiql-min.jslsl-min.jslua-min.jsluapage-min.jslucene-min.jsmakefile-min.jsmarkdown-min.jsmatlab-min.jsmel-min.jsmushcode-min.jsmushcode_high_rules-min.jsmysql-min.jsnix-min.jsocaml-min.jspascal-min.jsperl-min.jspgsql-min.jsplain_text-min.jspowershell-min.jsprolog-min.jsproperties-min.jspython-min.jsr-min.jsrdoc-min.jsrhtml-min.jsruby-min.jsrust-min.jsscad-min.jsscheme-min.jsscss-min.jssh-min.jssmarty-min.jssnippets-min.jssoy_template-min.jsspace-min.jsstylus-min.jssvg-min.js
clojure.jscobol.jscoffee.jscoldfusion.jscsharp.jscurly.jsd.jsdart.jsdiff.jsdjango.jsdockerfile.jsdot.jsejs.jserlang.jsforth.jsftl.jsgherkin.jsglsl.jsgolang.jsgroovy.jshaml.jshandlebars.jshaskell.jshaxe.jshtml_completions.jshtml_ruby.jsini.jsjack.jsjade.jsjava.jsjson.jsjsoniq.jsjsp.jsjsx.jsjulia.jslatex.jsliquid.jslisp.jslivescript.jslogiql.jslsl.jslua.jsluapage.jslucene.jsmakefile.jsmarkdown.jsmatlab.jsmel.jsmushcode.jsmushcode_high_rules.jsmysql.jsnix.jsobjectivec.jsocaml.jspascal.jsperl.jspgsql.jsphp.jsplain_text.jspowershell.jsprolog.jsproperties.jsprotobuf.jspython.jsr.jsrdoc.jsrhtml.jsruby.jsrust.jssass.jsscad.jsscala.jsscheme.jsscss.jssh.jssjs.jssmarty.jssnippets.jssoy_template.jsspace.jssql.jsstylus.jssvg.jstcl.jstex.jstextile.jstoml.jstwig.jstypescript.jsvala.jsvbscript.jsvelocity.jsverilog.jsvhdl.jsxml.jsxquery.jsyaml.jstinymce
classes
langs
plugins
codemirror
leanote_code
leanote_code2
leanote_nav
leanote_nav2
leaui_image
paste
spellchecker
table
themes
modern
1
public/js/ZeroClipboard/ZeroClipboard-min.js
vendored
1
public/js/ZeroClipboard/ZeroClipboard-min.js
vendored
File diff suppressed because one or more lines are too long
@ -1,458 +0,0 @@
|
||||
/*!
|
||||
* ZeroClipboard
|
||||
* The ZeroClipboard library provides an easy way to copy text to the clipboard using an invisible Adobe Flash movie and a JavaScript interface.
|
||||
* Copyright (c) 2013 Jon Rohan, James M. Greene
|
||||
* Licensed MIT
|
||||
* http://zeroclipboard.org/
|
||||
* v1.2.0-beta.4
|
||||
*/
|
||||
(function() {
|
||||
"use strict";
|
||||
var _camelizeCssPropName = function() {
|
||||
var matcherRegex = /\-([a-z])/g, replacerFn = function(match, group) {
|
||||
return group.toUpperCase();
|
||||
};
|
||||
return function(prop) {
|
||||
return prop.replace(matcherRegex, replacerFn);
|
||||
};
|
||||
}();
|
||||
var _getStyle = function(el, prop) {
|
||||
var value, camelProp, tagName, possiblePointers, i, len;
|
||||
if (window.getComputedStyle) {
|
||||
value = window.getComputedStyle(el, null).getPropertyValue(prop);
|
||||
} else {
|
||||
camelProp = _camelizeCssPropName(prop);
|
||||
if (el.currentStyle) {
|
||||
value = el.currentStyle[camelProp];
|
||||
} else {
|
||||
value = el.style[camelProp];
|
||||
}
|
||||
}
|
||||
if (prop === "cursor") {
|
||||
if (!value || value === "auto") {
|
||||
tagName = el.tagName.toLowerCase();
|
||||
possiblePointers = [ "a" ];
|
||||
for (i = 0, len = possiblePointers.length; i < len; i++) {
|
||||
if (tagName === possiblePointers[i]) {
|
||||
return "pointer";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return value;
|
||||
};
|
||||
var _elementMouseOver = function(event) {
|
||||
if (!ZeroClipboard.prototype._singleton) return;
|
||||
if (!event) {
|
||||
event = window.event;
|
||||
}
|
||||
var target;
|
||||
if (this !== window) {
|
||||
target = this;
|
||||
} else if (event.target) {
|
||||
target = event.target;
|
||||
} else if (event.srcElement) {
|
||||
target = event.srcElement;
|
||||
}
|
||||
ZeroClipboard.prototype._singleton.setCurrent(target);
|
||||
};
|
||||
var _addEventHandler = function(element, method, func) {
|
||||
if (element.addEventListener) {
|
||||
element.addEventListener(method, func, false);
|
||||
} else if (element.attachEvent) {
|
||||
element.attachEvent("on" + method, func);
|
||||
}
|
||||
};
|
||||
var _removeEventHandler = function(element, method, func) {
|
||||
if (element.removeEventListener) {
|
||||
element.removeEventListener(method, func, false);
|
||||
} else if (element.detachEvent) {
|
||||
element.detachEvent("on" + method, func);
|
||||
}
|
||||
};
|
||||
var _addClass = function(element, value) {
|
||||
if (element.addClass) {
|
||||
element.addClass(value);
|
||||
return element;
|
||||
}
|
||||
if (value && typeof value === "string") {
|
||||
var classNames = (value || "").split(/\s+/);
|
||||
if (element.nodeType === 1) {
|
||||
if (!element.className) {
|
||||
element.className = value;
|
||||
} else {
|
||||
var className = " " + element.className + " ", setClass = element.className;
|
||||
for (var c = 0, cl = classNames.length; c < cl; c++) {
|
||||
if (className.indexOf(" " + classNames[c] + " ") < 0) {
|
||||
setClass += " " + classNames[c];
|
||||
}
|
||||
}
|
||||
element.className = setClass.replace(/^\s+|\s+$/g, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
return element;
|
||||
};
|
||||
var _removeClass = function(element, value) {
|
||||
if (element.removeClass) {
|
||||
element.removeClass(value);
|
||||
return element;
|
||||
}
|
||||
if (value && typeof value === "string" || value === undefined) {
|
||||
var classNames = (value || "").split(/\s+/);
|
||||
if (element.nodeType === 1 && element.className) {
|
||||
if (value) {
|
||||
var className = (" " + element.className + " ").replace(/[\n\t]/g, " ");
|
||||
for (var c = 0, cl = classNames.length; c < cl; c++) {
|
||||
className = className.replace(" " + classNames[c] + " ", " ");
|
||||
}
|
||||
element.className = className.replace(/^\s+|\s+$/g, "");
|
||||
} else {
|
||||
element.className = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
return element;
|
||||
};
|
||||
var _getZoomFactor = function() {
|
||||
var rect, physicalWidth, logicalWidth, zoomFactor = 1;
|
||||
if (typeof document.body.getBoundingClientRect === "function") {
|
||||
rect = document.body.getBoundingClientRect();
|
||||
physicalWidth = rect.right - rect.left;
|
||||
logicalWidth = document.body.offsetWidth;
|
||||
zoomFactor = Math.round(physicalWidth / logicalWidth * 100) / 100;
|
||||
}
|
||||
return zoomFactor;
|
||||
};
|
||||
var _getDOMObjectPosition = function(obj) {
|
||||
var info = {
|
||||
left: 0,
|
||||
top: 0,
|
||||
width: 0,
|
||||
height: 0,
|
||||
zIndex: 999999999
|
||||
};
|
||||
var zi = _getStyle(obj, "z-index");
|
||||
if (zi && zi !== "auto") {
|
||||
info.zIndex = parseInt(zi, 10);
|
||||
}
|
||||
if (obj.getBoundingClientRect) {
|
||||
var rect = obj.getBoundingClientRect();
|
||||
var pageXOffset, pageYOffset, zoomFactor;
|
||||
if ("pageXOffset" in window && "pageYOffset" in window) {
|
||||
pageXOffset = window.pageXOffset;
|
||||
pageYOffset = window.pageYOffset;
|
||||
} else {
|
||||
zoomFactor = _getZoomFactor();
|
||||
pageXOffset = Math.round(document.documentElement.scrollLeft / zoomFactor);
|
||||
pageYOffset = Math.round(document.documentElement.scrollTop / zoomFactor);
|
||||
}
|
||||
var leftBorderWidth = document.documentElement.clientLeft || 0;
|
||||
var topBorderWidth = document.documentElement.clientTop || 0;
|
||||
info.left = rect.left + pageXOffset - leftBorderWidth;
|
||||
info.top = rect.top + pageYOffset - topBorderWidth;
|
||||
info.width = "width" in rect ? rect.width : rect.right - rect.left;
|
||||
info.height = "height" in rect ? rect.height : rect.bottom - rect.top;
|
||||
}
|
||||
return info;
|
||||
};
|
||||
var _noCache = function(path, options) {
|
||||
var useNoCache = !(options && options.useNoCache === false);
|
||||
if (useNoCache) {
|
||||
return (path.indexOf("?") === -1 ? "?" : "&") + "nocache=" + new Date().getTime();
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
};
|
||||
var _vars = function(options) {
|
||||
var str = [];
|
||||
var origins = [];
|
||||
if (options.trustedOrigins) {
|
||||
if (typeof options.trustedOrigins === "string") {
|
||||
origins = origins.push(options.trustedOrigins);
|
||||
} else if (typeof options.trustedOrigins === "object" && "length" in options.trustedOrigins) {
|
||||
origins = origins.concat(options.trustedOrigins);
|
||||
}
|
||||
}
|
||||
if (options.trustedDomains) {
|
||||
if (typeof options.trustedDomains === "string") {
|
||||
origins = origins.push(options.trustedDomains);
|
||||
} else if (typeof options.trustedDomains === "object" && "length" in options.trustedDomains) {
|
||||
origins = origins.concat(options.trustedDomains);
|
||||
}
|
||||
}
|
||||
if (origins.length) {
|
||||
str.push("trustedOrigins=" + encodeURIComponent(origins.join(",")));
|
||||
}
|
||||
if (typeof options.amdModuleId === "string" && options.amdModuleId) {
|
||||
str.push("amdModuleId=" + encodeURIComponent(options.amdModuleId));
|
||||
}
|
||||
if (typeof options.cjsModuleId === "string" && options.cjsModuleId) {
|
||||
str.push("cjsModuleId=" + encodeURIComponent(options.cjsModuleId));
|
||||
}
|
||||
return str.join("&");
|
||||
};
|
||||
var _inArray = function(elem, array) {
|
||||
if (array.indexOf) {
|
||||
return array.indexOf(elem);
|
||||
}
|
||||
for (var i = 0, length = array.length; i < length; i++) {
|
||||
if (array[i] === elem) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
};
|
||||
var _prepGlue = function(elements) {
|
||||
if (typeof elements === "string") throw new TypeError("ZeroClipboard doesn't accept query strings.");
|
||||
if (!elements.length) return [ elements ];
|
||||
return elements;
|
||||
};
|
||||
var _dispatchCallback = function(func, element, instance, args, async) {
|
||||
if (async) {
|
||||
window.setTimeout(function() {
|
||||
func.call(element, instance, args);
|
||||
}, 0);
|
||||
} else {
|
||||
func.call(element, instance, args);
|
||||
}
|
||||
};
|
||||
var ZeroClipboard = function(elements, options) {
|
||||
if (elements) (ZeroClipboard.prototype._singleton || this).glue(elements);
|
||||
if (ZeroClipboard.prototype._singleton) return ZeroClipboard.prototype._singleton;
|
||||
ZeroClipboard.prototype._singleton = this;
|
||||
this.options = {};
|
||||
for (var kd in _defaults) this.options[kd] = _defaults[kd];
|
||||
for (var ko in options) this.options[ko] = options[ko];
|
||||
this.handlers = {};
|
||||
if (ZeroClipboard.detectFlashSupport()) _bridge();
|
||||
};
|
||||
var currentElement, gluedElements = [];
|
||||
ZeroClipboard.prototype.setCurrent = function(element) {
|
||||
currentElement = element;
|
||||
this.reposition();
|
||||
var titleAttr = element.getAttribute("title");
|
||||
if (titleAttr) {
|
||||
this.setTitle(titleAttr);
|
||||
}
|
||||
var useHandCursor = this.options.forceHandCursor === true || _getStyle(element, "cursor") === "pointer";
|
||||
_setHandCursor.call(this, useHandCursor);
|
||||
};
|
||||
ZeroClipboard.prototype.setText = function(newText) {
|
||||
if (newText && newText !== "") {
|
||||
this.options.text = newText;
|
||||
if (this.ready()) this.flashBridge.setText(newText);
|
||||
}
|
||||
};
|
||||
ZeroClipboard.prototype.setTitle = function(newTitle) {
|
||||
if (newTitle && newTitle !== "") this.htmlBridge.setAttribute("title", newTitle);
|
||||
};
|
||||
ZeroClipboard.prototype.setSize = function(width, height) {
|
||||
if (this.ready()) this.flashBridge.setSize(width, height);
|
||||
};
|
||||
ZeroClipboard.prototype.setHandCursor = function(enabled) {
|
||||
enabled = typeof enabled === "boolean" ? enabled : !!enabled;
|
||||
_setHandCursor.call(this, enabled);
|
||||
this.options.forceHandCursor = enabled;
|
||||
};
|
||||
var _setHandCursor = function(enabled) {
|
||||
if (this.ready()) this.flashBridge.setHandCursor(enabled);
|
||||
};
|
||||
ZeroClipboard.version = "1.2.0-beta.4";
|
||||
var _defaults = {
|
||||
moviePath: "ZeroClipboard.swf",
|
||||
trustedOrigins: null,
|
||||
text: null,
|
||||
hoverClass: "zeroclipboard-is-hover",
|
||||
activeClass: "zeroclipboard-is-active",
|
||||
allowScriptAccess: "sameDomain",
|
||||
useNoCache: true,
|
||||
forceHandCursor: false
|
||||
};
|
||||
ZeroClipboard.setDefaults = function(options) {
|
||||
for (var ko in options) _defaults[ko] = options[ko];
|
||||
};
|
||||
ZeroClipboard.destroy = function() {
|
||||
ZeroClipboard.prototype._singleton.unglue(gluedElements);
|
||||
var bridge = ZeroClipboard.prototype._singleton.htmlBridge;
|
||||
bridge.parentNode.removeChild(bridge);
|
||||
delete ZeroClipboard.prototype._singleton;
|
||||
};
|
||||
ZeroClipboard.detectFlashSupport = function() {
|
||||
var hasFlash = false;
|
||||
if (typeof ActiveXObject === "function") {
|
||||
try {
|
||||
if (new ActiveXObject("ShockwaveFlash.ShockwaveFlash")) {
|
||||
hasFlash = true;
|
||||
}
|
||||
} catch (error) {}
|
||||
}
|
||||
if (!hasFlash && navigator.mimeTypes["application/x-shockwave-flash"]) {
|
||||
hasFlash = true;
|
||||
}
|
||||
return hasFlash;
|
||||
};
|
||||
var _amdModuleId = null;
|
||||
var _cjsModuleId = null;
|
||||
var _bridge = function() {
|
||||
var client = ZeroClipboard.prototype._singleton;
|
||||
var container = document.getElementById("global-zeroclipboard-html-bridge");
|
||||
if (!container) {
|
||||
var opts = {};
|
||||
for (var ko in client.options) opts[ko] = client.options[ko];
|
||||
opts.amdModuleId = _amdModuleId;
|
||||
opts.cjsModuleId = _cjsModuleId;
|
||||
var flashvars = _vars(opts);
|
||||
var html = ' <object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" id="global-zeroclipboard-flash-bridge" width="100%" height="100%"> <param name="movie" value="' + client.options.moviePath + _noCache(client.options.moviePath, client.options) + '"/> <param name="allowScriptAccess" value="' + client.options.allowScriptAccess + '"/> <param name="scale" value="exactfit"/> <param name="loop" value="false"/> <param name="menu" value="false"/> <param name="quality" value="best" /> <param name="bgcolor" value="#ffffff"/> <param name="wmode" value="transparent"/> <param name="flashvars" value="' + flashvars + '"/> <embed src="' + client.options.moviePath + _noCache(client.options.moviePath, client.options) + '" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="100%" height="100%" name="global-zeroclipboard-flash-bridge" allowScriptAccess="always" allowFullScreen="false" type="application/x-shockwave-flash" wmode="transparent" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="' + flashvars + '" scale="exactfit"> </embed> </object>';
|
||||
container = document.createElement("div");
|
||||
container.id = "global-zeroclipboard-html-bridge";
|
||||
container.setAttribute("class", "global-zeroclipboard-container");
|
||||
container.setAttribute("data-clipboard-ready", false);
|
||||
container.style.position = "absolute";
|
||||
container.style.left = "-9999px";
|
||||
container.style.top = "-9999px";
|
||||
container.style.width = "15px";
|
||||
container.style.height = "15px";
|
||||
container.style.zIndex = "9999";
|
||||
container.innerHTML = html;
|
||||
document.body.appendChild(container);
|
||||
}
|
||||
client.htmlBridge = container;
|
||||
client.flashBridge = document["global-zeroclipboard-flash-bridge"] || container.children[0].lastElementChild;
|
||||
};
|
||||
ZeroClipboard.prototype.resetBridge = function() {
|
||||
this.htmlBridge.style.left = "-9999px";
|
||||
this.htmlBridge.style.top = "-9999px";
|
||||
this.htmlBridge.removeAttribute("title");
|
||||
this.htmlBridge.removeAttribute("data-clipboard-text");
|
||||
_removeClass(currentElement, this.options.activeClass);
|
||||
currentElement = null;
|
||||
this.options.text = null;
|
||||
};
|
||||
ZeroClipboard.prototype.ready = function() {
|
||||
var ready = this.htmlBridge.getAttribute("data-clipboard-ready");
|
||||
return ready === "true" || ready === true;
|
||||
};
|
||||
ZeroClipboard.prototype.reposition = function() {
|
||||
if (!currentElement) return false;
|
||||
var pos = _getDOMObjectPosition(currentElement);
|
||||
this.htmlBridge.style.top = pos.top + "px";
|
||||
this.htmlBridge.style.left = pos.left + "px";
|
||||
this.htmlBridge.style.width = pos.width + "px";
|
||||
this.htmlBridge.style.height = pos.height + "px";
|
||||
this.htmlBridge.style.zIndex = pos.zIndex + 1;
|
||||
this.setSize(pos.width, pos.height);
|
||||
};
|
||||
ZeroClipboard.dispatch = function(eventName, args) {
|
||||
ZeroClipboard.prototype._singleton.receiveEvent(eventName, args);
|
||||
};
|
||||
ZeroClipboard.prototype.on = function(eventName, func) {
|
||||
var events = eventName.toString().split(/\s/g);
|
||||
for (var i = 0; i < events.length; i++) {
|
||||
eventName = events[i].toLowerCase().replace(/^on/, "");
|
||||
if (!this.handlers[eventName]) this.handlers[eventName] = func;
|
||||
}
|
||||
if (this.handlers.noflash && !ZeroClipboard.detectFlashSupport()) {
|
||||
this.receiveEvent("onNoFlash", null);
|
||||
}
|
||||
};
|
||||
ZeroClipboard.prototype.addEventListener = ZeroClipboard.prototype.on;
|
||||
ZeroClipboard.prototype.off = function(eventName, func) {
|
||||
var events = eventName.toString().split(/\s/g);
|
||||
for (var i = 0; i < events.length; i++) {
|
||||
eventName = events[i].toLowerCase().replace(/^on/, "");
|
||||
for (var event in this.handlers) {
|
||||
if (event === eventName && this.handlers[event] === func) {
|
||||
delete this.handlers[event];
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
ZeroClipboard.prototype.removeEventListener = ZeroClipboard.prototype.off;
|
||||
ZeroClipboard.prototype.receiveEvent = function(eventName, args) {
|
||||
eventName = eventName.toString().toLowerCase().replace(/^on/, "");
|
||||
var element = currentElement;
|
||||
var performCallbackAsync = true;
|
||||
switch (eventName) {
|
||||
case "load":
|
||||
if (args && parseFloat(args.flashVersion.replace(",", ".").replace(/[^0-9\.]/gi, "")) < 10) {
|
||||
this.receiveEvent("onWrongFlash", {
|
||||
flashVersion: args.flashVersion
|
||||
});
|
||||
return;
|
||||
}
|
||||
this.htmlBridge.setAttribute("data-clipboard-ready", true);
|
||||
break;
|
||||
|
||||
case "mouseover":
|
||||
_addClass(element, this.options.hoverClass);
|
||||
break;
|
||||
|
||||
case "mouseout":
|
||||
_removeClass(element, this.options.hoverClass);
|
||||
this.resetBridge();
|
||||
break;
|
||||
|
||||
case "mousedown":
|
||||
_addClass(element, this.options.activeClass);
|
||||
break;
|
||||
|
||||
case "mouseup":
|
||||
_removeClass(element, this.options.activeClass);
|
||||
break;
|
||||
|
||||
case "datarequested":
|
||||
var targetId = element.getAttribute("data-clipboard-target"), targetEl = !targetId ? null : document.getElementById(targetId);
|
||||
if (targetEl) {
|
||||
var textContent = targetEl.value || targetEl.textContent || targetEl.innerText;
|
||||
if (textContent) this.setText(textContent);
|
||||
} else {
|
||||
var defaultText = element.getAttribute("data-clipboard-text");
|
||||
if (defaultText) this.setText(defaultText);
|
||||
}
|
||||
performCallbackAsync = false;
|
||||
break;
|
||||
|
||||
case "complete":
|
||||
this.options.text = null;
|
||||
break;
|
||||
}
|
||||
if (this.handlers[eventName]) {
|
||||
var func = this.handlers[eventName];
|
||||
if (typeof func === "string" && typeof window[func] === "function") {
|
||||
func = window[func];
|
||||
}
|
||||
if (typeof func === "function") {
|
||||
_dispatchCallback(func, element, this, args, performCallbackAsync);
|
||||
}
|
||||
}
|
||||
};
|
||||
ZeroClipboard.prototype.glue = function(elements) {
|
||||
elements = _prepGlue(elements);
|
||||
for (var i = 0; i < elements.length; i++) {
|
||||
if (_inArray(elements[i], gluedElements) == -1) {
|
||||
gluedElements.push(elements[i]);
|
||||
_addEventHandler(elements[i], "mouseover", _elementMouseOver);
|
||||
}
|
||||
}
|
||||
};
|
||||
ZeroClipboard.prototype.unglue = function(elements) {
|
||||
elements = _prepGlue(elements);
|
||||
for (var i = 0; i < elements.length; i++) {
|
||||
_removeEventHandler(elements[i], "mouseover", _elementMouseOver);
|
||||
var arrayIndex = _inArray(elements[i], gluedElements);
|
||||
if (arrayIndex != -1) gluedElements.splice(arrayIndex, 1);
|
||||
}
|
||||
};
|
||||
if (typeof define === "function" && define.amd) {
|
||||
define([ "require", "exports", "module" ], function(require, exports, module) {
|
||||
_amdModuleId = module && module.id || null;
|
||||
return ZeroClipboard;
|
||||
});
|
||||
} else if (typeof module !== "undefined" && module) {
|
||||
_cjsModuleId = module.id || null;
|
||||
module.exports = ZeroClipboard;
|
||||
} else {
|
||||
window.ZeroClipboard = ZeroClipboard;
|
||||
}
|
||||
})();
|
9
public/js/ZeroClipboard/ZeroClipboard.min.js
vendored
9
public/js/ZeroClipboard/ZeroClipboard.min.js
vendored
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
1
public/js/app/attachment_upload-min.js
vendored
Normal file
1
public/js/app/attachment_upload-min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
var urlPrefix=UrlPrefix;define("attachment_upload",["jquery.ui.widget","fileupload"],function(){function formatFileSize(bytes){if(typeof bytes!=="number"){return""}if(bytes>=1e9){return(bytes/1e9).toFixed(2)+" GB"}if(bytes>=1e6){return(bytes/1e6).toFixed(2)+" MB"}return(bytes/1e3).toFixed(2)+" KB"}function setDropStyle(dropzoneId,formId){var dropZone=$(dropzoneId);$(formId).bind("dragover",function(e){e.preventDefault();var timeout=window.dropZoneTimeoutAttach;if(timeout){clearTimeout(timeout)}var found=false,node=e.target;do{if(node===dropZone[0]){found=true;break}node=node.parentNode}while(node!=null);if(found){dropZone.addClass("hover")}else{dropZone.removeClass("hover")}window.dropZoneTimeoutAttach=setTimeout(function(){window.dropZoneTimeoutAttach=null;dropZone.removeClass("in hover")},100)})}setDropStyle("#dropAttach","#uploadAttach");setDropStyle("#dropAvatar","#uploadAvatar");var initUploader=function(){$(".dropzone .btn-choose-file").click(function(){$(this).parent().find("input").click()});var $msg=$("#attachUploadMsg");$("#uploadAttach").fileupload({dataType:"json",pasteZone:"",dropZone:$("#dropAttach"),formData:function(form){return[{name:"noteId",value:Note.curNoteId}]},add:function(e,data){var note=Note.getCurNote();if(!note||note.IsNew){alert("This note hasn't saved, please save it firstly!");return}var tpl=$('<div class="alert alert-info"><img class="loader" src="/tinymce/plugins/leaui_image/public/images/ajax-loader.gif"> <a class="close" data-dismiss="alert">×</a></div>');tpl.append(data.files[0].name+" <small>[<i>"+formatFileSize(data.files[0].size)+"</i>]</small>");$msg.html(tpl);data.context=$msg;var size=data.files[0].size;var maxFileSize=+GlobalConfigs["uploadAttachSize"]||100;if(typeof size=="number"&&size>1024*1024*maxFileSize){tpl.find("img").remove();tpl.removeClass("alert-info").addClass("alert-danger");tpl.append(" Warning: File size is bigger than "+maxFileSize+"M");setTimeout(function(tpl){return function(){tpl.remove()}}(tpl),3e3);return}var jqXHR;setTimeout(function(){jqXHR=data.submit()},10)},done:function(e,data){if(data.result.Ok==true){data.context.html("");Attach.addAttach(data.result.Item)}else{var re=data.result;data.context.html("");var tpl=$('<div class="alert alert-danger"><a class="close" data-dismiss="alert">×</a></div>');tpl.append("<b>Error:</b> "+data.files[0].name+" <small>[<i>"+formatFileSize(data.files[0].size)+"</i>]</small> "+data.result.Msg);data.context.html(tpl);setTimeout(function(tpl){return function(){tpl.remove()}}(tpl),3e3)}$("#uploadAttachMsg").scrollTop(1e3)},fail:function(e,data){data.context.html("");var tpl=$('<div class="alert alert-danger"><a class="close" data-dismiss="alert">×</a></div>');tpl.append("<b>Error:</b> "+data.files[0].name+" <small>[<i>"+formatFileSize(data.files[0].size)+"</i>]</small> "+data.errorThrown);data.context.html(tpl);setTimeout(function(tpl){return function(){tpl.remove()}}(tpl),3e3);$("#uploadAttachMsg").scrollTop(1e3)}});var $msg2=$("#avatarUploadMsg");$("#uploadAvatar").fileupload({dataType:"json",dropZone:$("#dropAvatar"),pasteZone:"",add:function(e,data){var tpl=$('<div class="alert alert-info"><img class="loader" src="/tinymce/plugins/leaui_image/public/images/ajax-loader.gif"> <a class="close" data-dismiss="alert">×</a></div>');tpl.append(data.files[0].name+" <small>[<i>"+formatFileSize(data.files[0].size)+"</i>]</small>");$msg2.html(tpl);data.context=$msg2;var size=data.files[0].size;var maxFileSize=+GlobalConfigs["uploadAvatarSize"]||100;if(typeof size=="number"&&size>1024*1024*maxFileSize){tpl.find("img").remove();tpl.removeClass("alert-info").addClass("alert-danger");tpl.append(" Warning: File size is bigger than "+maxFileSize+"M");setTimeout(function(tpl){return function(){tpl.remove()}}(tpl),3e3);return}var jqXHR;setTimeout(function(){jqXHR=data.submit()},10)},done:function(e,data){if(data.result.Ok==true){data.context.html("");var re=data.result;$("#avatar").attr("src",UrlPrefix+"/"+re.Id)}else{var re=data.result;data.context.html("");var tpl=$('<div class="alert alert-danger"><a class="close" data-dismiss="alert">×</a></div>');tpl.append("<b>Error:</b> "+data.files[0].name+" <small>[<i>"+formatFileSize(data.files[0].size)+"</i>]</small> "+data.result.Msg);data.context.html(tpl);setTimeout(function(tpl){return function(){tpl.remove()}}(tpl),3e3)}},fail:function(e,data){data.context.html("");var tpl=$('<div class="alert alert-danger"><a class="close" data-dismiss="alert">×</a></div>');tpl.append("<b>Error:</b> "+data.files[0].name+" <small>[<i>"+formatFileSize(data.files[0].size)+"</i>]</small> "+data.errorThrown);data.context.html(tpl);setTimeout(function(tpl){return function(){tpl.remove()}}(tpl),3e3)}})};initUploader()});
|
@ -54,11 +54,12 @@ define('attachment_upload', ['jquery.ui.widget', 'fileupload'], function(){
|
||||
$('.dropzone .btn-choose-file').click(function() {
|
||||
$(this).parent().find('input').click();
|
||||
});
|
||||
|
||||
|
||||
var $msg = $('#attachUploadMsg');
|
||||
// Initialize the jQuery File Upload plugin
|
||||
$('#uploadAttach').fileupload({
|
||||
dataType: 'json',
|
||||
pasteZone: '', // 不能通过paste来上传图片
|
||||
// This element will accept file drag/drop uploading
|
||||
dropZone: $('#dropAttach'),
|
||||
formData: function(form) {
|
||||
@ -72,6 +73,7 @@ define('attachment_upload', ['jquery.ui.widget', 'fileupload'], function(){
|
||||
alert("This note hasn't saved, please save it firstly!")
|
||||
return;
|
||||
}
|
||||
|
||||
var tpl = $('<div class="alert alert-info"><img class="loader" src="/tinymce/plugins/leaui_image/public/images/ajax-loader.gif"> <a class="close" data-dismiss="alert">×</a></div>');
|
||||
|
||||
// Append the file name and file size
|
||||
@ -140,11 +142,13 @@ define('attachment_upload', ['jquery.ui.widget', 'fileupload'], function(){
|
||||
});
|
||||
|
||||
//-------------------
|
||||
// 已经过时, 没有avatar了
|
||||
|
||||
var $msg2 = $('#avatarUploadMsg');
|
||||
$('#uploadAvatar').fileupload({
|
||||
dataType: 'json',
|
||||
dropZone: $('#dropAvatar'),
|
||||
pasteZone: '',
|
||||
add: function(e, data) {
|
||||
var tpl = $('<div class="alert alert-info"><img class="loader" src="/tinymce/plugins/leaui_image/public/images/ajax-loader.gif"> <a class="close" data-dismiss="alert">×</a></div>');
|
||||
|
||||
@ -206,7 +210,7 @@ define('attachment_upload', ['jquery.ui.widget', 'fileupload'], function(){
|
||||
})(tpl), 3000);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
initUploader();
|
||||
});
|
1
public/js/app/editor_drop_paste-min.js
vendored
Normal file
1
public/js/app/editor_drop_paste-min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
375
public/js/app/editor_drop_paste.js
Normal file
375
public/js/app/editor_drop_paste.js
Normal file
@ -0,0 +1,375 @@
|
||||
// for editor.
|
||||
// drag image to editor
|
||||
var urlPrefix = UrlPrefix; // window.location.protocol + "//" + window.location.host;
|
||||
define('editor_drop_paste', ['jquery.ui.widget', 'fileupload'], function(){
|
||||
function Process(editor) {
|
||||
var id = '__mcenew' + (new Date()).getTime();
|
||||
var str = '<div contenteditable="false" id="' + id + '" class="leanote-image-container">' +
|
||||
'<img class="loader" src="/images/ajax-loader.gif">' +
|
||||
'<div class="progress">' +
|
||||
'<div class="progress-bar progress-bar-success progress-bar-striped" role="progressbar" aria-valuenow="2" aria-valuemin="0" aria-valuemax="100" style="width: 0%;">' +
|
||||
'0%' +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
'</div>';
|
||||
this.containerStr = str;
|
||||
editor.insertContent(str);
|
||||
var container = $('#' + id);
|
||||
this.container = container;
|
||||
this.id = id;
|
||||
this.processBar = container.find('.progress-bar');
|
||||
}
|
||||
Process.prototype.update = function(process) {
|
||||
var me = this;
|
||||
// 98%, 不要小数
|
||||
process = Math.ceil(process * 100);
|
||||
if(process >= 100) {
|
||||
process = 99;
|
||||
}
|
||||
process += "%";
|
||||
$('#' + me.id + ' .progress-bar').html(process).css('width', process);
|
||||
}
|
||||
Process.prototype.replace = function(src) {
|
||||
var me = this;
|
||||
getImageSize(src, function() {
|
||||
$('#' + me.id).replaceWith('<img src="' + src + '" />');
|
||||
});
|
||||
}
|
||||
Process.prototype.remove = function() {
|
||||
var me = this;
|
||||
$('#' + me.id).remove();
|
||||
}
|
||||
|
||||
// 当url改变时, 得到图片的大小
|
||||
function getImageSize(url, callback) {
|
||||
var img = document.createElement('img');
|
||||
|
||||
function done(width, height) {
|
||||
img.parentNode.removeChild(img);
|
||||
callback({width: width, height: height});
|
||||
}
|
||||
|
||||
img.onload = function() {
|
||||
done(img.clientWidth, img.clientHeight);
|
||||
};
|
||||
|
||||
img.onerror = function() {
|
||||
done();
|
||||
};
|
||||
|
||||
img.src = url;
|
||||
|
||||
var style = img.style;
|
||||
style.visibility = 'hidden';
|
||||
style.position = 'fixed';
|
||||
style.bottom = style.left = 0;
|
||||
style.width = style.height = 'auto';
|
||||
|
||||
document.body.appendChild(img);
|
||||
}
|
||||
|
||||
var i = 1;
|
||||
function insertImage(data) {
|
||||
var editor = tinymce.activeEditor;
|
||||
var dom = editor.dom;
|
||||
|
||||
var renderImage = function(data2) {
|
||||
// 这里, 如果图片宽度过大, 这里设置成500px
|
||||
var d = {};
|
||||
var imgElm;
|
||||
// 先显示loading...
|
||||
d.id = '__mcenew' + (i++);
|
||||
d.src = "http://leanote.com/images/loading-24.gif";
|
||||
imgElm = dom.createHTML('img', d);
|
||||
tinymce.activeEditor.insertContent(imgElm);
|
||||
imgElm = dom.get(d.id);
|
||||
|
||||
function callback (wh) {
|
||||
dom.setAttrib(imgElm, 'src', data2.src);
|
||||
// dom.setAttrib(imgElm, 'width', data2.width);
|
||||
if(data2.title) {
|
||||
dom.setAttrib(imgElm, 'title', data2.title);
|
||||
}
|
||||
|
||||
dom.setAttrib(imgElm, 'id', null);
|
||||
};
|
||||
getImageSize(data.src, callback);
|
||||
}
|
||||
|
||||
//-------------
|
||||
// outputImage?fileId=123232323
|
||||
var fileId = "";
|
||||
fileIds = data.src.split("fileId=")
|
||||
if(fileIds.length == 2 && fileIds[1].length == "53aecf8a8a039a43c8036282".length) {
|
||||
fileId = fileIds[1];
|
||||
}
|
||||
if(fileId) {
|
||||
// 得到fileId, 如果这个笔记不是我的, 那么肯定是协作的笔记, 那么需要将图片copy给原note owner
|
||||
var curNote = Note.getCurNote();
|
||||
if(curNote && curNote.UserId != UserInfo.UserId) {
|
||||
(function(data) {
|
||||
ajaxPost("/file/copyImage", {userId: UserInfo.UserId, fileId: fileId, toUserId: curNote.UserId}, function(re) {
|
||||
if(reIsOk(re) && re.Id) {
|
||||
var urlPrefix = window.location.protocol + "//" + window.location.host;
|
||||
data.src = urlPrefix + "/file/outputImage?fileId=" + re.Id;
|
||||
}
|
||||
renderImage(data);
|
||||
});
|
||||
})(data);
|
||||
} else {
|
||||
renderImage(data);
|
||||
}
|
||||
} else {
|
||||
renderImage(data);
|
||||
}
|
||||
}
|
||||
|
||||
var initUploader = function() {
|
||||
var ul = $('#upload ul');
|
||||
|
||||
$('#drop a').click(function() {
|
||||
// trigger to show file select
|
||||
$(this).parent().find('input').click();
|
||||
});
|
||||
|
||||
// Initialize the jQuery File Upload plugin
|
||||
$('#upload').fileupload({
|
||||
dataType: 'json',
|
||||
pasteZone: '', // 不允许paste
|
||||
acceptFileTypes: /(\.|\/)(gif|jpg|jpeg|png|jpe)$/i,
|
||||
maxFileSize: 210000,
|
||||
|
||||
// This element will accept file drag/drop uploading
|
||||
dropZone: $('#drop'),
|
||||
formData: function(form) {
|
||||
return [{name: 'albumId', value: ""}]
|
||||
},
|
||||
// This function is called when a file is added to the queue;
|
||||
// either via the browse button, or via drag/drop:
|
||||
add: function(e, data) {
|
||||
var tpl = $('<li><div class="alert alert-info"><img class="loader" src="/tinymce/plugins/leaui_image/public/images/ajax-loader.gif"> <a class="close" data-dismiss="alert">×</a></div></li>');
|
||||
|
||||
// Append the file name and file size
|
||||
tpl.find('div').append(data.files[0].name + ' <small>[<i>' + formatFileSize(data.files[0].size) + '</i>]</small>');
|
||||
|
||||
// Add the HTML to the UL element
|
||||
data.context = tpl.appendTo(ul);
|
||||
|
||||
// data.form[0].action += "&album_id=" + $("#albumsForUpload").val();
|
||||
|
||||
// Automatically upload the file once it is added to the queue
|
||||
var jqXHR = data.submit();
|
||||
},
|
||||
|
||||
done: function(e, data) {
|
||||
if (data.result.Ok == true) {
|
||||
data.context.remove();
|
||||
// life
|
||||
var data2 = {src: urlPrefix + "/file/outputImage?fileId=" + data.result.Id}
|
||||
insertImage(data2);
|
||||
} else {
|
||||
data.context.empty();
|
||||
var tpl = $('<li><div class="alert alert-danger"><a class="close" data-dismiss="alert">×</a></div></li>');
|
||||
tpl.find('div').append('<b>Error:</b> ' + data.files[0].name + ' <small>[<i>' + formatFileSize(data.files[0].size) + '</i>]</small> ' + data.result.Msg);
|
||||
data.context.append(tpl);
|
||||
setTimeout((function(tpl) {
|
||||
return function() {
|
||||
tpl.remove();
|
||||
}
|
||||
})(tpl), 2000);
|
||||
}
|
||||
$("#uploadMsg").scrollTop(1000);
|
||||
},
|
||||
fail: function(e, data) {
|
||||
data.context.empty();
|
||||
var tpl = $('<li><div class="alert alert-danger"><a class="close" data-dismiss="alert">×</a></div></li>');
|
||||
tpl.find('div').append('<b>Error:</b> ' + data.files[0].name + ' <small>[<i>' + formatFileSize(data.files[0].size) + '</i>]</small> ' + data.errorThrown);
|
||||
data.context.append(tpl);
|
||||
setTimeout((function(tpl) {
|
||||
return function() {
|
||||
tpl.remove();
|
||||
}
|
||||
})(tpl), 2000);
|
||||
|
||||
$("#uploadMsg").scrollTop(1000);
|
||||
}
|
||||
});
|
||||
|
||||
// Prevent the default action when a file is dropped on the window
|
||||
$(document).on('drop dragover', function(e) {
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
// Helper function that formats the file sizes
|
||||
function formatFileSize(bytes) {
|
||||
if (typeof bytes !== 'number') {
|
||||
return '';
|
||||
}
|
||||
if (bytes >= 1000000000) {
|
||||
return (bytes / 1000000000).toFixed(2) + ' GB';
|
||||
}
|
||||
if (bytes >= 1000000) {
|
||||
return (bytes / 1000000).toFixed(2) + ' MB';
|
||||
}
|
||||
return (bytes / 1000).toFixed(2) + ' KB';
|
||||
}
|
||||
|
||||
function showUpload() {
|
||||
$("#upload").css("z-index", 12);
|
||||
var top = +$("#mceToolbar").css("height").slice(0, -2); // px
|
||||
$("#upload").css("top", top - 8);
|
||||
$("#upload").show();
|
||||
}
|
||||
|
||||
function hideUpload() {
|
||||
$("#upload").css("z-index", 0).css("top", "auto").hide();
|
||||
}
|
||||
|
||||
// drag css
|
||||
$(document).bind('dragover', function (e) {
|
||||
var dropZone = $('#drop'),
|
||||
timeout = window.dropZoneTimeout;
|
||||
if (!timeout) {
|
||||
dropZone.addClass('in');
|
||||
showUpload();
|
||||
} else {
|
||||
clearTimeout(timeout);
|
||||
}
|
||||
|
||||
var found = false,
|
||||
node = e.target;
|
||||
do {
|
||||
if (node === dropZone[0]) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
node = node.parentNode;
|
||||
} while (node != null);
|
||||
if (found) {
|
||||
dropZone.addClass('hover');
|
||||
} else {
|
||||
dropZone.removeClass('hover');
|
||||
}
|
||||
window.dropZoneTimeout = setTimeout(function () {
|
||||
window.dropZoneTimeout = null;
|
||||
dropZone.removeClass('in hover');
|
||||
hideUpload();
|
||||
}, 100);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// pasteImage
|
||||
var pasteImageInit = function() {
|
||||
// Initialize the jQuery File Upload plugin
|
||||
var dom, editor;
|
||||
$('#editorContent').fileupload({
|
||||
dataType: 'json',
|
||||
pasteZone: $('#editorContent'),
|
||||
dropZone: '', // 只允许paste
|
||||
maxFileSize: 210000,
|
||||
url: "/file/pasteImage",
|
||||
paramName: 'file',
|
||||
formData: function(form) {
|
||||
return [{name: 'from', value: 'pasteImage'}, {name: 'noteId', value: Note.curNoteId}]
|
||||
},
|
||||
/*
|
||||
paste: function(e, data) {
|
||||
var jqXHR = data.submit();
|
||||
},
|
||||
*/
|
||||
progress: function(e, data) {
|
||||
data.process.update(data.loaded / data.total);
|
||||
},
|
||||
add: function(e, data) {
|
||||
var note = Note.getCurNote();
|
||||
if(!note || note.IsNew) {
|
||||
alert("This note hasn't saved, please save it firstly!")
|
||||
return;
|
||||
}
|
||||
// 先显示loading...
|
||||
editor = tinymce.EditorManager.activeEditor;
|
||||
var process = new Process(editor);
|
||||
data.process = process;
|
||||
var jqXHR = data.submit();
|
||||
/*
|
||||
d.id = '__mcenew' + (new Date()).getTime();
|
||||
d.src = "http://leanote.com/images/loading-24.gif"; // 写死了
|
||||
var img = '<img src="' + d.src + '" id="' + d.id + '" />';
|
||||
editor.insertContent(img);
|
||||
var imgElm = $(d.id);
|
||||
data.imgId = d.id;
|
||||
data.context = imgElm;
|
||||
*/
|
||||
|
||||
/*
|
||||
// 上传之
|
||||
var c = new FormData;
|
||||
c.append("from", "pasteImage");
|
||||
// var d;
|
||||
// d = $.ajaxSettings.xhr();
|
||||
// d.withCredentials = i;var d = {};
|
||||
|
||||
// 先显示loading...
|
||||
var editor = tinymce.EditorManager.activeEditor;
|
||||
var dom = editor.dom;
|
||||
var d = {};
|
||||
d.id = '__mcenew';
|
||||
d.src = "http://leanote.com/images/loading-24.gif"; // 写死了
|
||||
editor.insertContent(dom.createHTML('img', d));
|
||||
var imgElm = dom.get('__mcenew');
|
||||
$.ajax({url: "/file/pasteImage", contentType:false, processData:false , data: c, type: "POST"}
|
||||
).done(function(re) {
|
||||
if(!re || typeof re != "object" || !re.Ok) {
|
||||
// 删除
|
||||
dom.remove(imgElm);
|
||||
return;
|
||||
}
|
||||
// 这里, 如果图片宽度过大, 这里设置成500px
|
||||
var urlPrefix = UrlPrefix; // window.location.protocol + "//" + window.location.host;
|
||||
var src = urlPrefix + "/file/outputImage?fileId=" + re.Id;
|
||||
getImageSize(src, function(wh) {
|
||||
// life 4/25
|
||||
if(wh && wh.width) {
|
||||
if(wh.width > 600) {
|
||||
wh.width = 600;
|
||||
}
|
||||
d.width = wh.width;
|
||||
dom.setAttrib(imgElm, 'width', d.width);
|
||||
}
|
||||
dom.setAttrib(imgElm, 'src', src);
|
||||
});
|
||||
dom.setAttrib(imgElm, 'id', null);
|
||||
});
|
||||
};
|
||||
reader.readAsDataURL(blob);
|
||||
*/
|
||||
},
|
||||
|
||||
done: function(e, data) {
|
||||
if (data.result.Ok == true) {
|
||||
// 这里, 如果图片宽度过大, 这里设置成500px
|
||||
var re = data.result;
|
||||
var urlPrefix = UrlPrefix; // window.location.protocol + "//" + window.location.host;
|
||||
var src = urlPrefix + "/file/outputImage?fileId=" + re.Id;
|
||||
|
||||
data.process.replace(src);
|
||||
/*
|
||||
getImageSize(src, function() {
|
||||
$img.attr('src', src);
|
||||
$img.removeAttr('id');
|
||||
});
|
||||
*/
|
||||
} else {
|
||||
data.process.remove();
|
||||
}
|
||||
},
|
||||
fail: function(e, data) {
|
||||
data.process.remove();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
initUploader();
|
||||
pasteImageInit();
|
||||
});
|
2
public/js/app/note-min.js
vendored
2
public/js/app/note-min.js
vendored
File diff suppressed because one or more lines are too long
@ -14,15 +14,15 @@ Note.interval = ""; // 定时器
|
||||
Note.itemIsBlog = '<div class="item-blog"><i class="fa fa-bold" title="blog"></i></div><div class="item-setting"><i class="fa fa-cog" title="setting"></i></div>';
|
||||
// for render
|
||||
Note.itemTplNoImg = '<li href="#" class="item ?" noteId="?">'
|
||||
Note.itemTplNoImg += Note.itemIsBlog +'<div class="item-desc"><p class="item-title">?</p><p class="item-info"><i class="fa fa-book"></i> <span class="note-notebook">?</span> <i class="fa fa-calendar"></i> <span class="updated-time">?</span></p><p class="desc">?</p></div></li>';
|
||||
Note.itemTplNoImg += Note.itemIsBlog +'<div class="item-desc"><p class="item-title">?</p><p class="item-info"><i class="fa fa-book"></i> <span class="note-notebook">?</span> <i class="fa fa-clock-o"></i> <span class="updated-time">?</span></p><p class="desc">?</p></div></li>';
|
||||
|
||||
// 有image
|
||||
Note.itemTpl = '<li href="#" class="item ? item-image" noteId="?"><div class="item-thumb" style=""><img src="?"/></div>'
|
||||
Note.itemTpl +=Note.itemIsBlog + '<div class="item-desc" style=""><p class="item-title">?</p><p class="item-info"><i class="fa fa-book"></i> <span class="note-notebook">?</span> <i class="fa fa-calendar"></i> <span class="updated-time">?</span></p><p class="desc">?</p></div></li>';
|
||||
Note.itemTpl +=Note.itemIsBlog + '<div class="item-desc" style=""><p class="item-title">?</p><p class="item-info"><i class="fa fa-book"></i> <span class="note-notebook">?</span> <i class="fa fa-clock-o"></i> <span class="updated-time">?</span></p><p class="desc">?</p></div></li>';
|
||||
|
||||
// for new
|
||||
Note.newItemTpl = '<li href="#" class="item item-active ?" fromUserId="?" noteId="?">'
|
||||
Note.newItemTpl += Note.itemIsBlog + '<div class="item-desc" style="right: 0px;"><p class="item-title">?</p><p class="item-text"><i class="fa fa-book"></i> <span class="note-notebook">?</span> <i class="fa fa-calendar"></i> <span class="updated-time">?</span><br /><span class="desc">?</span></p></div></li>';
|
||||
Note.newItemTpl += Note.itemIsBlog + '<div class="item-desc" style="right: 0px;"><p class="item-title">?</p><p class="item-text"><i class="fa fa-book"></i> <span class="note-notebook">?</span> <i class="fa fa-clock-o"></i> <span class="updated-time">?</span><br /><span class="desc">?</span></p></div></li>';
|
||||
|
||||
Note.noteItemListO = $("#noteItemList");
|
||||
|
||||
@ -178,10 +178,9 @@ Note.renderNotesAndFirstOneContent = function(ret) {
|
||||
Note.renderNotes(ret);
|
||||
// 渲染第一个
|
||||
if(!isEmpty(ret[0])) {
|
||||
Note.changeNote(ret[0].NoteId);
|
||||
Note.changeNoteForPjax(ret[0].NoteId, true, false);
|
||||
} else {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 当前的note是否改变过了?
|
||||
@ -248,17 +247,19 @@ Note.curHasChanged = function(force) {
|
||||
}
|
||||
|
||||
// 比较text, 因为note Nav会添加dom会导致content改变
|
||||
if((force && cacheNote.Content != content) || (!force && $(cacheNote.Content).text() != contentText)) {
|
||||
if((force && cacheNote.Content != content) || (!force && (/**/(!cacheNote.IsMarkdown && $(cacheNote.Content).text() != contentText) || (cacheNote.IsMarkdown && cacheNote.Content != contentText)) /**/) ) {
|
||||
hasChanged.hasChanged = true;
|
||||
hasChanged.Content = content;
|
||||
|
||||
// 从html中得到...
|
||||
var c = preview || content;
|
||||
|
||||
hasChanged.Desc = Note.genDesc(c);
|
||||
hasChanged.ImgSrc = Note.getImgSrc(c);
|
||||
hasChanged.Abstract = Note.genAbstract(c);
|
||||
|
||||
// 不是博客或没有自定义设置的
|
||||
if(!cacheNote.HasSelfDefined || !cacheNote.IsBlog) {
|
||||
hasChanged.Desc = Note.genDesc(c);
|
||||
hasChanged.ImgSrc = Note.getImgSrc(c);
|
||||
hasChanged.Abstract = Note.genAbstract(c);
|
||||
}
|
||||
} else {
|
||||
log("text相同");
|
||||
log(cacheNote.Content == content);
|
||||
@ -303,6 +304,7 @@ Note.genDesc = function(content) {
|
||||
// 避免其它的<img 之类的不完全
|
||||
content = $("<div></div>").html(content).text();
|
||||
|
||||
|
||||
// pre下text()会将< => < > => >
|
||||
content = content.replace(/</g, "<");
|
||||
content = content.replace(/>/g, ">");
|
||||
@ -315,6 +317,9 @@ Note.genDesc = function(content) {
|
||||
|
||||
// 得到摘要
|
||||
Note.genAbstract = function(content, len) {
|
||||
if(!content) {
|
||||
return "";
|
||||
}
|
||||
if(len == undefined) {
|
||||
len = 1000;
|
||||
}
|
||||
@ -392,11 +397,14 @@ Note.curChangedSaveIt = function(force) {
|
||||
|
||||
// 保存之
|
||||
showMsg(getMsg("saving"));
|
||||
ajaxPost("/note/UpdateNoteOrContent", hasChanged, function(ret) {
|
||||
ajaxPost("/note/updateNoteOrContent", hasChanged, function(ret) {
|
||||
if(hasChanged.IsNew) {
|
||||
// 缓存之, 后台得到其它信息
|
||||
ret.IsNew = false;
|
||||
Note.setNoteCache(ret, false);
|
||||
|
||||
// 新建笔记也要change history
|
||||
Pjax.changeNote(ret);
|
||||
}
|
||||
showMsg(getMsg("saveSuccess"), 1000);
|
||||
});
|
||||
@ -418,14 +426,93 @@ Note.selectTarget = function(target) {
|
||||
// 2. ajax得到现在的note
|
||||
Note.showContentLoading = function() {
|
||||
$("#noteMaskForLoading").css("z-index", 99999);
|
||||
}
|
||||
};
|
||||
Note.hideContentLoading = function() {
|
||||
$("#noteMaskForLoading").css("z-index", -1);
|
||||
}
|
||||
};
|
||||
|
||||
Note.directToNote = function(noteId) {
|
||||
var $p = $("#noteItemList");
|
||||
var pHeight = $p.height();
|
||||
// 相对于父亲的位置
|
||||
var pTop = $("[noteId='" + noteId + "']").position().top;
|
||||
var scrollTop = $p.scrollTop();
|
||||
pTop += scrollTop;
|
||||
/*
|
||||
log("..");
|
||||
log(noteId);
|
||||
log(pTop + ' ' + pHeight + ' ' + scrollTop);
|
||||
*/
|
||||
|
||||
// 当前的可视范围的元素位置是[scrollTop, pHeight + scrollTop]
|
||||
if(pTop >= scrollTop && pTop <= pHeight + scrollTop) {
|
||||
} else {
|
||||
var top = pTop;
|
||||
log("定位到特定note, 在可视范围内");
|
||||
// 手机不用slimScroll
|
||||
if(!LEA.isMobile && !Mobile.isMobile()) {
|
||||
$("#noteItemList").scrollTop(top);
|
||||
$("#noteItemList").slimScroll({ scrollTo: top + 'px', height: "100%", onlyScrollBar: true});
|
||||
} else {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// mustPush表示是否将状态push到state中, 默认为true
|
||||
// 什么时候为false, 在popstate时
|
||||
// needTargetNobook默认为false, 在点击notebook, renderfirst时为false
|
||||
Note.changeNoteForPjax = function(noteId, mustPush, needTargetNotebook) {
|
||||
var me = this;
|
||||
var note = me.getNote(noteId);
|
||||
if(!note) {
|
||||
return;
|
||||
}
|
||||
var isShare = note.Perm != undefined;
|
||||
if(needTargetNotebook == undefined) {
|
||||
needTargetNotebook = true;
|
||||
}
|
||||
me.changeNote(noteId, isShare, true, function(note) {
|
||||
// push state
|
||||
if(mustPush == undefined) {
|
||||
mustPush = true;
|
||||
}
|
||||
if(mustPush) {
|
||||
Pjax.changeNote(note);
|
||||
}
|
||||
|
||||
// popstate时虽然选中了note, 但位置可能不可见
|
||||
if(needTargetNotebook) {
|
||||
Note.directToNote(noteId);
|
||||
}
|
||||
});
|
||||
|
||||
// 第一次render时定位到第一个笔记的notebook 12.06 life
|
||||
// 或通过pop时
|
||||
// 什么时候需要? 1. 第一次changeNote, 2. pop时, 只有当点击了notebook后才不要
|
||||
|
||||
// 这里, 万一是共享笔记呢?
|
||||
// 切换到共享中
|
||||
if(needTargetNotebook) {
|
||||
if(isShare) {
|
||||
if($("#myShareNotebooks").hasClass("closed")) {
|
||||
$("#myShareNotebooks .folderHeader").trigger("click");
|
||||
}
|
||||
} else {
|
||||
if($("#myNotebooks").hasClass("closed")) {
|
||||
$("#myNotebooks .folderHeader").trigger("click");
|
||||
}
|
||||
}
|
||||
// 如果是子笔记本, 那么要展开父笔记本
|
||||
Notebook.expandNotebookTo(note.NotebookId);
|
||||
}
|
||||
};
|
||||
|
||||
// 点击notebook时调用, 渲染第一个笔记
|
||||
Note.contentAjax = null;
|
||||
Note.contentAjaxSeq = 1;
|
||||
Note.changeNote = function(selectNoteId, isShare, needSaveChanged) {
|
||||
Note.changeNote = function(selectNoteId, isShare, needSaveChanged, callback) {
|
||||
var self = this;
|
||||
|
||||
// -1 停止定时器
|
||||
Note.stopInterval();
|
||||
|
||||
@ -486,6 +573,8 @@ Note.changeNote = function(selectNoteId, isShare, needSaveChanged) {
|
||||
Note.renderNoteContentReadOnly(ret);
|
||||
}
|
||||
self.hideContentLoading();
|
||||
|
||||
callback && callback(ret);
|
||||
}
|
||||
|
||||
if(cacheNote.Content) {
|
||||
@ -493,10 +582,10 @@ Note.changeNote = function(selectNoteId, isShare, needSaveChanged) {
|
||||
return;
|
||||
}
|
||||
|
||||
var url = "/note/GetNoteContent";
|
||||
var url = "/note/getNoteContent";
|
||||
var param = {noteId: selectNoteId};
|
||||
if(isShare) {
|
||||
url = "/share/GetShareNoteContent";
|
||||
url = "/share/getShareNoteContent";
|
||||
param.sharedUserId = cacheNote.UserId // 谁的笔记
|
||||
}
|
||||
|
||||
@ -550,8 +639,10 @@ Note.clearNoteInfo = function() {
|
||||
setEditorContent("");
|
||||
|
||||
// markdown editor
|
||||
/*
|
||||
$("#wmd-input").val("");
|
||||
$("#wmd-preview").html("");
|
||||
*/
|
||||
|
||||
// 只隐藏即可
|
||||
$("#noteRead").hide();
|
||||
@ -592,22 +683,22 @@ Note.renderNoteContent = function(content) {
|
||||
}
|
||||
|
||||
// 初始化时渲染最初的notes
|
||||
/**
|
||||
<div id="noteItemList">
|
||||
<!--
|
||||
<div href="#" class="item">
|
||||
<div class="item-thumb" style="">
|
||||
<img src="images/a.gif"/>
|
||||
</div>
|
||||
|
||||
<div class="item-desc" style="">
|
||||
<p class="item-title">?</p>
|
||||
<p class="item-text">
|
||||
?
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
-->
|
||||
/**
|
||||
<div id="noteItemList">
|
||||
<!--
|
||||
<div href="#" class="item">
|
||||
<div class="item-thumb" style="">
|
||||
<img src="images/a.gif"/>
|
||||
</div>
|
||||
|
||||
<div class="item-desc" style="">
|
||||
<p class="item-title">?</p>
|
||||
<p class="item-text">
|
||||
?
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
-->
|
||||
*/
|
||||
|
||||
Note.showEditorMask = function() {
|
||||
@ -891,7 +982,7 @@ Note.deleteNote = function(target, contextmenuItem, isShared) {
|
||||
// 显示共享信息
|
||||
Note.listNoteShareUserInfo = function(target) {
|
||||
var noteId = $(target).attr("noteId");
|
||||
showDialogRemote("share/listNoteShareUserInfo", {noteId: noteId});
|
||||
showDialogRemote("/share/listNoteShareUserInfo", {noteId: noteId});
|
||||
}
|
||||
|
||||
// 共享笔记
|
||||
@ -918,7 +1009,7 @@ Note.listNoteContentHistories = function() {
|
||||
options.show = true;
|
||||
$("#leanoteDialog").modal(options);
|
||||
|
||||
ajaxGet("noteContentHistory/listHistories", {noteId: Note.curNoteId}, function(re) {
|
||||
ajaxGet("/noteContentHistory/listHistories", {noteId: Note.curNoteId}, function(re) {
|
||||
if(!isArray(re)) {$content.html(getMsg("noHistories")); return}
|
||||
// 组装成一个tab
|
||||
var str = "<p>" + getMsg("historiesNum") + '</p><div id="historyList"><table class="table table-hover">';
|
||||
@ -968,6 +1059,13 @@ Note.listNoteContentHistories = function() {
|
||||
});
|
||||
}
|
||||
|
||||
// 导出成PDF
|
||||
Note.exportPDF = function(target) {
|
||||
var noteId = $(target).attr("noteId");
|
||||
ajaxGet("/note/exportPdf", {noteId: noteId}, function(ret) {
|
||||
});
|
||||
};
|
||||
|
||||
// 长微博
|
||||
Note.html2Image = function(target) {
|
||||
var noteId = $(target).attr("noteId");
|
||||
@ -1296,8 +1394,9 @@ Note.initContextmenu = function() {
|
||||
{ type: "splitLine" },
|
||||
{ text: getMsg("publicAsBlog"), alias: 'set2Blog', faIcon: "fa-bold", action: Note.setNote2Blog },
|
||||
{ text: getMsg("cancelPublic"), alias: 'unset2Blog', faIcon: "fa-undo", action: Note.setNote2Blog },
|
||||
//{ type: "splitLine" },
|
||||
//{ text: "分享到社区", alias: 'html2Image', icon: "", action: Note.html2Image},
|
||||
// { type: "splitLine" },
|
||||
// { text: "分享到社区", alias: 'html2Image', icon: "", action: Note.html2Image},
|
||||
// { text: "导出PDF", alias: 'exportPDF', icon: "", action: Note.exportPDF},
|
||||
{ type: "splitLine" },
|
||||
{ text: getMsg("delete"), icon: "", faIcon: "fa-trash-o", action: Note.deleteNote },
|
||||
{ text: getMsg("move"), alias: "move", faIcon: "fa-arrow-right",
|
||||
@ -1422,8 +1521,8 @@ var Attach = {
|
||||
var attachId = $(this).closest('li').data("id");
|
||||
var attach = self.attachsMap[attachId];
|
||||
var src = UrlPrefix + "/attach/download?attachId=" + attachId;
|
||||
if(LEA.isMarkdownEditor() && MarkdownEditor) {
|
||||
MarkdownEditor.insertLink(src, attach.Title);
|
||||
if(LEA.isMarkdownEditor() && MD) {
|
||||
MD.insertLink(src, attach.Title);
|
||||
} else {
|
||||
tinymce.activeEditor.insertContent('<a target="_blank" href="' + src + '">' + attach.Title + '</a>');
|
||||
}
|
||||
@ -1439,8 +1538,8 @@ var Attach = {
|
||||
var src = UrlPrefix + "/attach/downloadAll?noteId=" + Note.curNoteId
|
||||
var title = note.Title ? note.Title + ".tar.gz" : "all.tar.gz";
|
||||
|
||||
if(LEA.isMarkdownEditor() && MarkdownEditor) {
|
||||
MarkdownEditor.insertLink(src, title);
|
||||
if(LEA.isMarkdownEditor() && MD) {
|
||||
MD.insertLink(src, title);
|
||||
} else {
|
||||
tinymce.activeEditor.insertContent('<a target="_blank" href="' + src + '">' + title + '</a>');
|
||||
}
|
||||
@ -1573,9 +1672,15 @@ $(function() {
|
||||
Attach.init();
|
||||
|
||||
//-----------------
|
||||
// for list nav
|
||||
// 点击笔记展示之
|
||||
// 避免iphone, ipad两次点击
|
||||
// http://stackoverflow.com/questions/3038898/ipad-iphone-hover-problem-causes-the-user-to-double-click-a-link
|
||||
$("#noteItemList").on("mouseenter", ".item", function(event) {
|
||||
if(LEA.isIpad || LEA.isIphone) {
|
||||
$(this).trigger("click");
|
||||
}
|
||||
});
|
||||
$("#noteItemList").on("click", ".item", function(event) {
|
||||
log(event);
|
||||
event.stopPropagation();
|
||||
var noteId = $(this).attr("noteId");
|
||||
|
||||
@ -1587,7 +1692,8 @@ $(function() {
|
||||
}
|
||||
// 当前的和所选的是一个, 不改变
|
||||
if(Note.curNoteId != noteId) {
|
||||
Note.changeNote(noteId);
|
||||
// 不用重定向到notebook
|
||||
Note.changeNoteForPjax(noteId, true, false);
|
||||
}
|
||||
});
|
||||
|
||||
@ -1631,7 +1737,7 @@ $(function() {
|
||||
});
|
||||
*/
|
||||
$("#searchNoteInput").on("keydown", function(e) {
|
||||
var theEvent = e; // window.event || arguments.callee.caller.arguments[0];
|
||||
var theEvent = e; // window.event || arguments.callee.caller.arguments[0];
|
||||
if(theEvent.keyCode == 13 || theEvent.keyCode == 108) {
|
||||
theEvent.preventDefault();
|
||||
Note.searchNote();
|
||||
@ -1658,7 +1764,7 @@ $(function() {
|
||||
e.stopPropagation();
|
||||
// 得到ID
|
||||
var noteId = $(this).parent().attr('noteId');
|
||||
window.open("/blog/post/" + noteId);
|
||||
window.open("/blog/view/" + noteId);
|
||||
});
|
||||
|
||||
// note setting
|
||||
|
2
public/js/app/notebook-min.js
vendored
2
public/js/app/notebook-min.js
vendored
File diff suppressed because one or more lines are too long
@ -289,6 +289,41 @@ Notebook.cacheAllNotebooks = function(notebooks) {
|
||||
}
|
||||
}
|
||||
|
||||
// 展开到笔记本
|
||||
Notebook.expandNotebookTo = function(notebookId, userId) {
|
||||
var me = this;
|
||||
var selected = false;
|
||||
var tree = me.tree;
|
||||
|
||||
// 共享的
|
||||
if(userId) {
|
||||
tree = Share.trees[userId];
|
||||
}
|
||||
if(!tree) {
|
||||
return;
|
||||
}
|
||||
var curNode = tree.getNodeByTId(notebookId);
|
||||
if(!curNode) {
|
||||
return;
|
||||
}
|
||||
while(true) {
|
||||
var pNode = curNode.getParentNode();
|
||||
if(pNode) {
|
||||
tree.expandNode(pNode, true);
|
||||
if(!selected) {
|
||||
Notebook.changeNotebookNav(notebookId);
|
||||
selected = true;
|
||||
}
|
||||
curNode = pNode;
|
||||
} else {
|
||||
if(!selected) {
|
||||
Notebook.changeNotebookNav(notebookId);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// RenderNotebooks调用,
|
||||
// nav 为了新建, 快速选择, 移动笔记
|
||||
@ -507,10 +542,11 @@ Notebook.toggleToMyNav = function(userId, notebookId) {
|
||||
$("#tagSearch").hide();
|
||||
}
|
||||
Notebook.changeNotebookNav = function(notebookId) {
|
||||
Notebook.curNotebookId = notebookId;
|
||||
Notebook.toggleToMyNav();
|
||||
|
||||
// 1
|
||||
Notebook.selectNotebook($(tt('#notebookList [notebookId="?"]', notebookId)));
|
||||
// 1 改变当前的notebook
|
||||
Notebook.selectNotebook($(tt('#notebook [notebookId="?"]', notebookId)));
|
||||
|
||||
var notebook = Notebook.cache[notebookId];
|
||||
|
||||
@ -542,7 +578,9 @@ Notebook.curActiveNotebookIsAll = function() {
|
||||
// 1. 改变note, 此时需要先保存
|
||||
// 2. ajax得到该notebook下的所有note
|
||||
// 3. 使用Note.RederNotes()
|
||||
Notebook.changeNotebook = function(notebookId) {
|
||||
// callback Pjax, 当popstate时调用
|
||||
Notebook.changeNotebook = function(notebookId, callback) {
|
||||
var me = this;
|
||||
Notebook.changeNotebookNav(notebookId);
|
||||
|
||||
Notebook.curNotebookId = notebookId;
|
||||
@ -553,7 +591,7 @@ Notebook.changeNotebook = function(notebookId) {
|
||||
// 2 先清空所有
|
||||
Note.clearAll();
|
||||
|
||||
var url = "/note/ListNotes/";
|
||||
var url = "/note/listNotes/";
|
||||
var param = {notebookId: notebookId};
|
||||
|
||||
// 废纸篓
|
||||
@ -565,22 +603,46 @@ Notebook.changeNotebook = function(notebookId) {
|
||||
// 得到全部的...
|
||||
cacheNotes = Note.getNotesByNotebookId();
|
||||
if(!isEmpty(cacheNotes)) { // 万一真的是没有呢?
|
||||
Note.renderNotesAndFirstOneContent(cacheNotes);
|
||||
if(callback) {
|
||||
callback(cacheNotes);
|
||||
} else {
|
||||
Note.renderNotesAndFirstOneContent(cacheNotes);
|
||||
}
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
cacheNotes = Note.getNotesByNotebookId(notebookId);
|
||||
if(!isEmpty(cacheNotes)) { // 万一真的是没有呢?
|
||||
Note.renderNotesAndFirstOneContent(cacheNotes);
|
||||
if(!isEmpty(cacheNotes)) { // 万一真的是没有呢? 执行后面的ajax
|
||||
if(callback) {
|
||||
callback(cacheNotes);
|
||||
} else {
|
||||
Note.renderNotesAndFirstOneContent(cacheNotes);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 2 得到笔记本
|
||||
// 这里可以缓存起来, note按notebookId缓存
|
||||
ajaxGet(url, param, Note.renderNotesAndFirstOneContent);
|
||||
me.showNoteAndEditorLoading();
|
||||
ajaxGet(url, param, function(cacheNotes) {
|
||||
if(callback) {
|
||||
callback(cacheNotes);
|
||||
} else {
|
||||
Note.renderNotesAndFirstOneContent(cacheNotes);
|
||||
}
|
||||
me.hideNoteAndEditorLoading();
|
||||
});
|
||||
}
|
||||
|
||||
// 笔记列表与编辑器的mask loading
|
||||
Notebook.showNoteAndEditorLoading = function() {
|
||||
$("#noteAndEditorMask").show();
|
||||
};
|
||||
Notebook.hideNoteAndEditorLoading = function() {
|
||||
$("#noteAndEditorMask").hide();
|
||||
};
|
||||
|
||||
// 是否是当前选中的notebookId
|
||||
// 还包括共享
|
||||
// called by Note
|
||||
@ -596,10 +658,10 @@ Notebook.changeNotebookForNewNote = function(notebookId) {
|
||||
return;
|
||||
}
|
||||
|
||||
Notebook.changeNotebookNav(notebookId);
|
||||
Notebook.changeNotebookNav(notebookId, true);
|
||||
Notebook.curNotebookId = notebookId;
|
||||
|
||||
var url = "/note/ListNotes/";
|
||||
var url = "/note/listNotes/";
|
||||
var param = {notebookId: notebookId};
|
||||
|
||||
// 2 得到笔记本
|
||||
@ -614,7 +676,7 @@ Notebook.changeNotebookForNewNote = function(notebookId) {
|
||||
// 显示共享信息
|
||||
Notebook.listNotebookShareUserInfo = function(target) {
|
||||
var notebookId = $(target).attr("notebookId");
|
||||
showDialogRemote("share/listNotebookShareUserInfo", {notebookId: notebookId});
|
||||
showDialogRemote("/share/listNotebookShareUserInfo", {notebookId: notebookId});
|
||||
}
|
||||
// 共享笔记本
|
||||
Notebook.shareNotebooks= function(target) {
|
||||
@ -657,7 +719,7 @@ Notebook.setNotebook2Blog = function(target) {
|
||||
}
|
||||
});
|
||||
}
|
||||
ajaxPost("notebook/setNotebook2Blog", {notebookId: notebookId, isBlog: isBlog}, function(ret) {
|
||||
ajaxPost("/notebook/setNotebook2Blog", {notebookId: notebookId, isBlog: isBlog}, function(ret) {
|
||||
if(ret) {
|
||||
// 这里要设置notebook下的note的blog状态
|
||||
Note.setAllNoteBlogStatus(notebookId, isBlog);
|
||||
@ -849,12 +911,6 @@ $(function() {
|
||||
} else {
|
||||
items.push("set2Blog");
|
||||
}
|
||||
|
||||
//asktalk bebug#23
|
||||
if(notebookId=="548125adf4e872105c000007"){
|
||||
items.push("delete");
|
||||
}
|
||||
|
||||
// 是否还有笔记
|
||||
if(Note.notebookHasNotes(notebookId)) {
|
||||
items.push("delete");
|
||||
|
2
public/js/app/page-min.js
vendored
2
public/js/app/page-min.js
vendored
File diff suppressed because one or more lines are too long
@ -4,10 +4,9 @@
|
||||
//----------------------
|
||||
// 编辑器模式
|
||||
function editorMode() {
|
||||
this.writingHash = "#writing";
|
||||
this.normalHash = "#normal";
|
||||
this.isWritingMode = location.hash == this.writingHash;
|
||||
|
||||
this.writingHash = "writing";
|
||||
this.normalHash = "normal";
|
||||
this.isWritingMode = location.hash.indexOf(this.writingHash) >= 0;
|
||||
this.toggleA = null;
|
||||
}
|
||||
|
||||
@ -17,27 +16,33 @@ editorMode.prototype.toggleAText = function(isWriting) {
|
||||
var toggleA = $(".toggle-editor-mode a");
|
||||
var toggleSpan = $(".toggle-editor-mode span");
|
||||
if(isWriting) {
|
||||
toggleA.attr("href", self.normalHash);
|
||||
toggleA.attr("href", "#" + self.normalHash);
|
||||
toggleSpan.text(getMsg("normalMode"));
|
||||
} else {
|
||||
toggleA.attr("href", self.writingHash);
|
||||
toggleA.attr("href", "#" + self.writingHash);
|
||||
toggleSpan.text(getMsg("writingMode"));
|
||||
}
|
||||
}, 0);
|
||||
}
|
||||
editorMode.prototype.isWriting = function(hash) {
|
||||
return hash == this.writingHash;
|
||||
return hash.indexOf(this.writingHash) >= 0
|
||||
}
|
||||
editorMode.prototype.init = function() {
|
||||
this.changeMode(this.isWritingMode);
|
||||
var self = this;
|
||||
$(".toggle-editor-mode").click(function() {
|
||||
//
|
||||
$(".toggle-editor-mode").click(function(e) {
|
||||
e.preventDefault();
|
||||
saveBookmark();
|
||||
var $a = $(this).find("a");
|
||||
var isWriting = self.isWriting($a.attr("href"));
|
||||
self.changeMode(isWriting);
|
||||
//
|
||||
if(isWriting) {
|
||||
setHash("m", self.writingHash);
|
||||
} else {
|
||||
setHash("m", self.normalHash);
|
||||
}
|
||||
|
||||
restoreBookmark();
|
||||
});
|
||||
}
|
||||
@ -123,7 +128,7 @@ editorMode.prototype.writtingMode = function() {
|
||||
|
||||
editorMode.prototype.getWritingCss = function() {
|
||||
if(this.isWritingMode) {
|
||||
return ["css/editor/editor-writting-mode.css"];
|
||||
return ["/css/editor/editor-writting-mode.css"];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
@ -144,8 +149,8 @@ var Resize = {
|
||||
note: $("#note"),
|
||||
body: $("body"),
|
||||
leftColumn: $("#left-column"),
|
||||
rightColumn: $("#right-column"),
|
||||
mdSplitter: $("#mdSplitter"),
|
||||
rightColumn: $("#right-column"), // $("#preview-panel"), //
|
||||
mdSplitter: $("#mdSplitter2"),
|
||||
|
||||
init: function() {
|
||||
var self = this;
|
||||
@ -168,8 +173,10 @@ var Resize = {
|
||||
// 鼠标点下
|
||||
self.mdSplitter.bind("mousedown", function(event) {
|
||||
event.preventDefault(); // 防止选择文本
|
||||
self.mdLineMove = true;
|
||||
$(this).css("background-color", "#ccc");
|
||||
if($(this).hasClass('open')) {
|
||||
self.mdLineMove = true;
|
||||
}
|
||||
// $(this).css("background-color", "#ccc");
|
||||
});
|
||||
|
||||
// 鼠标移动时
|
||||
@ -189,6 +196,37 @@ var Resize = {
|
||||
// 取消遮罩
|
||||
$("#noteMask").css("z-index", -1);
|
||||
});
|
||||
|
||||
// 瞬间
|
||||
var everLeftWidth;
|
||||
$('.layout-toggler-preview').click(function() {
|
||||
var $t = $(this);
|
||||
var $p = self.leftColumn.parent();
|
||||
// 是开的
|
||||
if($t.hasClass('open')) {
|
||||
var totalWidth = $p.width();
|
||||
var minRightWidth = 22;
|
||||
var leftWidth = totalWidth - minRightWidth;
|
||||
everLeftWidth = self.leftColumn.width();
|
||||
self.leftColumn.width(leftWidth);
|
||||
self.rightColumn.css('left', 'auto').width(minRightWidth);
|
||||
|
||||
// 禁止split
|
||||
$t.removeClass('open');//.addClass('close');
|
||||
self.rightColumn.find('.layout-resizer').removeClass('open');
|
||||
$('.preview-container').hide();
|
||||
} else {
|
||||
$t.addClass('open');
|
||||
self.rightColumn.find('.layout-resizer').addClass('open');
|
||||
self.leftColumn.width(everLeftWidth);
|
||||
$('.preview-container').show();
|
||||
self.rightColumn.css('left', everLeftWidth).width('auto');
|
||||
|
||||
if(MD) {
|
||||
MD.onResize();
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
// 停止, 保存数据
|
||||
stopResize: function() {
|
||||
@ -252,7 +290,7 @@ var Resize = {
|
||||
resizeMdColumns: function(event) {
|
||||
var self = this;
|
||||
if (self.mdLineMove) {
|
||||
var mdEditorWidth = event.clientX - self.leftNotebook.width() - self.noteList.width();
|
||||
var mdEditorWidth = event.clientX - self.leftColumn.offset().left; // self.leftNotebook.width() - self.noteList.width();
|
||||
self.setMdColumnWidth(mdEditorWidth);
|
||||
}
|
||||
},
|
||||
@ -261,9 +299,15 @@ var Resize = {
|
||||
var self = this;
|
||||
if(mdEditorWidth > 100) {
|
||||
UserInfo.MdEditorWidth = mdEditorWidth;
|
||||
log(mdEditorWidth)
|
||||
self.leftColumn.width(mdEditorWidth);
|
||||
self.rightColumn.css("left", mdEditorWidth);
|
||||
self.mdSplitter.css("left", mdEditorWidth);
|
||||
// self.mdSplitter.css("left", mdEditorWidth);
|
||||
}
|
||||
|
||||
// 这样, scrollPreview 才会到正确的位置
|
||||
if(MD) {
|
||||
MD.onResize();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -276,6 +320,7 @@ Mobile = {
|
||||
noteO: $("#note"),
|
||||
bodyO: $("body"),
|
||||
setMenuO: $("#setMenu"),
|
||||
// 弃用, 统一使用Pjax
|
||||
hashChange: function() {
|
||||
var self = Mobile;
|
||||
var hash = location.hash;
|
||||
@ -292,8 +337,8 @@ Mobile = {
|
||||
init: function() {
|
||||
var self = this;
|
||||
self.isMobile();
|
||||
$(window).on("hashchange", self.hashChange);
|
||||
self.hashChange();
|
||||
// $(window).on("hashchange", self.hashChange);
|
||||
// self.hashChange();
|
||||
/*
|
||||
$("#noteItemList").on("tap", ".item", function(event) {
|
||||
$(this).click();
|
||||
@ -314,12 +359,15 @@ Mobile = {
|
||||
var u = navigator.userAgent;
|
||||
LEA.isMobile = false;
|
||||
LEA.isMobile = /Mobile|Android|iPhone|iPad/i.test(u);
|
||||
LEA.isIpad = /iPhone|iPad/i.test(u);
|
||||
LEA.isIpad = /iPad/i.test(u);
|
||||
LEA.isIphone = /iPhone/i.test(u);
|
||||
if(!LEA.isMobile && $(document).width() <= 700){
|
||||
LEA.isMobile = true
|
||||
}
|
||||
return LEA.isMobile;
|
||||
},
|
||||
// 改变笔记, 此时切换到编辑器模式下
|
||||
// note.js click事件处理, 先切换到纯编辑器下, 再调用Note.changeNote()
|
||||
changeNote: function(noteId) {
|
||||
var self = this;
|
||||
if(!LEA.isMobile) {return true;}
|
||||
@ -331,21 +379,25 @@ Mobile = {
|
||||
var self = this;
|
||||
self.bodyO.addClass("full-editor");
|
||||
self.noteO.addClass("editor-show");
|
||||
/*
|
||||
if(changeHash) {
|
||||
if(!noteId) {
|
||||
noteId = Note.curNoteId;
|
||||
}
|
||||
location.hash = "noteId=" + noteId;
|
||||
}
|
||||
*/
|
||||
},
|
||||
toNormal: function(changeHash) {
|
||||
var self = this;
|
||||
self.bodyO.removeClass("full-editor");
|
||||
self.noteO.removeClass("editor-show");
|
||||
|
||||
/*
|
||||
if(changeHash) {
|
||||
location.hash = "notebookAndNote";
|
||||
}
|
||||
*/
|
||||
},
|
||||
switchPage: function() {
|
||||
var self = this;
|
||||
@ -370,10 +422,12 @@ function initSlimScroll() {
|
||||
$("#noteItemList").slimScroll({
|
||||
height: "100%", // ($("#leftNotebook").height()-42)+"px"
|
||||
});
|
||||
/*
|
||||
$("#wmd-input").slimScroll({
|
||||
height: "100%", // $("#wmd-input").height()+"px"
|
||||
});
|
||||
$("#wmd-input").css("width", "100%");
|
||||
*/
|
||||
|
||||
$("#wmd-panel-preview").slimScroll({
|
||||
height: "100%", // $("#wmd-panel-preview").height()+"px"
|
||||
@ -410,43 +464,24 @@ function initEditor() {
|
||||
|
||||
// 初始化编辑器
|
||||
tinymce.init({
|
||||
inline: true,
|
||||
valid_children: "+pre[div|#text|p|span|textarea|i|b|strong]", // ace
|
||||
/*
|
||||
protect: [
|
||||
/\<\/?(if|endif)\>/g, // Protect <if> & </endif>
|
||||
/\<xsl\:[^>]+\>/g, // Protect <xsl:...>
|
||||
// /<pre.*?>.*?<\/pre>/g, // Protect <pre ></pre>
|
||||
// /<p.*?>.*?<\/p>/g, // Protect <pre ></pre>
|
||||
// /<\?php.*?\?>/g // Protect php code
|
||||
],
|
||||
*/
|
||||
setup: function(ed) {
|
||||
ed.on('keydown', Note.saveNote);
|
||||
// indent outdent
|
||||
ed.on('keydown', function(e) {
|
||||
var num = e.which ? e.which : e.keyCode;
|
||||
if (num == 9) { // tab pressed
|
||||
|
||||
if(!e.shiftKey) {
|
||||
// ed.execCommand('Indent');
|
||||
// TODO 如果当前在li, ul, ol下不执行!!
|
||||
// 如果在pre下就加tab
|
||||
var node = ed.selection.getNode();
|
||||
if(node.nodeName == "PRE") {
|
||||
ed.execCommand('mceInsertRawHTML', false, '\x09'); // inserts tab
|
||||
} else {
|
||||
ed.execCommand('mceInsertRawHTML', false, " "); // inserts 空格
|
||||
}
|
||||
} else {
|
||||
// delete 4 个空格
|
||||
// ed.execCommand('Outdent');
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
// 为了把下拉菜单关闭
|
||||
ed.on("click", function(e) {
|
||||
$("body").trigger("click");
|
||||
});
|
||||
|
||||
// 鼠标移上时
|
||||
ed.on("click", function() {
|
||||
log(ed.selection.getNode())
|
||||
});
|
||||
},
|
||||
|
||||
// fix TinyMCE Removes site base url
|
||||
@ -458,16 +493,17 @@ function initEditor() {
|
||||
selector : "#editorContent",
|
||||
// height: 100,//这个应该是文档的高度, 而其上层的高度是$("#content").height(),
|
||||
// parentHeight: $("#content").height(),
|
||||
content_css : ["css/bootstrap.css", "css/editor/editor.css"].concat(em.getWritingCss()),
|
||||
// content_css : ["/css/bootstrap.css", "/css/editor/editor.css"].concat(em.getWritingCss()),
|
||||
content_css : ["/css/editor/editor.css"].concat(em.getWritingCss()),
|
||||
skin : "custom",
|
||||
language: LEA.locale, // 语言
|
||||
plugins : [
|
||||
"autolink link leaui_image lists charmap hr", "paste",
|
||||
"searchreplace leanote_nav leanote_code tabfocus",
|
||||
"table directionality textcolor codemirror" ], // nonbreaking
|
||||
"table directionality textcolor" ], // nonbreaking
|
||||
|
||||
toolbar1 : "formatselect | forecolor backcolor | bold italic underline strikethrough | leaui_image | leanote_code | bullist numlist | alignleft aligncenter alignright alignjustify",
|
||||
toolbar2 : "outdent indent blockquote | link unlink | table | hr removeformat | subscript superscript |searchreplace | code | pastetext pasteCopyImage | fontselect fontsizeselect",
|
||||
toolbar1 : "formatselect | forecolor backcolor | bold italic underline strikethrough | leaui_image | leanote_code leanote_inline_code | bullist numlist | alignleft aligncenter alignright alignjustify",
|
||||
toolbar2 : "outdent indent blockquote | link unlink | table | hr removeformat | subscript superscript |searchreplace | pastetext pasteCopyImage | leanote_ace_pre | fontselect fontsizeselect",
|
||||
|
||||
// 使用tab键: http://www.tinymce.com/wiki.php/Plugin3x:nonbreaking
|
||||
// http://stackoverflow.com/questions/13543220/tiny-mce-how-to-allow-people-to-indent
|
||||
@ -485,7 +521,8 @@ function initEditor() {
|
||||
+ "Verdana=verdana,geneva;" + "宋体=SimSun;"
|
||||
+ "新宋体=NSimSun;" + "黑体=SimHei;"
|
||||
+ "微软雅黑=Microsoft YaHei",
|
||||
block_formats : "Header 1=h1;Header 2=h2;Header 3=h3; Header 4=h4;Pre=pre;Paragraph=p",
|
||||
block_formats : "Header 1=h1;Header 2=h2;Header 3=h3;Header 4=h4;Paragraph=p",
|
||||
/*
|
||||
codemirror: {
|
||||
indentOnInit: true, // Whether or not to indent code on init.
|
||||
path: 'CodeMirror', // Path to CodeMirror distribution
|
||||
@ -498,6 +535,7 @@ function initEditor() {
|
||||
//'mode/php/php.js'
|
||||
]
|
||||
},
|
||||
*/
|
||||
// This option specifies whether data:url images (inline images) should be removed or not from the pasted contents.
|
||||
// Setting this to "true" will allow the pasted images, and setting this to "false" will disallow pasted images.
|
||||
// For example, Firefox enables you to paste images directly into any contentEditable field. This is normally not something people want, so this option is "false" by default.
|
||||
@ -517,7 +555,7 @@ function initEditor() {
|
||||
// 导航
|
||||
var random = 1;
|
||||
function scrollTo(self, tagName, text) {
|
||||
var iframe = $("#editorContent_ifr").contents();
|
||||
var iframe = $("#editorContent"); // .contents();
|
||||
var target = iframe.find(tagName + ":contains(" + text + ")");
|
||||
random++;
|
||||
|
||||
@ -535,12 +573,15 @@ function scrollTo(self, tagName, text) {
|
||||
if (target.size() >= i+1) {
|
||||
target = target.eq(i);
|
||||
// 之前插入, 防止多行定位不准
|
||||
var top = target.offset().top;
|
||||
var nowTop = iframe.scrollTop();
|
||||
|
||||
// log(target.scrollTop());
|
||||
var top = iframe.scrollTop() - iframe.offset().top + target.offset().top; // 相对于iframe的位置
|
||||
// var nowTop = iframe.scrollTop();
|
||||
// log(nowTop);
|
||||
// log(top);
|
||||
// iframe.scrollTop(top);
|
||||
// $(iframe).animate({scrollTop: top}, 300); // 有问题
|
||||
iframe.animate({scrollTop: top}, 300); // 有问题
|
||||
|
||||
/*
|
||||
var d = 200; // 时间间隔
|
||||
for(var i = 0; i < d; i++) {
|
||||
setTimeout(
|
||||
@ -554,6 +595,7 @@ function scrollTo(self, tagName, text) {
|
||||
setTimeout(function() {
|
||||
iframe.scrollTop(top);
|
||||
}, d+5);
|
||||
*/
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -588,11 +630,12 @@ $(function() {
|
||||
});
|
||||
|
||||
// 导航隐藏与显示
|
||||
$("#leanoteNav h1").on("click", function(e) {
|
||||
if (!$("#leanoteNav").hasClass("unfolder")) {
|
||||
$("#leanoteNav").addClass("unfolder");
|
||||
$(".leanoteNav h1").on("click", function(e) {
|
||||
var $leanoteNav = $(this).closest('.leanoteNav');
|
||||
if (!$leanoteNav.hasClass("unfolder")) {
|
||||
$leanoteNav.addClass("unfolder");
|
||||
} else {
|
||||
$("#leanoteNav").removeClass("unfolder");
|
||||
$leanoteNav.removeClass("unfolder");
|
||||
}
|
||||
});
|
||||
|
||||
@ -690,10 +733,10 @@ $(function() {
|
||||
}
|
||||
}
|
||||
|
||||
$("#leftSwitcher2").click(function() {
|
||||
$("#leftSwitcher2").on('click', function() {
|
||||
maxLeft(true);
|
||||
});
|
||||
$("#leftSwitcher").click(function() {
|
||||
$("#leftSwitcher").click('click', function() {
|
||||
if(Mobile.switchPage()) {
|
||||
minLeft(true);
|
||||
}
|
||||
@ -797,3 +840,510 @@ $(function() {
|
||||
Mobile.init();
|
||||
});
|
||||
|
||||
|
||||
//------------
|
||||
// pjax
|
||||
//------------
|
||||
var Pjax = {
|
||||
init: function() {
|
||||
var me = this;
|
||||
// 当history改变时
|
||||
window.addEventListener('popstate', function(evt){
|
||||
var state = evt.state;
|
||||
if(!state) {
|
||||
return;
|
||||
}
|
||||
document.title = state.title || "Untitled";
|
||||
log("pop");
|
||||
me.changeNotebookAndNote(state.noteId);
|
||||
}, false);
|
||||
|
||||
// ie9
|
||||
if(!history.pushState) {
|
||||
$(window).on("hashchange", function() {
|
||||
var noteId = getHash("noteId");;
|
||||
if(noteId) {
|
||||
me.changeNotebookAndNote(noteId);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
// pjax调用
|
||||
// popstate事件发生时, 转换到noteId下, 此时要转换notebookId
|
||||
changeNotebookAndNote: function(noteId) {
|
||||
var note = Note.getNote(noteId);
|
||||
if(!note) {
|
||||
return;
|
||||
}
|
||||
var isShare = note.Perm != undefined;
|
||||
|
||||
var notebookId = note.NotebookId;
|
||||
// 如果是在当前notebook下, 就不要转换notebook了
|
||||
if(Notebook.curNotebookId == notebookId) {
|
||||
// 不push state
|
||||
Note.changeNoteForPjax(noteId, false);
|
||||
return;
|
||||
}
|
||||
|
||||
// 自己的
|
||||
if(!isShare) {
|
||||
// 先切换到notebook下, 得到notes列表, 再changeNote
|
||||
Notebook.changeNotebook(notebookId, function(notes) {
|
||||
Note.renderNotes(notes);
|
||||
// 不push state
|
||||
Note.changeNoteForPjax(noteId, false, true);
|
||||
});
|
||||
// 共享笔记
|
||||
} else {
|
||||
Share.changeNotebook(note.UserId, notebookId, function(notes) {
|
||||
Note.renderNotes(notes);
|
||||
// 不push state
|
||||
Note.changeNoteForPjax(noteId, false, true);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
// ajax后调用
|
||||
changeNote: function(noteInfo) {
|
||||
var me = this;
|
||||
log("push");
|
||||
var noteId = noteInfo.NoteId;
|
||||
var title = noteInfo.Title;
|
||||
var url = '/note/' + noteId;
|
||||
if(location.hash) {
|
||||
url += location.hash;
|
||||
}
|
||||
// 如果支持pushState
|
||||
if(history.pushState) {
|
||||
var state=({
|
||||
url: url,
|
||||
noteId: noteId,
|
||||
title: title,
|
||||
});
|
||||
history.pushState(state, title, url);
|
||||
document.title = title || 'Untitled';
|
||||
// 不支持, 则用hash
|
||||
} else {
|
||||
setHash("noteId", noteId);
|
||||
}
|
||||
}
|
||||
};
|
||||
$(function() {
|
||||
Pjax.init();
|
||||
});
|
||||
|
||||
//----------
|
||||
// aceEditor
|
||||
LeaAce = {
|
||||
// aceEditorID
|
||||
_aceId: 0,
|
||||
// {id=>ace}
|
||||
_aceEditors: {},
|
||||
_isInit: false,
|
||||
_canAce: false,
|
||||
isAce: true, // 切换pre, 默认是true
|
||||
disableAddHistory: function() {
|
||||
tinymce.activeEditor.undoManager.setCanAdd(false);
|
||||
},
|
||||
resetAddHistory: function() {
|
||||
tinymce.activeEditor.undoManager.setCanAdd(true);
|
||||
},
|
||||
canAce: function() {
|
||||
if(this._isInit) {
|
||||
return this._canAce;
|
||||
}
|
||||
if(getVendorPrefix() == "webkit" && !Mobile.isMobile()) {
|
||||
this._canAce = true;
|
||||
} else {
|
||||
this._canAce = false;
|
||||
}
|
||||
this._isInit = true;
|
||||
return this._canAce;
|
||||
},
|
||||
canAndIsAce: function() {
|
||||
return this.canAce() && this.isAce;
|
||||
},
|
||||
getAceId: function () {
|
||||
this.aceId++;
|
||||
return "leanote_ace_" + (new Date()).getTime() + "_" + this._aceId;
|
||||
},
|
||||
initAce: function(id, val, force) {
|
||||
var me = this;
|
||||
if(!force && !me.canAndIsAce()) {
|
||||
return;
|
||||
}
|
||||
me.disableAddHistory();
|
||||
var $pre = $('#' + id);
|
||||
$pre.find('.toggle-raw').remove();
|
||||
var preHtml = $pre.html();
|
||||
|
||||
$pre.removeClass('ace-to-pre');
|
||||
$pre.attr("contenteditable", false); // ? 避免tinymce编辑
|
||||
var aceEditor = ace.edit(id);
|
||||
aceEditor.setTheme("ace/theme/tomorrow");
|
||||
|
||||
var brush = me.getPreBrush($pre);
|
||||
var b = "";
|
||||
if(brush) {
|
||||
try {
|
||||
b = brush.split(':')[1];
|
||||
} catch(e) {}
|
||||
}
|
||||
b = b || "javascript";
|
||||
aceEditor.session.setMode("ace/mode/" + b);
|
||||
aceEditor.getSession().setUseWorker(false); // 不用语法检查
|
||||
aceEditor.setOption("showInvisibles", false); // 不显示空格, 没用
|
||||
aceEditor.setOption("wrap", "free");
|
||||
aceEditor.setShowInvisibles(false);
|
||||
aceEditor.setAutoScrollEditorIntoView(true);
|
||||
aceEditor.setOption("maxLines", 100);
|
||||
aceEditor.commands.addCommand({
|
||||
name: "undo",
|
||||
bindKey: {win: "Ctrl-z", mac: "Command-z"},
|
||||
exec: function(editor) {
|
||||
var undoManager = editor.getSession().getUndoManager();
|
||||
if(undoManager.hasUndo()){
|
||||
undoManager.undo();
|
||||
} else {
|
||||
undoManager.reset();
|
||||
tinymce.activeEditor.undoManager.undo();
|
||||
}
|
||||
}
|
||||
});
|
||||
this._aceEditors[id] = aceEditor;
|
||||
if(val) {
|
||||
aceEditor.setValue(val);
|
||||
// 不要选择代码
|
||||
// TODO
|
||||
} else {
|
||||
// 防止 <pre><div>xx</div></pre> 这里的<div>消失
|
||||
// preHtml = preHtml.replace('/ /g', ' '); // 以前是把' ' 全换成了
|
||||
// aceEditor.setValue(preHtml);
|
||||
// 全不选
|
||||
// aceEditor.selection.clearSelection();
|
||||
}
|
||||
|
||||
// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
|
||||
me.resetAddHistory();
|
||||
return aceEditor;
|
||||
},
|
||||
clearIntervalForInitAce: null,
|
||||
initAceFromContent: function(editor) {
|
||||
if(!this.canAndIsAce()) {
|
||||
var content = $(editor.getBody());
|
||||
content.find('pre').removeClass('ace_editor');
|
||||
return;
|
||||
}
|
||||
var me = this;
|
||||
// 延迟
|
||||
if(this.clearIntervalForInitAce) {
|
||||
clearInterval(this.clearIntervalForInitAce);
|
||||
}
|
||||
this.clearIntervalForInitAce = setTimeout(function() {
|
||||
var content = $(editor.getBody());
|
||||
var pres = content.find('pre');
|
||||
for(var i = 0 ; i < pres.length; ++i) {
|
||||
var pre = pres.eq(i);
|
||||
// 如果不是ace
|
||||
if(me.isInAce(pre)) {
|
||||
break;
|
||||
}
|
||||
setTimeout((function(pre) {
|
||||
return function() {
|
||||
pre.find('.toggle-raw').remove();
|
||||
var value = pre.html();
|
||||
log(value);
|
||||
value = value.replace(/ /g, " ").replace(/\<br *\/*\>/gi,"\n").replace(/</g, '<').replace(/>/g, '>');
|
||||
pre.html(value);
|
||||
var id = pre.attr('id');
|
||||
if(!id) {
|
||||
id = me.getAceId();
|
||||
pre.attr('id', id);
|
||||
}
|
||||
me.initAce(id);
|
||||
}
|
||||
})(pre));
|
||||
}
|
||||
}, 10);
|
||||
},
|
||||
|
||||
allToPre: function(editor) {
|
||||
if(!this.canAndIsAce()) {
|
||||
return;
|
||||
}
|
||||
var me = this;
|
||||
// 延迟
|
||||
if(me.clearIntervalForInitAce) {
|
||||
clearInterval(me.clearIntervalForInitAce);
|
||||
}
|
||||
me.clearIntervalForInitAce = setTimeout(function() {
|
||||
var content = $(editor.getBody());
|
||||
var pres = content.find('pre');
|
||||
for(var i = 0 ; i < pres.length; ++i) {
|
||||
var pre = pres.eq(i);
|
||||
setTimeout((function(pre) {
|
||||
return function() {
|
||||
me.aceToPre(pre);
|
||||
}
|
||||
})(pre));
|
||||
}
|
||||
}, 10);
|
||||
},
|
||||
|
||||
undo: function(editor) {
|
||||
if(!this.canAndIsAce()) {
|
||||
return;
|
||||
}
|
||||
var me = this;
|
||||
// 延迟
|
||||
if(this.clearIntervalForInitAce) {
|
||||
clearInterval(this.clearIntervalForInitAce);
|
||||
}
|
||||
this.clearIntervalForInitAce = setTimeout(function() {
|
||||
var content = $(editor.getBody());
|
||||
var pres = content.find('pre');
|
||||
for(var i = 0 ; i < pres.length; ++i) {
|
||||
var pre = pres.eq(i);
|
||||
setTimeout((function(pre) {
|
||||
return function() {
|
||||
var value = pre.html();
|
||||
var id = pre.attr('id');
|
||||
var aceEditor = me.getAce(id);
|
||||
if(aceEditor) {
|
||||
var value = aceEditor.getValue();
|
||||
aceEditor.destroy();
|
||||
var aceEditor = me.initAce(id, value);
|
||||
// 全不选
|
||||
aceEditor.selection.clearSelection();
|
||||
} else {
|
||||
value = value.replace(/ /g, " ").replace(/\<br *\/*\>/gi,"\n");
|
||||
pre.html(value);
|
||||
var id = pre.attr('id');
|
||||
if(!id) {
|
||||
id = me.getAceId();
|
||||
pre.attr('id', id);
|
||||
}
|
||||
me.initAce(id);
|
||||
}
|
||||
}
|
||||
})(pre));
|
||||
}
|
||||
}, 10);
|
||||
},
|
||||
destroyAceFromContent: function(everContent) {
|
||||
if(!this.canAce()) {
|
||||
return;
|
||||
}
|
||||
var pres = everContent.find('pre');
|
||||
for(var i = 0 ; i < pres.length; ++i) {
|
||||
var id = pres.eq(i).attr('id');
|
||||
var aceEditorAndPre = this.getAce(id);
|
||||
if(aceEditorAndPre) {
|
||||
aceEditorAndPre.destroy();
|
||||
this._aceEditors[id] = null;
|
||||
}
|
||||
}
|
||||
},
|
||||
getAce: function(id) {
|
||||
if(!this.canAce()) {
|
||||
return;
|
||||
}
|
||||
return this._aceEditors[id];
|
||||
},
|
||||
// 当前焦点是否在aceEditor中
|
||||
nowIsInAce: function () {
|
||||
if(!this.canAce()) {
|
||||
return;
|
||||
}
|
||||
|
||||
var node = tinymce.activeEditor.selection.getNode();
|
||||
// log("now...");
|
||||
// log(node);
|
||||
return this.isInAce(node);
|
||||
|
||||
},
|
||||
nowIsInPre: function(){
|
||||
var node = tinymce.activeEditor.selection.getNode();
|
||||
// log("now...");
|
||||
// log(node);
|
||||
return this.isInPre(node);
|
||||
},
|
||||
isInPre: function(node) {
|
||||
var $node = $(node);
|
||||
var node = $node.get(0);
|
||||
if(node.nodeName == "PRE") {
|
||||
return true;
|
||||
} else {
|
||||
// 找到父是pre
|
||||
$pre = $node.closest("pre");
|
||||
if($pre.length == 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
},
|
||||
// 是否在node内
|
||||
isInAce: function(node) {
|
||||
if(!this.canAce()) {
|
||||
return;
|
||||
}
|
||||
var $node = $(node);
|
||||
var node = $node.get(0);
|
||||
if(node.nodeName == "PRE") {
|
||||
// $node.data('brush', brush);
|
||||
var id = $node.attr('id');
|
||||
var aceEditor = this.getAce(id);
|
||||
if(aceEditor) {
|
||||
return [aceEditor, $node];
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
// 找到父是pre
|
||||
$pre = $node.closest("pre");
|
||||
if($pre.length == 0) {
|
||||
return false;
|
||||
}
|
||||
return this.isInAce($pre);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
getPreBrush: function (node) {
|
||||
var $pre = $(node);
|
||||
var classes = $pre.attr('class');
|
||||
if(!classes) {
|
||||
return '';
|
||||
}
|
||||
var m = classes.match(/brush:[^ ]*/);
|
||||
var everBrush = "";
|
||||
if(m && m.length > 0) {
|
||||
everBrush = m[0];
|
||||
}
|
||||
return everBrush;
|
||||
},
|
||||
// pre转换成ace
|
||||
preToAce: function (pre, force) {
|
||||
if(!force && !this.canAce()) {
|
||||
return;
|
||||
}
|
||||
var $pre = $(pre);
|
||||
var id = this.getAceId();
|
||||
$pre.attr('id', id);
|
||||
var editor = this.initAce(id, "", true);
|
||||
if(editor) {
|
||||
editor.focus();
|
||||
}
|
||||
},
|
||||
aceToPre: function(pre, isFocus) {
|
||||
var me = this;
|
||||
var $pre = $(pre);
|
||||
// 转成pre
|
||||
var aceEditorAndPre = me.isInAce($pre);
|
||||
if(aceEditorAndPre) {
|
||||
var aceEditor = aceEditorAndPre[0];
|
||||
var $pre = aceEditorAndPre[1];
|
||||
var value = aceEditor.getValue();
|
||||
value = value.replace(/</g, '<').replace(/>/g, '>');
|
||||
// var id = getAceId();
|
||||
var replacePre = $('<pre class="' + $pre.attr('class') + ' ace-to-pre">' + value + "</pre>");
|
||||
$pre.replaceWith(replacePre);
|
||||
aceEditor.destroy();
|
||||
me._aceEditors[$pre.attr('id')] = null;
|
||||
// log($replacePre);
|
||||
if(isFocus) {
|
||||
setTimeout(function() {
|
||||
var tinymceEditor = tinymce.activeEditor;
|
||||
var selection = tinymceEditor.selection;
|
||||
var rng = selection.getRng();
|
||||
// rng.setStart(replacePre.get(0), 1);
|
||||
// rng.setEnd(replacePre.get(0), 9);
|
||||
rng.selectNode(replacePre.get(0));
|
||||
// selection.setRng(rng);
|
||||
// replacePre.focus();
|
||||
tinymceEditor.focus();
|
||||
replacePre.trigger("click");
|
||||
replacePre.html(value + " ");
|
||||
// log(">>>>>>>>>>>>>>")
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
},
|
||||
// 转换raw <-> code
|
||||
handleEvent: function () {
|
||||
if(!this.canAce()) {
|
||||
return;
|
||||
}
|
||||
var me = this;
|
||||
$("#editorContent").on('mouseenter', 'pre', function(){
|
||||
// log('in');
|
||||
// log($(this));
|
||||
var $t = $(this);
|
||||
$raw = $t.find('.toggle-raw');
|
||||
if($raw.length == 0) {
|
||||
$t.append('<div class="toggle-raw" title="Toggle code with raw html"><input type="checkbox" /></div>');
|
||||
}
|
||||
$input = $t.find('.toggle-raw input');
|
||||
if(LeaAce.isInAce($t)) {
|
||||
$input.prop('checked', true);
|
||||
} else {
|
||||
$input.prop('checked', false);
|
||||
}
|
||||
});
|
||||
$("#editorContent").on('mouseleave', 'pre', function(){
|
||||
var $raw = $(this).find('.toggle-raw');
|
||||
$raw.remove();
|
||||
});
|
||||
$("#editorContent").on('change', '.toggle-raw input', function(){
|
||||
var checked = $(this).prop('checked');
|
||||
var $pre = $(this).closest('pre');
|
||||
if(checked) {
|
||||
// 转成ace
|
||||
me.preToAce($pre, true);
|
||||
} else {
|
||||
me.aceToPre($pre, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// note.html调用
|
||||
// 实始化页面
|
||||
function initPage() {
|
||||
$(function() {
|
||||
Notebook.renderNotebooks(notebooks);
|
||||
Share.renderShareNotebooks(sharedUserInfos, shareNotebooks);
|
||||
|
||||
// 如果初始打开的是共享的笔记
|
||||
// 那么定位到我的笔记
|
||||
if(curSharedNoteNotebookId) {
|
||||
Share.firstRenderShareNote(curSharedUserId, curSharedNoteNotebookId, curNoteId);
|
||||
// 初始打开的是我的笔记
|
||||
} else {
|
||||
Note.setNoteCache(noteContentJson);
|
||||
Note.renderNotes(notes);
|
||||
if(curNoteId) {
|
||||
// 指定某个note时才target notebook, /note定位到最新
|
||||
// ie10&+要setTimeout
|
||||
setTimeout(function() {
|
||||
Note.changeNoteForPjax(curNoteId, true, curNotebookId);
|
||||
});
|
||||
if(!curNotebookId) {
|
||||
Notebook.selectNotebook($(tt('#notebook [notebookId="?"]', Notebook.allNotebookId)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 指定笔记, 也要保存最新笔记
|
||||
if(latestNotes.length > 0) {
|
||||
for(var i = 0; i < latestNotes.length; ++i) {
|
||||
Note.addNoteCache(latestNotes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
Tag.renderTagNav(tagsJson);
|
||||
// init notebook后才调用
|
||||
initSlimScroll();
|
||||
|
||||
LeaAce.handleEvent();
|
||||
});
|
||||
}
|
||||
|
2
public/js/app/share-min.js
vendored
2
public/js/app/share-min.js
vendored
File diff suppressed because one or more lines are too long
@ -26,25 +26,25 @@ Share.setCache = function(note) {
|
||||
Share.cache[note.NoteId] = note;
|
||||
}
|
||||
|
||||
/**
|
||||
* 我的共享notebooks
|
||||
<div id="shareNotebooks">
|
||||
<div class="folderNote closed">
|
||||
<div class="folderHeader">
|
||||
<a>
|
||||
<h1>
|
||||
<i class="fa fa-angle-right"></i>
|
||||
Life's</h1>
|
||||
</a>
|
||||
</div>
|
||||
<ul class="folderBody">
|
||||
<li><a>Hadoop</a></li>
|
||||
<li><a>Node webkit</a></li>
|
||||
<li><a>Hadoop</a></li>
|
||||
<li><a>Node webkit</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
*/
|
||||
/**
|
||||
* 我的共享notebooks
|
||||
<div id="shareNotebooks">
|
||||
<div class="folderNote closed">
|
||||
<div class="folderHeader">
|
||||
<a>
|
||||
<h1>
|
||||
<i class="fa fa-angle-right"></i>
|
||||
Life's</h1>
|
||||
</a>
|
||||
</div>
|
||||
<ul class="folderBody">
|
||||
<li><a>Hadoop</a></li>
|
||||
<li><a>Node webkit</a></li>
|
||||
<li><a>Hadoop</a></li>
|
||||
<li><a>Node webkit</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
*/
|
||||
// TODO 层级
|
||||
// shareNotebooks = {userId => {}}
|
||||
Share.getNotebooksForNew = function(userId, notebooks) {
|
||||
@ -94,7 +94,7 @@ Share.renderShareNotebooks = function(sharedUserInfos, shareNotebooks) {
|
||||
}
|
||||
|
||||
if(!shareNotebooks || typeof shareNotebooks != "object" || shareNotebooks.length < 0) {
|
||||
shareNotebooks = {};
|
||||
shareNotebooks = {};
|
||||
}
|
||||
|
||||
var $shareNotebooks = $("#shareNotebooks");
|
||||
@ -113,7 +113,7 @@ Share.renderShareNotebooks = function(sharedUserInfos, shareNotebooks) {
|
||||
Share.sharedUserInfos[userInfo.UserId] = userInfo;
|
||||
var userId = userInfo.UserId;
|
||||
var header = tt('<li class="each-user"><div class="friend-header" fromUserId="?"><i class="fa fa-angle-down"></i><span>?</span> <span class="fa notebook-setting" title="setting"></span> </div>', userInfo.UserId, username);
|
||||
var friendId = "friendContainer_" + userId;
|
||||
var friendId = "friendContainer_" + userId;
|
||||
var body = '<ul class="friend-notebooks ztree" id="' + friendId + '" fromUserId="' + userId + '"></ul>';
|
||||
$shareNotebooks.append(header + body + "</li>")
|
||||
|
||||
@ -193,7 +193,7 @@ Share.renderShareNotebooks = function(sharedUserInfos, shareNotebooks) {
|
||||
e.stopPropagation();
|
||||
var $p = $(this).parent();
|
||||
menuNotebooks.showMenu(e, $p);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
Share.isDefaultNotebookId = function(notebookId) {
|
||||
@ -243,25 +243,47 @@ Share.toggleToSharedNav = function(userId, notebookId) {
|
||||
$("#tagSearch").hide();
|
||||
}
|
||||
|
||||
// 刷新加载共享的笔记本, page.js调用
|
||||
Share.firstRenderShareNote = function(ownerUserId, notebookId, noteId) {
|
||||
$("#myShareNotebooks .folderHeader").trigger("click");
|
||||
// 这里, 可能这个笔记本是子笔记本, 所以先扩展
|
||||
Notebook.expandNotebookTo(notebookId, ownerUserId);
|
||||
Share.changeNotebook(ownerUserId, notebookId, function(notes) {
|
||||
Note.renderNotes(notes);
|
||||
// 不push state
|
||||
Note.changeNoteForPjax(noteId, false, false);
|
||||
});
|
||||
};
|
||||
|
||||
//改变笔记本
|
||||
//0. 改变样式
|
||||
//1. 改变note, 此时需要先保存
|
||||
//2. ajax得到该notebook下的所有note
|
||||
//3. 使用Note.RederNotes()
|
||||
Share.changeNotebook = function(userId, notebookId) {
|
||||
Share.changeNotebook = function(userId, notebookId, callback) {
|
||||
var me = this;
|
||||
Notebook.curNotebookId = notebookId;
|
||||
// 选中
|
||||
Notebook.selectNotebook($(tt('#friendContainer_? a[notebookId="?"]', userId, notebookId)));
|
||||
var $t = $(tt('#friendContainer_? a[notebookId="?"]', userId, notebookId));
|
||||
if($t.length == 0) {
|
||||
// 切换到默认共享中
|
||||
// 表示是popstate的默认共享笔记本下
|
||||
Notebook.selectNotebook($(tt('#friendContainer_? a[notebookId="?"]', userId, me.defaultNotebookId)));
|
||||
notebookId = me.defaultNotebookId;
|
||||
} else {
|
||||
Notebook.selectNotebook($t);
|
||||
}
|
||||
|
||||
// 改变nav!!!! TODO
|
||||
Share.toggleToSharedNav(userId, notebookId);
|
||||
|
||||
|
||||
// 1
|
||||
Note.curChangedSaveIt();
|
||||
|
||||
// 2 先清空所有
|
||||
Note.clearAll();
|
||||
|
||||
var url = "/share/ListShareNotes/";
|
||||
var url = "/share/listShareNotes";
|
||||
var param = {userId: userId};
|
||||
if(!Share.isDefaultNotebookId(notebookId)) {
|
||||
param.notebookId = notebookId;
|
||||
@ -276,21 +298,28 @@ Share.changeNotebook = function(userId, notebookId) {
|
||||
if(param.notebookId) {
|
||||
|
||||
}
|
||||
Note.renderNotes(ret, false, true);
|
||||
// 渲染第一个
|
||||
// 这里, 有点小复杂, 还要判断权限...
|
||||
if(!isEmpty(ret)) {
|
||||
// 定位
|
||||
Note.changeNote(ret[0].NoteId, true);
|
||||
if(callback) {
|
||||
callback(ret);
|
||||
} else {
|
||||
Note.renderNotes(ret, false, true);
|
||||
// 渲染第一个
|
||||
// 这里, 有点小复杂, 还要判断权限...
|
||||
if(!isEmpty(ret)) {
|
||||
// 定位
|
||||
Note.changeNoteForPjax(ret[0].NoteId, true, false);
|
||||
} else {
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 是否有更新权限
|
||||
// called by Note
|
||||
Share.hasUpdatePerm = function(notebookId) {
|
||||
var note = Share.cache[notebookId];
|
||||
Share.hasUpdatePerm = function(noteId) {
|
||||
var note = Share.cache[noteId];
|
||||
if(!note) {
|
||||
note = Note.getNote(noteId);
|
||||
}
|
||||
if(!note || !note.Perm) {
|
||||
return false;
|
||||
}
|
||||
@ -338,7 +367,7 @@ Share.changeNotebookForNewNote = function(notebookId) {
|
||||
Share.toggleToSharedNav(userId, notebookId);
|
||||
|
||||
// 得到笔记本
|
||||
var url = "/share/ListShareNotes/";
|
||||
var url = "/share/listShareNotes";
|
||||
var param = {userId: userId, notebookId: notebookId};
|
||||
|
||||
// 2 得到笔记本
|
||||
@ -401,7 +430,7 @@ Share.initContextmenu = function(notebooksCopy) {
|
||||
}
|
||||
|
||||
Share.contextmenu = $("#noteItemList .item-shared").contextmenu(noteListMenu);
|
||||
}
|
||||
};
|
||||
|
||||
$(function() {
|
||||
// note setting
|
||||
@ -413,8 +442,6 @@ $(function() {
|
||||
Share.contextmenu.showMenu(e, $p);
|
||||
});
|
||||
|
||||
|
||||
|
||||
//---------------------------
|
||||
// 新建笔记
|
||||
// 1. 直接点击新建 OR
|
||||
@ -453,10 +480,10 @@ $(function() {
|
||||
toHtml = getMsg("readOnly");
|
||||
toPerm = "0";
|
||||
}
|
||||
var url = "/share/UpdateShareNotebookPerm";
|
||||
var url = "/share/updateShareNotebookPerm";
|
||||
var param = {perm: toPerm, toUserId: toUserId};
|
||||
if(Share.dialogIsNote) {
|
||||
url = "/share/UpdateShareNotePerm";
|
||||
url = "/share/updateShareNotePerm";
|
||||
param.noteId = noteOrNotebookId;
|
||||
} else {
|
||||
param.notebookId = noteOrNotebookId;
|
||||
@ -474,10 +501,10 @@ $(function() {
|
||||
var noteOrNotebookId = $(this).attr("noteOrNotebookId");
|
||||
var toUserId = $(this).attr("toUserId");
|
||||
|
||||
var url = "/share/DeleteShareNotebook";
|
||||
var url = "/share/deleteShareNotebook";
|
||||
var param = {toUserId: toUserId};
|
||||
if(Share.dialogIsNote) {
|
||||
url = "/share/DeleteShareNote";
|
||||
url = "/share/deleteShareNote";
|
||||
param.noteId = noteOrNotebookId;
|
||||
} else {
|
||||
param.notebookId = noteOrNotebookId;
|
||||
@ -533,10 +560,10 @@ function addShareNoteOrNotebook(trSeq) {
|
||||
var shareNotePerm = $(trId + ' input[name="perm' + trSeq + '"]:checked').val() || 0;
|
||||
var perm = shareNotePerm;
|
||||
// emails = emails.split(";");
|
||||
var url = "share/addShareNote";
|
||||
var url = "/share/addShareNote";
|
||||
var data = {noteId: id, emails: [emails], perm: shareNotePerm};
|
||||
if(!Share.dialogIsNote) {
|
||||
url = "share/addShareNotebook";
|
||||
url = "/share/addShareNotebook";
|
||||
data = {notebookId: id, emails: [emails], perm: shareNotePerm};
|
||||
}
|
||||
hideAlert("#shareMsg");
|
||||
@ -552,16 +579,8 @@ function addShareNoteOrNotebook(trSeq) {
|
||||
tpl += tt('<td><a href="#" noteOrNotebookId="?" toUserId="?" class="btn btn-warning delete-share">' + getMsg("delete") +'</a></td>', id, ret.Id);
|
||||
$(trId).html(tpl);
|
||||
} else {
|
||||
var shareUrl = UrlPrefix + '/register?from=' + UserInfo.Username;
|
||||
showAlert("#shareMsg", getMsg('friendNotExits', [getMsg("app"), shareUrl]) + ' <a id="shareCopy" data-clipboard-target="copyDiv">' + getMsg("clickToCopy") + '</a> <span id="copyStatus"></span> <br /> ' + getMsg("sendInviteEmailToYourFriend") + ', <a href="#" onclick="sendRegisterEmail(\'' + emails + '\')">' + getMsg("send"), "warning");
|
||||
$("#copyDiv").text(shareUrl);
|
||||
initCopy("shareCopy", function(args) {
|
||||
if(args.text) {
|
||||
showMsg2("#copyStatus", getMsg("copySuccess"), 1000);
|
||||
} else {
|
||||
showMsg2("#copyStatus", getMsg("copyFailed"), 1000);
|
||||
}
|
||||
});
|
||||
var shareUrl = UrlPrefix + '/register?iu=' + UserInfo.Username;
|
||||
showAlert("#shareMsg", getMsg('friendNotExits', [getMsg("app"), '<input style="background: none;border: 1px solid #ccc;width: 300px;padding: 3px;border-radius: 3px;outline: none;" onclick="$(this).focus().select()" type="text" value="' + shareUrl + '" />']) + '</a> <br /> ' + getMsg("sendInviteEmailToYourFriend") + ', <a href="#" onclick="sendRegisterEmail(\'' + emails + '\')">' + getMsg("send"), "warning");
|
||||
}
|
||||
}
|
||||
}, trId + " .btn-success");
|
||||
@ -580,4 +599,4 @@ function sendRegisterEmail(email) {
|
||||
|
||||
function deleteShareNoteOrNotebook(trSeq) {
|
||||
$("#tr" + trSeq).remove();
|
||||
}
|
||||
}
|
||||
|
6
public/js/common-min.js
vendored
6
public/js/common-min.js
vendored
File diff suppressed because one or more lines are too long
@ -18,11 +18,13 @@ var Tag = {};
|
||||
var Notebook = {};
|
||||
var Share = {};
|
||||
var Mobile = {}; // 手机端处理
|
||||
var LeaAce = {};
|
||||
|
||||
// markdown
|
||||
var Converter;
|
||||
var MarkdownEditor;
|
||||
var ScrollLink;
|
||||
var MD;
|
||||
|
||||
//---------------------
|
||||
// 公用方法
|
||||
@ -276,18 +278,39 @@ ajaxPostJson(
|
||||
});
|
||||
*/
|
||||
|
||||
function getVendorPrefix() {
|
||||
// 使用body是为了避免在还需要传入元素
|
||||
var body = document.body || document.documentElement,
|
||||
style = body.style,
|
||||
vendor = ['webkit', 'khtml', 'moz', 'ms', 'o'],
|
||||
i = 0;
|
||||
|
||||
while (i < vendor.length) {
|
||||
// 此处进行判断是否有对应的内核前缀
|
||||
if (typeof style[vendor[i] + 'Transition'] === 'string') {
|
||||
return vendor[i];
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------
|
||||
|
||||
// 切换编辑器时要修改tabIndex
|
||||
function editorIframeTabindex(index) {
|
||||
var $i = $("#editorContent_ifr");
|
||||
if($i.size() == 0) {
|
||||
setTimeout(function() {
|
||||
editorIframeTabindex(index);
|
||||
}, 100);
|
||||
} else {
|
||||
var $i = $("#editorContent");
|
||||
// var $i = $("#editorContent_ifr");
|
||||
// if($i.size() == 0) {
|
||||
$i.attr("tabindex", index);
|
||||
}
|
||||
setTimeout(function() {
|
||||
$i.attr("tabindex", index);
|
||||
}, 500);
|
||||
setTimeout(function() {
|
||||
$i.attr("tabindex", index);
|
||||
}, 1000);
|
||||
// } else {
|
||||
// $i.attr("tabindex", index);
|
||||
// }
|
||||
}
|
||||
//切换编辑器
|
||||
LEA.isM = false;
|
||||
@ -299,7 +322,7 @@ function switchEditor(isMarkdown) {
|
||||
// 富文本永远是2
|
||||
if(!isMarkdown) {
|
||||
$("#editor").show();
|
||||
$("#mdEditor").css("z-index", 1);
|
||||
$("#mdEditor").css("z-index", 1).hide();
|
||||
|
||||
// 刚开始没有
|
||||
editorIframeTabindex(2);
|
||||
@ -314,26 +337,56 @@ function switchEditor(isMarkdown) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// editor 设置内容
|
||||
// 可能是tinymce还没有渲染成功
|
||||
var previewToken = "<div style='display: none'>FORTOKEN</div>"
|
||||
var clearIntervalForSetContent;
|
||||
function setEditorContent(content, isMarkdown, preview) {
|
||||
if(!content) {
|
||||
content = "";
|
||||
}
|
||||
if(clearIntervalForSetContent) {
|
||||
clearInterval(clearIntervalForSetContent);
|
||||
}
|
||||
if(!isMarkdown) {
|
||||
// 先destroy之前的ace
|
||||
/*
|
||||
if(typeof tinymce != "undefined" && tinymce.activeEditor) {
|
||||
var editor = tinymce.activeEditor;
|
||||
var everContent = $(editor.getBody());
|
||||
if(everContent) {
|
||||
LeaAce.destroyAceFromContent(everContent);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
$("#editorContent").html(content);
|
||||
if(typeof tinymce != "undefined" && tinymce.activeEditor) {
|
||||
var editor = tinymce.activeEditor;
|
||||
editor.setContent(content);
|
||||
/*
|
||||
if(LeaAce.canAce() && LeaAce.isAce) {
|
||||
try {
|
||||
LeaAce.initAceFromContent(editor);
|
||||
} catch(e) {
|
||||
log(e);
|
||||
}
|
||||
} else {
|
||||
// 为了在firefox下有正常的显示
|
||||
$("#editorContent pre").removeClass("ace-tomorrow ace_editor");
|
||||
}
|
||||
*/
|
||||
editor.undoManager.clear(); // 4-7修复BUG
|
||||
} else {
|
||||
// 等下再设置
|
||||
setTimeout(function() {
|
||||
clearIntervalForSetContent = setTimeout(function() {
|
||||
setEditorContent(content, false);
|
||||
}, 100);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
$("#wmd-input").val(content);
|
||||
$("#wmd-preview").html(""); // 防止先点有的, 再点tinymce再点没内容的
|
||||
if(!content || preview) { // 没有内容就不要解析了
|
||||
@ -348,11 +401,19 @@ function setEditorContent(content, isMarkdown, preview) {
|
||||
MarkdownEditor.refreshPreview();
|
||||
} else {
|
||||
// 等下再设置
|
||||
setTimeout(function() {
|
||||
clearIntervalForSetContent = setTimeout(function() {
|
||||
setEditorContent(content, true, preview);
|
||||
}, 200);
|
||||
}
|
||||
}
|
||||
*/
|
||||
if(MD) {
|
||||
MD.setContent(content);
|
||||
} else {
|
||||
clearIntervalForSetContent = setTimeout(function() {
|
||||
setEditorContent(content, true);
|
||||
}, 100);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -369,7 +430,24 @@ function getEditorContent(isMarkdown) {
|
||||
if(!isMarkdown) {
|
||||
var editor = tinymce.activeEditor;
|
||||
if(editor) {
|
||||
var content = $(editor.getBody());
|
||||
var content = $(editor.getBody()).clone();
|
||||
// 删除toggle raw
|
||||
content.find('.toggle-raw').remove();
|
||||
|
||||
// 替换掉ace editor
|
||||
var pres = content.find('pre');
|
||||
for(var i = 0 ; i < pres.length; ++i) {
|
||||
var pre = pres.eq(i);
|
||||
var id = pre.attr('id');
|
||||
var aceEditor = LeaAce.getAce(id);
|
||||
if(aceEditor) {
|
||||
var val = aceEditor.getValue();
|
||||
val = val.replace(/</g, '<').replace(/>/g, '>');
|
||||
pre.removeAttr('style', '').removeAttr('contenteditable').removeClass('ace_editor');
|
||||
pre.html(val);
|
||||
}
|
||||
}
|
||||
|
||||
// 去掉恶心的花瓣注入
|
||||
// <pinit></pinit>
|
||||
// 把最后的<script>..</script>全去掉
|
||||
@ -404,7 +482,8 @@ function getEditorContent(isMarkdown) {
|
||||
return content;
|
||||
}
|
||||
} else {
|
||||
return [$("#wmd-input").val(), $("#wmd-preview").html()]
|
||||
// return [$("#wmd-input").val(), $("#wmd-preview").html()]
|
||||
return [MD.getContent(), '<div>' + $("#preview-contents").html() + '</div>']
|
||||
}
|
||||
}
|
||||
|
||||
@ -601,6 +680,10 @@ function resizeEditor(second) {
|
||||
ifrParent.height(height);
|
||||
// log(height + '---------------------------------------')
|
||||
$("#editorContent_ifr").height(height);
|
||||
|
||||
// life 12.9
|
||||
// inline editor
|
||||
$("#editorContent").css("top", $("#mceToolbar").height());
|
||||
|
||||
/*
|
||||
// 第一次时可能会被改变
|
||||
@ -720,7 +803,16 @@ function hideLoading() {
|
||||
}
|
||||
|
||||
// 注销, 先清空cookie
|
||||
function setCookie(c_name, value, expiredays){
|
||||
var exdate = new Date();
|
||||
exdate.setDate(exdate.getDate() + expiredays);
|
||||
document.cookie = c_name+ "=" + escape(value) + ((expiredays==null) ? "" : ";expires="+exdate.toGMTString());
|
||||
}
|
||||
function logout() {
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
setCookie("LEANOTE_SESSION", '', -1);
|
||||
>>>>>>> dev-life
|
||||
location.href = UrlPrefix + "/logout?id=1";
|
||||
}
|
||||
|
||||
@ -1145,4 +1237,45 @@ var vd = {
|
||||
return ok;
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// 返回hash的#a=1&b=3 返回{a:1, b:3}
|
||||
function getHashObject() {
|
||||
var hash = location.hash; // #life
|
||||
if(!hash) {
|
||||
return {};
|
||||
}
|
||||
var hashKV = hash.substr(1);
|
||||
var kvs = hashKV.split("&");
|
||||
var kvsObj = {};
|
||||
for(var i = 0; i < kvs.length; ++i) {
|
||||
var kv = kvs[i].split('=');
|
||||
if(kv.length == 2) {
|
||||
kvsObj[kv[0]] = kv[1];
|
||||
}
|
||||
}
|
||||
return kvsObj;
|
||||
}
|
||||
function getHash(key, value) {
|
||||
var kvs = getHashObject();
|
||||
return kvs[key];
|
||||
}
|
||||
function setHash(key, value) {
|
||||
var hash = location.hash; // #life
|
||||
if(!hash) {
|
||||
location.href = "#" + key + "=" + value;
|
||||
return;
|
||||
}
|
||||
var kvs = getHashObject();
|
||||
kvs[key] = value;
|
||||
var str = "";
|
||||
for(var i in kvs) {
|
||||
if(kvs[i]) {
|
||||
if(str) {
|
||||
str += "&";
|
||||
}
|
||||
str += i + '=' + kvs[i];
|
||||
}
|
||||
}
|
||||
location.href = "#" + str;
|
||||
}
|
822
public/js/fastclick.js
Normal file
822
public/js/fastclick.js
Normal file
@ -0,0 +1,822 @@
|
||||
/**
|
||||
* @preserve FastClick: polyfill to remove click delays on browsers with touch UIs.
|
||||
*
|
||||
* @version 1.0.3
|
||||
* @codingstandard ftlabs-jsv2
|
||||
* @copyright The Financial Times Limited [All Rights Reserved]
|
||||
* @license MIT License (see LICENSE.txt)
|
||||
*/
|
||||
|
||||
/*jslint browser:true, node:true*/
|
||||
/*global define, Event, Node*/
|
||||
|
||||
|
||||
/**
|
||||
* Instantiate fast-clicking listeners on the specified layer.
|
||||
*
|
||||
* @constructor
|
||||
* @param {Element} layer The layer to listen on
|
||||
* @param {Object} options The options to override the defaults
|
||||
*/
|
||||
function FastClick(layer, options) {
|
||||
'use strict';
|
||||
var oldOnClick;
|
||||
|
||||
options = options || {};
|
||||
|
||||
/**
|
||||
* Whether a click is currently being tracked.
|
||||
*
|
||||
* @type boolean
|
||||
*/
|
||||
this.trackingClick = false;
|
||||
|
||||
|
||||
/**
|
||||
* Timestamp for when click tracking started.
|
||||
*
|
||||
* @type number
|
||||
*/
|
||||
this.trackingClickStart = 0;
|
||||
|
||||
|
||||
/**
|
||||
* The element being tracked for a click.
|
||||
*
|
||||
* @type EventTarget
|
||||
*/
|
||||
this.targetElement = null;
|
||||
|
||||
|
||||
/**
|
||||
* X-coordinate of touch start event.
|
||||
*
|
||||
* @type number
|
||||
*/
|
||||
this.touchStartX = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Y-coordinate of touch start event.
|
||||
*
|
||||
* @type number
|
||||
*/
|
||||
this.touchStartY = 0;
|
||||
|
||||
|
||||
/**
|
||||
* ID of the last touch, retrieved from Touch.identifier.
|
||||
*
|
||||
* @type number
|
||||
*/
|
||||
this.lastTouchIdentifier = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Touchmove boundary, beyond which a click will be cancelled.
|
||||
*
|
||||
* @type number
|
||||
*/
|
||||
this.touchBoundary = options.touchBoundary || 10;
|
||||
|
||||
|
||||
/**
|
||||
* The FastClick layer.
|
||||
*
|
||||
* @type Element
|
||||
*/
|
||||
this.layer = layer;
|
||||
|
||||
/**
|
||||
* The minimum time between tap(touchstart and touchend) events
|
||||
*
|
||||
* @type number
|
||||
*/
|
||||
this.tapDelay = options.tapDelay || 200;
|
||||
|
||||
if (FastClick.notNeeded(layer)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Some old versions of Android don't have Function.prototype.bind
|
||||
function bind(method, context) {
|
||||
return function() { return method.apply(context, arguments); };
|
||||
}
|
||||
|
||||
|
||||
var methods = ['onMouse', 'onClick', 'onTouchStart', 'onTouchMove', 'onTouchEnd', 'onTouchCancel'];
|
||||
var context = this;
|
||||
for (var i = 0, l = methods.length; i < l; i++) {
|
||||
context[methods[i]] = bind(context[methods[i]], context);
|
||||
}
|
||||
|
||||
// Set up event handlers as required
|
||||
if (deviceIsAndroid) {
|
||||
layer.addEventListener('mouseover', this.onMouse, true);
|
||||
layer.addEventListener('mousedown', this.onMouse, true);
|
||||
layer.addEventListener('mouseup', this.onMouse, true);
|
||||
}
|
||||
|
||||
layer.addEventListener('click', this.onClick, true);
|
||||
layer.addEventListener('touchstart', this.onTouchStart, false);
|
||||
layer.addEventListener('touchmove', this.onTouchMove, false);
|
||||
layer.addEventListener('touchend', this.onTouchEnd, false);
|
||||
layer.addEventListener('touchcancel', this.onTouchCancel, false);
|
||||
|
||||
// Hack is required for browsers that don't support Event#stopImmediatePropagation (e.g. Android 2)
|
||||
// which is how FastClick normally stops click events bubbling to callbacks registered on the FastClick
|
||||
// layer when they are cancelled.
|
||||
if (!Event.prototype.stopImmediatePropagation) {
|
||||
layer.removeEventListener = function(type, callback, capture) {
|
||||
var rmv = Node.prototype.removeEventListener;
|
||||
if (type === 'click') {
|
||||
rmv.call(layer, type, callback.hijacked || callback, capture);
|
||||
} else {
|
||||
rmv.call(layer, type, callback, capture);
|
||||
}
|
||||
};
|
||||
|
||||
layer.addEventListener = function(type, callback, capture) {
|
||||
var adv = Node.prototype.addEventListener;
|
||||
if (type === 'click') {
|
||||
adv.call(layer, type, callback.hijacked || (callback.hijacked = function(event) {
|
||||
if (!event.propagationStopped) {
|
||||
callback(event);
|
||||
}
|
||||
}), capture);
|
||||
} else {
|
||||
adv.call(layer, type, callback, capture);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// If a handler is already declared in the element's onclick attribute, it will be fired before
|
||||
// FastClick's onClick handler. Fix this by pulling out the user-defined handler function and
|
||||
// adding it as listener.
|
||||
if (typeof layer.onclick === 'function') {
|
||||
|
||||
// Android browser on at least 3.2 requires a new reference to the function in layer.onclick
|
||||
// - the old one won't work if passed to addEventListener directly.
|
||||
oldOnClick = layer.onclick;
|
||||
layer.addEventListener('click', function(event) {
|
||||
oldOnClick(event);
|
||||
}, false);
|
||||
layer.onclick = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Android requires exceptions.
|
||||
*
|
||||
* @type boolean
|
||||
*/
|
||||
var deviceIsAndroid = navigator.userAgent.indexOf('Android') > 0;
|
||||
|
||||
|
||||
/**
|
||||
* iOS requires exceptions.
|
||||
*
|
||||
* @type boolean
|
||||
*/
|
||||
var deviceIsIOS = /iP(ad|hone|od)/.test(navigator.userAgent);
|
||||
|
||||
|
||||
/**
|
||||
* iOS 4 requires an exception for select elements.
|
||||
*
|
||||
* @type boolean
|
||||
*/
|
||||
var deviceIsIOS4 = deviceIsIOS && (/OS 4_\d(_\d)?/).test(navigator.userAgent);
|
||||
|
||||
|
||||
/**
|
||||
* iOS 6.0(+?) requires the target element to be manually derived
|
||||
*
|
||||
* @type boolean
|
||||
*/
|
||||
var deviceIsIOSWithBadTarget = deviceIsIOS && (/OS ([6-9]|\d{2})_\d/).test(navigator.userAgent);
|
||||
|
||||
/**
|
||||
* BlackBerry requires exceptions.
|
||||
*
|
||||
* @type boolean
|
||||
*/
|
||||
var deviceIsBlackBerry10 = navigator.userAgent.indexOf('BB10') > 0;
|
||||
|
||||
/**
|
||||
* Determine whether a given element requires a native click.
|
||||
*
|
||||
* @param {EventTarget|Element} target Target DOM element
|
||||
* @returns {boolean} Returns true if the element needs a native click
|
||||
*/
|
||||
FastClick.prototype.needsClick = function(target) {
|
||||
'use strict';
|
||||
switch (target.nodeName.toLowerCase()) {
|
||||
|
||||
// Don't send a synthetic click to disabled inputs (issue #62)
|
||||
case 'button':
|
||||
case 'select':
|
||||
case 'textarea':
|
||||
if (target.disabled) {
|
||||
return true;
|
||||
}
|
||||
|
||||
break;
|
||||
case 'input':
|
||||
|
||||
// File inputs need real clicks on iOS 6 due to a browser bug (issue #68)
|
||||
if ((deviceIsIOS && target.type === 'file') || target.disabled) {
|
||||
return true;
|
||||
}
|
||||
|
||||
break;
|
||||
case 'label':
|
||||
case 'video':
|
||||
return true;
|
||||
}
|
||||
|
||||
return (/\bneedsclick\b/).test(target.className);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Determine whether a given element requires a call to focus to simulate click into element.
|
||||
*
|
||||
* @param {EventTarget|Element} target Target DOM element
|
||||
* @returns {boolean} Returns true if the element requires a call to focus to simulate native click.
|
||||
*/
|
||||
FastClick.prototype.needsFocus = function(target) {
|
||||
'use strict';
|
||||
switch (target.nodeName.toLowerCase()) {
|
||||
case 'textarea':
|
||||
return true;
|
||||
case 'select':
|
||||
return !deviceIsAndroid;
|
||||
case 'input':
|
||||
switch (target.type) {
|
||||
case 'button':
|
||||
case 'checkbox':
|
||||
case 'file':
|
||||
case 'image':
|
||||
case 'radio':
|
||||
case 'submit':
|
||||
return false;
|
||||
}
|
||||
|
||||
// No point in attempting to focus disabled inputs
|
||||
return !target.disabled && !target.readOnly;
|
||||
default:
|
||||
return (/\bneedsfocus\b/).test(target.className);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Send a click event to the specified element.
|
||||
*
|
||||
* @param {EventTarget|Element} targetElement
|
||||
* @param {Event} event
|
||||
*/
|
||||
FastClick.prototype.sendClick = function(targetElement, event) {
|
||||
'use strict';
|
||||
var clickEvent, touch;
|
||||
|
||||
// On some Android devices activeElement needs to be blurred otherwise the synthetic click will have no effect (#24)
|
||||
if (document.activeElement && document.activeElement !== targetElement) {
|
||||
document.activeElement.blur();
|
||||
// $("#editorContent_ifr").blur();
|
||||
}
|
||||
|
||||
touch = event.changedTouches[0];
|
||||
|
||||
// Synthesise a click event, with an extra attribute so it can be tracked
|
||||
clickEvent = document.createEvent('MouseEvents');
|
||||
clickEvent.initMouseEvent(this.determineEventType(targetElement), true, true, window, 1, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null);
|
||||
clickEvent.forwardedTouchEvent = true;
|
||||
targetElement.dispatchEvent(clickEvent);
|
||||
};
|
||||
|
||||
FastClick.prototype.determineEventType = function(targetElement) {
|
||||
'use strict';
|
||||
|
||||
//Issue #159: Android Chrome Select Box does not open with a synthetic click event
|
||||
if (deviceIsAndroid && targetElement.tagName.toLowerCase() === 'select') {
|
||||
return 'mousedown';
|
||||
}
|
||||
|
||||
return 'click';
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {EventTarget|Element} targetElement
|
||||
*/
|
||||
FastClick.prototype.focus = function(targetElement) {
|
||||
'use strict';
|
||||
var length;
|
||||
|
||||
// Issue #160: on iOS 7, some input elements (e.g. date datetime) throw a vague TypeError on setSelectionRange. These elements don't have an integer value for the selectionStart and selectionEnd properties, but unfortunately that can't be used for detection because accessing the properties also throws a TypeError. Just check the type instead. Filed as Apple bug #15122724.
|
||||
if (deviceIsIOS && targetElement.setSelectionRange && targetElement.type.indexOf('date') !== 0 && targetElement.type !== 'time') {
|
||||
length = targetElement.value.length;
|
||||
targetElement.setSelectionRange(length, length);
|
||||
} else {
|
||||
targetElement.focus();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Check whether the given target element is a child of a scrollable layer and if so, set a flag on it.
|
||||
*
|
||||
* @param {EventTarget|Element} targetElement
|
||||
*/
|
||||
FastClick.prototype.updateScrollParent = function(targetElement) {
|
||||
'use strict';
|
||||
var scrollParent, parentElement;
|
||||
|
||||
scrollParent = targetElement.fastClickScrollParent;
|
||||
|
||||
// Attempt to discover whether the target element is contained within a scrollable layer. Re-check if the
|
||||
// target element was moved to another parent.
|
||||
if (!scrollParent || !scrollParent.contains(targetElement)) {
|
||||
parentElement = targetElement;
|
||||
do {
|
||||
if (parentElement.scrollHeight > parentElement.offsetHeight) {
|
||||
scrollParent = parentElement;
|
||||
targetElement.fastClickScrollParent = parentElement;
|
||||
break;
|
||||
}
|
||||
|
||||
parentElement = parentElement.parentElement;
|
||||
} while (parentElement);
|
||||
}
|
||||
|
||||
// Always update the scroll top tracker if possible.
|
||||
if (scrollParent) {
|
||||
scrollParent.fastClickLastScrollTop = scrollParent.scrollTop;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {EventTarget} targetElement
|
||||
* @returns {Element|EventTarget}
|
||||
*/
|
||||
FastClick.prototype.getTargetElementFromEventTarget = function(eventTarget) {
|
||||
'use strict';
|
||||
|
||||
// On some older browsers (notably Safari on iOS 4.1 - see issue #56) the event target may be a text node.
|
||||
if (eventTarget.nodeType === Node.TEXT_NODE) {
|
||||
return eventTarget.parentNode;
|
||||
}
|
||||
|
||||
return eventTarget;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* On touch start, record the position and scroll offset.
|
||||
*
|
||||
* @param {Event} event
|
||||
* @returns {boolean}
|
||||
*/
|
||||
FastClick.prototype.onTouchStart = function(event) {
|
||||
'use strict';
|
||||
var targetElement, touch, selection;
|
||||
|
||||
// Ignore multiple touches, otherwise pinch-to-zoom is prevented if both fingers are on the FastClick element (issue #111).
|
||||
if (event.targetTouches.length > 1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
targetElement = this.getTargetElementFromEventTarget(event.target);
|
||||
touch = event.targetTouches[0];
|
||||
|
||||
if (deviceIsIOS) {
|
||||
|
||||
// Only trusted events will deselect text on iOS (issue #49)
|
||||
selection = window.getSelection();
|
||||
if (selection.rangeCount && !selection.isCollapsed) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!deviceIsIOS4) {
|
||||
|
||||
// Weird things happen on iOS when an alert or confirm dialog is opened from a click event callback (issue #23):
|
||||
// when the user next taps anywhere else on the page, new touchstart and touchend events are dispatched
|
||||
// with the same identifier as the touch event that previously triggered the click that triggered the alert.
|
||||
// Sadly, there is an issue on iOS 4 that causes some normal touch events to have the same identifier as an
|
||||
// immediately preceeding touch event (issue #52), so this fix is unavailable on that platform.
|
||||
// Issue 120: touch.identifier is 0 when Chrome dev tools 'Emulate touch events' is set with an iOS device UA string,
|
||||
// which causes all touch events to be ignored. As this block only applies to iOS, and iOS identifiers are always long,
|
||||
// random integers, it's safe to to continue if the identifier is 0 here.
|
||||
if (touch.identifier && touch.identifier === this.lastTouchIdentifier) {
|
||||
event.preventDefault();
|
||||
return false;
|
||||
}
|
||||
|
||||
this.lastTouchIdentifier = touch.identifier;
|
||||
|
||||
// If the target element is a child of a scrollable layer (using -webkit-overflow-scrolling: touch) and:
|
||||
// 1) the user does a fling scroll on the scrollable layer
|
||||
// 2) the user stops the fling scroll with another tap
|
||||
// then the event.target of the last 'touchend' event will be the element that was under the user's finger
|
||||
// when the fling scroll was started, causing FastClick to send a click event to that layer - unless a check
|
||||
// is made to ensure that a parent layer was not scrolled before sending a synthetic click (issue #42).
|
||||
this.updateScrollParent(targetElement);
|
||||
}
|
||||
}
|
||||
|
||||
this.trackingClick = true;
|
||||
this.trackingClickStart = event.timeStamp;
|
||||
this.targetElement = targetElement;
|
||||
|
||||
this.touchStartX = touch.pageX;
|
||||
this.touchStartY = touch.pageY;
|
||||
|
||||
// Prevent phantom clicks on fast double-tap (issue #36)
|
||||
if ((event.timeStamp - this.lastClickTime) < this.tapDelay) {
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Based on a touchmove event object, check whether the touch has moved past a boundary since it started.
|
||||
*
|
||||
* @param {Event} event
|
||||
* @returns {boolean}
|
||||
*/
|
||||
FastClick.prototype.touchHasMoved = function(event) {
|
||||
'use strict';
|
||||
var touch = event.changedTouches[0], boundary = this.touchBoundary;
|
||||
|
||||
if (Math.abs(touch.pageX - this.touchStartX) > boundary || Math.abs(touch.pageY - this.touchStartY) > boundary) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Update the last position.
|
||||
*
|
||||
* @param {Event} event
|
||||
* @returns {boolean}
|
||||
*/
|
||||
FastClick.prototype.onTouchMove = function(event) {
|
||||
'use strict';
|
||||
if (!this.trackingClick) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If the touch has moved, cancel the click tracking
|
||||
if (this.targetElement !== this.getTargetElementFromEventTarget(event.target) || this.touchHasMoved(event)) {
|
||||
this.trackingClick = false;
|
||||
this.targetElement = null;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Attempt to find the labelled control for the given label element.
|
||||
*
|
||||
* @param {EventTarget|HTMLLabelElement} labelElement
|
||||
* @returns {Element|null}
|
||||
*/
|
||||
FastClick.prototype.findControl = function(labelElement) {
|
||||
'use strict';
|
||||
|
||||
// Fast path for newer browsers supporting the HTML5 control attribute
|
||||
if (labelElement.control !== undefined) {
|
||||
return labelElement.control;
|
||||
}
|
||||
|
||||
// All browsers under test that support touch events also support the HTML5 htmlFor attribute
|
||||
if (labelElement.htmlFor) {
|
||||
return document.getElementById(labelElement.htmlFor);
|
||||
}
|
||||
|
||||
// If no for attribute exists, attempt to retrieve the first labellable descendant element
|
||||
// the list of which is defined here: http://www.w3.org/TR/html5/forms.html#category-label
|
||||
return labelElement.querySelector('button, input:not([type=hidden]), keygen, meter, output, progress, select, textarea');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* On touch end, determine whether to send a click event at once.
|
||||
*
|
||||
* @param {Event} event
|
||||
* @returns {boolean}
|
||||
*/
|
||||
FastClick.prototype.onTouchEnd = function(event) {
|
||||
'use strict';
|
||||
var forElement, trackingClickStart, targetTagName, scrollParent, touch, targetElement = this.targetElement;
|
||||
|
||||
if (!this.trackingClick) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Prevent phantom clicks on fast double-tap (issue #36)
|
||||
if ((event.timeStamp - this.lastClickTime) < this.tapDelay) {
|
||||
this.cancelNextClick = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Reset to prevent wrong click cancel on input (issue #156).
|
||||
this.cancelNextClick = false;
|
||||
|
||||
this.lastClickTime = event.timeStamp;
|
||||
|
||||
trackingClickStart = this.trackingClickStart;
|
||||
this.trackingClick = false;
|
||||
this.trackingClickStart = 0;
|
||||
|
||||
// On some iOS devices, the targetElement supplied with the event is invalid if the layer
|
||||
// is performing a transition or scroll, and has to be re-detected manually. Note that
|
||||
// for this to function correctly, it must be called *after* the event target is checked!
|
||||
// See issue #57; also filed as rdar://13048589 .
|
||||
if (deviceIsIOSWithBadTarget) {
|
||||
touch = event.changedTouches[0];
|
||||
|
||||
// In certain cases arguments of elementFromPoint can be negative, so prevent setting targetElement to null
|
||||
targetElement = document.elementFromPoint(touch.pageX - window.pageXOffset, touch.pageY - window.pageYOffset) || targetElement;
|
||||
targetElement.fastClickScrollParent = this.targetElement.fastClickScrollParent;
|
||||
}
|
||||
|
||||
targetTagName = targetElement.tagName.toLowerCase();
|
||||
if (targetTagName === 'label') {
|
||||
forElement = this.findControl(targetElement);
|
||||
if (forElement) {
|
||||
this.focus(targetElement);
|
||||
if (deviceIsAndroid) {
|
||||
return false;
|
||||
}
|
||||
|
||||
targetElement = forElement;
|
||||
}
|
||||
} else if (this.needsFocus(targetElement)) {
|
||||
|
||||
// Case 1: If the touch started a while ago (best guess is 100ms based on tests for issue #36) then focus will be triggered anyway. Return early and unset the target element reference so that the subsequent click will be allowed through.
|
||||
// Case 2: Without this exception for input elements tapped when the document is contained in an iframe, then any inputted text won't be visible even though the value attribute is updated as the user types (issue #37).
|
||||
if ((event.timeStamp - trackingClickStart) > 100 || (deviceIsIOS && window.top !== window && targetTagName === 'input')) {
|
||||
this.targetElement = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
this.focus(targetElement);
|
||||
this.sendClick(targetElement, event);
|
||||
|
||||
// Select elements need the event to go through on iOS 4, otherwise the selector menu won't open.
|
||||
// Also this breaks opening selects when VoiceOver is active on iOS6, iOS7 (and possibly others)
|
||||
if (!deviceIsIOS || targetTagName !== 'select') {
|
||||
this.targetElement = null;
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (deviceIsIOS && !deviceIsIOS4) {
|
||||
|
||||
// Don't send a synthetic click event if the target element is contained within a parent layer that was scrolled
|
||||
// and this tap is being used to stop the scrolling (usually initiated by a fling - issue #42).
|
||||
scrollParent = targetElement.fastClickScrollParent;
|
||||
if (scrollParent && scrollParent.fastClickLastScrollTop !== scrollParent.scrollTop) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Prevent the actual click from going though - unless the target node is marked as requiring
|
||||
// real clicks or if it is in the whitelist in which case only non-programmatic clicks are permitted.
|
||||
if (!this.needsClick(targetElement)) {
|
||||
event.preventDefault();
|
||||
this.sendClick(targetElement, event);
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* On touch cancel, stop tracking the click.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
FastClick.prototype.onTouchCancel = function() {
|
||||
'use strict';
|
||||
this.trackingClick = false;
|
||||
this.targetElement = null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Determine mouse events which should be permitted.
|
||||
*
|
||||
* @param {Event} event
|
||||
* @returns {boolean}
|
||||
*/
|
||||
FastClick.prototype.onMouse = function(event) {
|
||||
'use strict';
|
||||
|
||||
// If a target element was never set (because a touch event was never fired) allow the event
|
||||
if (!this.targetElement) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (event.forwardedTouchEvent) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Programmatically generated events targeting a specific element should be permitted
|
||||
if (!event.cancelable) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Derive and check the target element to see whether the mouse event needs to be permitted;
|
||||
// unless explicitly enabled, prevent non-touch click events from triggering actions,
|
||||
// to prevent ghost/doubleclicks.
|
||||
if (!this.needsClick(this.targetElement) || this.cancelNextClick) {
|
||||
|
||||
// Prevent any user-added listeners declared on FastClick element from being fired.
|
||||
if (event.stopImmediatePropagation) {
|
||||
event.stopImmediatePropagation();
|
||||
} else {
|
||||
|
||||
// Part of the hack for browsers that don't support Event#stopImmediatePropagation (e.g. Android 2)
|
||||
event.propagationStopped = true;
|
||||
}
|
||||
|
||||
// Cancel the event
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the mouse event is permitted, return true for the action to go through.
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* On actual clicks, determine whether this is a touch-generated click, a click action occurring
|
||||
* naturally after a delay after a touch (which needs to be cancelled to avoid duplication), or
|
||||
* an actual click which should be permitted.
|
||||
*
|
||||
* @param {Event} event
|
||||
* @returns {boolean}
|
||||
*/
|
||||
FastClick.prototype.onClick = function(event) {
|
||||
'use strict';
|
||||
var permitted;
|
||||
|
||||
// It's possible for another FastClick-like library delivered with third-party code to fire a click event before FastClick does (issue #44). In that case, set the click-tracking flag back to false and return early. This will cause onTouchEnd to return early.
|
||||
if (this.trackingClick) {
|
||||
this.targetElement = null;
|
||||
this.trackingClick = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Very odd behaviour on iOS (issue #18): if a submit element is present inside a form and the user hits enter in the iOS simulator or clicks the Go button on the pop-up OS keyboard the a kind of 'fake' click event will be triggered with the submit-type input element as the target.
|
||||
if (event.target.type === 'submit' && event.detail === 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
permitted = this.onMouse(event);
|
||||
|
||||
// Only unset targetElement if the click is not permitted. This will ensure that the check for !targetElement in onMouse fails and the browser's click doesn't go through.
|
||||
if (!permitted) {
|
||||
this.targetElement = null;
|
||||
}
|
||||
|
||||
// If clicks are permitted, return true for the action to go through.
|
||||
return permitted;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Remove all FastClick's event listeners.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
FastClick.prototype.destroy = function() {
|
||||
'use strict';
|
||||
var layer = this.layer;
|
||||
|
||||
if (deviceIsAndroid) {
|
||||
layer.removeEventListener('mouseover', this.onMouse, true);
|
||||
layer.removeEventListener('mousedown', this.onMouse, true);
|
||||
layer.removeEventListener('mouseup', this.onMouse, true);
|
||||
}
|
||||
|
||||
layer.removeEventListener('click', this.onClick, true);
|
||||
layer.removeEventListener('touchstart', this.onTouchStart, false);
|
||||
layer.removeEventListener('touchmove', this.onTouchMove, false);
|
||||
layer.removeEventListener('touchend', this.onTouchEnd, false);
|
||||
layer.removeEventListener('touchcancel', this.onTouchCancel, false);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Check whether FastClick is needed.
|
||||
*
|
||||
* @param {Element} layer The layer to listen on
|
||||
*/
|
||||
FastClick.notNeeded = function(layer) {
|
||||
'use strict';
|
||||
var metaViewport;
|
||||
var chromeVersion;
|
||||
var blackberryVersion;
|
||||
|
||||
// Devices that don't support touch don't need FastClick
|
||||
if (typeof window.ontouchstart === 'undefined') {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Chrome version - zero for other browsers
|
||||
chromeVersion = +(/Chrome\/([0-9]+)/.exec(navigator.userAgent) || [,0])[1];
|
||||
|
||||
if (chromeVersion) {
|
||||
|
||||
if (deviceIsAndroid) {
|
||||
metaViewport = document.querySelector('meta[name=viewport]');
|
||||
|
||||
if (metaViewport) {
|
||||
// Chrome on Android with user-scalable="no" doesn't need FastClick (issue #89)
|
||||
if (metaViewport.content.indexOf('user-scalable=no') !== -1) {
|
||||
return true;
|
||||
}
|
||||
// Chrome 32 and above with width=device-width or less don't need FastClick
|
||||
if (chromeVersion > 31 && document.documentElement.scrollWidth <= window.outerWidth) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Chrome desktop doesn't need FastClick (issue #15)
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (deviceIsBlackBerry10) {
|
||||
blackberryVersion = navigator.userAgent.match(/Version\/([0-9]*)\.([0-9]*)/);
|
||||
|
||||
// BlackBerry 10.3+ does not require Fastclick library.
|
||||
// https://github.com/ftlabs/fastclick/issues/251
|
||||
if (blackberryVersion[1] >= 10 && blackberryVersion[2] >= 3) {
|
||||
metaViewport = document.querySelector('meta[name=viewport]');
|
||||
|
||||
if (metaViewport) {
|
||||
// user-scalable=no eliminates click delay.
|
||||
if (metaViewport.content.indexOf('user-scalable=no') !== -1) {
|
||||
return true;
|
||||
}
|
||||
// width=device-width (or less than device-width) eliminates click delay.
|
||||
if (document.documentElement.scrollWidth <= window.outerWidth) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// IE10 with -ms-touch-action: none, which disables double-tap-to-zoom (issue #97)
|
||||
if (layer.style.msTouchAction === 'none') {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Factory method for creating a FastClick object
|
||||
*
|
||||
* @param {Element} layer The layer to listen on
|
||||
* @param {Object} options The options to override the defaults
|
||||
*/
|
||||
FastClick.attach = function(layer, options) {
|
||||
'use strict';
|
||||
return new FastClick(layer, options);
|
||||
};
|
||||
|
||||
|
||||
if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
|
||||
|
||||
// AMD. Register as an anonymous module.
|
||||
define(function() {
|
||||
'use strict';
|
||||
return FastClick;
|
||||
});
|
||||
} else if (typeof module !== 'undefined' && module.exports) {
|
||||
module.exports = FastClick.attach;
|
||||
module.exports.FastClick = FastClick;
|
||||
} else {
|
||||
window.FastClick = FastClick;
|
||||
}
|
10
public/js/jquery.mobile-1.4.4.min.js
vendored
Normal file
10
public/js/jquery.mobile-1.4.4.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
3
public/js/jquery.ztree.all-3.5-min.js
vendored
Normal file
3
public/js/jquery.ztree.all-3.5-min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -830,8 +830,10 @@
|
||||
}
|
||||
|
||||
if (!isSilent) {
|
||||
if(parentNode.Subs.length > 0) {
|
||||
if(parentNode.Subs && parentNode.Subs.length > 0) {
|
||||
view.expandCollapseParentNode(setting, parentNode, true);
|
||||
} else {
|
||||
parentNode.Subs = [];
|
||||
}
|
||||
}
|
||||
|
||||
|
2
public/js/main-min.js
vendored
2
public/js/main-min.js
vendored
@ -1 +1 @@
|
||||
require.config({baseUrl:"/public",paths:{tinymce:"tinymce/tinymce","jquery.slimscroll":"js/jQuery-slimScroll-1.3.0/jquery.slimscroll",contextmenu:"js/contextmenu/jquery.contextmenu","jquery.cookie":"js/jquery-cookie",page:"js/app/page",note:"js/app/note",notebook:"js/app/notebook",tag:"js/app/tag",share:"js/app/share",objectId:"js/object_id-min",ZeroClipboard:"js/ZeroClipboard/ZeroClipboard-min",bootstrap:"js/bootstrap-min",leanote:"js/main",leaui_image:"tinymce/plugins/leaui_image/public/js/for_editor",attachment_upload:"js/app/attachment_upload","jquery.ui.widget":"tinymce/plugins/leaui_image/public/js/jquery.ui.widget",fileupload:"/tinymce/plugins/leaui_image/public/js/jquery.fileupload","iframe-transport":"/tinymce/plugins/leaui_image/public/js/jquery.iframe-transport","Markdown.Converter":"mdeditor/editor/pagedown/Markdown.Converter-min","Markdown.Sanitizer":"mdeditor/editor/pagedown/Markdown.Sanitizer-min","Markdown.Editor":"mdeditor/editor/pagedown/Markdown.Editor","Markdown.zh":"mdeditor/editor/pagedown/local/Markdown.local.zh-min","Markdown.en":"mdeditor/editor/pagedown/local/Markdown.local.en-min","Markdown.Extra":"mdeditor/editor/Markdown.Extra-min",underscore:"mdeditor/editor/underscore-min",scrollLink:"mdeditor/editor/scrollLink",mathJax:"mdeditor/editor/mathJax","jquery.waitforimages":"mdeditor/editor/jquery.waitforimages-min",pretty:"mdeditor/editor/google-code-prettify/prettify",mdeditor:"mdeditor/editor/mdeditor","jquery.mobile":"js/jquery.mobile-1.4.4.min",fastclick:"js/fastclick"},shim:{page:{deps:["tinymce"]},fileupload:{deps:["jquery.ui.widget","iframe-transport"]},"Markdown.Sanitizer":{deps:["Markdown.Converter"]},"Markdown.Editor":{deps:["Markdown.Converter"]},"Markdown.Extra":{deps:["Markdown.Editor"]},"Markdown.zh":{deps:["Markdown.Editor"]},"Markdown.en":{deps:["Markdown.Editor"]}}});require(["mdeditor"],function(mdeditor){});require(["leaui_image"],function(leaui_image){});require(["attachment_upload"],function(attachment_upload){});require(["attachment_upload"],function(attachment_upload){});if(Mobile.isMobile()){require(["fastclick"],function(){})}
|
||||
require.config({baseUrl:"/public",paths:{tinymce:"tinymce/tinymce","jquery.slimscroll":"js/jQuery-slimScroll-1.3.0/jquery.slimscroll",contextmenu:"js/contextmenu/jquery.contextmenu-min","jquery.cookie":"js/jquery-cookie",page:"js/app/page-min",note:"js/app/note-min",notebook:"js/app/notebook-min",tag:"js/app/tag-min",share:"js/app/share-min",objectId:"js/object_id-min",ZeroClipboard:"js/ZeroClipboard/ZeroClipboard-min",bootstrap:"js/bootstrap-min",leanote:"js/main",editor_drop_paste:"js/app/editor_drop_paste-min",attachment_upload:"js/app/attachment_upload-min","jquery.ui.widget":"tinymce/plugins/leaui_image/public/js/jquery.ui.widget",fileupload:"/tinymce/plugins/leaui_image/public/js/jquery.fileupload","iframe-transport":"/tinymce/plugins/leaui_image/public/js/jquery.iframe-transport","Markdown.Converter":"mdeditor/editor/pagedown/Markdown.Converter-min","Markdown.Sanitizer":"mdeditor/editor/pagedown/Markdown.Sanitizer-min","Markdown.Editor":"mdeditor/editor/pagedown/Markdown.Editor","Markdown.zh":"mdeditor/editor/pagedown/local/Markdown.local.zh-min","Markdown.en":"mdeditor/editor/pagedown/local/Markdown.local.en-min","Markdown.Extra":"mdeditor/editor/Markdown.Extra-min",underscore:"mdeditor/editor/underscore-min",scrollLink:"mdeditor/editor/scrollLink-min",mathJax:"mdeditor/editor/mathJax-min","jquery.waitforimages":"mdeditor/editor/jquery.waitforimages-min",pretty:"mdeditor/editor/google-code-prettify/prettify",mdeditor:"mdeditor/editor/mdeditor","jquery.mobile":"js/jquery.mobile-1.4.4.min",fastclick:"js/fastclick"},shim:{page:{deps:["tinymce"]},fileupload:{deps:["jquery.ui.widget","iframe-transport"]},"Markdown.Sanitizer":{deps:["Markdown.Converter"]},"Markdown.Editor":{deps:["Markdown.Converter"]},"Markdown.Extra":{deps:["Markdown.Editor"]},"Markdown.zh":{deps:["Markdown.Editor"]},"Markdown.en":{deps:["Markdown.Editor"]}}});require(["editor_drop_paste"],function(leaui_image){});require(["attachment_upload"],function(attachment_upload){});
|
@ -5,21 +5,21 @@ require.config({
|
||||
// base editor
|
||||
'tinymce': 'tinymce/tinymce',
|
||||
'jquery.slimscroll': 'js/jQuery-slimScroll-1.3.0/jquery.slimscroll',
|
||||
'contextmenu': 'js/contextmenu/jquery.contextmenu',
|
||||
'contextmenu': 'js/contextmenu/jquery.contextmenu-min',
|
||||
'jquery.cookie': 'js/jquery-cookie',
|
||||
'page': 'js/app/page',
|
||||
'note': 'js/app/note',
|
||||
'notebook': 'js/app/notebook',
|
||||
'tag': 'js/app/tag',
|
||||
'share': 'js/app/share',
|
||||
'page': 'js/app/page-min',
|
||||
'note': 'js/app/note-min',
|
||||
'notebook': 'js/app/notebook-min',
|
||||
'tag': 'js/app/tag-min',
|
||||
'share': 'js/app/share-min',
|
||||
'objectId': 'js/object_id-min',
|
||||
'ZeroClipboard': 'js/ZeroClipboard/ZeroClipboard-min',
|
||||
'bootstrap': 'js/bootstrap-min',
|
||||
'leanote': 'js/main',
|
||||
|
||||
// ajax upload image/attach
|
||||
'leaui_image': 'tinymce/plugins/leaui_image/public/js/for_editor',
|
||||
'attachment_upload': 'js/app/attachment_upload',
|
||||
'editor_drop_paste': 'js/app/editor_drop_paste-min',
|
||||
'attachment_upload': 'js/app/attachment_upload-min',
|
||||
'jquery.ui.widget': 'tinymce/plugins/leaui_image/public/js/jquery.ui.widget',
|
||||
'fileupload': '/tinymce/plugins/leaui_image/public/js/jquery.fileupload',
|
||||
'iframe-transport': '/tinymce/plugins/leaui_image/public/js/jquery.iframe-transport',
|
||||
@ -32,8 +32,8 @@ require.config({
|
||||
'Markdown.en': 'mdeditor/editor/pagedown/local/Markdown.local.en-min',
|
||||
'Markdown.Extra': 'mdeditor/editor/Markdown.Extra-min',
|
||||
'underscore': 'mdeditor/editor/underscore-min',
|
||||
'scrollLink': 'mdeditor/editor/scrollLink',
|
||||
'mathJax': 'mdeditor/editor/mathJax',
|
||||
'scrollLink': 'mdeditor/editor/scrollLink-min',
|
||||
'mathJax': 'mdeditor/editor/mathJax-min',
|
||||
'jquery.waitforimages': 'mdeditor/editor/jquery.waitforimages-min',
|
||||
'pretty': 'mdeditor/editor/google-code-prettify/prettify',
|
||||
'mdeditor': 'mdeditor/editor/mdeditor',
|
||||
@ -80,26 +80,6 @@ require(['jquery.slimscroll', 'contextmenu', 'jquery.cookie',
|
||||
});
|
||||
*/
|
||||
|
||||
require(['mdeditor'], function(mdeditor) {});
|
||||
require(['leaui_image'], function(leaui_image) {});
|
||||
require(['attachment_upload'], function(attachment_upload) {});
|
||||
|
||||
require(['attachment_upload'], function(attachment_upload) {});
|
||||
if(Mobile.isMobile()) {
|
||||
// 不能要, 要了样式会有问题, 会增加一些class(也会减少之前的class)
|
||||
// fastclick会focus
|
||||
require(['fastclick'], function() {
|
||||
/*
|
||||
FastClick.attach($("#noteItemList").get(0));
|
||||
FastClick.attach($("#leftNotebook").get(0));
|
||||
FastClick.attach($("#switcher").get(0));
|
||||
*/
|
||||
});
|
||||
/*
|
||||
$("#noteItemList,#leftSwitcher").on("touchend", function(e) {
|
||||
$(this).trigger("click");
|
||||
e.stopPropagation();
|
||||
});
|
||||
*/
|
||||
}
|
||||
|
||||
// require(['mdeditor'], function(mdeditor) {});
|
||||
require(['editor_drop_paste'], function(leaui_image) {});
|
||||
require(['attachment_upload'], function(attachment_upload) {});
|
14
public/js/other.js
Normal file
14
public/js/other.js
Normal file
@ -0,0 +1,14 @@
|
||||
require.config({
|
||||
paths: {
|
||||
'editor_drop_paste': '/public/js/app/editor_drop_paste-min',
|
||||
'attachment_upload': '/public/js/app/attachment_upload-min',
|
||||
'jquery.ui.widget': '/public/tinymce/plugins/leaui_image/public/js/jquery.ui.widget',
|
||||
'fileupload': '/public/tinymce/plugins/leaui_image/public/js/jquery.fileupload',
|
||||
'iframe-transport': '/public/tinymce/plugins/leaui_image/public/js/jquery.iframe-transport',
|
||||
},
|
||||
shim: {
|
||||
'fileupload': {deps: ['jquery.ui.widget', 'iframe-transport']},
|
||||
}
|
||||
});
|
||||
require(['editor_drop_paste'], function(leaui_image) {});
|
||||
require(['attachment_upload'], function(attachment_upload) {});
|
Reference in New Issue
Block a user