Fossil SCM
Added a doc section about CSRF/HTTP Referrer. Other minor doc/message cleanups.
Commit
6de7e480214ca6a034bceb1e6852e665cc40bc44a1da84408d651156235a0a84
Parent
7a95a0f178fdc1c…
2 files changed
+4
-1
+65
-23
+4
-1
| --- src/fileedit.c | ||
| +++ src/fileedit.c | ||
| @@ -1081,11 +1081,14 @@ | ||
| 1081 | 1081 | login_check_credentials(); |
| 1082 | 1082 | if( !g.perm.Write ){ |
| 1083 | 1083 | fileedit_ajax_error(403,"Write permissions required."); |
| 1084 | 1084 | return 0; |
| 1085 | 1085 | }else if(0==cgi_csrf_safe(requirePost)){ |
| 1086 | - fileedit_ajax_error(403, "CSRF violation?"); | |
| 1086 | + fileedit_ajax_error(403, | |
| 1087 | + "CSRF violation (make sure sending of HTTP " | |
| 1088 | + "Referer headers is enabled for XHR " | |
| 1089 | + "connections)."); | |
| 1087 | 1090 | return 0; |
| 1088 | 1091 | } |
| 1089 | 1092 | return 1; |
| 1090 | 1093 | } |
| 1091 | 1094 | /* |
| 1092 | 1095 |
| --- src/fileedit.c | |
| +++ src/fileedit.c | |
| @@ -1081,11 +1081,14 @@ | |
| 1081 | login_check_credentials(); |
| 1082 | if( !g.perm.Write ){ |
| 1083 | fileedit_ajax_error(403,"Write permissions required."); |
| 1084 | return 0; |
| 1085 | }else if(0==cgi_csrf_safe(requirePost)){ |
| 1086 | fileedit_ajax_error(403, "CSRF violation?"); |
| 1087 | return 0; |
| 1088 | } |
| 1089 | return 1; |
| 1090 | } |
| 1091 | /* |
| 1092 |
| --- src/fileedit.c | |
| +++ src/fileedit.c | |
| @@ -1081,11 +1081,14 @@ | |
| 1081 | login_check_credentials(); |
| 1082 | if( !g.perm.Write ){ |
| 1083 | fileedit_ajax_error(403,"Write permissions required."); |
| 1084 | return 0; |
| 1085 | }else if(0==cgi_csrf_safe(requirePost)){ |
| 1086 | fileedit_ajax_error(403, |
| 1087 | "CSRF violation (make sure sending of HTTP " |
| 1088 | "Referer headers is enabled for XHR " |
| 1089 | "connections)."); |
| 1090 | return 0; |
| 1091 | } |
| 1092 | return 1; |
| 1093 | } |
| 1094 | /* |
| 1095 |
+65
-23
| --- www/fileedit-page.md | ||
| +++ www/fileedit-page.md | ||
| @@ -1,33 +1,68 @@ | ||
| 1 | 1 | # The fileedit Page |
| 2 | 2 | |
| 3 | -This document describes some tips and tricks for the [](/fileedit) | |
| 4 | -page, which provides, for users with [checkin | |
| 5 | -privileges](./caps/index.md), basic editing features for files via the | |
| 6 | -web interface. | |
| 3 | +This document describes the limitations of, caveats for, and | |
| 4 | +disclaimers for the [](/fileedit) page, which provides users with | |
| 5 | +[checkin privileges](./caps/index.md) basic editing features for files | |
| 6 | +via the web interface. | |
| 7 | 7 | |
| 8 | 8 | # Important Caveats and Disclaimers |
| 9 | 9 | |
| 10 | 10 | Predictably, the ability to edit files in a repository from a web |
| 11 | 11 | browser halfway around the world comes with several obligatory caveats |
| 12 | 12 | and disclaimers... |
| 13 | 13 | |
| 14 | -### `/fileedit` Does *Nothing* by Default. | |
| 14 | +## `/fileedit` Does *Nothing* by Default. | |
| 15 | 15 | |
| 16 | 16 | In order to "activate" it, a user with [the "setup" |
| 17 | 17 | permission](./caps/index.md) must set the |
| 18 | 18 | [fileedit-glob](/help?cmd=fileedit-glob) repository setting to a |
| 19 | 19 | comma- or newline-delimited list of globs representing a whitelist of |
| 20 | 20 | files which may be edited online. Any user with commit access may then |
| 21 | -edit files matching one of those globs. | |
| 21 | +edit files matching one of those globs. Certain pages within the UI | |
| 22 | +get an "edit" link added to them when the current user's permissions | |
| 23 | +and the whitelist both permit editing of that file. | |
| 24 | + | |
| 25 | +## CSRF & HTTP Referrer Headers | |
| 26 | + | |
| 27 | +In order to protect against [Cross-site Request Forgery (CSRF)][csrf] | |
| 28 | +attacks, Fossil UI features which write to the database require that | |
| 29 | +the browser send the so-called [HTTP `Referer` header][referer] | |
| 30 | +(noting that the misspelling of "referrer" is a historical accident | |
| 31 | +which has long-since been standardized!). Modern browsers, by default, | |
| 32 | +include such information automatically for *interactive* actions which | |
| 33 | +lead to a request, e.g. clicking on a link back to the same | |
| 34 | +server. However, `/fileedit` uses asynchronous ["XHR"][xhr] | |
| 35 | +connections, which browsers *may* treat differently than strictly | |
| 36 | +interactive elements. | |
| 37 | + | |
| 38 | +- **Firefox**: configuration option `network.http.sendRefererHeader` | |
| 39 | + specifies whether the `Referer` header is sent. It must have a value | |
| 40 | + of 2 (which is the default) for XHR requests to get the `Referer` | |
| 41 | + header. Purely interactive Fossil features, in which users directly | |
| 42 | + activate links or forms, work with a level of 1 or higher. | |
| 43 | +- **Chrome**: apparently requires an add-on in order to change this | |
| 44 | + policy, so Chrome without such an add-on will not suppress this | |
| 45 | + header. | |
| 46 | +- **Safari**: ??? | |
| 47 | +- **Other browsers**: ??? | |
| 48 | + | |
| 49 | +If `/filepage` shows an error message saying "CSRF violation," the | |
| 50 | +problem is that the browser is not sending a `Referer` header to XHR | |
| 51 | +connections. Fossil does not offer a way to disable its CSRF | |
| 52 | +protections. | |
| 53 | + | |
| 54 | +[referer]: https://en.wikipedia.org/wiki/HTTP_referer | |
| 55 | +[csrf]: https://en.wikipedia.org/wiki/Cross-site_request_forgery | |
| 56 | +[xhr]: https://en.wikipedia.org/wiki/XMLHttpRequest | |
| 22 | 57 | |
| 23 | -### `/fileedit` **Works by Creating Commits** | |
| 58 | +## `/fileedit` **Works by Creating Commits** | |
| 24 | 59 | |
| 25 | 60 | Thus any edits made via that page become a normal part of the |
| 26 | 61 | repository's blockchain. |
| 27 | 62 | |
| 28 | -### `/fileedit` is **Intended for use with Embedded Docs** | |
| 63 | +## `/fileedit` is *Intended* for use with Embedded Docs | |
| 29 | 64 | |
| 30 | 65 | ... and similar text files, and is most certainly |
| 31 | 66 | **not intended for editing code**. |
| 32 | 67 | |
| 33 | 68 | Editing files with unusual syntax requirements, e.g. hard tabs in |
| @@ -38,13 +73,13 @@ | ||
| 38 | 73 | textarea element may change the EOLs. The Commit section of the page |
| 39 | 74 | offers three different options for how to treat newlines when saving |
| 40 | 75 | changes. **Files with mixed EOL styles** *will be normalized to a single |
| 41 | 76 | EOL style* when modified using `/fileedit`. When "inheriting" the EOL |
| 42 | 77 | style from a previous version which has mixed styles, the first EOL |
| 43 | -style detected in the file is used. | |
| 78 | +style detected in the previous version of the file is used. | |
| 44 | 79 | |
| 45 | -### `/fileedit` **is Not a Replacement for a Checkout** | |
| 80 | +## `/fileedit` **is Not a Replacement for a Checkout** | |
| 46 | 81 | |
| 47 | 82 | A full-featured checkout allows far more possibilities than this basic |
| 48 | 83 | online editor permits, and the feature scope of `/fileedit` is |
| 49 | 84 | intentionally kept small, implementing only the bare necessities |
| 50 | 85 | needed for performing basic edits online. It *is not, and will never |
| @@ -64,47 +99,54 @@ | ||
| 64 | 99 | `/fileedit`.) |
| 65 | 100 | - Editing of non-text files, e.g. images. Use a checkout and your |
| 66 | 101 | preferred graphics editor. |
| 67 | 102 | - Support for syncing/pulling/pushing of a repository before and/or |
| 68 | 103 | after edits. Those features cannot be *reliably* provided via a web |
| 69 | -interface for several reasons, not the least of which is that some | |
| 70 | -backend servers simply do not permit outbound network connections to | |
| 71 | -arbitrary hosts. | |
| 104 | +interface for several reasons. | |
| 72 | 105 | |
| 73 | 106 | Similarly, some *potential* features have significant downsides, |
| 74 | 107 | abuses, and/or implementation hurdles which make the decision of |
| 75 | 108 | whether or not to implement them subject to notable contributor |
| 76 | 109 | debate. e.g. the ability to add new files or remove/rename older |
| 77 | 110 | files. |
| 78 | 111 | |
| 79 | 112 | |
| 80 | -### `/fileedit` **Stores Only Limited Local Edits While Working** | |
| 113 | +## `/fileedit` **Stores Only Limited Local Edits While Working** | |
| 81 | 114 | |
| 82 | 115 | When changes are made to a given checkin/file combination, |
| 83 | -`/fileedit` will, if possible, store them in `window.fileStorage` | |
| 84 | -or `window.sessionStorage`, if available, but... | |
| 116 | +`/fileedit` will, if possible, store them in [`window.localStorage` | |
| 117 | +or `window.sessionStorage`][html5storage], if available, but... | |
| 85 | 118 | |
| 86 | 119 | - Which storage is used is unspecified and may differ across |
| 87 | 120 | environments. |
| 88 | 121 | - If neither of those is available, the storage is transient and |
| 89 | - will not survive a page reload. | |
| 122 | + will not survive a page reload. In this case, the UI issues a clear | |
| 123 | + warning in the editor tab. | |
| 90 | 124 | - It stores only the most recent checkin/file combinations which have |
| 91 | 125 | been modified (exactly how many may differ - the number will be |
| 92 | 126 | noted somewhere in the UI). Note that changing the "executable bit" |
| 93 | - is counted as a modification, but the checkin comment is not stored | |
| 94 | - separately for each file. If the limit is exceeded, it silently | |
| 95 | - discards the oldest edits. | |
| 127 | + is counted as a modification, but the checkin *comment* is *not* | |
| 128 | + and is reset after a commit. | |
| 129 | +- If its internal limit on the number of modified files is exceeded, | |
| 130 | + it silently discards the oldest edits to keep the list at its limit. | |
| 131 | + | |
| 132 | +Edits are saved whenever the editor component fires its "change" | |
| 133 | +event, which essentially means as soon as it loses input focus. Thus | |
| 134 | +to force the browser to save any pending changes, simply click | |
| 135 | +somwhere on the page outside of the editor. | |
| 96 | 136 | |
| 97 | -Exactly how long `fileStorage` will survive, and how much it or | |
| 137 | +Exactly how long `localStorage` will survive, and how much it or | |
| 98 | 138 | `sessionStorage` can hold, is environment-dependent. `sessionStorage` |
| 99 | 139 | will survive until the current browser tab is closed, but it survives |
| 100 | 140 | across reloads of the same tab. |
| 101 | 141 | |
| 102 | 142 | If `/filepage` determines that no peristent storage is available a |
| 103 | 143 | warning is displayed on the editor page. |
| 104 | 144 | |
| 105 | -### The Power is Yours, but... | |
| 145 | +[html5storage]: https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API | |
| 146 | + | |
| 147 | +## The Power is Yours, but... | |
| 106 | 148 | |
| 107 | 149 | > "With great power comes great responsibility." |
| 108 | 150 | |
| 109 | 151 | **Use this feature judiciously, *if at all*.** |
| 110 | 152 | |
| @@ -132,11 +174,11 @@ | ||
| 132 | 174 | ## Integrating Syntax Highlighting |
| 133 | 175 | |
| 134 | 176 | Assuming a repository has integrated a 3rd-party syntax highlighting |
| 135 | 177 | solution, it can probably (depending on its API) be told how to |
| 136 | 178 | highlight `/fileedit`'s wiki/markdown-format previews. Here are |
| 137 | -instructions for doing so with highlightjs: | |
| 179 | +instructions for doing so with [highlightjs](https://highlightjs.org/): | |
| 138 | 180 | |
| 139 | 181 | At the very bottom of the [site skin's footer](customskin.md), add a |
| 140 | 182 | script tag similar to the following: |
| 141 | 183 | |
| 142 | 184 | ```javascript |
| 143 | 185 |
| --- www/fileedit-page.md | |
| +++ www/fileedit-page.md | |
| @@ -1,33 +1,68 @@ | |
| 1 | # The fileedit Page |
| 2 | |
| 3 | This document describes some tips and tricks for the [](/fileedit) |
| 4 | page, which provides, for users with [checkin |
| 5 | privileges](./caps/index.md), basic editing features for files via the |
| 6 | web interface. |
| 7 | |
| 8 | # Important Caveats and Disclaimers |
| 9 | |
| 10 | Predictably, the ability to edit files in a repository from a web |
| 11 | browser halfway around the world comes with several obligatory caveats |
| 12 | and disclaimers... |
| 13 | |
| 14 | ### `/fileedit` Does *Nothing* by Default. |
| 15 | |
| 16 | In order to "activate" it, a user with [the "setup" |
| 17 | permission](./caps/index.md) must set the |
| 18 | [fileedit-glob](/help?cmd=fileedit-glob) repository setting to a |
| 19 | comma- or newline-delimited list of globs representing a whitelist of |
| 20 | files which may be edited online. Any user with commit access may then |
| 21 | edit files matching one of those globs. |
| 22 | |
| 23 | ### `/fileedit` **Works by Creating Commits** |
| 24 | |
| 25 | Thus any edits made via that page become a normal part of the |
| 26 | repository's blockchain. |
| 27 | |
| 28 | ### `/fileedit` is **Intended for use with Embedded Docs** |
| 29 | |
| 30 | ... and similar text files, and is most certainly |
| 31 | **not intended for editing code**. |
| 32 | |
| 33 | Editing files with unusual syntax requirements, e.g. hard tabs in |
| @@ -38,13 +73,13 @@ | |
| 38 | textarea element may change the EOLs. The Commit section of the page |
| 39 | offers three different options for how to treat newlines when saving |
| 40 | changes. **Files with mixed EOL styles** *will be normalized to a single |
| 41 | EOL style* when modified using `/fileedit`. When "inheriting" the EOL |
| 42 | style from a previous version which has mixed styles, the first EOL |
| 43 | style detected in the file is used. |
| 44 | |
| 45 | ### `/fileedit` **is Not a Replacement for a Checkout** |
| 46 | |
| 47 | A full-featured checkout allows far more possibilities than this basic |
| 48 | online editor permits, and the feature scope of `/fileedit` is |
| 49 | intentionally kept small, implementing only the bare necessities |
| 50 | needed for performing basic edits online. It *is not, and will never |
| @@ -64,47 +99,54 @@ | |
| 64 | `/fileedit`.) |
| 65 | - Editing of non-text files, e.g. images. Use a checkout and your |
| 66 | preferred graphics editor. |
| 67 | - Support for syncing/pulling/pushing of a repository before and/or |
| 68 | after edits. Those features cannot be *reliably* provided via a web |
| 69 | interface for several reasons, not the least of which is that some |
| 70 | backend servers simply do not permit outbound network connections to |
| 71 | arbitrary hosts. |
| 72 | |
| 73 | Similarly, some *potential* features have significant downsides, |
| 74 | abuses, and/or implementation hurdles which make the decision of |
| 75 | whether or not to implement them subject to notable contributor |
| 76 | debate. e.g. the ability to add new files or remove/rename older |
| 77 | files. |
| 78 | |
| 79 | |
| 80 | ### `/fileedit` **Stores Only Limited Local Edits While Working** |
| 81 | |
| 82 | When changes are made to a given checkin/file combination, |
| 83 | `/fileedit` will, if possible, store them in `window.fileStorage` |
| 84 | or `window.sessionStorage`, if available, but... |
| 85 | |
| 86 | - Which storage is used is unspecified and may differ across |
| 87 | environments. |
| 88 | - If neither of those is available, the storage is transient and |
| 89 | will not survive a page reload. |
| 90 | - It stores only the most recent checkin/file combinations which have |
| 91 | been modified (exactly how many may differ - the number will be |
| 92 | noted somewhere in the UI). Note that changing the "executable bit" |
| 93 | is counted as a modification, but the checkin comment is not stored |
| 94 | separately for each file. If the limit is exceeded, it silently |
| 95 | discards the oldest edits. |
| 96 | |
| 97 | Exactly how long `fileStorage` will survive, and how much it or |
| 98 | `sessionStorage` can hold, is environment-dependent. `sessionStorage` |
| 99 | will survive until the current browser tab is closed, but it survives |
| 100 | across reloads of the same tab. |
| 101 | |
| 102 | If `/filepage` determines that no peristent storage is available a |
| 103 | warning is displayed on the editor page. |
| 104 | |
| 105 | ### The Power is Yours, but... |
| 106 | |
| 107 | > "With great power comes great responsibility." |
| 108 | |
| 109 | **Use this feature judiciously, *if at all*.** |
| 110 | |
| @@ -132,11 +174,11 @@ | |
| 132 | ## Integrating Syntax Highlighting |
| 133 | |
| 134 | Assuming a repository has integrated a 3rd-party syntax highlighting |
| 135 | solution, it can probably (depending on its API) be told how to |
| 136 | highlight `/fileedit`'s wiki/markdown-format previews. Here are |
| 137 | instructions for doing so with highlightjs: |
| 138 | |
| 139 | At the very bottom of the [site skin's footer](customskin.md), add a |
| 140 | script tag similar to the following: |
| 141 | |
| 142 | ```javascript |
| 143 |
| --- www/fileedit-page.md | |
| +++ www/fileedit-page.md | |
| @@ -1,33 +1,68 @@ | |
| 1 | # The fileedit Page |
| 2 | |
| 3 | This document describes the limitations of, caveats for, and |
| 4 | disclaimers for the [](/fileedit) page, which provides users with |
| 5 | [checkin privileges](./caps/index.md) basic editing features for files |
| 6 | via the web interface. |
| 7 | |
| 8 | # Important Caveats and Disclaimers |
| 9 | |
| 10 | Predictably, the ability to edit files in a repository from a web |
| 11 | browser halfway around the world comes with several obligatory caveats |
| 12 | and disclaimers... |
| 13 | |
| 14 | ## `/fileedit` Does *Nothing* by Default. |
| 15 | |
| 16 | In order to "activate" it, a user with [the "setup" |
| 17 | permission](./caps/index.md) must set the |
| 18 | [fileedit-glob](/help?cmd=fileedit-glob) repository setting to a |
| 19 | comma- or newline-delimited list of globs representing a whitelist of |
| 20 | files which may be edited online. Any user with commit access may then |
| 21 | edit files matching one of those globs. Certain pages within the UI |
| 22 | get an "edit" link added to them when the current user's permissions |
| 23 | and the whitelist both permit editing of that file. |
| 24 | |
| 25 | ## CSRF & HTTP Referrer Headers |
| 26 | |
| 27 | In order to protect against [Cross-site Request Forgery (CSRF)][csrf] |
| 28 | attacks, Fossil UI features which write to the database require that |
| 29 | the browser send the so-called [HTTP `Referer` header][referer] |
| 30 | (noting that the misspelling of "referrer" is a historical accident |
| 31 | which has long-since been standardized!). Modern browsers, by default, |
| 32 | include such information automatically for *interactive* actions which |
| 33 | lead to a request, e.g. clicking on a link back to the same |
| 34 | server. However, `/fileedit` uses asynchronous ["XHR"][xhr] |
| 35 | connections, which browsers *may* treat differently than strictly |
| 36 | interactive elements. |
| 37 | |
| 38 | - **Firefox**: configuration option `network.http.sendRefererHeader` |
| 39 | specifies whether the `Referer` header is sent. It must have a value |
| 40 | of 2 (which is the default) for XHR requests to get the `Referer` |
| 41 | header. Purely interactive Fossil features, in which users directly |
| 42 | activate links or forms, work with a level of 1 or higher. |
| 43 | - **Chrome**: apparently requires an add-on in order to change this |
| 44 | policy, so Chrome without such an add-on will not suppress this |
| 45 | header. |
| 46 | - **Safari**: ??? |
| 47 | - **Other browsers**: ??? |
| 48 | |
| 49 | If `/filepage` shows an error message saying "CSRF violation," the |
| 50 | problem is that the browser is not sending a `Referer` header to XHR |
| 51 | connections. Fossil does not offer a way to disable its CSRF |
| 52 | protections. |
| 53 | |
| 54 | [referer]: https://en.wikipedia.org/wiki/HTTP_referer |
| 55 | [csrf]: https://en.wikipedia.org/wiki/Cross-site_request_forgery |
| 56 | [xhr]: https://en.wikipedia.org/wiki/XMLHttpRequest |
| 57 | |
| 58 | ## `/fileedit` **Works by Creating Commits** |
| 59 | |
| 60 | Thus any edits made via that page become a normal part of the |
| 61 | repository's blockchain. |
| 62 | |
| 63 | ## `/fileedit` is *Intended* for use with Embedded Docs |
| 64 | |
| 65 | ... and similar text files, and is most certainly |
| 66 | **not intended for editing code**. |
| 67 | |
| 68 | Editing files with unusual syntax requirements, e.g. hard tabs in |
| @@ -38,13 +73,13 @@ | |
| 73 | textarea element may change the EOLs. The Commit section of the page |
| 74 | offers three different options for how to treat newlines when saving |
| 75 | changes. **Files with mixed EOL styles** *will be normalized to a single |
| 76 | EOL style* when modified using `/fileedit`. When "inheriting" the EOL |
| 77 | style from a previous version which has mixed styles, the first EOL |
| 78 | style detected in the previous version of the file is used. |
| 79 | |
| 80 | ## `/fileedit` **is Not a Replacement for a Checkout** |
| 81 | |
| 82 | A full-featured checkout allows far more possibilities than this basic |
| 83 | online editor permits, and the feature scope of `/fileedit` is |
| 84 | intentionally kept small, implementing only the bare necessities |
| 85 | needed for performing basic edits online. It *is not, and will never |
| @@ -64,47 +99,54 @@ | |
| 99 | `/fileedit`.) |
| 100 | - Editing of non-text files, e.g. images. Use a checkout and your |
| 101 | preferred graphics editor. |
| 102 | - Support for syncing/pulling/pushing of a repository before and/or |
| 103 | after edits. Those features cannot be *reliably* provided via a web |
| 104 | interface for several reasons. |
| 105 | |
| 106 | Similarly, some *potential* features have significant downsides, |
| 107 | abuses, and/or implementation hurdles which make the decision of |
| 108 | whether or not to implement them subject to notable contributor |
| 109 | debate. e.g. the ability to add new files or remove/rename older |
| 110 | files. |
| 111 | |
| 112 | |
| 113 | ## `/fileedit` **Stores Only Limited Local Edits While Working** |
| 114 | |
| 115 | When changes are made to a given checkin/file combination, |
| 116 | `/fileedit` will, if possible, store them in [`window.localStorage` |
| 117 | or `window.sessionStorage`][html5storage], if available, but... |
| 118 | |
| 119 | - Which storage is used is unspecified and may differ across |
| 120 | environments. |
| 121 | - If neither of those is available, the storage is transient and |
| 122 | will not survive a page reload. In this case, the UI issues a clear |
| 123 | warning in the editor tab. |
| 124 | - It stores only the most recent checkin/file combinations which have |
| 125 | been modified (exactly how many may differ - the number will be |
| 126 | noted somewhere in the UI). Note that changing the "executable bit" |
| 127 | is counted as a modification, but the checkin *comment* is *not* |
| 128 | and is reset after a commit. |
| 129 | - If its internal limit on the number of modified files is exceeded, |
| 130 | it silently discards the oldest edits to keep the list at its limit. |
| 131 | |
| 132 | Edits are saved whenever the editor component fires its "change" |
| 133 | event, which essentially means as soon as it loses input focus. Thus |
| 134 | to force the browser to save any pending changes, simply click |
| 135 | somwhere on the page outside of the editor. |
| 136 | |
| 137 | Exactly how long `localStorage` will survive, and how much it or |
| 138 | `sessionStorage` can hold, is environment-dependent. `sessionStorage` |
| 139 | will survive until the current browser tab is closed, but it survives |
| 140 | across reloads of the same tab. |
| 141 | |
| 142 | If `/filepage` determines that no peristent storage is available a |
| 143 | warning is displayed on the editor page. |
| 144 | |
| 145 | [html5storage]: https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API |
| 146 | |
| 147 | ## The Power is Yours, but... |
| 148 | |
| 149 | > "With great power comes great responsibility." |
| 150 | |
| 151 | **Use this feature judiciously, *if at all*.** |
| 152 | |
| @@ -132,11 +174,11 @@ | |
| 174 | ## Integrating Syntax Highlighting |
| 175 | |
| 176 | Assuming a repository has integrated a 3rd-party syntax highlighting |
| 177 | solution, it can probably (depending on its API) be told how to |
| 178 | highlight `/fileedit`'s wiki/markdown-format previews. Here are |
| 179 | instructions for doing so with [highlightjs](https://highlightjs.org/): |
| 180 | |
| 181 | At the very bottom of the [site skin's footer](customskin.md), add a |
| 182 | script tag similar to the following: |
| 183 | |
| 184 | ```javascript |
| 185 |