diff options
| -rw-r--r-- | ext/bg/js/settings/clipboard-popups-controller.js | 26 | ||||
| -rw-r--r-- | ext/bg/settings.html | 2 | ||||
| -rw-r--r-- | ext/bg/settings2.html | 139 | ||||
| -rw-r--r-- | ext/mixed/css/material.css | 1 | ||||
| -rw-r--r-- | ext/mixed/img/clipboard.svg | 1 | ||||
| -rw-r--r-- | resources/icons.svg | 69 | 
6 files changed, 158 insertions, 80 deletions
| diff --git a/ext/bg/js/settings/clipboard-popups-controller.js b/ext/bg/js/settings/clipboard-popups-controller.js index fcff444c..ab1a8288 100644 --- a/ext/bg/js/settings/clipboard-popups-controller.js +++ b/ext/bg/js/settings/clipboard-popups-controller.js @@ -15,14 +15,22 @@   * along with this program.  If not, see <https://www.gnu.org/licenses/>.   */ +/* global + * ObjectPropertyAccessor + */ +  class ClipboardPopupsController {      constructor(settingsController) {          this._settingsController = settingsController; -        this._checkbox = document.querySelector('#clipboard-enable-background-monitor'); +        this._toggles = null;      }      async prepare() { -        this._checkbox.addEventListener('change', this._onEnableBackgroundMonitorChanged.bind(this), false); +        this._toggles = document.querySelectorAll('.clipboard-toggle'); + +        for (const toggle of this._toggles) { +            toggle.addEventListener('change', this._onClipboardToggleChange.bind(this), false); +        }          this._settingsController.on('optionsChanged', this._onOptionsChanged.bind(this));          const options = await this._settingsController.getOptions(); @@ -32,10 +40,20 @@ class ClipboardPopupsController {      // Private      _onOptionsChanged({options}) { -        this._checkbox.checked = options.clipboard.enableBackgroundMonitor; +        const accessor = new ObjectPropertyAccessor(options); +        for (const toggle of this._toggles) { +            const path = ObjectPropertyAccessor.getPathArray(toggle.dataset.clipboardSetting); +            let value; +            try { +                value = accessor.get(path, path.length); +            } catch (e) { +                continue; +            } +            toggle.checked = !!value; +        }      } -    async _onEnableBackgroundMonitorChanged(e) { +    async _onClipboardToggleChange(e) {          const checkbox = e.currentTarget;          let value = checkbox.checked; diff --git a/ext/bg/settings.html b/ext/bg/settings.html index 208ac27c..e09a180e 100644 --- a/ext/bg/settings.html +++ b/ext/bg/settings.html @@ -162,7 +162,7 @@                  </div>                  <div class="checkbox options-advanced ignore-form-changes" data-hide-for-browser="firefox-mobile"> -                    <label><input type="checkbox" id="clipboard-enable-background-monitor"> Enable native popups when copying Japanese text</label> +                    <label><input type="checkbox" class="clipboard-toggle" data-clipboard-setting="clipboard.enableBackgroundMonitor"> Enable native popups when copying Japanese text</label>                  </div>                  <div class="checkbox options-advanced"> diff --git a/ext/bg/settings2.html b/ext/bg/settings2.html index c8c35c3d..fce4d9a4 100644 --- a/ext/bg/settings2.html +++ b/ext/bg/settings2.html @@ -34,6 +34,7 @@              <a href="#!sentence-parsing" class="outline-item advanced-only"><span class="outline-item-left"><span class="outline-item-icon icon" data-icon="sentence-parsing"></span></span><span class="outline-item-label">Sentence Parsing</span></a>              <a href="#!translation"      class="outline-item"><span class="outline-item-left"><span class="outline-item-icon icon" data-icon="translation"></span></span><span class="outline-item-label">Translation</span></a>              <a href="#!anki"             class="outline-item"><span class="outline-item-left"><span class="outline-item-icon icon" data-icon="note-card"></span></span><span class="outline-item-label">Anki</span></a> +            <a href="#!clipboard"        class="outline-item"><span class="outline-item-left"><span class="outline-item-icon icon" data-icon="clipboard"></span></span><span class="outline-item-label">Clipboard</span></a>              <a href="#!shortcuts"        class="outline-item"><span class="outline-item-left"><span class="outline-item-icon icon" data-icon="keyboard"></span></span><span class="outline-item-label">Shortcuts</span></a>              <a href="#!backup"           class="outline-item"><span class="outline-item-left"><span class="outline-item-icon icon" data-icon="backup"></span></span><span class="outline-item-label">Backup</span></a>              <a href="#!security"         class="outline-item advanced-only"><span class="outline-item-left"><span class="outline-item-icon icon" data-icon="lock"></span></span><span class="outline-item-label">Security</span></a> @@ -951,69 +952,6 @@                  </p>              </div>          </div> -        <div class="settings-item"> -            <div class="settings-item-inner"> -                <div class="settings-item-left"> -                    <div class="settings-item-label"> -                        Open a native browser window when copying Japanese text -                        <a class="more-toggle more-only" data-parent-distance="4">(?)</a> -                    </div> -                </div> -                <div class="settings-item-right"> -                    <label class="toggle"><input type="checkbox" id="clipboard-enable-background-monitor"><span class="toggle-body"><span class="toggle-track"></span><span class="toggle-knob"></span></span></label> -                </div> -            </div> -            <div class="settings-item-children more" hidden> -                <p> -                    When Japanese text is copied to the clipboard, a browser window popup searching for the clipboard -                    text will be opened. -                    This can be useful for using Yomichan to scan text from external applications. -                </p> -                <p> -                    This feature requires Yomichan to have clipboard reading permissions, and when this option is enabled, -                    the clipboard will be frequently polled for new text. -                </p> -                <p> -                    Alternatively, this feature can be enabled only on the search page, and clipboard contents polling will -                    only be performed when the search page is already open. -                </p> -                <p> -                    <a class="more-toggle" data-parent-distance="3">Less…</a> -                </p> -            </div> -        </div> -        <div class="settings-item"><div class="settings-item-inner settings-item-inner-wrappable"> -            <div class="settings-item-left"> -                <div class="settings-item-label">Maximum clipboard text search length</div> -                <div class="settings-item-description">Limit the number of text characters used when searching clipboard content.</div> -            </div> -            <div class="settings-item-right"> -                <input type="number" min="0" step="1" data-setting="clipboard.maximumSearchLength"> -            </div> -        </div></div> -        <div class="settings-item"><div class="settings-item-inner settings-item-inner-wrappable"> -            <div class="settings-item-left"> -                <div class="settings-item-label">Clipboard text search mode</div> -                <div class="settings-item-description">Change how the search page reacts to new text in the clipboard.</div> -            </div> -            <div class="settings-item-right"> -                <select data-setting="clipboard.autoSearchContent" -                    data-transform='[ -                        { -                            "step": "pre", -                            "type": "toBoolean" -                        }, -                        { -                            "step": "post", -                            "type": "toString" -                        } -                    ]' -                > -                    <option value="true">Search for definitions</option> -                    <option value="false">Update search query only</option> -                </select> -            </div> -        </div></div>          <div class="settings-item"><div class="settings-item-inner settings-item-inner-wrappable">              <div class="settings-item-left">                  <div class="settings-item-label">Size</div> @@ -1605,6 +1543,81 @@          </div></div>      </div> +    <!-- Clipboard --> +    <div> +        <div class="heading-container"> +            <div class="heading-container-icon"><span class="icon" data-icon="clipboard"></span></div> +            <div class="heading-container-left"><h2 id="clipboard"><a href="#!clipboard">Clipboard</a></h2></div> +            <div class="heading-container-right"><a class="more-toggle more-only heading-link-light" data-parent-distance="3">Info…</a></div> +        </div> +        <div class="heading-description more" hidden> +            <p> +                Yomichan can watch the system copy clipboard for Japanese text and automatically search the +                text on the search page. +                This can be useful for using Yomichan to scan text from external applications. +            </p> +            <p> +                This feature requires Yomichan to have clipboard reading permissions, and when this option is enabled, +                the clipboard will be frequently checked for new text. +            </p> +            <p> +                <a class="more-toggle" data-parent-distance="3">Less…</a> +            </p> +        </div> +    </div> +    <div class="settings-group"> +        <div class="settings-item"><div class="settings-item-inner"> +            <div class="settings-item-left"> +                <div class="settings-item-label">Enable background clipboard text monitoring</div> +                <div class="settings-item-description">Open the search page in a new window when the clipboard contains Japanese text.</div> +            </div> +            <div class="settings-item-right"> +                <label class="toggle"><input type="checkbox" class="clipboard-toggle" data-clipboard-setting="clipboard.enableBackgroundMonitor"><span class="toggle-body"><span class="toggle-track"></span><span class="toggle-knob"></span></span></label> +            </div> +        </div></div> +        <div class="settings-item"><div class="settings-item-inner"> +            <div class="settings-item-left"> +                <div class="settings-item-label">Enable search page clipboard text monitoring</div> +                <div class="settings-item-description">The query on the search page will be automatically updated with text in the clipboard.</div> +            </div> +            <div class="settings-item-right"> +                <label class="toggle"><input type="checkbox" class="clipboard-toggle" data-clipboard-setting="clipboard.enableSearchPageMonitor"><span class="toggle-body"><span class="toggle-track"></span><span class="toggle-knob"></span></span></label> +            </div> +        </div></div> +        <div class="settings-item"><div class="settings-item-inner settings-item-inner-wrappable"> +            <div class="settings-item-left"> +                <div class="settings-item-label">Maximum clipboard text search length</div> +                <div class="settings-item-description">Limit the number of characters used when searching clipboard text.</div> +            </div> +            <div class="settings-item-right"> +                <input type="number" min="0" step="1" data-setting="clipboard.maximumSearchLength"> +            </div> +        </div></div> +        <div class="settings-item"><div class="settings-item-inner settings-item-inner-wrappable"> +            <div class="settings-item-left"> +                <div class="settings-item-label">Clipboard text search mode</div> +                <div class="settings-item-description">Change how the search page reacts to new text in the clipboard.</div> +            </div> +            <div class="settings-item-right"> +                <select data-setting="clipboard.autoSearchContent" +                    data-transform='[ +                        { +                            "step": "pre", +                            "type": "toBoolean" +                        }, +                        { +                            "step": "post", +                            "type": "toString" +                        } +                    ]' +                > +                    <option value="true">Search for definitions</option> +                    <option value="false">Update query only</option> +                </select> +            </div> +        </div></div> +    </div> +      <!-- Shortcuts -->      <div class="heading-container">          <div class="heading-container-icon"><span class="icon" data-icon="keyboard"></span></div> diff --git a/ext/mixed/css/material.css b/ext/mixed/css/material.css index d144937b..2dd10791 100644 --- a/ext/mixed/css/material.css +++ b/ext/mixed/css/material.css @@ -214,6 +214,7 @@  .icon[data-icon=left-chevron]            { --icon-image: url(/mixed/img/left-chevron.svg); }  .icon[data-icon=right-chevron]           { --icon-image: url(/mixed/img/right-chevron.svg); }  .icon[data-icon=plus-thick]              { --icon-image: url(/mixed/img/plus-thick.svg); } +.icon[data-icon=clipboard]               { --icon-image: url(/mixed/img/clipboard.svg); }  .icon[data-icon=material-down-arrow] {      --icon-image: url(/mixed/img/material-down-arrow.svg);      --icon-size: var(--material-arrow-dimension2) var(--material-arrow-dimension1); diff --git a/ext/mixed/img/clipboard.svg b/ext/mixed/img/clipboard.svg new file mode 100644 index 00000000..75545134 --- /dev/null +++ b/ext/mixed/img/clipboard.svg @@ -0,0 +1 @@ +<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path d="M8 .5c-.41421 0-.75.33579-.75.75 0 .25-.25.25-.75.25-.554 0-1 .446-1 1V3h5v-.5c0-.554-.446-1-1-1-.5 0-.75 0-.75-.25C8.75.83579 8.41421.5 8 .5zM2.5 2v13h11V2h-2.5938c.05663.15724.09375.32437.09375.5V3h1.5v11h-9V3h1.5v-.5c0-.17563.03712-.34276.09375-.5zm2 3v1h7V5zm0 2v1h7V7zm0 2v1h7V9zm0 2v1h5v-1z"/></svg>
\ No newline at end of file diff --git a/resources/icons.svg b/resources/icons.svg index 0ace4793..e009bc47 100644 --- a/resources/icons.svg +++ b/resources/icons.svg @@ -1,6 +1,4 @@  <?xml version="1.0" encoding="UTF-8" standalone="no"?> -<!-- Created with Inkscape (http://www.inkscape.org/) --> -  <svg     xmlns:dc="http://purl.org/dc/elements/1.1/"     xmlns:cc="http://creativecommons.org/ns#" @@ -14,7 +12,7 @@     inkscape:export-ydpi="192"     inkscape:export-xdpi="192"     sodipodi:docname="icons.svg" -   inkscape:version="0.92.4 (5da689c313, 2019-01-14)" +   inkscape:version="1.0.2 (e86c870879, 2021-01-15, custom)"     id="svg8"     version="1.1"     viewBox="0 0 16 16" @@ -27,11 +25,11 @@       borderopacity="1.0"       inkscape:pageopacity="0.0"       inkscape:pageshadow="2" -     inkscape:zoom="45.254834" -     inkscape:cx="8.4539164" -     inkscape:cy="8.0625778" +     inkscape:zoom="32" +     inkscape:cx="7.2634756" +     inkscape:cy="9.0903162"       inkscape:document-units="px" -     inkscape:current-layer="layer49" +     inkscape:current-layer="layer50"       showgrid="true"       units="px"       inkscape:snap-center="true" @@ -48,7 +46,8 @@       inkscape:snap-intersection-paths="true"       inkscape:object-paths="true"       inkscape:snap-others="true" -     inkscape:snap-nodes="true"> +     inkscape:snap-nodes="true" +     inkscape:document-rotation="0">      <inkscape:grid         type="xygrid"         id="grid815" @@ -64,6 +63,40 @@    </sodipodi:namedview>    <defs       id="defs2"> +    <inkscape:path-effect +       effect="fillet_chamfer" +       id="path-effect1089" +       is_visible="true" +       lpeversion="1" +       satellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,1,1,0,0.5,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,1,1,0,0.5,0,1 @ F,0,0,1,0,0,0,1" +       unit="px" +       method="auto" +       mode="F" +       radius="0.5" +       chamfer_steps="1" +       flexible="false" +       use_knot_distance="true" +       apply_no_radius="true" +       apply_with_radius="true" +       only_selected="true" +       hide_knots="false" /> +    <inkscape:path-effect +       effect="fillet_chamfer" +       id="path-effect1087" +       is_visible="false" +       lpeversion="1" +       satellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1" +       unit="px" +       method="auto" +       mode="F" +       radius="0.5" +       chamfer_steps="1" +       flexible="false" +       use_knot_distance="true" +       apply_no_radius="true" +       apply_with_radius="true" +       only_selected="true" +       hide_knots="false" />      <linearGradient         id="linearGradient5225"         inkscape:collect="always"> @@ -1098,7 +1131,7 @@       inkscape:groupmode="layer"       id="layer34"       inkscape:label="Note Card" -     style="display:none" +     style="display:none;opacity:1"       sodipodi:insensitive="true">      <path         inkscape:connector-curvature="0" @@ -1550,10 +1583,22 @@    <g       inkscape:groupmode="layer"       id="layer49" -     inkscape:label="Plus Thick"> +     inkscape:label="Plus Thick" +     style="display:none"> +    <path +       style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" +       d="M 6,2 V 6 H 2 v 4 h 4 v 4 h 4 v -4 h 4 V 6 H 10 V 2 Z" +       id="rect1068" +       inkscape:connector-curvature="0" /> +  </g> +  <g +     inkscape:groupmode="layer" +     id="layer50" +     inkscape:label="Clipboard">      <path +       id="rect1074"         style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" -       d="M 6 2 L 6 6 L 2 6 L 2 10 L 6 10 L 6 14 L 10 14 L 10 10 L 14 10 L 14 6 L 10 6 L 10 2 L 6 2 z " -       id="rect1068" /> +       d="M 8,0.5 C 7.5857864,0.5 7.25,0.83578644 7.25,1.25 7.25,1.5 7,1.5 6.5,1.5 c -0.554,0 -1,0.446 -1,1 V 3 h 5 V 2.5 c 0,-0.554 -0.446,-1 -1,-1 C 9,1.5 8.75,1.5 8.75,1.25 8.75,0.83578644 8.4142136,0.5 8,0.5 Z M 2.5,2 v 13 h 11 V 2 H 10.90625 C 10.962878,2.1572391 11,2.3243683 11,2.5 V 3 h 1.5 v 11 h -9 V 3 H 5 V 2.5 C 5,2.3243683 5.0371223,2.1572391 5.09375,2 Z m 2,3 v 1 h 7 V 5 Z m 0,2 v 1 h 7 V 7 Z m 0,2 v 1 h 7 V 9 Z m 0,2 v 1 h 5 v -1 z" +       sodipodi:nodetypes="ssssccsssscccccsccccccscccccccccccccccccccccc" />    </g>  </svg> |