Compare commits

..

340 Commits

Author SHA1 Message Date
Dan Brown
22df25a480 Updated assets and version for v0.19.0 2017-12-10 18:21:07 +00:00
Dan Brown
8b30c7f02e Merge branch 'master' into release 2017-12-10 18:19:20 +00:00
Dan Brown
03eb63ec77 Made it possible to pre-fill login via url
Allows email to be passed to email field.
Also allows password only if in demo mode (Due to security concerns).
2017-12-10 13:56:25 +00:00
Dan Brown
3ed5426315 Moved book cover image input into collapsible section
Prevent extra friction when creating a new book and makes it easier to
skip if grid view is not in use
2017-12-10 13:46:50 +00:00
Dan Brown
90bf13c1ab Updated okta config keys, made SVG fully vector
Also added some additional error handling to login.
2017-12-09 13:32:45 +00:00
Dan Brown
d17eb0f54c Merge branch 'master' of git://github.com/lommes/BookStack into lommes-master 2017-12-09 12:48:08 +00:00
Dan Brown
ac7e3977de Fixed WYSIWYG fullscreen mode on firefox
Prevented overlapping sidebar and collapsed content.
Fixes #605
2017-12-09 12:38:30 +00:00
Dan Brown
d7edc389a6 Enabled custom HTML head content to work within editors
Closes #562
2017-12-08 11:52:43 +00:00
Dan Brown
56d5af1336 Made it possible to configure proxies via env
In reference to #146
2017-12-07 19:46:47 +00:00
Dan Brown
06cf175b08 Prevented page navigation highlighting erroring
This was when no page nav was on the page
2017-12-07 19:27:54 +00:00
Dan Brown
b65abd25e0 Made small var name and formatting tweaks 2017-12-07 19:19:25 +00:00
Dan Brown
a5e49f642b Merge branch 'disable-comments' of git://github.com/Abijeet/BookStack into Abijeet-disable-comments 2017-12-07 19:15:26 +00:00
Dan Brown
91444e83fd Cleaned up some page-show JS 2017-12-07 19:10:31 +00:00
Dan Brown
6063ac4a11 Merge branch 'master' of git://github.com/Abijeet/BookStack 2017-12-07 18:47:07 +00:00
Dan Brown
02fd1c48ed Added meta+enter shortcut for page save
Closes #604
2017-12-07 18:44:20 +00:00
Dan Brown
6ee35f55cc Refactored image picker to js component
Also adjusted default cover image size
2017-12-06 17:32:29 +00:00
Dan Brown
261e57fc4e Converted books view setting to user setting
Also cleaned up/moved new CSS and removed redundant new book methods.
2017-12-06 16:34:26 +00:00
Dan Brown
bc1302a8d8 Merge branch 'BookStackApp-master' of git://github.com/OsmosysSoftware/BookStack into OsmosysSoftware-BookStackApp-master 2017-12-06 15:52:54 +00:00
Dan Brown
eeb2b8cbe5 Prevented finding of check script in lang tests 2017-12-06 11:17:34 +00:00
Dan Brown
b167ae795e Added script to check translation files
Closes #373
2017-12-04 20:25:04 +00:00
Dan Brown
6ebe8bf619 Fixed conflicting PDF facade namespace and corrected php version
Updated composer to have the correct config to install dependancies that
work for 7.0
2017-12-04 17:59:53 +00:00
Timo Bartholomes
009af9736e Add socialite authentication for okta 2017-11-26 16:41:29 +01:00
Dan Brown
7668a999a2 Fixed heavy init breakages made in last commit 2017-11-19 18:31:24 +00:00
Dan Brown
ed88c623d6 Made some further laravel 5.5 cleanup
Removed old bootstrap files that are not needed and
amended composer to laravel upgrade guide
2017-11-19 17:59:12 +00:00
Dan Brown
873b1099f8 Updated to laravel 5.5
Closes #590
2017-11-19 15:56:19 +00:00
Abijeet
6a54733f2b Adding testcases for comments disable / enable setting. 2017-11-16 23:32:36 +05:30
Abijeet
7a5bd23909 Added language translation for the new settings icons. 2017-11-16 00:22:22 +05:30
Abijeet
6bb7b5465f Added code in the settings to disable comments. Based on that hiding the comments section on the page display. 2017-11-16 00:05:24 +05:30
Abijeet Patro
0b967d84ad Merge pull request #2 from BookStackApp/master
Getting the latest code.
2017-11-15 08:05:20 +05:30
Abijeet
2261308415 Removed invalid comments, and formatted the code. 2017-11-15 00:04:35 +05:30
Abijeet
7b5edb4d62 Merge branch 'master' of https://github.com/Abijeet/BookStack 2017-11-15 00:01:48 +05:30
Abijeet
8378f06889 Highlights all headings currently visible. Also fixes extra scrollbar appearing in Firefox. 2017-11-14 23:54:25 +05:30
Abijeet Patro
10dc851697 Merge pull request #1 from BookStackApp/master
Getting the latest changes.
2017-11-13 23:22:45 +05:30
Dan Brown
757cdddc7c Updated version and JS for release v0.18.5 2017-11-11 18:33:04 +00:00
Dan Brown
65579214e2 Allowed custom session expiry time
Closes #570
2017-11-11 18:30:55 +00:00
Dan Brown
d89440d198 Fixed required email confirmation with domain restriction
Added test to cover scenario.

Closes #573
2017-11-11 18:09:48 +00:00
Dan Brown
08e58bab79 Fixed vue component error 2017-11-11 17:10:15 +00:00
Dan Brown
d29b177c84 Merge pull request #563 from 10bass/master
Fix ajax tag suggestion for subdir installs
2017-11-11 17:03:36 +00:00
Dan Brown
151d72e42c Merge pull request #558 from lbguilherme/ptbr
Update pt_BR translations
2017-11-11 16:30:16 +00:00
Dan Brown
711ba258f1 Prevented mulitple hypens incorrectly in slug
Added test to check slug format.
Fixes #589
2017-11-11 16:27:29 +00:00
Dan Brown
df4d4f30f1 Added package-lock file for npm version locking 2017-11-11 16:19:24 +00:00
Dan Brown
f094837709 Added test to cover multi-byte slugs
Also removed check for 'mb_' functions since mbstring is a dependancy
2017-11-11 16:15:08 +00:00
Dan Brown
e27cbb9dce Merge branch 'wowkaster-patch-1' 2017-11-11 16:07:23 +00:00
Abijeet
bdba25b6f2 Refactored all functionality into one function. Changed margin-top. 2017-11-05 20:23:16 +05:30
Vladimir
6b2581de63 Russian slug and Multibyte String 2017-11-03 14:00:07 +02:00
Abijeet
1031c61d0c Fixes #466. Adds support for header highlighting using intersection observer. 2017-11-02 01:14:06 +05:30
10bass
46fc0e5026 Fix ajax tag suggestion for subdir installs
tag suggest URLs were hardcoded to /ajax in blade template. Wrapped them in baseUrl()
2017-10-16 18:24:47 -04:00
Guilherme Bernal
332f678ed0 Update pt_BR translations 2017-10-15 16:15:53 -03:00
Dan Brown
df95e99680 Updated assets and version for release v0.18.4 2017-10-15 19:28:29 +01:00
Dan Brown
5a6d544db7 Merge branch 'master' into release 2017-10-15 19:27:50 +01:00
Dan Brown
0d5d77d8ab Updated search test to fit with new tokenization 2017-10-15 19:24:06 +01:00
Dan Brown
db51cee2d8 Prevented custom homepage being deleted
Fixes #546
2017-10-15 19:14:46 +01:00
Dan Brown
a988438946 Expanded list of indexing split chars
Expands on #531
2017-10-15 19:14:31 +01:00
Dan Brown
3bf7cac030 Prevented flexbox contains overflowing page
Fixes #552
2017-10-15 18:34:37 +01:00
Dan Brown
79c3a07e9a Fixed include syntax erroring within vue
Fixes #553
2017-10-15 18:20:13 +01:00
Dan Brown
16117d329c Merge branch 'master' into release, Updated version 2017-10-06 21:05:45 +01:00
Dan Brown
9758872baf Updated image fetching in exporting
Added domain check to see if possibly local even when whole url found.
Changed image fetch from file_get_contents to curl for external
resources.

Hopeful solution to #392
2017-10-06 20:49:25 +01:00
Dan Brown
e90da18ada Updated assets and version for v0.18.2 release 2017-10-01 18:12:59 +01:00
Dan Brown
a08d80e1cc Merge branch 'master' into release 2017-10-01 18:12:07 +01:00
Dan Brown
b711bc6816 Prevented 'Discard draft' option showing after saving a draft page 2017-10-01 18:11:24 +01:00
Dan Brown
247e6dba85 Fixed some design issues around cards
Reverted drop shadow change.
Fixed header line-height when linked.
Fixed overflowing paragraph text. Fixes #533.
2017-10-01 17:59:51 +01:00
Dan Brown
2b3d6e4e4a Updated search-regen command description 2017-10-01 17:51:59 +01:00
Dan Brown
6b1980c4f3 Merge branch 'master' of github.com:BookStackApp/BookStack 2017-10-01 13:19:41 +01:00
Dan Brown
9ba29770e1 Added azureAD social auth option
Closes #509
2017-10-01 13:19:17 +01:00
Dan Brown
3d375fae55 Merge pull request #529 from cipi1965/master
Updated italian translation
2017-10-01 11:44:45 +01:00
Dan Brown
c99a50de2c Merge pull request #528 from turbotankist/master
russian lang fixes
2017-10-01 11:43:31 +01:00
Dan Brown
1a32b25b5e Merge pull request #523 from sanderdw/master
Update dutch translations
2017-10-01 11:33:22 +01:00
Dan Brown
481aa5b5b0 Added 'last_commented' sort option to search
Closes #440
2017-10-01 11:24:33 +01:00
Dan Brown
c943eb4d0d Removed empty string null middleware as was causing issues 2017-09-30 14:44:52 +01:00
Dan Brown
aca6de49b0 Added missing middleware to trim input 2017-09-30 14:31:27 +01:00
Dan Brown
5fd04fa470 Updated search indexer to split words better
Will now split up words based on more chars than just spaces.
Not takes into account newlines, tabs, periods & commas.

Fixed #531
2017-09-30 14:14:23 +01:00
Dan Brown
87339e4cd0 Added missing codemirror theme class
Fixes #535
2017-09-30 13:48:38 +01:00
Dan Brown
a9eb058dad Updated issue template 2017-09-30 13:41:06 +01:00
Dan Brown
61fad6a665 Finished migration of last angular code 2017-09-30 13:27:08 +01:00
Matteo Piccina
fa4bee2d98 Updated italian translation 2017-09-27 10:44:08 +02:00
alexey
ce63260fa6 russian lang fixes 2017-09-27 11:17:56 +03:00
Dan Brown
a3557d5bb2 Tweaked shadows on cards 2017-09-24 18:47:34 +01:00
Dan Brown
9ca22976c3 Migrated editor toolbox, No more directives! 2017-09-24 18:30:21 +01:00
Dan Brown
9e2934fe17 Migrated editor inputs to non-angular JS 2017-09-23 12:24:06 +01:00
sanderdw
2259263214 Update entities.php 2017-09-23 00:52:08 +02:00
sanderdw
762cf5f183 Update components.php 2017-09-23 00:47:02 +02:00
sanderdw
07175f2b3e Update dutch translations 2017-09-23 00:28:25 +02:00
Dan Brown
6258175922 Updated assets and version for v0.18.1 release 2017-09-20 21:36:17 +01:00
Dan Brown
15736777a0 Merge branch 'master' into release 2017-09-20 21:35:33 +01:00
Dan Brown
0c4ddf16a5 Moved details card above book nav 2017-09-20 21:32:19 +01:00
Dan Brown
74a5e3113e Fixed page includes erroring on save
Closes #514
2017-09-20 21:03:40 +01:00
Dan Brown
df0a982433 Merge branch 'master' of github.com:BookStackApp/BookStack 2017-09-20 20:27:50 +01:00
Dan Brown
212f924ffa Refactored WYSIWYG editor image upload code
Added sketchy timeout to fix images being pasted at end of page.
Fixes #489
2017-09-20 20:27:00 +01:00
Dan Brown
09936566dd Upgrade tinymce version 2017-09-20 20:26:34 +01:00
Dan Brown
9469c04eab Merge pull request #517 from leomartinez/master
Added 'Spanish Argentina' translation
2017-09-20 20:17:39 +01:00
Leonardo Martinez
941bb73a68 Added missing colon 2017-09-19 14:25:44 -03:00
Leonardo Martinez
8e652f5d8f Added 'Spanish Argentina' translation. 2017-09-19 13:43:17 -03:00
Leonardo Martinez
eec1b21928 Added 'Spanish Argentina' translation. 2017-09-19 13:42:39 -03:00
Dan Brown
1baeb7bec9 Merge pull request #510 from sanderdw/patch-1
Update entities.php
2017-09-17 11:09:12 +01:00
Dan Brown
61475ca0a3 Merge pull request #506 from turbotankist/master
Russian lang added
2017-09-14 20:44:19 +01:00
sanderdw
244c5a3ebb Update entities.php 2017-09-14 21:43:47 +02:00
Dan Brown
39e7ac1c15 Updated social login to redirect to intended page.
Closes #508.
2017-09-14 20:20:47 +01:00
alexey
ab7f5def04 Russian lang added 2017-09-12 16:42:04 +03:00
Dan Brown
75915e8a94 Updated assets for release v0.18 2017-09-10 17:07:57 +01:00
Dan Brown
9bde0ae4ea Merge branch 'master' into release 2017-09-10 17:05:05 +01:00
Dan Brown
cd7e727f8c Modified IT comment translations as per recent changes 2017-09-10 16:43:05 +01:00
Dan Brown
2329a5cedf Merge branch 'master' of github.com:BookStackApp/BookStack 2017-09-10 16:36:47 +01:00
Dan Brown
d1a4ff9308 Merge pull request #501 from cipi1965/master
Added Italian language
2017-09-10 16:29:44 +01:00
Dan Brown
9a3bc27ef4 Fixed bullet styles and added code highlight on comments 2017-09-10 16:14:04 +01:00
Matteo Piccina
f8315fb9c4 Added Italian language 2017-09-10 16:55:23 +02:00
Dan Brown
bb62dee5a2 Merge pull request #500 from timoschwarzer/translation_update_de
Update german translation
2017-09-10 14:08:23 +01:00
Timo Schwarzer
8acc188e16 Update german translation 2017-09-10 15:01:25 +02:00
Dan Brown
874386ceab Used trans_choice on profile view
Closes #417
2017-09-10 13:43:08 +01:00
Dan Brown
9dfbea8bf9 Restored seeder and fixed scroll on firefox 2017-09-10 13:29:48 +01:00
Dan Brown
c1627a1468 Fixed sidebar scroll on mobile 2017-09-10 13:19:47 +01:00
Dan Brown
576a59a693 Fixed line-height difference in tinymce 2017-09-10 13:08:12 +01:00
Dan Brown
fec6c65b78 Fixed quick save shortcut in wysiwyg editor
Fixes #467
2017-09-10 13:01:48 +01:00
Dan Brown
f8c046d182 Fixed markdown callout tags and cursor pos
Closes #470
2017-09-09 19:41:11 +01:00
Dan Brown
9ca2184f09 Attempt to fix travis switching phpunit version 2017-09-09 19:17:00 +01:00
Dan Brown
fd449582bd Removed comments from seeder since they are not used by tests 2017-09-09 18:48:47 +01:00
Dan Brown
621142a46e Removed outdated translations and updated tests 2017-09-09 18:41:59 +01:00
Dan Brown
0275d2ad58 Added loading icons, Added comment activity 2017-09-09 17:06:30 +01:00
Dan Brown
41f56e659d Added comment reply and delete confirmation.
Also fixed local_id bug
Added component helpers
Added global scroll & Highlight helpers
2017-09-09 15:56:24 +01:00
Bharadwaja G
5034f21394 Added migration file. 2017-09-05 19:53:29 +05:30
Bharadwaja G
e02fcbe983 Added Book cover image description in all languages. 2017-09-05 12:46:31 +05:30
Bharadwaja G
1c88d21abf Fixed books cover image ratio. 2017-09-04 20:50:24 +05:30
Bharadwaja G
c1a1bc0135 Books grid view 2017-09-04 20:27:52 +05:30
Dan Brown
fea5630ea4 Made some changes to the comment system
Changed to be rendered server side along with page content.
Changed deletion to fully delete comments from the database.
Added 'local_id' to comments for referencing.
Updated reply system to be non-nested (Incomplete)
Made database comment format entity-agnostic to be more future proof.
Updated designs of comment sections.
2017-09-03 16:37:51 +01:00
Dan Brown
e3f2bde26d Merge branch 'Abijeet-master' to convert comment system to vue 2017-09-02 17:40:40 +01:00
Dan Brown
756ee0b172 Merge branch 'master' of git://github.com/Abijeet/BookStack into Abijeet-master 2017-09-02 17:36:58 +01:00
Dan Brown
c81b63b56f Fixed broken page content includes 2017-09-02 16:06:03 +01:00
Dan Brown
70ee28ee13 Fixed long attachment names breaking outer boxes
Closes #460
2017-09-02 15:21:05 +01:00
Dan Brown
1c9ecc3edd Reformatted sortable toolbox components 2017-09-02 15:06:52 +01:00
Dan Brown
9bd5d6a422 Merge pull request #483 from msaus/japanese_lang_update
Japanese lang update
2017-09-02 14:39:14 +01:00
Dan Brown
1e41ccbc7a Added ability to override codemirror theme
Also cleaned codemirror file while there.
In referece to #455
2017-09-02 13:34:37 +01:00
Bharadwaja G
6200948eec Merge branch 'master' of git://github.com/BookStackApp/BookStack into BookStackApp-master
Conflicts:
	app/Http/Controllers/BookController.php
	resources/lang/en/common.php
	resources/views/books/create.blade.php
	resources/views/books/form.blade.php
	resources/views/books/index.blade.php
	resources/views/users/edit.blade.php
	tests/Entity/EntityTest.php
2017-08-29 12:19:00 +05:30
Dan Brown
0a402e3c63 Made custom home ignore permissions and added tests
Closes #126 and #372
2017-08-28 13:55:39 +01:00
Dan Brown
55759bd22a Added ability to set a page to view on the homepage.
Relates to #372 and #126
2017-08-28 13:38:32 +01:00
Dan Brown
d8e1f52ddd Made new sidebar layout responsive 2017-08-27 15:16:51 +01:00
Dan Brown
baea92b206 Migrated entity selector out of angular 2017-08-27 14:31:34 +01:00
Dan Brown
cfc05c1b22 Improved primary color control in settings 2017-08-27 12:59:56 +01:00
Dan Brown
ebf78d49a8 Merge pull request #480 from BookStackApp/design_update_2017
Design update 2017
2017-08-26 17:22:30 +01:00
Dan Brown
4cb4c9e568 Updated remaining views to 2017 design update.
Also fixed issue with duplicate confirmation email.
2017-08-26 17:17:04 +01:00
Dan Brown
36f524a354 Updated page view styles to align with 2017 update 2017-08-26 15:41:33 +01:00
Dan Brown
b60d2190ac Updated error views for redesign 2017-08-26 14:53:23 +01:00
Dan Brown
2f8b8c580d Resolved current failing tests 2017-08-26 14:41:46 +01:00
Dan Brown
5187d3fa78 Updated chapter views with new design 2017-08-26 14:36:48 +01:00
Dan Brown
9c07741972 Updated readme with project definition 2017-08-26 13:49:56 +01:00
Dan Brown
8fcbe44d3e Updated styles for auth and books views.
Also added sourcemaps to gulp sass build
2017-08-26 13:24:55 +01:00
Bharadwaja G
7f902e41c7 Resolved conflicts 2017-08-24 12:21:43 +05:30
soseki
3966fb1df6 update Japanese language for code editor 2017-08-24 15:30:07 +09:00
soseki
830614fb19 add Japanese language for code editor 2017-08-24 15:24:43 +09:00
Abijeet
76ae5c7398 Removes some unused code. 2017-08-23 01:04:36 +05:30
Abijeet
769935f99e Reverting database.php and app.php 2017-08-23 00:52:50 +05:30
Abijeet
6920d6eef1 Fixes the comment check for linked comment. 2017-08-22 01:39:09 +05:30
Abijeet
b5cd3bff3c Added functionality to highlight a comment. 2017-08-22 01:31:11 +05:30
Abijeet
ac07cb41b6 Fixed formatting and added error messages. 2017-08-21 02:21:31 +05:30
Abijeet
e8fa58f201 Removed code from the directives. 2017-08-21 00:38:59 +05:30
Abijeet
1f6994b62c Added code for permissions, removed unnecessary code. 2017-08-20 21:26:44 +05:30
Abijeet
47d82a1ac2 Merge branch 'master' of https://github.com/BookStackApp/BookStack
Conflicts:
	resources/assets/js/vues/vues.js
2017-08-20 20:35:56 +05:30
Abijeet
703d579561 Refactored Angular code to instead use VueJS, left with permissions, testing and load testing. 2017-08-20 20:21:32 +05:30
Abijeet
ed375bfaf7 Refactored Angular code to instead use VueJS, left with permissions, testing and load testing. 2017-08-20 20:21:27 +05:30
Dan Brown
3da8c01c1f Rolled out new design further 2017-08-20 13:57:25 +01:00
Dan Brown
295f520f21 Started design update 2017-08-19 18:32:24 +01:00
Dan Brown
fba7ae923d Darkened a few cm code styles for improved legibility 2017-08-19 15:51:51 +01:00
Dan Brown
28a9bd514f Updated header design 2017-08-19 15:33:22 +01:00
Dan Brown
666c86b108 Removed included fonts, Set to use system fonts.
All font definitions moved into _text.scss.
Needs override documentation to complete.
Relates to #423.
2017-08-19 14:33:55 +01:00
Dan Brown
194293664f Removed v-show delayed content display 2017-08-19 14:09:03 +01:00
Dan Brown
039ee5d06c Aligned entity dash name and fixed chapter toggle on dash 2017-08-19 14:04:38 +01:00
Dan Brown
afc66b3c3d Migrated attachment manager to vue 2017-08-19 13:55:56 +01:00
Dan Brown
a04b31866d Cleaned social callback 2017-08-17 19:44:35 +01:00
Dan Brown
db3dde98ef Merge pull request #474 from timoschwarzer/translation_update_de
Update and fix German translation
2017-08-17 18:51:35 +01:00
Timo Schwarzer
0d6a6b5b63 Update/fix german translation 2017-08-16 22:31:07 +02:00
Abijeet Patro
4df3267521 Merge pull request #13 from BookStackApp/master
Getting the latest changes.
2017-08-14 23:09:26 +05:30
Dan Brown
d3e4a1a6f9 Converted tag autosuggestion to vue component 2017-08-13 13:25:30 +01:00
Dan Brown
b023699f1b Converted tag manager to be fully vue based 2017-08-13 11:50:40 +01:00
Dan Brown
f338dbe3f8 Started vueifying tag system 2017-08-10 20:11:25 +01:00
Dan Brown
ab07f7df6c Converted image manager into vue component 2017-08-09 21:33:00 +01:00
Dan Brown
a59d73de7b Fixed bug causing image manager popup not to show 2017-08-07 19:32:31 +01:00
Dan Brown
1ac7618bb1 Updated clipboard lib reference and version used 2017-08-06 21:21:20 +01:00
Dan Brown
2a069880cd Converted jQuery bits into raw JS components 2017-08-06 21:08:03 +01:00
Dan Brown
5e5928a8a6 Added vanilla JS component system 2017-08-06 18:01:49 +01:00
Dan Brown
d6e87420c3 Merged comment migrations and incremented dev version 2017-08-01 20:05:49 +01:00
Dan Brown
79cfd39fde Merge branch 'Abijeet-master' 2017-08-01 20:04:33 +01:00
Dan Brown
e9831a7507 Merge branch 'master' of git://github.com/Abijeet/BookStack into Abijeet-master 2017-08-01 19:24:33 +01:00
Dan Brown
0c802d1f86 Updated assets and version for release v0.17.4 2017-07-28 13:04:21 +01:00
Dan Brown
b7a96c6466 Merge branch 'master' into release 2017-07-28 13:03:36 +01:00
Dan Brown
9126da6299 Updated dev command details
Closes #453
2017-07-28 11:32:42 +01:00
Dan Brown
fea139d8e7 Merge branch 'master' of github.com:BookStackApp/BookStack 2017-07-27 19:09:44 +01:00
Dan Brown
ac7a8a8e1e Expanded the available editor shortcuts in both editors
Adds formatting on ctrl+nums for everything on formats dropdown.
Closes #85.
2017-07-27 19:07:58 +01:00
Dan Brown
bbaa2f4cda Merge pull request #435 from JachuPL/polish-localization
Polish translation
2017-07-27 16:48:19 +01:00
Dan Brown
9d61eecd81 Merge branch 'Cyber-Duck-master' 2017-07-27 16:29:09 +01:00
Dan Brown
21247e10d0 Reverted travis changes and added html escaping 2017-07-27 16:28:23 +01:00
Dan Brown
c1fc06ae34 Merge branch 'master' of git://github.com/Cyber-Duck/BookStack into Cyber-Duck-master 2017-07-27 16:20:38 +01:00
Dan Brown
a0eb3d1079 Merge pull request #446 from Joorem/french-spelling
French spelling
2017-07-27 16:18:57 +01:00
Dan Brown
164aea3a3a Merge pull request #448 from 10bass/subdir-search-fix
Update search.js
2017-07-27 16:17:57 +01:00
Dan Brown
ec83f83017 Added breadcrumbs to pages in entity select
Fixes #391
2017-07-27 16:10:58 +01:00
Dan Brown
5cd08ab2f5 Fixed custom plugin when developing 2017-07-27 15:43:17 +01:00
Dan Brown
072f6b103e Vastly sped up gulp watch and added livereload 2017-07-27 15:14:53 +01:00
10bass
b4dcde252b Update search.js
Trying to apply an exact match or tag would previously redirect to /search, regardless of the installation path.
2017-07-24 20:06:15 -04:00
Jérôme Le Gal
0b2c3c1aa7 settings.php: add missing french translation 2017-07-22 23:45:09 +02:00
Jérôme Le Gal
0dc9d0bed7 errors.php: add missing french translation 2017-07-22 23:45:09 +02:00
Jérôme Le Gal
a2a2e37797 settings.php: fix some spelling issues in french translation 2017-07-22 23:45:09 +02:00
Jérôme Le Gal
3d9819f97c passwords.php: fix some spelling issues in french translation 2017-07-22 23:45:09 +02:00
Jérôme Le Gal
b2b4a24d7c errors.php: fix some spelling issues in french translation 2017-07-22 23:45:08 +02:00
Jérôme Le Gal
7557d6d619 entities.php: fix some spelling issues in french translation 2017-07-22 23:45:08 +02:00
Jérôme Le Gal
57eeb9b0a3 common.php: fix some spelling issues in french translation 2017-07-22 23:45:08 +02:00
Jérôme Le Gal
813c7d5902 auth.php: fix some spelling issues in french translation 2017-07-22 23:45:08 +02:00
Dan Brown
4b645a82c7 Updated version for release 2017-07-22 17:27:01 +01:00
Dan Brown
d599b77b6f Merge branch 'master' into release 2017-07-22 17:26:44 +01:00
Dan Brown
f200b4183d Defined LDAP constant for testing without LDAP installed 2017-07-22 17:22:31 +01:00
Dan Brown
33642c20ec Fixed faulty text rendering calls and LDAP tests 2017-07-22 17:10:52 +01:00
Dan Brown
26e93dc8c1 Updated assets and version for release v0.17.2 2017-07-22 16:49:07 +01:00
Dan Brown
a4c9a8491b Merge branch 'master' into release 2017-07-22 16:46:57 +01:00
Dan Brown
2704962277 Updated utfmb4 upgrade command 2017-07-22 16:19:17 +01:00
Dan Brown
6bcd89acf7 Moved utf8mb4 migration to command instead of migration
To prevent errors upon migration.
Command generates out the SQL syntax to make the change instead
so the upgrade can be done manually.

In reference to #425
2017-07-22 15:54:17 +01:00
Dan Brown
433cb9b3b2 Improved breadcrumb responsiveness
Closes #426
2017-07-22 15:20:36 +01:00
Dan Brown
7f43372dd4 Fixed broken code block rendering when using DOMPDF
Fixes #427
2017-07-22 14:34:17 +01:00
Dan Brown
b12e2ceada Added included content into page's text view
Allows rendered content to be shown in listings and used in searches.
Also prevented angular tags in content being parsed in listings.

Fixes #442
2017-07-22 14:21:56 +01:00
Dan Brown
bc067e9ad4 Updated dropdowns to hide after option click
Fixes #429
2017-07-22 14:03:06 +01:00
Clément Blanco
245294fbc5 Trying to make the tests green. 2017-07-17 14:42:08 +01:00
Clément Blanco
f38bc75ab4 Trying to make the tests green. 2017-07-17 14:21:41 +01:00
Clément Blanco
3407900abb Trying to make the tests green. 2017-07-17 14:18:03 +01:00
Clément Blanco
684c20c4ea Trying to make the tests green. 2017-07-17 14:09:21 +01:00
Clément Blanco
6ef522df7e Trying to make the tests green. 2017-07-17 14:05:41 +01:00
Clément Blanco
3b771f2976 Trying to make the tests green. 2017-07-17 14:03:31 +01:00
Clément Blanco
afc56c12fe Trying to make the tests green. 2017-07-17 14:01:10 +01:00
Clément Blanco
5eeed03dcd Trying to make the tests green. 2017-07-17 13:53:02 +01:00
Clément Blanco
0d98b4ce5e Trying to make the tests green. 2017-07-17 13:37:15 +01:00
Clément Blanco
ae2ec43a82 Avoid having to wait until all tests are processed to exit upon error/failure. 2017-07-17 13:35:38 +01:00
Clément Blanco
265ed34ffd Update travis.yml to try and solve the test issue around LDAP. 2017-07-17 13:34:19 +01:00
Clément Blanco
711dcb4a48 Update travis.yml to try and solve the test issue around LDAP. 2017-07-17 13:29:29 +01:00
Nilesh Deepak
3079a9f4de Reverted required changes. 2017-07-15 19:07:32 +05:30
Nilesh Deepak
a7d2cfdee2 Resolving test cases 2017-07-15 19:03:02 +05:30
Nilesh Deepak
a149e87ca7 Resolving test cases 2017-07-15 19:00:23 +05:30
Nilesh Deepak
854fd52a27 Resolving test cases 2017-07-15 18:57:09 +05:30
Nilesh Deepak
3d808ac75f Test for cover image 2017-07-15 18:39:13 +05:30
Nilesh Deepak
39b924f158 Merge branch 'master' of https://github.com/OsmosysSoftware/BookStack 2017-07-15 18:37:55 +05:30
Nilesh Deepak
a488ef6b00 Test for cover image. 2017-07-15 18:36:49 +05:30
abijeetp
6d66c38c12 Fixes issues with the test case, now creating a user with the required profile setting. 2017-07-15 18:00:39 +05:30
Nilesh Deepak
922964ecf2 Changes grid container size 2017-07-15 17:50:09 +05:30
Nilesh Deepak
0c70416b5c Test books display options. 2017-07-15 16:33:52 +05:30
Nilesh Deepak
770f30c3a8 Test books display options. 2017-07-15 16:29:42 +05:30
Nilesh Deepak
b4044e6c3a Resolves heading issues in grid view 2017-07-15 16:22:29 +05:30
Nilesh Deepak
9872767f20 Test for cover image upload 2017-07-15 16:19:35 +05:30
Nilesh Deepak
dd4d2f4696 Resolves book heading issues in grid view. 2017-07-15 16:15:45 +05:30
Nilesh Deepak
e5dc0e6bb8 Merge branch 'master' of https://github.com/OsmosysSoftware/BookStack 2017-07-15 16:13:48 +05:30
Nilesh Deepak
85fbe820c4 Adding getHeadingExcerpt to get heading. 2017-07-15 16:11:10 +05:30
abijeetp
832f8eaa94 Fixes the test case related to UserProfileTest. 2017-07-15 15:50:42 +05:30
Abijeet
3435dcc91e Merge pull request #10 from OsmosysSoftware/test-issue-181
Tests for issue 181
2017-07-15 14:29:38 +05:30
Nilesh Deepak
1ed74b8598 Test for grid and list layout selection. 2017-07-15 13:19:49 +05:30
Nilesh Deepak
fd36978c13 Test for layout selection. 2017-07-15 12:26:57 +05:30
Nilesh Deepak
1278a0b818 Test for layout selection. 2017-07-15 11:40:51 +05:30
Nilesh Deepak
6a6516ddd5 Test for layout selection. 2017-07-15 11:31:43 +05:30
Clément Blanco
67bc7007aa Support new lines for book/chapter descriptions
Avoid ignoring new lines when renderring the book/chapter descriptions on their respective detailed views.
2017-07-14 16:05:46 +01:00
Nilesh Deepak
1fe8f13503 Cover image test case 2017-07-14 18:36:50 +05:30
Nilesh Deepak
8f3adcda5d Cover image test case 2017-07-14 18:02:45 +05:30
JachuPL
9e0c931573 Polish translation 2017-07-13 16:00:42 +02:00
Abijeet
21a8df78ee Merge pull request #9 from OsmosysSoftware/feature-181
Feature 181
2017-07-13 15:50:43 +05:30
Nilesh Deepak
7f8351e044 Removed avatar class from form.blade.php 2017-07-13 15:20:53 +05:30
Nilesh Deepak
afc1ecafe9 4. Changed the border color of the gallery item to #ccc 2017-07-13 12:27:14 +05:30
Nilesh Deepak
ab6ff5fda2 3. New default.png 2017-07-13 12:26:01 +05:30
Nilesh Deepak
b0ba1a43a9 2. Added classed col-xs-6 col-sm-4 col-md-4 col-lg-3 in grid-item.blade.php
5. Added <div class="row"> in index.blade.php
2017-07-13 12:24:47 +05:30
Nilesh Deepak
e919cab3d1 1. Thumbnail size when creating or editing book. 2017-07-13 12:22:43 +05:30
Abijeet
f37509062e Merge pull request #8 from OsmosysSoftware/feature-181
Issue 181
2017-07-12 18:41:35 +05:30
Nilesh Deepak
24ee78ccd8 Update. 2017-07-12 18:04:06 +05:30
Nilesh Deepak
d37b398e79 Updates styles. 2017-07-12 13:52:21 +05:30
Nilesh Deepak
7a724f9134 Updated modifications. 2017-07-12 13:44:37 +05:30
Abijeet
f3b2e0fb91 Merge pull request #7 from OsmosysSoftware/revert-3-revert-1-issue-181
Revert "Revert "Bookstack grid view.""
2017-07-12 11:41:01 +05:30
Abijeet
844976c85b Revert "Revert "Bookstack grid view."" 2017-07-12 11:40:50 +05:30
Abijeet
f0d914abbf Merge pull request #5 from BookStackApp/master
Getting latest changes
2017-07-12 11:33:58 +05:30
Dan Brown
70ee636d87 Updated css and version for release 2017-07-10 20:52:32 +01:00
Dan Brown
b35f6dbb03 Merge branch 'master' into release 2017-07-10 20:51:25 +01:00
Dan Brown
2ea7e10923 Set ldap to not follow referrals by default
Added LDAP_FOLLOW_REFERRALS .env option to override.
Fixes #317
2017-07-10 19:43:49 +01:00
Dan Brown
e7f8188ee5 Prevented textarea styles interfering with codemirror
Closes #424
2017-07-10 19:29:35 +01:00
Abijeet
0ed3023b42 Merge pull request #3 from OsmosysSoftware/revert-1-issue-181
Revert "Bookstack grid view."
2017-07-07 17:28:47 +05:30
Abijeet
3fd61a3600 Revert "Bookstack grid view." 2017-07-07 17:28:34 +05:30
Nilesh Deepak
a663fc8aa8 Merge pull request #1 from OsmosysSoftware/issue-181
Bookstack grid view issue 181.
2017-07-07 17:08:19 +05:30
Nilesh Deepak
d84315fff8 Indentation correction. 2017-07-07 17:06:08 +05:30
Nilesh Deepak
144a6e469d Updated cover image upload and delete function. 2017-07-07 16:29:38 +05:30
Nilesh Deepak
c5f11e4516 Fixed pagination on change of display type. 2017-07-06 10:05:11 +05:30
Nilesh Deepak
16a09e8ff6 Deletion of image file on book deletion. 2017-07-06 10:03:40 +05:30
Nilesh Deepak
f51db4b9f6 Resolved responsiveness issues 2017-07-05 19:58:52 +05:30
Nilesh Deepak
6ad24a6bee Changed public getImageURL function to private. 2017-07-05 18:32:38 +05:30
Nilesh Deepak
5b736c3b36 Updated views to support different languages. 2017-07-05 16:12:29 +05:30
Nilesh Deepak
cc553cc93d Added labels for 'Thumbnail toggle' and 'Cover image' in different languages. 2017-07-05 16:11:15 +05:30
Nilesh Deepak
e88a06291e Updated toggle thumbnails function. 2017-07-05 16:09:20 +05:30
Nilesh Deepak
6eccb3d5b9 Adding new migration. 2017-07-05 16:08:04 +05:30
Nilesh Deepak
026de8c5ca Thumbnail toggle function. 2017-07-05 12:48:41 +05:30
Nilesh Deepak
e10d4b91cf styles.scss 2017-07-05 12:36:26 +05:30
Nilesh Deepak
d089eaf754 Changes in User edit profile page. 2017-07-05 12:32:39 +05:30
Nilesh Deepak
bb2d85965f Removed duplicated styles. 2017-07-05 12:29:16 +05:30
Nilesh Deepak
d99fd1fd65 Applied required changes 2017-07-05 12:26:02 +05:30
Nilesh Deepak
947c58f227 Applied required changes in BookStack. 2017-07-05 12:09:01 +05:30
Nilesh Deepak
bce5fdd5cd Merge branch 'master' into issue-181 2017-07-04 15:16:46 +05:30
Nilesh Deepak
fdf139edb2 Changing column size for responsiveness 2017-07-04 15:04:57 +05:30
Nilesh Deepak
af72f0d490 Bookstack grid view. 2017-06-29 18:54:04 +05:30
Nilesh Deepak
8924618d12 test 2017-06-28 18:56:17 +05:30
Nilesh Deepak
6557fbb666 commit 2017-06-28 18:51:32 +05:30
Abijeet
574ee820a9 #47 - Fixes the issues with the test case. 2017-06-13 02:37:50 +05:30
Abijeet
7d02f77e67 #47 - Added more test cases to test the APIs and permission for comments. 2017-06-13 02:31:17 +05:30
Abijeet
fd50efb503 #47 - Putting the comments right under the page. 2017-06-11 11:41:33 +05:30
Abijeet
9dbd7fa618 #47 - Adding comments to the dummy content seeder. 2017-06-11 11:40:37 +05:30
Abijeet
8dab31b87a Merge branch 'master' of https://github.com/Abijeet/BookStack 2017-06-10 22:56:07 +05:30
Abijeet
e155c52256 #47 - Fixes a few issues with the code. 2017-06-10 22:55:36 +05:30
Abijeet Patro
c76e7c706c adding a comment on top. 2017-06-10 19:47:45 +05:30
Abijeet
552943c033 #47 - Undos changes in config files. 2017-06-10 19:46:00 +05:30
Abijeet
4efe3b41da #47 - Added translations for other language files using Google translate. 2017-06-10 15:21:28 +05:30
Abijeet
218376a41c #47 - Fetching values from language files. 2017-06-08 01:30:43 +05:30
Abijeet
e647ec22b1 #47 - Adds direct linking to comments. 2017-06-08 01:14:53 +05:30
Abijeet
38fe756725 #47 - Fixes a couple of issues found during testing - delete not updating the UI, delete none not working properly. 2017-06-07 23:45:29 +05:30
Abijeet
652a67ad65 Removes some unncessary code. 2017-06-06 23:20:40 +05:30
Abijeet
5bd9da6054 #47 - Adds various translations in English, and a few code improvements. 2017-06-06 01:46:59 +05:30
Abijeet
7c6fe8c4e2 #47 - Changes the location of the reply and edit comment box. 2017-06-05 00:20:37 +05:30
Abijeet
689d1eb082 #47 - Adds a cancel button for edit and reply button. 2017-06-04 20:43:56 +05:30
Abijeet
06d75e1804 #47 - Updates the total comments when a comment is added. 2017-06-04 20:12:01 +05:30
Abijeet
9558f84b97 #47 - Adds functionality to delete a comment. Also reduces the number of watchers. 2017-06-04 18:52:44 +05:30
Abijeet
2fd421b115 #47 - Adds comment level permissions to the front-end. 2017-06-04 11:17:14 +05:30
Abijeet
6ff440e677 Merge branch 'BookStackApp-master' 2017-06-04 10:20:25 +05:30
Abijeet
0bda5554dd Getting the latest changes 2017-06-04 10:20:01 +05:30
Abijeet
860d4d4be5 #47 - Changes the way we are handling fetching of data for the comment section. 2017-05-30 09:02:47 +05:30
Abijeet
9a97995f18 #47 Displays the time for comments and border bottom for sub comments. 2017-05-25 08:04:19 +05:30
Abijeet
1a1e71cd60 #47 Adds two attributes updated and created to display time to user. 2017-05-25 08:03:27 +05:30
Abijeet
34802ff8a6 #47 Inserts null for updated_at when the user is creating a comment. 2017-05-25 08:02:49 +05:30
Abijeet
0ff5aad9c0 #47 Hides the reply button based if comments are 2 levels deep. 2017-05-24 07:02:11 +05:30
Abijeet
03e5d61798 #47 Implements the reply and edit functionality for comments. 2017-05-16 00:40:14 +05:30
Abijeet Patro
4f231d1bf0 Merge pull request #11 from BookStackApp/master
Fixed chapter check for non-mysqlnd instances
2017-05-15 22:25:33 +05:30
Abijeet
8b82753218 #47 - Gets rid of simplemde 2017-05-03 02:42:04 +05:30
Abijeet Patro
3368fe42d8 Merge pull request #10 from BookStackApp/master
Latest changes
2017-05-03 01:41:08 +05:30
Abijeet
c3ea0d333e #47 - Adds functionality to display child comments. Also has some code towards the reply functionality. 2017-04-27 02:35:29 +05:30
Abijeet
d447355a61 Adding the view templates and styles. 2017-04-19 01:24:33 +05:30
Abijeet
8e2437498f Merge branch 'master' of https://github.com/Abijeet/BookStack 2017-04-19 01:23:27 +05:30
Abijeet Patro
9de85283cd Merge pull request #9 from BookStackApp/master
Get the latest changes.
2017-04-19 01:23:21 +05:30
Abijeet
b3d4c199ae Merge branch 'master' of https://github.com/Abijeet/BookStack
Conflicts:
	.gitignore
2017-04-19 01:21:45 +05:30
Abijeet Patro
4e71a5a47b Merge pull request #8 from BookStackApp/master
Getting the latest changes.
2017-03-25 23:56:05 +05:30
Abijeet
410e967eb1 Merge branch 'master' of https://github.com/Abijeet/BookStack 2017-02-05 16:46:32 +05:30
Abijeet Patro
388f2f40dc Merge pull request #7 from BookStackApp/master
Getting the latest.
2017-02-05 16:46:03 +05:30
Abijeet
148350009c #47 Adds comment permission to each role. 2017-01-29 14:25:20 +05:30
Abijeet
70991fc1e5 Merge branch 'master' of https://github.com/Abijeet/BookStack 2017-01-29 09:35:46 +05:30
Abijeet Patro
e5c4e0ac86 Merge pull request #6 from BookStackApp/master
Getting the latest
2017-01-29 09:35:21 +05:30
Abijeet
397db04428 Added comments controller, model, repo, and the database schema. Modified existing Page model to associate with comments. 2017-01-13 21:45:48 +05:30
Abijeet Patro
cd6572b61a Merge pull request #3 from BookStackApp/master
Getting the latest
2017-01-03 07:54:28 +05:30
Abijeet
581881d0ca Merging gitignore. 2016-11-29 00:24:15 +05:30
Abijeet Patro
d2efc2f47f Merge pull request #2 from BookStackApp/master
Getting the latest
2016-11-29 00:23:30 +05:30
Abijeet Patro
4cc73657a1 Merge pull request #1 from ssddanbrown/master
Getting the latest of BookStack.
2016-09-25 13:29:22 +05:30
337 changed files with 20204 additions and 7437 deletions

View File

@@ -46,6 +46,9 @@ GITHUB_APP_ID=false
GITHUB_APP_SECRET=false
GOOGLE_APP_ID=false
GOOGLE_APP_SECRET=false
OKTA_BASE_URL=false
OKTA_KEY=false
OKTA_SECRET=false
# External services such as Gravatar
DISABLE_EXTERNAL_SERVICES=false

View File

@@ -4,10 +4,18 @@ Desired Feature:
### For Bug Reports
* BookStack Version:
* BookStack Version *(Found in settings, Please don't put 'latest')*:
* PHP Version:
* MySQL Version:
##### Expected Behavior
##### Actual Behavior
##### Current Behavior
##### Steps to Reproduce

12
.gitignore vendored
View File

@@ -2,22 +2,22 @@
/node_modules
Homestead.yaml
.env
/public/dist
.idea
npm-debug.log
yarn-error.log
/public/dist
/public/plugins
/public/css/*.map
/public/js/*.map
/public/bower
/public/build/
/storage/images
_ide_helper.php
/storage/debugbar
.phpstorm.meta.php
yarn.lock
/bin
nbproject
.buildpath
.project
.settings/org.eclipse.wst.common.project.facet.core.xml
.settings/org.eclipse.php.core.prefs
.settings/

View File

@@ -2,7 +2,8 @@ dist: trusty
sudo: false
language: php
php:
- 7.0
- 7.0.20
- 7.1.9
cache:
directories:
@@ -14,7 +15,6 @@ before_script:
- mysql -u root -e "GRANT ALL ON \`bookstack-test\`.* TO 'bookstack-test'@'localhost';"
- mysql -u root -e "FLUSH PRIVILEGES;"
- phpenv config-rm xdebug.ini
- composer dump-autoload --no-interaction
- composer install --prefer-dist --no-interaction
- php artisan clear-compiled -n
- php artisan optimize -n
@@ -25,4 +25,4 @@ after_failure:
- cat storage/logs/laravel.log
script:
- phpunit
- phpunit

View File

@@ -3,7 +3,7 @@
class Book extends Entity
{
protected $fillable = ['name', 'description'];
protected $fillable = ['name', 'description', 'image_id'];
/**
* Get the url for this book.
@@ -18,6 +18,33 @@ class Book extends Entity
return baseUrl('/books/' . urlencode($this->slug));
}
/**
* Returns book cover image, if book cover not exists return default cover image.
* @param int $width - Width of the image
* @param int $height - Height of the image
* @return string
*/
public function getBookCover($width = 440, $height = 250)
{
$default = baseUrl('/book_default_cover.png');
if (!$this->image_id) return $default;
try {
$cover = $this->cover ? baseUrl($this->cover->getThumb($width, $height, false)) : $default;
} catch (\Exception $err) {
$cover = $default;
}
return $cover;
}
/**
* Get the cover image of the book
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function cover()
{
return $this->belongsTo(Image::class, 'image_id');
}
/*
* Get the edit url for this book.
* @return string

43
app/Comment.php Normal file
View File

@@ -0,0 +1,43 @@
<?php namespace BookStack;
class Comment extends Ownable
{
protected $fillable = ['text', 'html', 'parent_id'];
protected $appends = ['created', 'updated'];
/**
* Get the entity that this comment belongs to
* @return \Illuminate\Database\Eloquent\Relations\MorphTo
*/
public function entity()
{
return $this->morphTo('entity');
}
/**
* Check if a comment has been updated since creation.
* @return bool
*/
public function isUpdated()
{
return $this->updated_at->timestamp > $this->created_at->timestamp;
}
/**
* Get created date as a relative diff.
* @return mixed
*/
public function getCreatedAttribute()
{
return $this->created_at->diffForHumans();
}
/**
* Get updated date as a relative diff.
* @return mixed
*/
public function getUpdatedAttribute()
{
return $this->updated_at->diffForHumans();
}
}

View File

@@ -19,7 +19,7 @@ class RegenerateSearch extends Command
*
* @var string
*/
protected $description = 'Command description';
protected $description = 'Re-index all content for searching';
protected $searchService;

View File

@@ -0,0 +1,57 @@
<?php
namespace BookStack\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
class UpgradeDatabaseEncoding extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'bookstack:db-utf8mb4 {--database= : The database connection to use.}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Generate SQL commands to upgrade the database to UTF8mb4';
/**
* Create a new command instance.
*
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$connection = DB::getDefaultConnection();
if ($this->option('database') !== null) {
DB::setDefaultConnection($this->option('database'));
}
$database = DB::getDatabaseName();
$tables = DB::select('SHOW TABLES');
$this->line('ALTER DATABASE `'.$database.'` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;');
$this->line('USE `'.$database.'`;');
$key = 'Tables_in_' . $database;
foreach ($tables as $table) {
$tableName = $table->$key;
$this->line('ALTER TABLE `'.$tableName.'` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;');
}
DB::setDefaultConnection($connection);
}
}

View File

@@ -11,11 +11,7 @@ class Kernel extends ConsoleKernel
* @var array
*/
protected $commands = [
Commands\ClearViews::class,
Commands\ClearActivity::class,
Commands\ClearRevisions::class,
Commands\RegeneratePermissions::class,
Commands\RegenerateSearch::class
//
];
/**
@@ -28,4 +24,14 @@ class Kernel extends ConsoleKernel
{
//
}
/**
* Register the commands for the application.
*
* @return void
*/
protected function commands()
{
$this->load(__DIR__.'/Commands');
}
}

View File

@@ -1,6 +1,8 @@
<?php namespace BookStack;
use Illuminate\Database\Eloquent\Relations\MorphMany;
class Entity extends Ownable
{
@@ -65,6 +67,17 @@ class Entity extends Ownable
return $this->morphMany(Tag::class, 'entity')->orderBy('order', 'asc');
}
/**
* Get the comments for an entity
* @param bool $orderByCreated
* @return MorphMany
*/
public function comments($orderByCreated = true)
{
$query = $this->morphMany(Comment::class, 'entity');
return $orderByCreated ? $query->orderBy('created_at', 'asc') : $query;
}
/**
* Get the related search terms.
* @return \Illuminate\Database\Eloquent\Relations\MorphMany

View File

@@ -26,10 +26,10 @@ class Handler extends ExceptionHandler
/**
* Report or log an exception.
*
* This is a great spot to send exceptions to Sentry, Bugsnag, etc.
*
* @param \Exception $e
* @return mixed
*/
public function report(Exception $e)
{
@@ -103,4 +103,16 @@ class Handler extends ExceptionHandler
return redirect()->guest('login');
}
/**
* Convert a validation exception into a JSON response.
*
* @param \Illuminate\Http\Request $request
* @param \Illuminate\Validation\ValidationException $exception
* @return \Illuminate\Http\JsonResponse
*/
protected function invalidJson($request, ValidationException $exception)
{
return response()->json($exception->errors(), $exception->status);
}
}

View File

@@ -72,13 +72,13 @@ class LoginController extends Controller
// Explicitly log them out for now if they do no exist.
if (!$user->exists) auth()->logout($user);
if (!$user->exists && $user->email === null && !$request->has('email')) {
if (!$user->exists && $user->email === null && !$request->filled('email')) {
$request->flash();
session()->flash('request-email', true);
return redirect('/login');
}
if (!$user->exists && $user->email === null && $request->has('email')) {
if (!$user->exists && $user->email === null && $request->filled('email')) {
$user->email = $request->get('email');
}
@@ -102,12 +102,21 @@ class LoginController extends Controller
/**
* Show the application login form.
* @param Request $request
* @return \Illuminate\Http\Response
*/
public function getLogin()
public function getLogin(Request $request)
{
$socialDrivers = $this->socialAuthService->getActiveDrivers();
$authMethod = config('auth.method');
if ($request->has('email')) {
session()->flashInput([
'email' => $request->get('email'),
'password' => (config('app.env') === 'demo') ? $request->get('password', '') : ''
]);
}
return view('auth/login', ['socialDrivers' => $socialDrivers, 'authMethod' => $authMethod]);
}

View File

@@ -8,6 +8,7 @@ use BookStack\Exceptions\UserRegistrationException;
use BookStack\Repos\UserRepo;
use BookStack\Services\EmailConfirmationService;
use BookStack\Services\SocialAuthService;
use BookStack\SocialAccount;
use BookStack\User;
use Exception;
use Illuminate\Http\Request;
@@ -52,7 +53,7 @@ class RegisterController extends Controller
*/
public function __construct(SocialAuthService $socialAuthService, EmailConfirmationService $emailConfirmationService, UserRepo $userRepo)
{
$this->middleware('guest')->except(['socialCallback', 'detachSocialAccount']);
$this->middleware('guest')->only(['getRegister', 'postRegister', 'socialRegister']);
$this->socialAuthService = $socialAuthService;
$this->emailConfirmationService = $emailConfirmationService;
$this->userRepo = $userRepo;
@@ -103,7 +104,7 @@ class RegisterController extends Controller
* @param Request|\Illuminate\Http\Request $request
* @return Response
* @throws UserRegistrationException
* @throws \Illuminate\Foundation\Validation\ValidationException
* @throws \Illuminate\Validation\ValidationException
*/
public function postRegister(Request $request)
{
@@ -230,7 +231,6 @@ class RegisterController extends Controller
return redirect('/register/confirm');
}
$this->emailConfirmationService->sendConfirmation($user);
session()->flash('success', trans('auth.email_confirm_resent'));
return redirect('/register/confirm');
}
@@ -250,21 +250,30 @@ class RegisterController extends Controller
/**
* The callback for social login services.
* @param $socialDriver
* @param Request $request
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
* @throws SocialSignInException
* @throws UserRegistrationException
* @throws \BookStack\Exceptions\SocialDriverNotConfigured
* @throws ConfirmationEmailException
*/
public function socialCallback($socialDriver)
public function socialCallback($socialDriver, Request $request)
{
if (session()->has('social-callback')) {
$action = session()->pull('social-callback');
if ($action == 'login') {
return $this->socialAuthService->handleLoginCallback($socialDriver);
} elseif ($action == 'register') {
return $this->socialRegisterCallback($socialDriver);
}
} else {
if (!session()->has('social-callback')) {
throw new SocialSignInException(trans('errors.social_no_action_defined'), '/login');
}
// Check request for error information
if ($request->has('error') && $request->has('error_description')) {
throw new SocialSignInException(trans('errors.social_login_bad_response', [
'socialAccount' => $socialDriver,
'error' => $request->get('error_description'),
]), '/login');
}
$action = session()->pull('social-callback');
if ($action == 'login') return $this->socialAuthService->handleLoginCallback($socialDriver);
if ($action == 'register') return $this->socialRegisterCallback($socialDriver);
return redirect()->back();
}
@@ -282,7 +291,9 @@ class RegisterController extends Controller
* Register a new user after a registration callback.
* @param $socialDriver
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
* @throws ConfirmationEmailException
* @throws UserRegistrationException
* @throws \BookStack\Exceptions\SocialDriverNotConfigured
*/
protected function socialRegisterCallback($socialDriver)
{

View File

@@ -36,11 +36,19 @@ class BookController extends Controller
*/
public function index()
{
$books = $this->entityRepo->getAllPaginated('book', 10);
$books = $this->entityRepo->getAllPaginated('book', 20);
$recents = $this->signedIn ? $this->entityRepo->getRecentlyViewed('book', 4, 0) : false;
$popular = $this->entityRepo->getPopular('book', 4, 0);
$this->setPageTitle('Books');
return view('books/index', ['books' => $books, 'recents' => $recents, 'popular' => $popular]);
$new = $this->entityRepo->getRecentlyCreated('book', 4, 0);
$booksViewType = setting()->getUser($this->currentUser, 'books_view_type', 'list');
$this->setPageTitle(trans('entities.books'));
return view('books/index', [
'books' => $books,
'recents' => $recents,
'popular' => $popular,
'new' => $new,
'booksViewType' => $booksViewType
]);
}
/**
@@ -84,7 +92,12 @@ class BookController extends Controller
$bookChildren = $this->entityRepo->getBookChildren($book);
Views::add($book);
$this->setPageTitle($book->getShortName());
return view('books/show', ['book' => $book, 'current' => $book, 'bookChildren' => $bookChildren]);
return view('books/show', [
'book' => $book,
'current' => $book,
'bookChildren' => $bookChildren,
'activity' => Activity::entityActivity($book, 20, 0)
]);
}
/**
@@ -114,9 +127,9 @@ class BookController extends Controller
'name' => 'required|string|max:255',
'description' => 'string|max:1000'
]);
$book = $this->entityRepo->updateFromInput('book', $book, $request->all());
Activity::add($book, 'book_update', $book->id);
return redirect($book->getUrl());
$book = $this->entityRepo->updateFromInput('book', $book, $request->all());
Activity::add($book, 'book_update', $book->id);
return redirect($book->getUrl());
}
/**
@@ -172,7 +185,7 @@ class BookController extends Controller
$this->checkOwnablePermission('book-update', $book);
// Return if no map sent
if (!$request->has('sort-tree')) {
if (!$request->filled('sort-tree')) {
return redirect($book->getUrl());
}

View File

@@ -0,0 +1,93 @@
<?php namespace BookStack\Http\Controllers;
use Activity;
use BookStack\Repos\CommentRepo;
use BookStack\Repos\EntityRepo;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Http\Request;
class CommentController extends Controller
{
protected $entityRepo;
protected $commentRepo;
/**
* CommentController constructor.
* @param EntityRepo $entityRepo
* @param CommentRepo $commentRepo
*/
public function __construct(EntityRepo $entityRepo, CommentRepo $commentRepo)
{
$this->entityRepo = $entityRepo;
$this->commentRepo = $commentRepo;
parent::__construct();
}
/**
* Save a new comment for a Page
* @param Request $request
* @param integer $pageId
* @param null|integer $commentId
* @return \Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\JsonResponse|\Symfony\Component\HttpFoundation\Response
*/
public function savePageComment(Request $request, $pageId, $commentId = null)
{
$this->validate($request, [
'text' => 'required|string',
'html' => 'required|string',
]);
try {
$page = $this->entityRepo->getById('page', $pageId, true);
} catch (ModelNotFoundException $e) {
return response('Not found', 404);
}
$this->checkOwnablePermission('page-view', $page);
// Prevent adding comments to draft pages
if ($page->draft) {
return $this->jsonError(trans('errors.cannot_add_comment_to_draft'), 400);
}
// Create a new comment.
$this->checkPermission('comment-create-all');
$comment = $this->commentRepo->create($page, $request->only(['html', 'text', 'parent_id']));
Activity::add($page, 'commented_on', $page->book->id);
return view('comments/comment', ['comment' => $comment]);
}
/**
* Update an existing comment.
* @param Request $request
* @param integer $commentId
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function update(Request $request, $commentId)
{
$this->validate($request, [
'text' => 'required|string',
'html' => 'required|string',
]);
$comment = $this->commentRepo->getById($commentId);
$this->checkOwnablePermission('page-view', $comment->entity);
$this->checkOwnablePermission('comment-update', $comment);
$comment = $this->commentRepo->update($comment, $request->only(['html', 'text']));
return view('comments/comment', ['comment' => $comment]);
}
/**
* Delete a comment from the system.
* @param integer $id
* @return \Illuminate\Http\JsonResponse
*/
public function destroy($id)
{
$comment = $this->commentRepo->getById($id);
$this->checkOwnablePermission('comment-delete', $comment);
$this->commentRepo->delete($comment);
return response()->json(['message' => trans('entities.comment_deleted')]);
}
}

View File

@@ -29,21 +29,32 @@ class HomeController extends Controller
$activity = Activity::latest(10);
$draftPages = $this->signedIn ? $this->entityRepo->getUserDraftPages(6) : [];
$recentFactor = count($draftPages) > 0 ? 0.5 : 1;
$recents = $this->signedIn ? Views::getUserRecentlyViewed(12*$recentFactor, 0) : $this->entityRepo->getRecentlyCreated('book', 10*$recentFactor);
$recentlyCreatedPages = $this->entityRepo->getRecentlyCreated('page', 5);
$recentlyUpdatedPages = $this->entityRepo->getRecentlyUpdated('page', 5);
return view('home', [
$recents = $this->signedIn ? Views::getUserRecentlyViewed(12*$recentFactor, 0) : $this->entityRepo->getRecentlyCreated('book', 12*$recentFactor);
$recentlyUpdatedPages = $this->entityRepo->getRecentlyUpdated('page', 12);
// Custom homepage
$customHomepage = false;
$homepageSetting = setting('app-homepage');
if ($homepageSetting) {
$id = intval(explode(':', $homepageSetting)[0]);
$customHomepage = $this->entityRepo->getById('page', $id, false, true);
$this->entityRepo->renderPage($customHomepage, true);
}
$view = $customHomepage ? 'home-custom' : 'home';
return view($view, [
'activity' => $activity,
'recents' => $recents,
'recentlyCreatedPages' => $recentlyCreatedPages,
'recentlyUpdatedPages' => $recentlyUpdatedPages,
'draftPages' => $draftPages
'draftPages' => $draftPages,
'customHomepage' => $customHomepage
]);
}
/**
* Get a js representation of the current translations
* @return \Illuminate\Contracts\Routing\ResponseFactory|\Symfony\Component\HttpFoundation\Response
* @throws \Exception
*/
public function getTranslations() {
$locale = app()->getLocale();
@@ -76,4 +87,13 @@ class HomeController extends Controller
]);
}
/**
* Get custom head HTML, Used in ajax calls to show in editor.
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function customHeadContent()
{
return view('partials/custom-head-content');
}
}

View File

@@ -107,7 +107,7 @@ class ImageController extends Controller
$imageUpload = $request->file('file');
try {
$uploadedTo = $request->has('uploaded_to') ? $request->get('uploaded_to') : 0;
$uploadedTo = $request->filled('uploaded_to') ? $request->get('uploaded_to') : 0;
$image = $this->imageRepo->saveNew($imageUpload, $type, $uploadedTo);
} catch (ImageUploadException $e) {
return response($e->getMessage(), 500);
@@ -162,7 +162,7 @@ class ImageController extends Controller
$this->checkOwnablePermission('image-delete', $image);
// Check if this image is used on any pages
$isForced = ($request->has('force') && ($request->get('force') === 'true') || $request->get('force') === true);
$isForced = in_array($request->get('force', ''), [true, 'true']);
if (!$isForced) {
$pageSearch = $entityRepo->searchForImage($image->url);
if ($pageSearch !== false) {

View File

@@ -158,16 +158,25 @@ class PageController extends Controller
$this->checkOwnablePermission('page-view', $page);
$pageContent = $this->entityRepo->renderPage($page);
$page->html = $this->entityRepo->renderPage($page);
$sidebarTree = $this->entityRepo->getBookChildren($page->book);
$pageNav = $this->entityRepo->getPageNav($pageContent);
$pageNav = $this->entityRepo->getPageNav($page->html);
// check if the comment's are enabled
$commentsEnabled = !setting('app-disable-comments');
if ($commentsEnabled) {
$page->load(['comments.createdBy']);
}
Views::add($page);
$this->setPageTitle($page->getShortName());
return view('pages/show', [
'page' => $page,'book' => $page->book,
'current' => $page, 'sidebarTree' => $sidebarTree,
'pageNav' => $pageNav, 'pageContent' => $pageContent]);
'current' => $page,
'sidebarTree' => $sidebarTree,
'commentsEnabled' => $commentsEnabled,
'pageNav' => $pageNav
]);
}
/**
@@ -323,9 +332,10 @@ class PageController extends Controller
$page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug);
$book = $page->book;
$this->checkOwnablePermission('page-delete', $page);
$this->entityRepo->destroyPage($page);
Activity::addMessage('page_delete', $book->id, $page->name);
session()->flash('success', trans('entities.pages_delete_success'));
$this->entityRepo->destroyPage($page);
return redirect($book->getUrl());
}
@@ -376,10 +386,11 @@ class PageController extends Controller
$page->fill($revision->toArray());
$this->setPageTitle(trans('entities.pages_revision_named', ['pageName' => $page->getShortName()]));
return view('pages/revision', [
'page' => $page,
'book' => $page->book,
'revision' => $revision
]);
}
@@ -409,6 +420,7 @@ class PageController extends Controller
'page' => $page,
'book' => $page->book,
'diff' => $diff,
'revision' => $revision
]);
}
@@ -438,6 +450,7 @@ class PageController extends Controller
public function exportPdf($bookSlug, $pageSlug)
{
$page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug);
$page->html = $this->entityRepo->renderPage($page);
$pdfContent = $this->exportService->pageToPdf($page);
return response()->make($pdfContent, 200, [
'Content-Type' => 'application/octet-stream',
@@ -454,6 +467,7 @@ class PageController extends Controller
public function exportHtml($bookSlug, $pageSlug)
{
$page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug);
$page->html = $this->entityRepo->renderPage($page);
$containedHtml = $this->exportService->pageToContainedHtml($page);
return response()->make($containedHtml, 200, [
'Content-Type' => 'application/octet-stream',

View File

@@ -36,7 +36,7 @@ class SearchController extends Controller
$searchTerm = $request->get('term');
$this->setPageTitle(trans('entities.search_for_term', ['term' => $searchTerm]));
$page = $request->has('page') && is_int(intval($request->get('page'))) ? intval($request->get('page')) : 1;
$page = intval($request->get('page', '0')) ?: 1;
$nextPageLink = baseUrl('/search?term=' . urlencode($searchTerm) . '&page=' . ($page+1));
$results = $this->searchService->searchEntities($searchTerm, 'all', $page, 20);
@@ -88,8 +88,8 @@ class SearchController extends Controller
*/
public function searchEntitiesAjax(Request $request)
{
$entityTypes = $request->has('types') ? collect(explode(',', $request->get('types'))) : collect(['page', 'chapter', 'book']);
$searchTerm = ($request->has('term') && trim($request->get('term')) !== '') ? $request->get('term') : false;
$entityTypes = $request->filled('types') ? collect(explode(',', $request->get('types'))) : collect(['page', 'chapter', 'book']);
$searchTerm = $request->get('term', false);
// Search for entities otherwise show most popular
if ($searchTerm !== false) {

View File

@@ -37,7 +37,7 @@ class TagController extends Controller
*/
public function getNameSuggestions(Request $request)
{
$searchTerm = $request->has('search') ? $request->get('search') : false;
$searchTerm = $request->get('search', false);
$suggestions = $this->tagRepo->getNameSuggestions($searchTerm);
return response()->json($suggestions);
}
@@ -49,8 +49,8 @@ class TagController extends Controller
*/
public function getValueSuggestions(Request $request)
{
$searchTerm = $request->has('search') ? $request->get('search') : false;
$tagName = $request->has('name') ? $request->get('name') : false;
$searchTerm = $request->get('search', false);
$tagName = $request->get('name', false);
$suggestions = $this->tagRepo->getValueSuggestions($searchTerm, $tagName);
return response()->json($suggestions);
}

View File

@@ -34,9 +34,9 @@ class UserController extends Controller
{
$this->checkPermission('users-manage');
$listDetails = [
'order' => $request->has('order') ? $request->get('order') : 'asc',
'search' => $request->has('search') ? $request->get('search') : '',
'sort' => $request->has('sort') ? $request->get('sort') : 'name',
'order' => $request->get('order', 'asc'),
'search' => $request->get('search', ''),
'sort' => $request->get('sort', 'name'),
];
$users = $this->userRepo->getAllUsersPaginatedAndSorted(20, $listDetails);
$this->setPageTitle(trans('settings.users'));
@@ -88,7 +88,7 @@ class UserController extends Controller
$user->save();
if ($request->has('roles')) {
if ($request->filled('roles')) {
$roles = $request->get('roles');
$user->roles()->sync($roles);
}
@@ -155,24 +155,24 @@ class UserController extends Controller
$user->fill($request->all());
// Role updates
if (userCan('users-manage') && $request->has('roles')) {
if (userCan('users-manage') && $request->filled('roles')) {
$roles = $request->get('roles');
$user->roles()->sync($roles);
}
// Password updates
if ($request->has('password') && $request->get('password') != '') {
if ($request->filled('password')) {
$password = $request->get('password');
$user->password = bcrypt($password);
}
// External auth id updates
if ($this->currentUser->can('users-manage') && $request->has('external_auth_id')) {
if ($this->currentUser->can('users-manage') && $request->filled('external_auth_id')) {
$user->external_auth_id = $request->get('external_auth_id');
}
// Save an user-specific settings
if ($request->has('setting')) {
if ($request->filled('setting')) {
foreach ($request->get('setting') as $key => $value) {
setting()->putUser($user, $key, $value);
}

View File

@@ -13,8 +13,9 @@ class Kernel extends HttpKernel
*/
protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\BookStack\Http\Middleware\TrimStrings::class,
\BookStack\Http\Middleware\TrustProxies::class,
];
/**
@@ -26,6 +27,8 @@ class Kernel extends HttpKernel
'web' => [
\BookStack\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\BookStack\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\BookStack\Http\Middleware\Localization::class
@@ -42,10 +45,11 @@ class Kernel extends HttpKernel
* @var array
*/
protected $routeMiddleware = [
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'auth' => \BookStack\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \BookStack\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'perm' => \BookStack\Http\Middleware\PermissionMiddleware::class
];
}

View File

@@ -30,8 +30,11 @@ class Authenticate
*/
public function handle($request, Closure $next)
{
if ($this->auth->check() && setting('registration-confirmation') && !$this->auth->user()->email_confirmed) {
return redirect(baseUrl('/register/confirm/awaiting'));
if ($this->auth->check()) {
$requireConfirmation = (setting('registration-confirmation') || setting('registration-restrict'));
if ($requireConfirmation && !$this->auth->user()->email_confirmed) {
return redirect('/register/confirm/awaiting');
}
}
if ($this->auth->guest() && !setting('app-public')) {

View File

@@ -2,9 +2,9 @@
namespace BookStack\Http\Middleware;
use Illuminate\Cookie\Middleware\EncryptCookies as BaseEncrypter;
use Illuminate\Cookie\Middleware\EncryptCookies as Middleware;
class EncryptCookies extends BaseEncrypter
class EncryptCookies extends Middleware
{
/**
* The names of the cookies that should not be encrypted.

View File

@@ -0,0 +1,19 @@
<?php
namespace BookStack\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\TrimStrings as Middleware;
class TrimStrings extends Middleware
{
/**
* The names of the attributes that should not be trimmed.
*
* @var array
*/
protected $except = [
'password',
'password_confirmation',
'password-confirm',
];
}

View File

@@ -0,0 +1,47 @@
<?php
namespace BookStack\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Fideloper\Proxy\TrustProxies as Middleware;
class TrustProxies extends Middleware
{
/**
* The trusted proxies for this application.
*
* @var array
*/
protected $proxies;
/**
* The current proxy header mappings.
*
* @var array
*/
protected $headers = [
Request::HEADER_FORWARDED => 'FORWARDED',
Request::HEADER_X_FORWARDED_FOR => 'X_FORWARDED_FOR',
Request::HEADER_X_FORWARDED_HOST => 'X_FORWARDED_HOST',
Request::HEADER_X_FORWARDED_PORT => 'X_FORWARDED_PORT',
Request::HEADER_X_FORWARDED_PROTO => 'X_FORWARDED_PROTO',
];
/**
* Handle the request, Set the correct user-configured proxy information.
* @param Request $request
* @param Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$setProxies = config('app.proxies');
if ($setProxies !== '**' && $setProxies !== '*' && $setProxies !== '') {
$setProxies = explode(',', $setProxies);
}
$this->proxies = $setProxies;
return parent::handle($request, $next);
}
}

View File

@@ -2,9 +2,9 @@
namespace BookStack\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
class VerifyCsrfToken extends BaseVerifier
class VerifyCsrfToken extends Middleware
{
/**
* The URIs that should be excluded from CSRF verification.

View File

@@ -47,4 +47,16 @@ class PageRevision extends Model
return null;
}
/**
* Allows checking of the exact class, Used to check entity type.
* Included here to align with entities in similar use cases.
* (Yup, Bit of an awkward hack)
* @param $type
* @return bool
*/
public static function isA($type)
{
return $type === 'revision';
}
}

View File

@@ -16,6 +16,8 @@ class EventServiceProvider extends ServiceProvider
protected $listen = [
SocialiteWasCalled::class => [
'SocialiteProviders\Slack\SlackExtendSocialite@handle',
'SocialiteProviders\Azure\AzureExtendSocialite@handle',
'SocialiteProviders\Okta\OktaExtendSocialite@handle',
],
];

87
app/Repos/CommentRepo.php Normal file
View File

@@ -0,0 +1,87 @@
<?php namespace BookStack\Repos;
use BookStack\Comment;
use BookStack\Entity;
/**
* Class CommentRepo
* @package BookStack\Repos
*/
class CommentRepo {
/**
* @var Comment $comment
*/
protected $comment;
/**
* CommentRepo constructor.
* @param Comment $comment
*/
public function __construct(Comment $comment)
{
$this->comment = $comment;
}
/**
* Get a comment by ID.
* @param $id
* @return Comment|\Illuminate\Database\Eloquent\Model
*/
public function getById($id)
{
return $this->comment->newQuery()->findOrFail($id);
}
/**
* Create a new comment on an entity.
* @param Entity $entity
* @param array $data
* @return Comment
*/
public function create (Entity $entity, $data = [])
{
$userId = user()->id;
$comment = $this->comment->newInstance($data);
$comment->created_by = $userId;
$comment->updated_by = $userId;
$comment->local_id = $this->getNextLocalId($entity);
$entity->comments()->save($comment);
return $comment;
}
/**
* Update an existing comment.
* @param Comment $comment
* @param array $input
* @return mixed
*/
public function update($comment, $input)
{
$comment->updated_by = user()->id;
$comment->update($input);
return $comment;
}
/**
* Delete a comment from the system.
* @param Comment $comment
* @return mixed
*/
public function delete($comment)
{
return $comment->delete();
}
/**
* Get the next local ID relative to the linked entity.
* @param Entity $entity
* @return int
*/
protected function getNextLocalId(Entity $entity)
{
$comments = $entity->comments(false)->orderBy('local_id', 'desc')->first();
if ($comments === null) return 1;
return $comments->local_id + 1;
}
}

View File

@@ -4,6 +4,7 @@ use BookStack\Book;
use BookStack\Chapter;
use BookStack\Entity;
use BookStack\Exceptions\NotFoundException;
use BookStack\Exceptions\NotifyException;
use BookStack\Page;
use BookStack\PageRevision;
use BookStack\Services\AttachmentService;
@@ -137,10 +138,15 @@ class EntityRepo
* @param string $type
* @param integer $id
* @param bool $allowDrafts
* @param bool $ignorePermissions
* @return Entity
*/
public function getById($type, $id, $allowDrafts = false)
public function getById($type, $id, $allowDrafts = false, $ignorePermissions = false)
{
if ($ignorePermissions) {
$entity = $this->getEntity($type);
return $entity->newQuery()->find($id);
}
return $this->entityQuery($type, $allowDrafts)->find($id);
}
@@ -436,9 +442,10 @@ class EntityRepo
*/
public function updateEntityPermissionsFromRequest($request, Entity $entity)
{
$entity->restricted = $request->has('restricted') && $request->get('restricted') === 'true';
$entity->restricted = $request->get('restricted', '') === 'true';
$entity->permissions()->delete();
if ($request->has('restrictions')) {
if ($request->filled('restrictions')) {
foreach ($request->get('restrictions') as $roleId => $restrictions) {
foreach ($restrictions as $action => $value) {
$entity->permissions()->create([
@@ -448,6 +455,7 @@ class EntityRepo
}
}
}
$entity->save();
$this->permissionService->buildJointPermissionsForEntity($entity);
}
@@ -547,8 +555,9 @@ class EntityRepo
*/
protected function nameToSlug($name)
{
$slug = str_replace(' ', '-', strtolower($name));
$slug = preg_replace('/[\+\/\\\?\@\}\{\.\,\=\[\]\#\&\!\*\'\;\:\$\%]/', '', $slug);
$slug = preg_replace('/[\+\/\\\?\@\}\{\.\,\=\[\]\#\&\!\*\'\;\:\$\%]/', '', mb_strtolower($name));
$slug = preg_replace('/\s{2,}/', ' ', $slug);
$slug = str_replace(' ', '-', $slug);
if ($slug === "") $slug = substr(md5(rand(1, 500)), 0, 5);
return $slug;
}
@@ -571,7 +580,7 @@ class EntityRepo
$draftPage->slug = $this->findSuitableSlug('page', $draftPage->name, false, $draftPage->book->id);
$draftPage->html = $this->formatHtml($input['html']);
$draftPage->text = strip_tags($draftPage->html);
$draftPage->text = $this->pageToPlainText($draftPage);
$draftPage->draft = false;
$draftPage->revision_count = 1;
@@ -671,9 +680,10 @@ class EntityRepo
/**
* Render the page for viewing, Parsing and performing features such as page transclusion.
* @param Page $page
* @param bool $ignorePermissions
* @return mixed|string
*/
public function renderPage(Page $page)
public function renderPage(Page $page, $ignorePermissions = false)
{
$content = $page->html;
$matches = [];
@@ -685,19 +695,19 @@ class EntityRepo
$pageId = intval($splitInclude[0]);
if (is_nan($pageId)) continue;
$page = $this->getById('page', $pageId);
if ($page === null) {
$matchedPage = $this->getById('page', $pageId, false, $ignorePermissions);
if ($matchedPage === null) {
$content = str_replace($matches[0][$index], '', $content);
continue;
}
if (count($splitInclude) === 1) {
$content = str_replace($matches[0][$index], $page->html, $content);
$content = str_replace($matches[0][$index], $matchedPage->html, $content);
continue;
}
$doc = new DOMDocument();
$doc->loadHTML(mb_convert_encoding('<body>'.$page->html.'</body>', 'HTML-ENTITIES', 'UTF-8'));
$doc->loadHTML(mb_convert_encoding('<body>'.$matchedPage->html.'</body>', 'HTML-ENTITIES', 'UTF-8'));
$matchingElem = $doc->getElementById($splitInclude[1]);
if ($matchingElem === null) {
$content = str_replace($matches[0][$index], '', $content);
@@ -713,6 +723,17 @@ class EntityRepo
return $content;
}
/**
* Get the plain text version of a page's content.
* @param Page $page
* @return string
*/
public function pageToPlainText(Page $page)
{
$html = $this->renderPage($page);
return strip_tags($html);
}
/**
* Get a new draft page instance.
* @param Book $book
@@ -816,7 +837,7 @@ class EntityRepo
$userId = user()->id;
$page->fill($input);
$page->html = $this->formatHtml($input['html']);
$page->text = strip_tags($page->html);
$page->text = $this->pageToPlainText($page);
if (setting('app-editor') !== 'markdown') $page->markdown = '';
$page->updated_by = $userId;
$page->revision_count++;
@@ -933,7 +954,7 @@ class EntityRepo
$revision = $page->revisions()->where('id', '=', $revisionId)->first();
$page->fill($revision->toArray());
$page->slug = $this->findSuitableSlug('page', $page->name, $page->id, $book->id);
$page->text = strip_tags($page->html);
$page->text = $this->pageToPlainText($page);
$page->updated_by = user()->id;
$page->save();
$this->searchService->indexEntity($page);
@@ -953,7 +974,7 @@ class EntityRepo
if ($page->draft) {
$page->fill($data);
if (isset($data['html'])) {
$page->text = strip_tags($data['html']);
$page->text = $this->pageToPlainText($page);
}
$page->save();
return $page;
@@ -1056,6 +1077,7 @@ class EntityRepo
/**
* Destroy a given page along with its dependencies.
* @param Page $page
* @throws NotifyException
*/
public function destroyPage(Page $page)
{
@@ -1067,6 +1089,12 @@ class EntityRepo
$this->permissionService->deleteJointPermissionsForEntity($page);
$this->searchService->deleteEntityTerms($page);
// Check if set as custom homepage
$customHome = setting('app-homepage', '0:');
if (intval($page->id) === intval(explode(':', $customHome)[0])) {
throw new NotifyException(trans('errors.page_custom_home_deletion'), $page->getUrl());
}
// Delete Attached Files
$attachmentService = app(AttachmentService::class);
foreach ($page->attachments as $attachment) {

View File

@@ -33,6 +33,7 @@ class TagRepo
* @param $entityType
* @param $entityId
* @param string $action
* @return \Illuminate\Database\Eloquent\Model|null|static
*/
public function getEntity($entityType, $entityId, $action = 'view')
{

View File

@@ -27,9 +27,9 @@ class ExportService
*/
public function pageToContainedHtml(Page $page)
{
$this->entityRepo->renderPage($page);
$pageHtml = view('pages/export', [
'page' => $page,
'pageContent' => $this->entityRepo->renderPage($page)
'page' => $page
])->render();
return $this->containHtml($pageHtml);
}
@@ -74,9 +74,9 @@ class ExportService
*/
public function pageToPdf(Page $page)
{
$this->entityRepo->renderPage($page);
$html = view('pages/pdf', [
'page' => $page,
'pageContent' => $this->entityRepo->renderPage($page)
'page' => $page
])->render();
return $this->htmlToPdf($html);
}
@@ -127,7 +127,7 @@ class ExportService
$pdf = \SnappyPDF::loadHTML($containedHtml);
$pdf->setOption('print-media-type', true);
} else {
$pdf = \PDF::loadHTML($containedHtml);
$pdf = \DomPDF::loadHTML($containedHtml);
}
return $pdf->output();
}
@@ -136,6 +136,7 @@ class ExportService
* Bundle of the contents of a html file to be self-contained.
* @param $htmlContent
* @return mixed|string
* @throws \Exception
*/
protected function containHtml($htmlContent)
{
@@ -153,9 +154,27 @@ class ExportService
} else {
$pathString = $srcString;
}
// Attempt to find local files even if url not absolute
$base = baseUrl('/');
if (strpos($srcString, $base) === 0) {
$isLocal = true;
$relString = str_replace($base, '', $srcString);
$pathString = public_path(trim($relString, '/'));
}
if ($isLocal && !file_exists($pathString)) continue;
try {
$imageContent = file_get_contents($pathString);
if ($isLocal) {
$imageContent = file_get_contents($pathString);
} else {
$ch = curl_init();
curl_setopt_array($ch, [CURLOPT_URL => $pathString, CURLOPT_RETURNTRANSFER => 1, CURLOPT_CONNECTTIMEOUT => 5]);
$imageContent = curl_exec($ch);
$err = curl_error($ch);
curl_close($ch);
if ($err) throw new \Exception("Image fetch failed, Received error: " . $err);
}
$imageEncoded = 'data:image/' . pathinfo($pathString, PATHINFO_EXTENSION) . ';base64,' . base64_encode($imageContent);
$newImageString = str_replace($srcString, $imageEncoded, $oldImgString);
} catch (\ErrorException $e) {

View File

@@ -42,6 +42,8 @@ class LdapService
$userFilter = $this->buildFilter($this->config['user_filter'], ['user' => $userName]);
$baseDn = $this->config['base_dn'];
$emailAttr = $this->config['email_attribute'];
$followReferrals = $this->config['follow_referrals'] ? 1 : 0;
$this->ldap->setOption($ldapConnection, LDAP_OPT_REFERRALS, $followReferrals);
$users = $this->ldap->searchAndGetEntries($ldapConnection, $baseDn, $userFilter, ['cn', 'uid', 'dn', $emailAttr]);
if ($users['count'] === 0) return null;

View File

@@ -205,12 +205,17 @@ class PermissionService
}
$entities[] = $entity->book;
if ($entity->isA('page') && $entity->chapter_id) $entities[] = $entity->chapter;
if ($entity->isA('page') && $entity->chapter_id) {
$entities[] = $entity->chapter;
}
if ($entity->isA('chapter')) {
foreach ($entity->pages as $page) {
$entities[] = $page;
}
}
$this->deleteManyJointPermissionsForEntities($entities);
$this->buildJointPermissionsForEntities(collect($entities));
}
@@ -468,7 +473,7 @@ class PermissionService
$action = end($explodedPermission);
$this->currentAction = $action;
$nonJointPermissions = ['restrictions', 'image', 'attachment'];
$nonJointPermissions = ['restrictions', 'image', 'attachment', 'comment'];
// Handle non entity specific jointPermissions
if (in_array($explodedPermission[0], $nonJointPermissions)) {

View File

@@ -92,7 +92,7 @@ class SearchService
return [
'total' => $total,
'count' => count($results),
'results' => $results->sortByDesc('score')
'results' => $results->sortByDesc('score')->values()
];
}
@@ -382,11 +382,13 @@ class SearchService
protected function generateTermArrayFromText($text, $scoreAdjustment = 1)
{
$tokenMap = []; // {TextToken => OccurrenceCount}
$splitText = explode(' ', $text);
foreach ($splitText as $token) {
if ($token === '') continue;
$splitChars = " \n\t.,!?:;()[]{}<>`'\"";
$token = strtok($text, $splitChars);
while ($token !== false) {
if (!isset($tokenMap[$token])) $tokenMap[$token] = 0;
$tokenMap[$token]++;
$token = strtok($splitChars);
}
$terms = [];
@@ -479,4 +481,23 @@ class SearchService
});
}
protected function filterSortBy(\Illuminate\Database\Eloquent\Builder $query, Entity $model, $input)
{
$functionName = camel_case('sort_by_' . $input);
if (method_exists($this, $functionName)) $this->$functionName($query, $model);
}
/**
* Sorting filter options
*/
protected function sortByLastCommented(\Illuminate\Database\Eloquent\Builder $query, Entity $model)
{
$commentsTable = $this->db->getTablePrefix() . 'comments';
$morphClass = str_replace('\\', '\\\\', $model->getMorphClass());
$commentQuery = $this->db->raw('(SELECT c1.entity_id, c1.entity_type, c1.created_at as last_commented FROM '.$commentsTable.' c1 LEFT JOIN '.$commentsTable.' c2 ON (c1.entity_id = c2.entity_id AND c1.entity_type = c2.entity_type AND c1.created_at < c2.created_at) WHERE c1.entity_type = \''. $morphClass .'\' AND c2.created_at IS NULL) as comments');
$query->join($commentQuery, $model->getTable() . '.id', '=', 'comments.entity_id')->orderBy('last_commented', 'desc');
}
}

View File

@@ -1,5 +1,7 @@
<?php namespace BookStack\Services;
use BookStack\Http\Requests\Request;
use GuzzleHttp\Exception\ClientException;
use Laravel\Socialite\Contracts\Factory as Socialite;
use BookStack\Exceptions\SocialDriverNotConfigured;
use BookStack\Exceptions\SocialSignInException;
@@ -14,7 +16,7 @@ class SocialAuthService
protected $socialite;
protected $socialAccount;
protected $validSocialDrivers = ['google', 'github', 'facebook', 'slack', 'twitter'];
protected $validSocialDrivers = ['google', 'github', 'facebook', 'slack', 'twitter', 'azure', 'okta'];
/**
* SocialAuthService constructor.
@@ -91,7 +93,6 @@ class SocialAuthService
public function handleLoginCallback($socialDriver)
{
$driver = $this->validateDriver($socialDriver);
// Get user details from social driver
$socialUser = $this->socialite->driver($driver)->user();
$socialId = $socialUser->getId();
@@ -104,7 +105,8 @@ class SocialAuthService
// When a user is not logged in and a matching SocialAccount exists,
// Simply log the user into the application.
if (!$isLoggedIn && $socialAccount !== null) {
return $this->logUserIn($socialAccount->user);
auth()->login($socialAccount->user);
return redirect()->intended('/');
}
// When a user is logged in but the social account does not exist,
@@ -134,14 +136,7 @@ class SocialAuthService
$message .= trans('errors.social_account_register_instructions', ['socialAccount' => title_case($socialDriver)]);
}
throw new SocialSignInException($message . '.', '/login');
}
private function logUserIn($user)
{
auth()->login($user);
return redirect('/');
throw new SocialSignInException($message, '/login');
}
/**

View File

@@ -62,7 +62,7 @@ class ViewService
$query->whereIn('viewable_type', $filterModel);
} else if ($filterModel) {
$query->where('viewable_type', '=', get_class($filterModel));
};
}
return $query->with('viewable')->skip($skipCount)->take($count)->get()->pluck('viewable');
}

16
artisan
View File

@@ -1,19 +1,19 @@
#!/usr/bin/env php
<?php
define('LARAVEL_START', microtime(true));
/*
|--------------------------------------------------------------------------
| Register The Auto Loader
| Initialize The App
|--------------------------------------------------------------------------
|
| Composer provides a convenient, automatically generated class loader
| for our application. We just need to utilize it! We'll require it
| into the script here so that we do not have to worry about the
| loading of any our classes "manually". Feels great to relax.
| We need to get things going before we start up the app.
| The init file loads everything in, in the correct order.
|
*/
require __DIR__.'/bootstrap/autoload.php';
require __DIR__.'/bootstrap/init.php';
$app = require_once __DIR__.'/bootstrap/app.php';
@@ -40,7 +40,7 @@ $status = $kernel->handle(
| Shutdown The Application
|--------------------------------------------------------------------------
|
| Once Artisan has finished running. We will fire off the shutdown events
| Once Artisan has finished running, we will fire off the shutdown events
| so that any final work may be done by the application before we shut
| down the process. This is the last thing to happen to the request.
|
@@ -48,4 +48,4 @@ $status = $kernel->handle(
$kernel->terminate($input, $status);
exit($status);
exit($status);

View File

@@ -1,6 +1,15 @@
<?php
define('LARAVEL_START', microtime(true));
/*
|--------------------------------------------------------------------------
| Load Our Own Helpers
|--------------------------------------------------------------------------
|
| This custom function loads any helpers, before the Laravel Framework
| is built so we can override any helpers as we please.
|
*/
require __DIR__.'/../app/helpers.php';
/*
|--------------------------------------------------------------------------
@@ -13,23 +22,4 @@ define('LARAVEL_START', microtime(true));
| loading of any our classes "manually". Feels great to relax.
|
*/
require __DIR__.'/../app/helpers.php';
require __DIR__.'/../vendor/autoload.php';
/*
|--------------------------------------------------------------------------
| Include The Compiled Class File
|--------------------------------------------------------------------------
|
| To dramatically increase your application's performance, you may use a
| compiled class file which contains all of the classes commonly used
| by a request. The Artisan "optimize" is used to create this file.
|
*/
$compiledPath = __DIR__.'/cache/compiled.php';
if (file_exists($compiledPath)) {
require $compiledPath;
}
require __DIR__.'/../vendor/autoload.php';

View File

@@ -1,31 +1,35 @@
{
"name": "ssddanbrown/bookstack",
"name": "bookstackapp/bookstack",
"description": "BookStack documentation platform",
"keywords": ["BookStack", "Documentation"],
"license": "MIT",
"type": "project",
"require": {
"php": ">=5.6.4",
"laravel/framework": "5.4.*",
"php": ">=7.0.0",
"laravel/framework": "5.5.*",
"fideloper/proxy": "~3.3",
"ext-tidy": "*",
"intervention/image": "^2.3",
"intervention/image": "^2.4",
"laravel/socialite": "^3.0",
"barryvdh/laravel-ide-helper": "^2.2.3",
"barryvdh/laravel-debugbar": "^2.3.2",
"league/flysystem-aws-s3-v3": "^1.0",
"barryvdh/laravel-dompdf": "^0.8",
"barryvdh/laravel-dompdf": "^0.8.1",
"predis/predis": "^1.1",
"gathercontent/htmldiff": "^0.2.1",
"barryvdh/laravel-snappy": "^0.3.1",
"laravel/browser-kit-testing": "^1.0",
"socialiteproviders/slack": "^3.0"
"barryvdh/laravel-snappy": "^0.4.0",
"socialiteproviders/slack": "^3.0",
"socialiteproviders/microsoft-azure": "^3.0",
"socialiteproviders/okta": "^1.0"
},
"require-dev": {
"filp/whoops": "~2.0",
"fzaninotto/faker": "~1.4",
"mockery/mockery": "0.9.*",
"phpunit/phpunit": "~5.0",
"mockery/mockery": "~1.0",
"phpunit/phpunit": "~6.0",
"symfony/css-selector": "3.1.*",
"symfony/dom-crawler": "3.1.*"
"symfony/dom-crawler": "3.1.*",
"laravel/browser-kit-testing": "^2.0",
"barryvdh/laravel-ide-helper": "^2.4.1",
"barryvdh/laravel-debugbar": "^3.1.0"
},
"autoload": {
"classmap": [
@@ -56,14 +60,12 @@
"php -r \"!file_exists('bootstrap/cache/compiled.php') || @unlink('bootstrap/cache/compiled.php');\""
],
"post-install-cmd": [
"Illuminate\\Foundation\\ComposerScripts::postInstall",
"php artisan optimize",
"php artisan cache:clear",
"php artisan view:clear"
],
"post-update-cmd": [
"Illuminate\\Foundation\\ComposerScripts::postUpdate",
"php artisan optimize"
"post-autoload-dump": [
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
"@php artisan package:discover"
],
"refresh-test-database": [
"php artisan migrate:refresh --database=mysql_testing",
@@ -71,6 +73,10 @@
]
},
"config": {
"preferred-install": "dist"
"optimize-autoloader": true,
"preferred-install": "dist",
"platform": {
"php": "7.0"
}
}
}

5864
composer.lock generated

File diff suppressed because it is too large Load Diff

6
config/app.php Normal file → Executable file
View File

@@ -58,7 +58,7 @@ return [
*/
'locale' => env('APP_LANG', 'en'),
'locales' => ['en', 'de', 'es', 'fr', 'nl', 'pt_BR', 'sk', 'ja'],
'locales' => ['en', 'de', 'es', 'es_AR', 'fr', 'nl', 'pt_BR', 'sk', 'ja', 'pl', 'it', 'ru'],
/*
|--------------------------------------------------------------------------
@@ -219,7 +219,7 @@ return [
*/
'ImageTool' => Intervention\Image\Facades\Image::class,
'PDF' => Barryvdh\DomPDF\Facade::class,
'DomPDF' => Barryvdh\DomPDF\Facade::class,
'SnappyPDF' => Barryvdh\Snappy\Facades\SnappyPdf::class,
'Debugbar' => Barryvdh\Debugbar\Facade::class,
@@ -234,4 +234,6 @@ return [
],
'proxies' => env('APP_PROXIES', ''),
];

View File

@@ -72,6 +72,22 @@ return [
'name' => 'Twitter',
],
'azure' => [
'client_id' => env('AZURE_APP_ID', false),
'client_secret' => env('AZURE_APP_SECRET', false),
'tenant' => env('AZURE_TENANT', false),
'redirect' => env('APP_URL') . '/login/service/azure/callback',
'name' => 'Microsoft Azure',
],
'okta' => [
'client_id' => env('OKTA_APP_ID'),
'client_secret' => env('OKTA_APP_SECRET'),
'redirect' => env('APP_URL') . '/login/service/okta/callback',
'base_url' => env('OKTA_BASE_URL'),
'name' => 'Okta',
],
'ldap' => [
'server' => env('LDAP_SERVER', false),
'dn' => env('LDAP_DN', false),
@@ -80,6 +96,7 @@ return [
'user_filter' => env('LDAP_USER_FILTER', '(&(uid=${user}))'),
'version' => env('LDAP_VERSION', false),
'email_attribute' => env('LDAP_EMAIL_ATTRIBUTE', 'mail'),
'follow_referrals' => env('LDAP_FOLLOW_REFERRALS', false),
]
];

View File

@@ -29,7 +29,7 @@ return [
|
*/
'lifetime' => 120,
'lifetime' => env('SESSION_LIFETIME', 120),
'expire_on_close' => false,

View File

@@ -70,4 +70,14 @@ $factory->define(BookStack\Image::class, function ($faker) {
'type' => 'gallery',
'uploaded_to' => 0
];
});
$factory->define(BookStack\Comment::class, function($faker) {
$text = $faker->paragraph(1);
$html = '<p>' . $text. '</p>';
return [
'html' => $html,
'text' => $text,
'parent_id' => null
];
});

View File

@@ -1,7 +1,5 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class UpdateDbEncodingToUt8mb4 extends Migration
@@ -13,16 +11,9 @@ class UpdateDbEncodingToUt8mb4 extends Migration
*/
public function up()
{
$database = DB::getDatabaseName();
$tables = DB::select('SHOW TABLES');
$pdo = DB::getPdo();
$pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
$pdo->exec('ALTER DATABASE `'.$database.'` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci');
$key = 'Tables_in_' . $database;
foreach ($tables as $table) {
$tableName = $table->$key;
$pdo->exec('ALTER TABLE `'.$tableName.'` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci');
}
// Migration removed due to issues during live migration.
// Instead you can run the command `artisan bookstack:db-utf8mb4`
// which will generate out the SQL request to upgrade your DB to utf8mb4.
}
/**
@@ -32,15 +23,6 @@ class UpdateDbEncodingToUt8mb4 extends Migration
*/
public function down()
{
$database = DB::getDatabaseName();
$tables = DB::select('SHOW TABLES');
$pdo = DB::getPdo();
$pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
$pdo->exec('ALTER DATABASE `'.$database.'` CHARACTER SET utf8 COLLATE utf8_unicode_ci');
$key = 'Tables_in_' . $database;
foreach ($tables as $table) {
$tableName = $table->$key;
$pdo->exec('ALTER TABLE `'.$tableName.'` CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci');
}
//
}
}

View File

@@ -0,0 +1,68 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateCommentsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('comments', function (Blueprint $table) {
$table->increments('id')->unsigned();
$table->integer('entity_id')->unsigned();
$table->string('entity_type');
$table->longText('text')->nullable();
$table->longText('html')->nullable();
$table->integer('parent_id')->unsigned()->nullable();
$table->integer('local_id')->unsigned()->nullable();
$table->integer('created_by')->unsigned();
$table->integer('updated_by')->unsigned()->nullable();
$table->timestamps();
$table->index(['entity_id', 'entity_type']);
$table->index(['local_id']);
// Assign new comment permissions to admin role
$adminRoleId = DB::table('roles')->where('system_name', '=', 'admin')->first()->id;
// Create & attach new entity permissions
$ops = ['Create All', 'Create Own', 'Update All', 'Update Own', 'Delete All', 'Delete Own'];
$entity = 'Comment';
foreach ($ops as $op) {
$permissionId = DB::table('role_permissions')->insertGetId([
'name' => strtolower($entity) . '-' . strtolower(str_replace(' ', '-', $op)),
'display_name' => $op . ' ' . $entity . 's',
'created_at' => \Carbon\Carbon::now()->toDateTimeString(),
'updated_at' => \Carbon\Carbon::now()->toDateTimeString()
]);
DB::table('permission_role')->insert([
'role_id' => $adminRoleId,
'permission_id' => $permissionId
]);
}
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('comments');
// Delete comment role permissions
$ops = ['Create All', 'Create Own', 'Update All', 'Update Own', 'Delete All', 'Delete Own'];
$entity = 'Comment';
foreach ($ops as $op) {
$permName = strtolower($entity) . '-' . strtolower(str_replace(' ', '-', $op));
DB::table('role_permissions')->where('name', '=', $permName)->delete();
}
}
}

View File

@@ -0,0 +1,32 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddCoverImageDisplay extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('books', function (Blueprint $table) {
$table->integer('image_id')->nullable()->default(null);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('books', function (Blueprint $table) {
$table->dropColumn('image_id');
});
}
}

View File

@@ -11,29 +11,33 @@ class DummyContentSeeder extends Seeder
*/
public function run()
{
$user = factory(\BookStack\User::class)->create();
$role = \BookStack\Role::getRole('editor');
$user->attachRole($role);
// Create an editor user
$editorUser = factory(\BookStack\User::class)->create();
$editorRole = \BookStack\Role::getRole('editor');
$editorUser->attachRole($editorRole);
// Create a viewer user
$viewerUser = factory(\BookStack\User::class)->create();
$role = \BookStack\Role::getRole('viewer');
$viewerUser->attachRole($role);
factory(\BookStack\Book::class, 20)->create(['created_by' => $user->id, 'updated_by' => $user->id])
->each(function($book) use ($user) {
$chapters = factory(\BookStack\Chapter::class, 5)->create(['created_by' => $user->id, 'updated_by' => $user->id])
->each(function($chapter) use ($user, $book){
$pages = factory(\BookStack\Page::class, 5)->make(['created_by' => $user->id, 'updated_by' => $user->id, 'book_id' => $book->id]);
factory(\BookStack\Book::class, 20)->create(['created_by' => $editorUser->id, 'updated_by' => $editorUser->id])
->each(function($book) use ($editorUser) {
$chapters = factory(\BookStack\Chapter::class, 5)->create(['created_by' => $editorUser->id, 'updated_by' => $editorUser->id])
->each(function($chapter) use ($editorUser, $book){
$pages = factory(\BookStack\Page::class, 5)->make(['created_by' => $editorUser->id, 'updated_by' => $editorUser->id, 'book_id' => $book->id]);
$chapter->pages()->saveMany($pages);
});
$pages = factory(\BookStack\Page::class, 3)->make(['created_by' => $user->id, 'updated_by' => $user->id]);
$pages = factory(\BookStack\Page::class, 3)->make(['created_by' => $editorUser->id, 'updated_by' => $editorUser->id]);
$book->chapters()->saveMany($chapters);
$book->pages()->saveMany($pages);
});
$largeBook = factory(\BookStack\Book::class)->create(['name' => 'Large book' . str_random(10), 'created_by' => $user->id, 'updated_by' => $user->id]);
$pages = factory(\BookStack\Page::class, 200)->make(['created_by' => $user->id, 'updated_by' => $user->id]);
$chapters = factory(\BookStack\Chapter::class, 50)->make(['created_by' => $user->id, 'updated_by' => $user->id]);
$largeBook = factory(\BookStack\Book::class)->create(['name' => 'Large book' . str_random(10), 'created_by' => $editorUser->id, 'updated_by' => $editorUser->id]);
$pages = factory(\BookStack\Page::class, 200)->make(['created_by' => $editorUser->id, 'updated_by' => $editorUser->id]);
$chapters = factory(\BookStack\Chapter::class, 50)->make(['created_by' => $editorUser->id, 'updated_by' => $editorUser->id]);
$largeBook->pages()->saveMany($pages);
$largeBook->chapters()->saveMany($chapters);
app(\BookStack\Services\PermissionService::class)->buildJointPermissions();
app(\BookStack\Services\SearchService::class)->indexAllEntities();
}

View File

@@ -1,22 +1,31 @@
'use strict';
const argv = require('yargs').argv;
const gulp = require('gulp'),
plumber = require('gulp-plumber');
const autoprefixer = require('gulp-autoprefixer');
const uglify = require('gulp-uglify');
const minifycss = require('gulp-clean-css');
const sass = require('gulp-sass');
const sourcemaps = require('gulp-sourcemaps');
const browserify = require("browserify");
const source = require('vinyl-source-stream');
const buffer = require('vinyl-buffer');
const babelify = require("babelify");
const watchify = require("watchify");
const envify = require("envify");
const uglify = require('gulp-uglify');
const gutil = require("gulp-util");
const liveReload = require('gulp-livereload');
if (argv.production) process.env.NODE_ENV = 'production';
let isProduction = argv.production || process.env.NODE_ENV === 'production';
gulp.task('styles', () => {
let chain = gulp.src(['resources/assets/sass/**/*.scss'])
.pipe(sourcemaps.init())
.pipe(plumber({
errorHandler: function (error) {
console.log(error.message);
@@ -24,31 +33,41 @@ gulp.task('styles', () => {
}}))
.pipe(sass())
.pipe(autoprefixer('last 2 versions'));
if (argv.production) chain = chain.pipe(minifycss());
return chain.pipe(gulp.dest('public/css/'));
if (isProduction) chain = chain.pipe(minifycss());
chain = chain.pipe(sourcemaps.write());
return chain.pipe(gulp.dest('public/css/')).pipe(liveReload());
});
function scriptTask(watch=false) {
function scriptTask(watch = false) {
let props = {
basedir: 'resources/assets/js',
debug: true,
entries: ['global.js']
entries: ['global.js'],
fast: !isProduction,
cache: {},
packageCache: {},
};
let bundler = watch ? watchify(browserify(props), { poll: true }) : browserify(props);
bundler.transform(envify, {global: true}).transform(babelify, {presets: ['es2015']});
if (isProduction) {
bundler.transform(envify, {global: true}).transform(babelify, {presets: ['es2015']});
}
function rebundle() {
let stream = bundler.bundle();
stream = stream.pipe(source('common.js'));
if (argv.production) stream = stream.pipe(buffer()).pipe(uglify());
return stream.pipe(gulp.dest('public/js/'));
if (isProduction) stream = stream.pipe(buffer()).pipe(uglify());
return stream.pipe(gulp.dest('public/js/')).pipe(liveReload());
}
bundler.on('update', function() {
rebundle();
gutil.log('Rebundle...');
gutil.log('Rebundling assets...');
});
bundler.on('log', gutil.log);
return rebundle();
}
@@ -57,6 +76,7 @@ gulp.task('scripts', () => {scriptTask(false)});
gulp.task('scripts-watch', () => {scriptTask(true)});
gulp.task('default', ['styles', 'scripts-watch'], () => {
liveReload.listen();
gulp.watch("resources/assets/sass/**/*.scss", ['styles']);
});

5977
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -4,7 +4,8 @@
"build": "gulp build",
"production": "gulp build --production",
"dev": "gulp",
"watch": "gulp"
"watch": "gulp",
"permissions": "chown -R $USER:$USER bootstrap/cache storage public/uploads"
},
"devDependencies": {
"babelify": "^7.3.0",
@@ -13,6 +14,7 @@
"gulp": "3.9.1",
"gulp-autoprefixer": "3.1.1",
"gulp-clean-css": "^3.0.4",
"gulp-livereload": "^3.8.1",
"gulp-minify-css": "1.2.4",
"gulp-plumber": "1.1.0",
"gulp-sass": "3.1.0",
@@ -23,21 +25,19 @@
"yargs": "^7.1.0"
},
"dependencies": {
"angular": "^1.5.5",
"angular-animate": "^1.5.5",
"angular-resource": "^1.5.5",
"angular-sanitize": "^1.5.5",
"angular-ui-sortable": "^0.17.0",
"axios": "^0.16.1",
"babel-polyfill": "^6.23.0",
"babel-preset-es2015": "^6.24.1",
"clipboard": "^1.5.16",
"clipboard": "^1.7.1",
"codemirror": "^5.26.0",
"dropzone": "^4.0.1",
"gulp-sourcemaps": "^2.6.1",
"gulp-util": "^3.0.8",
"markdown-it": "^8.3.1",
"markdown-it-task-lists": "^2.0.0",
"moment": "^2.12.0",
"vue": "^2.2.6"
"vue": "^2.2.6",
"vuedraggable": "^2.14.1"
},
"browser": {
"vue": "vue/dist/vue.common.js"

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
bootstrap="bootstrap/autoload.php"
bootstrap="bootstrap/init.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

File diff suppressed because one or more lines are too long

View File

@@ -1 +1,2 @@
header{display:none}body{font-size:12px}.faded-small{display:none}.page-content{margin:0 auto}.print-hidden{display:none}.print-full-width{width:100%;float:none;display:block}h2{font-size:2em;line-height:1;margin-top:.6em;margin-bottom:.3em}
header{display:none}body{font-size:12px}.faded-small{display:none}.page-content{margin:0 auto}.print-hidden{display:none}.print-full-width{width:100%;float:none;display:block}h2{font-size:2em;line-height:1;margin-top:.6em;margin-bottom:.3em}
/*# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInByaW50LXN0eWxlcy5zY3NzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLE9BQ0UsUUFBQSxLQUdGLEtBQ0UsVUFBQSxLQUdGLGFBQ0UsUUFBQSxLQUdGLGNBQ0UsT0FBQSxFQUFBLEtBR0YsY0FDRSxRQUFBLEtBR0Ysa0JBQ0UsTUFBQSxLQUNBLE1BQUEsS0FDQSxRQUFBLE1BR0YsR0FDRSxVQUFBLElBQ0EsWUFBQSxFQUNBLFdBQUEsS0FDQSxjQUFBIiwiZmlsZSI6InByaW50LXN0eWxlcy5jc3MiLCJzb3VyY2VzQ29udGVudCI6WyJAaW1wb3J0IFwidmFyaWFibGVzXCI7XG5cbmhlYWRlciB7XG4gIGRpc3BsYXk6IG5vbmU7XG59XG5cbmJvZHkge1xuICBmb250LXNpemU6IDEycHg7XG59XG5cbi5mYWRlZC1zbWFsbCB7XG4gIGRpc3BsYXk6IG5vbmU7XG59XG5cbi5wYWdlLWNvbnRlbnQge1xuICBtYXJnaW46IDAgYXV0bztcbn1cblxuLnByaW50LWhpZGRlbiB7XG4gIGRpc3BsYXk6IG5vbmU7XG59XG5cbi5wcmludC1mdWxsLXdpZHRoIHtcbiAgd2lkdGg6IDEwMCU7XG4gIGZsb2F0OiBub25lO1xuICBkaXNwbGF5OiBibG9jaztcbn1cblxuaDIge1xuICBmb250LXNpemU6IDJlbTtcbiAgbGluZS1oZWlnaHQ6IDE7XG4gIG1hcmdpbi10b3A6IDAuNmVtO1xuICBtYXJnaW4tYm90dG9tOiAwLjNlbTtcbn0iXX0= */

File diff suppressed because one or more lines are too long

View File

@@ -4,22 +4,22 @@
* Laravel - A PHP Framework For Web Artisans
*
* @package Laravel
* @author Taylor Otwell <taylorotwell@gmail.com>
* @author Taylor Otwell <taylor@laravel.com>
*/
define('LARAVEL_START', microtime(true));
/*
|--------------------------------------------------------------------------
| Register The Auto Loader
| Initialize The App
|--------------------------------------------------------------------------
|
| Composer provides a convenient, automatically generated class loader for
| our application. We just need to utilize it! We'll simply require it
| into the script here so that we don't have to worry about manual
| loading any of our classes later on. It feels nice to relax.
| We need to get things going before we start up the app.
| The init file loads everything in, in the correct order.
|
*/
require __DIR__.'/../bootstrap/autoload.php';
require __DIR__.'/../bootstrap/init.php';
/*
|--------------------------------------------------------------------------
@@ -55,4 +55,4 @@ $response = $kernel->handle(
$response->send();
$kernel->terminate($request, $response);
$kernel->terminate($request, $response);

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
!function(){var a={},b=function(b){for(var c=a[b],e=c.deps,f=c.defn,g=e.length,h=new Array(g),i=0;i<g;++i)h[i]=d(e[i]);var j=f.apply(null,h);if(void 0===j)throw"module ["+b+"] returned undefined";c.instance=j},c=function(b,c,d){if("string"!=typeof b)throw"module id must be a string";if(void 0===c)throw"no dependencies for "+b;if(void 0===d)throw"no definition function for "+b;a[b]={deps:c,defn:d,instance:void 0}},d=function(c){var d=a[c];if(void 0===d)throw"module ["+c+"] was undefined";return void 0===d.instance&&b(c),d.instance},e=function(a,b){for(var c=a.length,e=new Array(c),f=0;f<c;++f)e.push(d(a[f]));b.apply(null,b)},f={};f.bolt={module:{api:{define:c,require:e,demand:d}}};var g=c,h=function(a,b){g(a,[],function(){return b})};h("3",tinymce.util.Tools.resolve),g("1",["3"],function(a){return a("tinymce.PluginManager")}),g("2",["3"],function(a){return a("tinymce.util.Tools")}),g("0",["1","2"],function(a,b){return a.add("advlist",function(a){function c(b){return a.$.contains(a.getBody(),b)}function d(a){return a&&/^(OL|UL|DL)$/.test(a.nodeName)&&c(a)}function e(a,c){var d=[];return c&&b.each(c.split(/[ ,]/),function(a){d.push({text:a.replace(/\-/g," ").replace(/\b\w/g,function(a){return a.toUpperCase()}),data:"default"==a?"":a})}),d}function f(c,d){a.undoManager.transact(function(){var e,f=a.dom,g=a.selection;if(e=f.getParent(g.getNode(),"ol,ul"),!e||e.nodeName!=c||d===!1){var h={"list-style-type":d?d:""};a.execCommand("UL"==c?"InsertUnorderedList":"InsertOrderedList",!1,h)}e=f.getParent(g.getNode(),"ol,ul"),e&&b.each(f.select("ol,ul",e).concat([e]),function(a){a.nodeName!==c&&d!==!1&&(a=f.rename(a,c)),f.setStyle(a,"listStyleType",d?d:null),a.removeAttribute("data-mce-style")}),a.focus()})}function g(b){var c=a.dom.getStyle(a.dom.getParent(a.selection.getNode(),"ol,ul"),"listStyleType")||"";b.control.items().each(function(a){a.active(a.settings.data===c)})}var h,i,j=function(a,c){var d=a.settings.plugins?a.settings.plugins:"";return b.inArray(d.split(/[ ,]/),c)!==-1};h=e("OL",a.getParam("advlist_number_styles","default,lower-alpha,lower-greek,lower-roman,upper-alpha,upper-roman")),i=e("UL",a.getParam("advlist_bullet_styles","default,circle,disc,square"));var k=function(c){return function(){var e=this;a.on("NodeChange",function(a){var f=b.grep(a.parents,d);e.active(f.length>0&&f[0].nodeName===c)})}};j(a,"lists")&&(a.addCommand("ApplyUnorderedListStyle",function(a,b){f("UL",b["list-style-type"])}),a.addCommand("ApplyOrderedListStyle",function(a,b){f("OL",b["list-style-type"])}),a.addButton("numlist",{type:h.length>0?"splitbutton":"button",tooltip:"Numbered list",menu:h,onPostRender:k("OL"),onshow:g,onselect:function(a){f("OL",a.control.settings.data)},onclick:function(){f("OL",!1)}}),a.addButton("bullist",{type:i.length>0?"splitbutton":"button",tooltip:"Bullet list",onPostRender:k("UL"),menu:i,onshow:g,onselect:function(a){f("UL",a.control.settings.data)},onclick:function(){f("UL",!1)}}))}),function(){}}),d("0")()}();
!function(){var a={},b=function(b){for(var c=a[b],e=c.deps,f=c.defn,g=e.length,h=new Array(g),i=0;i<g;++i)h[i]=d(e[i]);var j=f.apply(null,h);if(void 0===j)throw"module ["+b+"] returned undefined";c.instance=j},c=function(b,c,d){if("string"!=typeof b)throw"module id must be a string";if(void 0===c)throw"no dependencies for "+b;if(void 0===d)throw"no definition function for "+b;a[b]={deps:c,defn:d,instance:void 0}},d=function(c){var d=a[c];if(void 0===d)throw"module ["+c+"] was undefined";return void 0===d.instance&&b(c),d.instance},e=function(a,b){for(var c=a.length,e=new Array(c),f=0;f<c;++f)e.push(d(a[f]));b.apply(null,b)},f={};f.bolt={module:{api:{define:c,require:e,demand:d}}};var g=c,h=function(a,b){g(a,[],function(){return b})};h("3",tinymce.util.Tools.resolve),g("1",["3"],function(a){return a("tinymce.PluginManager")}),g("2",["3"],function(a){return a("tinymce.util.Tools")}),g("0",["1","2"],function(a,b){return a.add("advlist",function(a){function c(b){return a.$.contains(a.getBody(),b)}function d(a){return a&&/^(OL|UL|DL)$/.test(a.nodeName)&&c(a)}function e(a,c){var d=[];return c&&b.each(c.split(/[ ,]/),function(a){d.push({text:a.replace(/\-/g," ").replace(/\b\w/g,function(a){return a.toUpperCase()}),data:"default"==a?"":a})}),d}function f(b,c){var d="UL"==b?"InsertUnorderedList":"InsertOrderedList";a.execCommand(d,!1,c===!1?null:{"list-style-type":c})}function g(b){var c=a.dom.getStyle(a.dom.getParent(a.selection.getNode(),"ol,ul"),"listStyleType")||"";b.control.items().each(function(a){a.active(a.settings.data===c)})}var h,i,j=function(a,c){var d=a.settings.plugins?a.settings.plugins:"";return b.inArray(d.split(/[ ,]/),c)!==-1};h=e("OL",a.getParam("advlist_number_styles","default,lower-alpha,lower-greek,lower-roman,upper-alpha,upper-roman")),i=e("UL",a.getParam("advlist_bullet_styles","default,circle,disc,square"));var k=function(c){return function(){var e=this;a.on("NodeChange",function(a){var f=b.grep(a.parents,d);e.active(f.length>0&&f[0].nodeName===c)})}};j(a,"lists")&&(a.addCommand("ApplyUnorderedListStyle",function(a,b){f("UL",b["list-style-type"])}),a.addCommand("ApplyOrderedListStyle",function(a,b){f("OL",b["list-style-type"])}),a.addButton("numlist",{type:h.length>0?"splitbutton":"button",tooltip:"Numbered list",menu:h,onPostRender:k("OL"),onshow:g,onselect:function(a){f("OL",a.control.settings.data)},onclick:function(){a.execCommand("InsertOrderedList")}}),a.addButton("bullist",{type:i.length>0?"splitbutton":"button",tooltip:"Bullet list",onPostRender:k("UL"),menu:i,onshow:g,onselect:function(a){f("UL",a.control.settings.data)},onclick:function(){a.execCommand("InsertUnorderedList")}}))}),function(){}}),d("0")()}();

View File

@@ -1 +1 @@
!function(){var a={},b=function(b){for(var c=a[b],e=c.deps,f=c.defn,g=e.length,h=new Array(g),i=0;i<g;++i)h[i]=d(e[i]);var j=f.apply(null,h);if(void 0===j)throw"module ["+b+"] returned undefined";c.instance=j},c=function(b,c,d){if("string"!=typeof b)throw"module id must be a string";if(void 0===c)throw"no dependencies for "+b;if(void 0===d)throw"no definition function for "+b;a[b]={deps:c,defn:d,instance:void 0}},d=function(c){var d=a[c];if(void 0===d)throw"module ["+c+"] was undefined";return void 0===d.instance&&b(c),d.instance},e=function(a,b){for(var c=a.length,e=new Array(c),f=0;f<c;++f)e.push(d(a[f]));b.apply(null,b)},f={};f.bolt={module:{api:{define:c,require:e,demand:d}}};var g=c,h=function(a,b){g(a,[],function(){return b})};h("3",tinymce.util.Tools.resolve),g("1",["3"],function(a){return a("tinymce.Env")}),g("2",["3"],function(a){return a("tinymce.PluginManager")}),g("0",["1","2"],function(a,b){return b.add("autolink",function(b){function c(a){f(a,-1,"(",!0)}function d(a){f(a,0,"",!0)}function e(a){f(a,-1,"",!1)}function f(a,b,c){function d(a,b){if(b<0&&(b=0),3==a.nodeType){var c=a.data.length;b>c&&(b=c)}return b}function e(a,b){1!=a.nodeType||a.hasChildNodes()?g.setStart(a,d(a,b)):g.setStartBefore(a)}function f(a,b){1!=a.nodeType||a.hasChildNodes()?g.setEnd(a,d(a,b)):g.setEndAfter(a)}var g,i,j,k,l,m,n,o,p,q;if("A"!=a.selection.getNode().tagName){if(g=a.selection.getRng(!0).cloneRange(),g.startOffset<5){if(o=g.endContainer.previousSibling,!o){if(!g.endContainer.firstChild||!g.endContainer.firstChild.nextSibling)return;o=g.endContainer.firstChild.nextSibling}if(p=o.length,e(o,p),f(o,p),g.endOffset<5)return;i=g.endOffset,k=o}else{if(k=g.endContainer,3!=k.nodeType&&k.firstChild){for(;3!=k.nodeType&&k.firstChild;)k=k.firstChild;3==k.nodeType&&(e(k,0),f(k,k.nodeValue.length))}i=1==g.endOffset?2:g.endOffset-1-b}j=i;do e(k,i>=2?i-2:0),f(k,i>=1?i-1:0),i-=1,q=g.toString();while(" "!=q&&""!==q&&160!=q.charCodeAt(0)&&i-2>=0&&q!=c);g.toString()==c||160==g.toString().charCodeAt(0)?(e(k,i),f(k,j),i+=1):0===g.startOffset?(e(k,0),f(k,j)):(e(k,i),f(k,j)),m=g.toString(),"."==m.charAt(m.length-1)&&f(k,j-1),m=g.toString(),n=m.match(h),n&&("www."==n[1]?n[1]="http://www.":/@$/.test(n[1])&&!/^mailto:/.test(n[1])&&(n[1]="mailto:"+n[1]),l=a.selection.getBookmark(),a.selection.setRng(g),a.execCommand("createlink",!1,n[1]+n[2]),a.settings.default_link_target&&a.dom.setAttrib(a.selection.getNode(),"target",a.settings.default_link_target),a.selection.moveToBookmark(l),a.nodeChanged())}}var g,h=/^(https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.|(?:mailto:)?[A-Z0-9._%+\-]+@)(.+)$/i;return b.settings.autolink_pattern&&(h=b.settings.autolink_pattern),b.on("keydown",function(a){if(13==a.keyCode)return e(b)}),a.ie?void b.on("focus",function(){if(!g){g=!0;try{b.execCommand("AutoUrlDetect",!1,!0)}catch(a){}}}):(b.on("keypress",function(a){if(41==a.keyCode)return c(b)}),void b.on("keyup",function(a){if(32==a.keyCode)return d(b)}))}),function(){}}),d("0")()}();
!function(){var a={},b=function(b){for(var c=a[b],e=c.deps,f=c.defn,g=e.length,h=new Array(g),i=0;i<g;++i)h[i]=d(e[i]);var j=f.apply(null,h);if(void 0===j)throw"module ["+b+"] returned undefined";c.instance=j},c=function(b,c,d){if("string"!=typeof b)throw"module id must be a string";if(void 0===c)throw"no dependencies for "+b;if(void 0===d)throw"no definition function for "+b;a[b]={deps:c,defn:d,instance:void 0}},d=function(c){var d=a[c];if(void 0===d)throw"module ["+c+"] was undefined";return void 0===d.instance&&b(c),d.instance},e=function(a,b){for(var c=a.length,e=new Array(c),f=0;f<c;++f)e.push(d(a[f]));b.apply(null,b)},f={};f.bolt={module:{api:{define:c,require:e,demand:d}}};var g=c,h=function(a,b){g(a,[],function(){return b})};h("3",tinymce.util.Tools.resolve),g("1",["3"],function(a){return a("tinymce.Env")}),g("2",["3"],function(a){return a("tinymce.PluginManager")}),g("0",["1","2"],function(a,b){var c=function(a,b){return a===b||" "===a||160===a.charCodeAt(0)};return b.add("autolink",function(b){function d(a){g(a,-1,"(",!0)}function e(a){g(a,0,"",!0)}function f(a){g(a,-1,"",!1)}function g(a,b,d){function e(a,b){if(b<0&&(b=0),3==a.nodeType){var c=a.data.length;b>c&&(b=c)}return b}function f(a,b){1!=a.nodeType||a.hasChildNodes()?h.setStart(a,e(a,b)):h.setStartBefore(a)}function g(a,b){1!=a.nodeType||a.hasChildNodes()?h.setEnd(a,e(a,b)):h.setEndAfter(a)}var h,j,k,l,m,n,o,p,q,r;if("A"!=a.selection.getNode().tagName){if(h=a.selection.getRng(!0).cloneRange(),h.startOffset<5){if(p=h.endContainer.previousSibling,!p){if(!h.endContainer.firstChild||!h.endContainer.firstChild.nextSibling)return;p=h.endContainer.firstChild.nextSibling}if(q=p.length,f(p,q),g(p,q),h.endOffset<5)return;j=h.endOffset,l=p}else{if(l=h.endContainer,3!=l.nodeType&&l.firstChild){for(;3!=l.nodeType&&l.firstChild;)l=l.firstChild;3==l.nodeType&&(f(l,0),g(l,l.nodeValue.length))}j=1==h.endOffset?2:h.endOffset-1-b}k=j;do f(l,j>=2?j-2:0),g(l,j>=1?j-1:0),j-=1,r=h.toString();while(" "!=r&&""!==r&&160!=r.charCodeAt(0)&&j-2>=0&&r!=d);c(h.toString(),d)?(f(l,j),g(l,k),j+=1):0===h.startOffset?(f(l,0),g(l,k)):(f(l,j),g(l,k)),n=h.toString(),"."==n.charAt(n.length-1)&&g(l,k-1),n=h.toString(),o=n.match(i),o&&("www."==o[1]?o[1]="http://www.":/@$/.test(o[1])&&!/^mailto:/.test(o[1])&&(o[1]="mailto:"+o[1]),m=a.selection.getBookmark(),a.selection.setRng(h),a.execCommand("createlink",!1,o[1]+o[2]),a.settings.default_link_target&&a.dom.setAttrib(a.selection.getNode(),"target",a.settings.default_link_target),a.selection.moveToBookmark(m),a.nodeChanged())}}var h,i=/^(https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.|(?:mailto:)?[A-Z0-9._%+\-]+@)(.+)$/i;return b.settings.autolink_pattern&&(i=b.settings.autolink_pattern),b.on("keydown",function(a){if(13==a.keyCode)return f(b)}),a.ie?void b.on("focus",function(){if(!h){h=!0;try{b.execCommand("AutoUrlDetect",!1,!0)}catch(a){}}}):(b.on("keypress",function(a){if(41==a.keyCode)return d(b)}),void b.on("keyup",function(a){if(32==a.keyCode)return e(b)}))}),function(){}}),d("0")()}();

View File

@@ -1 +1 @@
!function(){var a={},b=function(b){for(var c=a[b],e=c.deps,f=c.defn,g=e.length,h=new Array(g),i=0;i<g;++i)h[i]=d(e[i]);var j=f.apply(null,h);if(void 0===j)throw"module ["+b+"] returned undefined";c.instance=j},c=function(b,c,d){if("string"!=typeof b)throw"module id must be a string";if(void 0===c)throw"no dependencies for "+b;if(void 0===d)throw"no definition function for "+b;a[b]={deps:c,defn:d,instance:void 0}},d=function(c){var d=a[c];if(void 0===d)throw"module ["+c+"] was undefined";return void 0===d.instance&&b(c),d.instance},e=function(a,b){for(var c=a.length,e=new Array(c),f=0;f<c;++f)e.push(d(a[f]));b.apply(null,b)},f={};f.bolt={module:{api:{define:c,require:e,demand:d}}};var g=c,h=function(a,b){g(a,[],function(){return b})};h("6",tinymce.util.Tools.resolve),g("1",["6"],function(a){return a("tinymce.EditorManager")}),g("2",["6"],function(a){return a("tinymce.PluginManager")}),g("3",["6"],function(a){return a("tinymce.util.LocalStorage")}),g("4",["6"],function(a){return a("tinymce.util.Tools")}),h("5",window),g("0",["1","2","3","4","5"],function(a,b,c,d,e){return a._beforeUnloadHandler=function(){var b;return d.each(a.editors,function(a){a.plugins.autosave&&a.plugins.autosave.storeDraft(),!b&&a.isDirty()&&a.getParam("autosave_ask_before_unload",!0)&&(b=a.translate("You have unsaved changes are you sure you want to navigate away?"))}),b},b.add("autosave",function(b){function f(a,b){var c={s:1e3,m:6e4};return a=/^(\d+)([ms]?)$/.exec(""+(a||b)),(a[2]?c[a[2]]:1)*parseInt(a,10)}function g(){var a=parseInt(c.getItem(o+"time"),10)||0;return!((new Date).getTime()-a>q.autosave_retention)||(h(!1),!1)}function h(a){c.removeItem(o+"draft"),c.removeItem(o+"time"),a!==!1&&b.fire("RemoveDraft")}function i(){!n()&&b.isDirty()&&(c.setItem(o+"draft",b.getContent({format:"raw",no_events:!0})),c.setItem(o+"time",(new Date).getTime()),b.fire("StoreDraft"))}function j(){g()&&(b.setContent(c.getItem(o+"draft"),{format:"raw"}),b.fire("RestoreDraft"))}function k(){p||(setInterval(function(){b.removed||i()},q.autosave_interval),p=!0)}function l(){var a=this;a.disabled(!g()),b.on("StoreDraft RestoreDraft RemoveDraft",function(){a.disabled(!g())}),k()}function m(){b.undoManager.beforeChange(),j(),h(),b.undoManager.add()}function n(a){var c=b.settings.forced_root_block;return a=d.trim("undefined"==typeof a?b.getBody().innerHTML:a),""===a||new RegExp("^<"+c+"[^>]*>((\xa0|&nbsp;|[ \t]|<br[^>]*>)+?|)</"+c+">|<br>$","i").test(a)}var o,p,q=b.settings;o=q.autosave_prefix||"tinymce-autosave-{path}{query}-{id}-",o=o.replace(/\{path\}/g,document.location.pathname),o=o.replace(/\{query\}/g,document.location.search),o=o.replace(/\{id\}/g,b.id),q.autosave_interval=f(q.autosave_interval,"30s"),q.autosave_retention=f(q.autosave_retention,"20m"),b.addButton("restoredraft",{title:"Restore last draft",onclick:m,onPostRender:l}),b.addMenuItem("restoredraft",{text:"Restore last draft",onclick:m,onPostRender:l,context:"file"}),b.settings.autosave_restore_when_empty!==!1&&(b.on("init",function(){g()&&n()&&j()}),b.on("saveContent",function(){h()})),e.onbeforeunload=a._beforeUnloadHandler,this.hasDraft=g,this.storeDraft=i,this.restoreDraft=j,this.removeDraft=h,this.isEmpty=n}),function(){}}),d("0")()}();
!function(){var a={},b=function(b){for(var c=a[b],e=c.deps,f=c.defn,g=e.length,h=new Array(g),i=0;i<g;++i)h[i]=d(e[i]);var j=f.apply(null,h);if(void 0===j)throw"module ["+b+"] returned undefined";c.instance=j},c=function(b,c,d){if("string"!=typeof b)throw"module id must be a string";if(void 0===c)throw"no dependencies for "+b;if(void 0===d)throw"no definition function for "+b;a[b]={deps:c,defn:d,instance:void 0}},d=function(c){var d=a[c];if(void 0===d)throw"module ["+c+"] was undefined";return void 0===d.instance&&b(c),d.instance},e=function(a,b){for(var c=a.length,e=new Array(c),f=0;f<c;++f)e.push(d(a[f]));b.apply(null,b)},f={};f.bolt={module:{api:{define:c,require:e,demand:d}}};var g=c,h=function(a,b){g(a,[],function(){return b})};h("6",tinymce.util.Tools.resolve),g("1",["6"],function(a){return a("tinymce.EditorManager")}),g("2",["6"],function(a){return a("tinymce.PluginManager")}),g("3",["6"],function(a){return a("tinymce.util.LocalStorage")}),g("4",["6"],function(a){return a("tinymce.util.Tools")}),h("5",window),g("0",["1","2","3","4","5"],function(a,b,c,d,e){return a._beforeUnloadHandler=function(){var b;return d.each(a.get(),function(a){a.plugins.autosave&&a.plugins.autosave.storeDraft(),!b&&a.isDirty()&&a.getParam("autosave_ask_before_unload",!0)&&(b=a.translate("You have unsaved changes are you sure you want to navigate away?"))}),b},b.add("autosave",function(b){function f(a,b){var c={s:1e3,m:6e4};return a=/^(\d+)([ms]?)$/.exec(""+(a||b)),(a[2]?c[a[2]]:1)*parseInt(a,10)}function g(){var a=parseInt(c.getItem(o+"time"),10)||0;return!((new Date).getTime()-a>q.autosave_retention)||(h(!1),!1)}function h(a){c.removeItem(o+"draft"),c.removeItem(o+"time"),a!==!1&&b.fire("RemoveDraft")}function i(){!n()&&b.isDirty()&&(c.setItem(o+"draft",b.getContent({format:"raw",no_events:!0})),c.setItem(o+"time",(new Date).getTime()),b.fire("StoreDraft"))}function j(){g()&&(b.setContent(c.getItem(o+"draft"),{format:"raw"}),b.fire("RestoreDraft"))}function k(){p||(setInterval(function(){b.removed||i()},q.autosave_interval),p=!0)}function l(){var a=this;a.disabled(!g()),b.on("StoreDraft RestoreDraft RemoveDraft",function(){a.disabled(!g())}),k()}function m(){b.undoManager.beforeChange(),j(),h(),b.undoManager.add()}function n(a){var c=b.settings.forced_root_block;return a=d.trim("undefined"==typeof a?b.getBody().innerHTML:a),""===a||new RegExp("^<"+c+"[^>]*>((\xa0|&nbsp;|[ \t]|<br[^>]*>)+?|)</"+c+">|<br>$","i").test(a)}var o,p,q=b.settings;o=q.autosave_prefix||"tinymce-autosave-{path}{query}-{id}-",o=o.replace(/\{path\}/g,document.location.pathname),o=o.replace(/\{query\}/g,document.location.search),o=o.replace(/\{id\}/g,b.id),q.autosave_interval=f(q.autosave_interval,"30s"),q.autosave_retention=f(q.autosave_retention,"20m"),b.addButton("restoredraft",{title:"Restore last draft",onclick:m,onPostRender:l}),b.addMenuItem("restoredraft",{text:"Restore last draft",onclick:m,onPostRender:l,context:"file"}),b.settings.autosave_restore_when_empty!==!1&&(b.on("init",function(){g()&&n()&&j()}),b.on("saveContent",function(){h()})),e.onbeforeunload=a._beforeUnloadHandler,this.hasDraft=g,this.storeDraft=i,this.restoreDraft=j,this.removeDraft=h,this.isEmpty=n}),function(){}}),d("0")()}();

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
!function(){var a={},b=function(b){for(var c=a[b],e=c.deps,f=c.defn,g=e.length,h=new Array(g),i=0;i<g;++i)h[i]=d(e[i]);var j=f.apply(null,h);if(void 0===j)throw"module ["+b+"] returned undefined";c.instance=j},c=function(b,c,d){if("string"!=typeof b)throw"module id must be a string";if(void 0===c)throw"no dependencies for "+b;if(void 0===d)throw"no definition function for "+b;a[b]={deps:c,defn:d,instance:void 0}},d=function(c){var d=a[c];if(void 0===d)throw"module ["+c+"] was undefined";return void 0===d.instance&&b(c),d.instance},e=function(a,b){for(var c=a.length,e=new Array(c),f=0;f<c;++f)e.push(d(a[f]));b.apply(null,b)},f={};f.bolt={module:{api:{define:c,require:e,demand:d}}};var g=c,h=function(a,b){g(a,[],function(){return b})};h("2",tinymce.util.Tools.resolve),g("1",["2"],function(a){return a("tinymce.PluginManager")}),g("0",["1"],function(a){return a.add("nonbreaking",function(a){var b=a.getParam("nonbreaking_force_tab");if(a.addCommand("mceNonBreaking",function(){a.insertContent(a.plugins.visualchars&&a.plugins.visualchars.state?'<span class="mce-nbsp">&nbsp;</span>':"&nbsp;"),a.dom.setAttrib(a.dom.select("span.mce-nbsp"),"data-mce-bogus","1")}),a.addButton("nonbreaking",{title:"Nonbreaking space",cmd:"mceNonBreaking"}),a.addMenuItem("nonbreaking",{text:"Nonbreaking space",cmd:"mceNonBreaking",context:"insert"}),b){var c=+b>1?+b:3;a.on("keydown",function(b){if(9==b.keyCode){if(b.shiftKey)return;b.preventDefault();for(var d=0;d<c;d++)a.execCommand("mceNonBreaking")}})}}),function(){}}),d("0")()}();
!function(){var a={},b=function(b){for(var c=a[b],e=c.deps,f=c.defn,g=e.length,h=new Array(g),i=0;i<g;++i)h[i]=d(e[i]);var j=f.apply(null,h);if(void 0===j)throw"module ["+b+"] returned undefined";c.instance=j},c=function(b,c,d){if("string"!=typeof b)throw"module id must be a string";if(void 0===c)throw"no dependencies for "+b;if(void 0===d)throw"no definition function for "+b;a[b]={deps:c,defn:d,instance:void 0}},d=function(c){var d=a[c];if(void 0===d)throw"module ["+c+"] was undefined";return void 0===d.instance&&b(c),d.instance},e=function(a,b){for(var c=a.length,e=new Array(c),f=0;f<c;++f)e.push(d(a[f]));b.apply(null,b)},f={};f.bolt={module:{api:{define:c,require:e,demand:d}}};var g=c,h=function(a,b){g(a,[],function(){return b})};h("2",tinymce.util.Tools.resolve),g("1",["2"],function(a){return a("tinymce.PluginManager")}),g("0",["1"],function(a){return a.add("nonbreaking",function(a){var b=a.getParam("nonbreaking_force_tab"),c=function(a,b){for(var c="",d=0;d<b;d++)c+=a;return c},d=function(b){var d=a.plugins.visualchars&&a.plugins.visualchars.state?'<span class="mce-nbsp">&nbsp;</span>':"&nbsp;";a.insertContent(c(d,b)),a.dom.setAttrib(a.dom.select("span.mce-nbsp"),"data-mce-bogus","1")};if(a.addCommand("mceNonBreaking",function(){d(1)}),a.addButton("nonbreaking",{title:"Nonbreaking space",cmd:"mceNonBreaking"}),a.addMenuItem("nonbreaking",{text:"Nonbreaking space",cmd:"mceNonBreaking",context:"insert"}),b){var e=+b>1?+b:3;a.on("keydown",function(a){if(9==a.keyCode){if(a.shiftKey)return;a.preventDefault(),d(e)}})}}),function(){}}),d("0")()}();

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
!function(){var a={},b=function(b){for(var c=a[b],e=c.deps,f=c.defn,g=e.length,h=new Array(g),i=0;i<g;++i)h[i]=d(e[i]);var j=f.apply(null,h);if(void 0===j)throw"module ["+b+"] returned undefined";c.instance=j},c=function(b,c,d){if("string"!=typeof b)throw"module id must be a string";if(void 0===c)throw"no dependencies for "+b;if(void 0===d)throw"no definition function for "+b;a[b]={deps:c,defn:d,instance:void 0}},d=function(c){var d=a[c];if(void 0===d)throw"module ["+c+"] was undefined";return void 0===d.instance&&b(c),d.instance},e=function(a,b){for(var c=a.length,e=new Array(c),f=0;f<c;++f)e.push(d(a[f]));b.apply(null,b)},f={};f.bolt={module:{api:{define:c,require:e,demand:d}}};var g=c,h=function(a,b){g(a,[],function(){return b})};h("4",tinymce.util.Tools.resolve),g("1",["4"],function(a){return a("tinymce.PluginManager")}),g("2",["4"],function(a){return a("tinymce.Env")}),g("3",["4"],function(a){return a("tinymce.util.Tools")}),g("0",["1","2","3"],function(a,b,c){return a.add("preview",function(a){var d=a.settings,e=!b.ie;a.addCommand("mcePreview",function(){a.windowManager.open({title:"Preview",width:parseInt(a.getParam("plugin_preview_width","650"),10),height:parseInt(a.getParam("plugin_preview_height","500"),10),html:'<iframe src="javascript:\'\'" frameborder="0"'+(e?' sandbox="allow-scripts"':"")+"></iframe>",buttons:{text:"Close",onclick:function(){this.parent().parent().close()}},onPostRender:function(){var b,f="";f+='<base href="'+a.documentBaseURI.getURI()+'">',c.each(a.contentCSS,function(b){f+='<link type="text/css" rel="stylesheet" href="'+a.documentBaseURI.toAbsolute(b)+'">'});var g=d.body_id||"tinymce";g.indexOf("=")!=-1&&(g=a.getParam("body_id","","hash"),g=g[a.id]||g);var h=d.body_class||"";h.indexOf("=")!=-1&&(h=a.getParam("body_class","","hash"),h=h[a.id]||"");var i='<script>document.addEventListener && document.addEventListener("click", function(e) {for (var elm = e.target; elm; elm = elm.parentNode) {if (elm.nodeName === "A") {e.preventDefault();}}}, false);</script> ',j=a.settings.directionality?' dir="'+a.settings.directionality+'"':"";if(b="<!DOCTYPE html><html><head>"+f+'</head><body id="'+g+'" class="mce-content-body '+h+'"'+j+">"+a.getContent()+i+"</body></html>",e)this.getEl("body").firstChild.src="data:text/html;charset=utf-8,"+encodeURIComponent(b);else{var k=this.getEl("body").firstChild.contentWindow.document;k.open(),k.write(b),k.close()}}})}),a.addButton("preview",{title:"Preview",cmd:"mcePreview"}),a.addMenuItem("preview",{text:"Preview",cmd:"mcePreview",context:"view"})}),function(){}}),d("0")()}();
!function(){var a={},b=function(b){for(var c=a[b],e=c.deps,f=c.defn,g=e.length,h=new Array(g),i=0;i<g;++i)h[i]=d(e[i]);var j=f.apply(null,h);if(void 0===j)throw"module ["+b+"] returned undefined";c.instance=j},c=function(b,c,d){if("string"!=typeof b)throw"module id must be a string";if(void 0===c)throw"no dependencies for "+b;if(void 0===d)throw"no definition function for "+b;a[b]={deps:c,defn:d,instance:void 0}},d=function(c){var d=a[c];if(void 0===d)throw"module ["+c+"] was undefined";return void 0===d.instance&&b(c),d.instance},e=function(a,b){for(var c=a.length,e=new Array(c),f=0;f<c;++f)e.push(d(a[f]));b.apply(null,b)},f={};f.bolt={module:{api:{define:c,require:e,demand:d}}};var g=c,h=function(a,b){g(a,[],function(){return b})};h("4",tinymce.util.Tools.resolve),g("1",["4"],function(a){return a("tinymce.PluginManager")}),g("2",["4"],function(a){return a("tinymce.Env")}),g("3",["4"],function(a){return a("tinymce.util.Tools")}),g("0",["1","2","3"],function(a,b,c){return a.add("preview",function(a){var d=a.settings,e=!b.ie;a.addCommand("mcePreview",function(){a.windowManager.open({title:"Preview",width:parseInt(a.getParam("plugin_preview_width","650"),10),height:parseInt(a.getParam("plugin_preview_height","500"),10),html:'<iframe src="javascript:\'\'" frameborder="0"'+(e?' sandbox="allow-scripts"':"")+"></iframe>",buttons:{text:"Close",onclick:function(){this.parent().parent().close()}},onPostRender:function(){var b,f="",g=a.dom.encode;f+='<base href="'+g(a.documentBaseURI.getURI())+'">',c.each(a.contentCSS,function(b){f+='<link type="text/css" rel="stylesheet" href="'+g(a.documentBaseURI.toAbsolute(b))+'">'});var h=d.body_id||"tinymce";h.indexOf("=")!=-1&&(h=a.getParam("body_id","","hash"),h=h[a.id]||h);var i=d.body_class||"";i.indexOf("=")!=-1&&(i=a.getParam("body_class","","hash"),i=i[a.id]||"");var j='<script>document.addEventListener && document.addEventListener("click", function(e) {for (var elm = e.target; elm; elm = elm.parentNode) {if (elm.nodeName === "A") {e.preventDefault();}}}, false);</script> ',k=a.settings.directionality?' dir="'+a.settings.directionality+'"':"";if(b="<!DOCTYPE html><html><head>"+f+'</head><body id="'+g(h)+'" class="mce-content-body '+g(i)+'"'+g(k)+">"+a.getContent()+j+"</body></html>",e)this.getEl("body").firstChild.src="data:text/html;charset=utf-8,"+encodeURIComponent(b);else{var l=this.getEl("body").firstChild.contentWindow.document;l.open(),l.write(b),l.close()}}})}),a.addButton("preview",{title:"Preview",cmd:"mcePreview"}),a.addMenuItem("preview",{text:"Preview",cmd:"mcePreview",context:"view"})}),function(){}}),d("0")()}();

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
.mce-content-body .mce-reset{margin:0;padding:0;border:0;outline:0;vertical-align:top;background:transparent;text-decoration:none;color:black;font-family:Arial;font-size:11px;text-shadow:none;float:none;position:static;width:auto;height:auto;white-space:nowrap;cursor:inherit;line-height:normal;font-weight:normal;text-align:left;-webkit-tap-highlight-color:transparent;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;direction:ltr;max-width:none}.mce-object{border:1px dotted #3A3A3A;background:#D5D5D5 url(img/object.gif) no-repeat center}.mce-preview-object{display:inline-block;position:relative;margin:0 2px 0 2px;line-height:0;border:1px solid gray}.mce-preview-object[data-mce-selected="2"] .mce-shim{display:none}.mce-preview-object .mce-shim{position:absolute;top:0;left:0;width:100%;height:100%;background:url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)}figure.align-left{float:left}figure.align-right{float:right}figure.image.align-center{display:table;margin-left:auto;margin-right:auto}figure.image{display:inline-block;border:1px solid gray;margin:0 2px 0 1px;background:#f5f2f0}figure.image img{margin:8px 8px 0 8px}figure.image figcaption{margin:6px 8px 6px 8px;text-align:center}.mce-toc{border:1px solid gray}.mce-toc h2{margin:4px}.mce-toc li{list-style-type:none}.mce-pagebreak{cursor:default;display:block;border:0;width:100%;height:5px;border:1px dashed #666;margin-top:15px;page-break-before:always}@media print{.mce-pagebreak{border:0}}.mce-item-anchor{cursor:default;display:inline-block;-webkit-user-select:all;-webkit-user-modify:read-only;-moz-user-select:all;-moz-user-modify:read-only;user-select:all;user-modify:read-only;width:9px !important;height:9px !important;border:1px dotted #3A3A3A;background:#D5D5D5 url(img/anchor.gif) no-repeat center}.mce-nbsp,.mce-shy{background:#AAA}.mce-shy::after{content:'-'}.mce-match-marker{background:#AAA;color:#fff}.mce-match-marker-selected{background:#3399ff;color:#fff}.mce-spellchecker-word{border-bottom:2px solid #F00;cursor:default}.mce-spellchecker-grammar{border-bottom:2px solid #008000;cursor:default}.mce-item-table,.mce-item-table td,.mce-item-table th,.mce-item-table caption{border:1px dashed #BBB}td[data-mce-selected],th[data-mce-selected]{background-color:#3399ff !important}.mce-edit-focus{outline:1px dotted #333}.mce-resize-bar-dragging{background-color:blue;opacity:.25;filter:alpha(opacity=25);zoom:1}.mce-content-body p,.mce-content-body div,.mce-content-body h1,.mce-content-body h2,.mce-content-body h3,.mce-content-body h4,.mce-content-body h5,.mce-content-body h6{line-height:1.2em}.mce-content-body *[contentEditable=false] *[contentEditable=true]:focus{outline:2px solid #2d8ac7}.mce-content-body *[contentEditable=false] *[contentEditable=true]:hover{outline:2px solid #7ACAFF}.mce-content-body *[contentEditable=false][data-mce-selected]{outline:2px solid #2d8ac7}.mce-content-body a[data-mce-selected],.mce-content-body code[data-mce-selected]{background:#bfe6ff}.mce-content-body hr{cursor:default}
.word-wrap{word-wrap:break-word;-ms-word-break:break-all;word-break:break-all;word-break:break-word;-ms-hyphens:auto;-moz-hyphens:auto;-webkit-hyphens:auto;hyphens:auto}.mce-content-body .mce-reset{margin:0;padding:0;border:0;outline:0;vertical-align:top;background:transparent;text-decoration:none;color:black;font-family:Arial;font-size:11px;text-shadow:none;float:none;position:static;width:auto;height:auto;white-space:nowrap;cursor:inherit;line-height:normal;font-weight:normal;text-align:left;-webkit-tap-highlight-color:transparent;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;direction:ltr;max-width:none}.mce-object{border:1px dotted #3A3A3A;background:#D5D5D5 url(img/object.gif) no-repeat center}.mce-preview-object{display:inline-block;position:relative;margin:0 2px 0 2px;line-height:0;border:1px solid gray}.mce-preview-object[data-mce-selected="2"] .mce-shim{display:none}.mce-preview-object .mce-shim{position:absolute;top:0;left:0;width:100%;height:100%;background:url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)}figure.align-left{float:left}figure.align-right{float:right}figure.image.align-center{display:table;margin-left:auto;margin-right:auto}figure.image{display:inline-block;border:1px solid gray;margin:0 2px 0 1px;background:#f5f2f0}figure.image img{margin:8px 8px 0 8px}figure.image figcaption{margin:6px 8px 6px 8px;text-align:center}.mce-toc{border:1px solid gray}.mce-toc h2{margin:4px}.mce-toc li{list-style-type:none}.mce-pagebreak{cursor:default;display:block;border:0;width:100%;height:5px;border:1px dashed #666;margin-top:15px;page-break-before:always}@media print{.mce-pagebreak{border:0}}.mce-item-anchor{cursor:default;display:inline-block;-webkit-user-select:all;-webkit-user-modify:read-only;-moz-user-select:all;-moz-user-modify:read-only;user-select:all;user-modify:read-only;width:9px !important;height:9px !important;border:1px dotted #3A3A3A;background:#D5D5D5 url(img/anchor.gif) no-repeat center}.mce-nbsp,.mce-shy{background:#AAA}.mce-shy::after{content:'-'}.mce-match-marker{background:#AAA;color:#fff}.mce-match-marker-selected{background:#3399ff;color:#fff}.mce-spellchecker-word{border-bottom:2px solid #F00;cursor:default}.mce-spellchecker-grammar{border-bottom:2px solid #008000;cursor:default}.mce-item-table,.mce-item-table td,.mce-item-table th,.mce-item-table caption{border:1px dashed #BBB}td[data-mce-selected],th[data-mce-selected]{background-color:#3399ff !important}.mce-edit-focus{outline:1px dotted #333}.mce-resize-bar-dragging{background-color:blue;opacity:.25;filter:alpha(opacity=25);zoom:1}.mce-content-body *[contentEditable=false] *[contentEditable=true]:focus{outline:2px solid #2d8ac7}.mce-content-body *[contentEditable=false] *[contentEditable=true]:hover{outline:2px solid #7ACAFF}.mce-content-body *[contentEditable=false][data-mce-selected]{outline:2px solid #2d8ac7}.mce-content-body a[data-mce-selected],.mce-content-body code[data-mce-selected],.mce-content-body b[data-mce-selected],.mce-content-body i[data-mce-selected],.mce-content-body em[data-mce-selected],.mce-content-body strong[data-mce-selected],.mce-content-body sup[data-mce-selected],.mce-content-body sub[data-mce-selected]{background:#bfe6ff}.mce-content-body hr{cursor:default}.mce-content-body{line-height:1.3}

Some files were not shown because too many files have changed in this diff Show More