├── .circleci └── config.yml ├── .codecov.yml ├── .eslintrc.js ├── .gitignore ├── .nvmrc ├── .prettierrc ├── .vscode └── settings.json ├── CODEOWNERS ├── LICENSE ├── README.md ├── browserslist ├── docs ├── assets │ ├── Shopify-Product-Demo.gif │ ├── ace-editor-extension.png │ ├── ai-image-tagging.jpg │ ├── alloy-editor.png │ ├── bacon-ipsum.png │ ├── chessboard.gif │ ├── diff-extension.png │ ├── external-api-extension.jpg │ ├── inbound-links-extension.png │ ├── json-editor.png │ ├── json-form-editor.png │ ├── marketo_get_munchkin_id.png │ ├── marketo_make_new_role.png │ ├── marketo_make_new_service.png │ ├── marketo_view_details.png │ ├── netlify-build-step-2.png │ ├── netlify-build-step-3.png │ ├── netlify-build.png │ ├── optimizely-audiences.png │ ├── rating-dropdown.png │ ├── router-page-extension.gif │ ├── shopify-object.png │ ├── shopify-parameters.jpg │ ├── slug-widget.png │ ├── translate-widget.png │ ├── uiextensions-default-field-value-assign.png │ ├── uiextensions-default-field-value.png │ ├── uiextensions-vanilla-extension-params.png │ ├── uiextensions-vanilla-extension.png │ ├── wistia-api-key-password.png │ ├── wistia-create-api-key.png │ └── youtube-id.png └── libs │ └── alloy-editor │ ├── BREAKING_CHANGES.md │ ├── LICENSE.md │ ├── README.md │ ├── alloy-editor-all-min.js │ ├── alloy-editor-all.js │ ├── alloy-editor-core-min.js │ ├── alloy-editor-core.js │ ├── alloy-editor-no-ckeditor-min.js │ ├── alloy-editor-no-ckeditor.js │ ├── alloy-editor-no-react-min.js │ ├── alloy-editor-no-react.js │ ├── assets │ ├── alloy-editor-atlas-min.css │ ├── alloy-editor-atlas.css │ ├── alloy-editor-moono-min.css │ ├── alloy-editor-moono.css │ ├── alloy-editor-ocean-min.css │ ├── alloy-editor-ocean.css │ └── fonts │ │ ├── alloyeditor-atlas.eot │ │ ├── alloyeditor-atlas.ttf │ │ ├── alloyeditor-atlas.woff │ │ ├── alloyeditor-atlas.woff2 │ │ ├── alloyeditor-default.eot │ │ ├── alloyeditor-default.ttf │ │ ├── alloyeditor-default.woff │ │ ├── alloyeditor-default.woff2 │ │ ├── alloyeditor-moono.eot │ │ ├── alloyeditor-moono.ttf │ │ ├── alloyeditor-moono.woff │ │ ├── alloyeditor-moono.woff2 │ │ ├── alloyeditor-ocean.eot │ │ ├── alloyeditor-ocean.ttf │ │ ├── alloyeditor-ocean.woff │ │ └── alloyeditor-ocean.woff2 │ ├── build-config.js │ ├── ckeditor.js │ ├── config.js │ ├── contents.css │ ├── lang │ ├── af.js │ ├── alloy-editor │ │ ├── af.js │ │ ├── ar.js │ │ ├── bg.js │ │ ├── bn.js │ │ ├── bs.js │ │ ├── ca.js │ │ ├── cs.js │ │ ├── cy.js │ │ ├── da.js │ │ ├── de.js │ │ ├── el.js │ │ ├── en-au.js │ │ ├── en-ca.js │ │ ├── en-gb.js │ │ ├── en.js │ │ ├── eo.js │ │ ├── es.js │ │ ├── et.js │ │ ├── eu.js │ │ ├── fa.js │ │ ├── fi.js │ │ ├── fo.js │ │ ├── fr-ca.js │ │ ├── fr.js │ │ ├── gl.js │ │ ├── gu.js │ │ ├── he.js │ │ ├── hi.js │ │ ├── hr.js │ │ ├── hu.js │ │ ├── id.js │ │ ├── is.js │ │ ├── it.js │ │ ├── ja.js │ │ ├── ka.js │ │ ├── km.js │ │ ├── ko.js │ │ ├── ku.js │ │ ├── lt.js │ │ ├── lv.js │ │ ├── mk.js │ │ ├── mn.js │ │ ├── ms.js │ │ ├── nb.js │ │ ├── nl.js │ │ ├── no.js │ │ ├── pl.js │ │ ├── pt-br.js │ │ ├── pt.js │ │ ├── ro.js │ │ ├── ru.js │ │ ├── si.js │ │ ├── sk.js │ │ ├── sl.js │ │ ├── sq.js │ │ ├── sr-latn.js │ │ ├── sr.js │ │ ├── sv.js │ │ ├── th.js │ │ ├── tr.js │ │ ├── tt.js │ │ ├── ug.js │ │ ├── uk.js │ │ ├── vi.js │ │ ├── zh-cn.js │ │ └── zh.js │ ├── ar.js │ ├── bg.js │ ├── bn.js │ ├── bs.js │ ├── ca.js │ ├── cs.js │ ├── cy.js │ ├── da.js │ ├── de.js │ ├── el.js │ ├── en-au.js │ ├── en-ca.js │ ├── en-gb.js │ ├── en.js │ ├── eo.js │ ├── es.js │ ├── et.js │ ├── eu.js │ ├── fa.js │ ├── fi.js │ ├── fo.js │ ├── fr-ca.js │ ├── fr.js │ ├── gl.js │ ├── gu.js │ ├── he.js │ ├── hi.js │ ├── hr.js │ ├── hu.js │ ├── id.js │ ├── is.js │ ├── it.js │ ├── ja.js │ ├── ka.js │ ├── km.js │ ├── ko.js │ ├── ku.js │ ├── lt.js │ ├── lv.js │ ├── mk.js │ ├── mn.js │ ├── ms.js │ ├── nb.js │ ├── nl.js │ ├── no.js │ ├── pl.js │ ├── pt-br.js │ ├── pt.js │ ├── ro.js │ ├── ru.js │ ├── si.js │ ├── sk.js │ ├── sl.js │ ├── sq.js │ ├── sr-latn.js │ ├── sr.js │ ├── sv.js │ ├── th.js │ ├── tr.js │ ├── tt.js │ ├── ug.js │ ├── uk.js │ ├── vi.js │ ├── zh-cn.js │ └── zh.js │ ├── plugins │ ├── clipboard │ │ └── dialogs │ │ │ └── paste.js │ ├── dialog │ │ └── dialogDefinition.js │ ├── icons.png │ ├── icons_hidpi.png │ └── pastefromword │ │ └── filter │ │ └── default.js │ ├── skins │ └── moono │ │ ├── dialog.css │ │ ├── dialog_ie.css │ │ ├── dialog_ie7.css │ │ ├── dialog_ie8.css │ │ ├── dialog_iequirks.css │ │ ├── editor.css │ │ ├── editor_gecko.css │ │ ├── editor_ie.css │ │ ├── editor_ie7.css │ │ ├── editor_ie8.css │ │ ├── editor_iequirks.css │ │ ├── icons.png │ │ ├── icons_hidpi.png │ │ ├── images │ │ ├── arrow.png │ │ ├── close.png │ │ ├── hidpi │ │ │ ├── close.png │ │ │ ├── lock-open.png │ │ │ ├── lock.png │ │ │ └── refresh.png │ │ ├── lock-open.png │ │ ├── lock.png │ │ ├── refresh.png │ │ └── spinner.gif │ │ └── readme.md │ └── styles.js ├── lerna.json ├── marketplace ├── Readme.md ├── gatsby-preview │ ├── .babelrc │ ├── .eslintrc.js │ ├── .gitignore │ ├── README.md │ ├── assets │ │ ├── demo.gif │ │ ├── demo.mp4 │ │ └── screenshot.png │ ├── extension.json │ ├── package-lock.json │ ├── package.json │ ├── src │ │ ├── AppConfig.js │ │ ├── GatsbyIcon.js │ │ ├── Sidebar.js │ │ ├── index.css │ │ ├── index.html │ │ ├── index.js │ │ └── styles.js │ └── test │ │ ├── __snapshots__ │ │ └── sidebar.spec.js.snap │ │ ├── index.spec.js │ │ └── sidebar.spec.js └── sensitive-language │ ├── .babelrc │ ├── .eslintrc.js │ ├── MARKETPLACE.md │ ├── README.md │ ├── extension.json │ ├── package-lock.json │ ├── package.json │ ├── screenshot.png │ ├── src │ ├── app.js │ ├── index.css │ ├── index.html │ ├── index.js │ ├── language-checker.js │ ├── message.js │ ├── no-issues.js │ └── unsupported-language.js │ └── test │ ├── __snapshots__ │ ├── app.test.js.snap │ ├── message.test.js.snap │ ├── no-issues.test.js.snap │ └── unsupported-language.test.js.snap │ ├── app.test.js │ ├── message.test.js │ ├── mock-component.js │ ├── no-issues.test.js │ └── unsupported-language.test.js ├── package-lock.json ├── package.json ├── samples ├── README.md ├── ace-editor │ ├── README.md │ ├── app.html │ └── extension.json ├── alloy-editor │ ├── README.md │ ├── extension.json │ └── index.html ├── bacon-ipsum │ ├── README.md │ ├── app.html │ └── extension.json ├── basic-approval-workflow │ ├── .babelrc │ ├── .eslintrc.js │ ├── .gitignore │ ├── README.md │ ├── build │ │ └── index.html │ ├── extension.json │ ├── package-lock.json │ ├── package.json │ └── src │ │ ├── app.js │ │ ├── avatar.js │ │ ├── dialog.js │ │ ├── events.js │ │ ├── find-user.js │ │ ├── id.js │ │ ├── index.html │ │ ├── index.js │ │ ├── log.js │ │ ├── pubnub-client.js │ │ ├── pubnub-loader.js │ │ ├── review-box.js │ │ ├── sidebar.js │ │ ├── user-name.js │ │ └── vspace.js ├── chessboard │ ├── README.md │ ├── extension.json │ └── index.html ├── content-tree │ ├── .babelrc │ ├── .gitignore │ ├── README.md │ ├── build │ │ └── index.html │ ├── extension.json │ ├── package-lock.json │ ├── package.json │ └── src │ │ ├── index.css │ │ ├── index.html │ │ └── index.js ├── default-field-value │ ├── README.md │ ├── extension.html │ └── extension.json ├── diff │ ├── README.md │ ├── extension.json │ └── index.html ├── entry-editor-extension │ ├── .babelrc │ ├── .gitignore │ ├── README.md │ ├── build │ │ └── index.html │ ├── entry-extension.gif │ ├── entry-extension.png │ ├── extension.json │ ├── package-lock.json │ ├── package.json │ ├── sample-content-type.json │ ├── src │ │ ├── index.css │ │ ├── index.html │ │ └── index.tsx │ └── tsconfig.json ├── external-api │ ├── .babelrc │ ├── .gitignore │ ├── README.md │ ├── build │ │ └── index.html │ ├── extension.json │ ├── package-lock.json │ ├── package.json │ └── src │ │ ├── index.css │ │ ├── index.html │ │ └── index.js ├── gatsby-preview │ ├── .babelrc │ ├── .gitignore │ ├── README.md │ ├── build │ │ └── index.html │ ├── demo.gif │ ├── demo.mp4 │ ├── extension.json │ ├── package.json │ ├── screenshot.png │ ├── src │ │ ├── index.css │ │ ├── index.html │ │ └── index.js │ └── yarn.lock ├── image-uploader │ ├── .babelrc │ ├── .gitignore │ ├── README.md │ ├── build │ │ └── index.html │ ├── extension.json │ ├── gifcast.gif │ ├── package-lock.json │ ├── package.json │ └── src │ │ ├── components │ │ ├── Dropzone.js │ │ ├── FileView │ │ │ ├── fileview.css │ │ │ └── index.js │ │ ├── ProgressView │ │ │ ├── index.js │ │ │ └── progress-view.css │ │ └── UploadView │ │ │ ├── index.js │ │ │ └── upload-view.css │ │ ├── index.css │ │ ├── index.html │ │ ├── index.js │ │ └── utils.js ├── json-editor │ ├── README.md │ ├── extension.json │ └── index.html ├── json-form-editor │ ├── README.md │ ├── extension.json │ └── index.html ├── marketo-forms │ ├── README.md │ ├── app.html │ ├── extension.json │ └── lambda-function.js ├── page-extension-react-router │ ├── .babelrc │ ├── .eslintrc.js │ ├── .gitignore │ ├── README.md │ ├── build │ │ └── index.html │ ├── extension.json │ ├── package-lock.json │ ├── package.json │ └── src │ │ ├── index.css │ │ ├── index.html │ │ └── index.js ├── publish-confirm │ ├── .babelrc │ ├── .gitignore │ ├── README.md │ ├── build │ │ └── index.html │ ├── extension.json │ ├── package.json │ ├── publish_button_with_confirmation_screenshot1.png │ ├── publish_button_with_confirmation_screenshot2.png │ ├── publish_button_with_confirmation_screenshot3.png │ └── src │ │ ├── index.css │ │ ├── index.html │ │ └── index.js ├── rating-dropdown │ ├── README.md │ ├── app.html │ └── extension.json ├── slug │ ├── README.md │ ├── extension.json │ └── index.html ├── template-vanilla │ ├── README.md │ ├── extension.json │ └── index.html ├── translate │ ├── README.md │ ├── extension.json │ └── index.html ├── wistia-videos │ ├── README.md │ ├── app.html │ ├── extension.json │ ├── lambda-function.js │ └── screenshot.png └── youtube-id │ ├── README.md │ ├── extension.json │ └── index.html ├── scripts ├── .eslintrc ├── build.js └── utils.js ├── test ├── .eslintrc ├── dist-file-structure.test.js ├── matchers │ └── filesystem.js ├── setup.js └── source-file-structure.test.js └── tsconfig.json /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2.1 2 | 3 | docker: &docker 4 | - image: circleci/node:10.15.3 5 | 6 | cache-key: &cache-key 7 | key: dependency-cache-primary-{{ arch }}-{{ checksum ".nvmrc" }}-{{ checksum "package-lock.json" }} 8 | 9 | jobs: 10 | build: 11 | docker: *docker 12 | steps: 13 | - checkout 14 | - restore_cache: *cache-key 15 | - run: 16 | name: Installing dependencies 17 | command: npm install 18 | - save_cache: 19 | <<: *cache-key 20 | paths: 21 | - ./node_modules 22 | - run: 23 | name: Install extension dependencies 24 | command: npm run bootstrap -- --concurrency=2 25 | - run: 26 | name: Check code style 27 | command: npm run prettier-check 28 | - run: 29 | name: Linting code 30 | command: npm run lint 31 | - run: 32 | name: Typechecking code 33 | command: npm run tsc 34 | - run: 35 | name: Running unit tests 36 | command: npm run test 37 | - run: 38 | name: Building extension code 39 | command: npm run build 40 | - persist_to_workspace: 41 | root: . 42 | paths: 43 | - ./dist 44 | 45 | workflows: 46 | version: 2 47 | all: 48 | jobs: 49 | - build 50 | -------------------------------------------------------------------------------- /.codecov.yml: -------------------------------------------------------------------------------- 1 | parsers: 2 | javascript: 3 | enable_partials: yes 4 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: [require.resolve('@contentful/eslint-config-extension')], 3 | globals: { 4 | module: true, 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | .env 4 | npm-debug.log 5 | .cache 6 | samples/.vscode/settings.json 7 | .idea/ 8 | .contentfulrc.json 9 | marketplace/**/build/ 10 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | 10.15 2 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 100, 3 | "tabWidth": 2, 4 | "useTabs": false, 5 | "jsxBracketSameLine": true, 6 | "singleQuote": true 7 | } 8 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "eslint.autoFixOnSave": false, 3 | "eslint.validate": [ 4 | "javascript", 5 | "javascriptreact", 6 | "typescript", 7 | "typescriptreact" 8 | ], 9 | "tslint.enable": false, 10 | "files.exclude": { 11 | "**/.git": true, 12 | "**/.DS_Store": true 13 | }, 14 | "search.exclude": { 15 | "**/node_modules": true 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | # These owners will be the default owners for everything in 2 | # the repo. 3 | 4 | * @contentful/team-extensibility 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016, Contentful 2 | 3 | Permission to use, copy, modify, and/or distribute this software for any 4 | purpose with or without fee is hereby granted, provided that the above 5 | copyright notice and this permission notice appear in all copies. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 | -------------------------------------------------------------------------------- /browserslist: -------------------------------------------------------------------------------- 1 | last 2 versions 2 | IE >= 11 3 | not IE 10 4 | -------------------------------------------------------------------------------- /docs/assets/Shopify-Product-Demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/assets/Shopify-Product-Demo.gif -------------------------------------------------------------------------------- /docs/assets/ace-editor-extension.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/assets/ace-editor-extension.png -------------------------------------------------------------------------------- /docs/assets/ai-image-tagging.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/assets/ai-image-tagging.jpg -------------------------------------------------------------------------------- /docs/assets/alloy-editor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/assets/alloy-editor.png -------------------------------------------------------------------------------- /docs/assets/bacon-ipsum.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/assets/bacon-ipsum.png -------------------------------------------------------------------------------- /docs/assets/chessboard.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/assets/chessboard.gif -------------------------------------------------------------------------------- /docs/assets/diff-extension.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/assets/diff-extension.png -------------------------------------------------------------------------------- /docs/assets/external-api-extension.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/assets/external-api-extension.jpg -------------------------------------------------------------------------------- /docs/assets/inbound-links-extension.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/assets/inbound-links-extension.png -------------------------------------------------------------------------------- /docs/assets/json-editor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/assets/json-editor.png -------------------------------------------------------------------------------- /docs/assets/json-form-editor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/assets/json-form-editor.png -------------------------------------------------------------------------------- /docs/assets/marketo_get_munchkin_id.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/assets/marketo_get_munchkin_id.png -------------------------------------------------------------------------------- /docs/assets/marketo_make_new_role.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/assets/marketo_make_new_role.png -------------------------------------------------------------------------------- /docs/assets/marketo_make_new_service.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/assets/marketo_make_new_service.png -------------------------------------------------------------------------------- /docs/assets/marketo_view_details.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/assets/marketo_view_details.png -------------------------------------------------------------------------------- /docs/assets/netlify-build-step-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/assets/netlify-build-step-2.png -------------------------------------------------------------------------------- /docs/assets/netlify-build-step-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/assets/netlify-build-step-3.png -------------------------------------------------------------------------------- /docs/assets/netlify-build.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/assets/netlify-build.png -------------------------------------------------------------------------------- /docs/assets/optimizely-audiences.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/assets/optimizely-audiences.png -------------------------------------------------------------------------------- /docs/assets/rating-dropdown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/assets/rating-dropdown.png -------------------------------------------------------------------------------- /docs/assets/router-page-extension.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/assets/router-page-extension.gif -------------------------------------------------------------------------------- /docs/assets/shopify-object.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/assets/shopify-object.png -------------------------------------------------------------------------------- /docs/assets/shopify-parameters.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/assets/shopify-parameters.jpg -------------------------------------------------------------------------------- /docs/assets/slug-widget.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/assets/slug-widget.png -------------------------------------------------------------------------------- /docs/assets/translate-widget.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/assets/translate-widget.png -------------------------------------------------------------------------------- /docs/assets/uiextensions-default-field-value-assign.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/assets/uiextensions-default-field-value-assign.png -------------------------------------------------------------------------------- /docs/assets/uiextensions-default-field-value.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/assets/uiextensions-default-field-value.png -------------------------------------------------------------------------------- /docs/assets/uiextensions-vanilla-extension-params.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/assets/uiextensions-vanilla-extension-params.png -------------------------------------------------------------------------------- /docs/assets/uiextensions-vanilla-extension.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/assets/uiextensions-vanilla-extension.png -------------------------------------------------------------------------------- /docs/assets/wistia-api-key-password.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/assets/wistia-api-key-password.png -------------------------------------------------------------------------------- /docs/assets/wistia-create-api-key.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/assets/wistia-create-api-key.png -------------------------------------------------------------------------------- /docs/assets/youtube-id.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/assets/youtube-id.png -------------------------------------------------------------------------------- /docs/libs/alloy-editor/BREAKING_CHANGES.md: -------------------------------------------------------------------------------- 1 | 0.4.0 2 | All AlloyEditor plugins are renamed and they are now prefixed with "ae_". Example: previously "addimages", 3 | now "ae_addimages". The goal of this change is to isolate as much as possible AlloyEditor's plugins 4 | from these of CKEDitor and prevent possibilities for clashing. 5 | 6 | 0.3.0 7 | Issue #219 removes the event 'imageDrop' when user D&D image inside the editor. Instead, an event 'imageAdd' 8 | will be fired. -------------------------------------------------------------------------------- /docs/libs/alloy-editor/README.md: -------------------------------------------------------------------------------- 1 | Alloy Editor 2 | ================== 3 | 4 | Alloy Editor is a modern WYSIWYG editor built on top of CKEditor, designed to create modern and gorgeous web content. 5 | 6 | Works on IE9+, Chrome, Firefox and Safari. 7 | 8 | ## Demo 9 | 10 | * [All-in-one self-guided demo](http://alloyeditor.com/demo/) 11 | * [Screencasts and code samples for specific features](http://alloyeditor.com/features/) 12 | 13 | ## Features 14 | 15 | * Smart toolbars appear right near the selected text and offer different functionality based on context 16 | * Easily add your own buttons (see the "marquee" example in [the demo](http://alloyeditor.com/demo/)) 17 | * Paste images from clipboard, or Drag&Drop them from another application 18 | * Insert images from the device's camera! 19 | * Paste rich text from any web page and preserve its formatting 20 | * The full styling power of CKEditor... 21 | * ...with a much more modern UI 22 | * The core is fully separated from the UI 23 | * The example UI is built with React 24 | * Plugin architecture 25 | 26 | ## Documentation 27 | 28 | Look for documentation and examples on [http://alloyeditor.com/](http://alloyeditor.com/) 29 | 30 | ### License 31 | [LGPL License](LICENSE.md) 32 | 33 | [![Build Status](https://travis-ci.org/liferay/alloy-editor.svg)](https://travis-ci.org/liferay/alloy-editor) 34 | 35 | [![Sauce Test Status](https://saucelabs.com/browser-matrix/alloyui.svg)](https://saucelabs.com/u/alloyui) 36 | -------------------------------------------------------------------------------- /docs/libs/alloy-editor/assets/fonts/alloyeditor-atlas.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/libs/alloy-editor/assets/fonts/alloyeditor-atlas.eot -------------------------------------------------------------------------------- /docs/libs/alloy-editor/assets/fonts/alloyeditor-atlas.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/libs/alloy-editor/assets/fonts/alloyeditor-atlas.ttf -------------------------------------------------------------------------------- /docs/libs/alloy-editor/assets/fonts/alloyeditor-atlas.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/libs/alloy-editor/assets/fonts/alloyeditor-atlas.woff -------------------------------------------------------------------------------- /docs/libs/alloy-editor/assets/fonts/alloyeditor-atlas.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/libs/alloy-editor/assets/fonts/alloyeditor-atlas.woff2 -------------------------------------------------------------------------------- /docs/libs/alloy-editor/assets/fonts/alloyeditor-default.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/libs/alloy-editor/assets/fonts/alloyeditor-default.eot -------------------------------------------------------------------------------- /docs/libs/alloy-editor/assets/fonts/alloyeditor-default.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/libs/alloy-editor/assets/fonts/alloyeditor-default.ttf -------------------------------------------------------------------------------- /docs/libs/alloy-editor/assets/fonts/alloyeditor-default.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/libs/alloy-editor/assets/fonts/alloyeditor-default.woff -------------------------------------------------------------------------------- /docs/libs/alloy-editor/assets/fonts/alloyeditor-default.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/libs/alloy-editor/assets/fonts/alloyeditor-default.woff2 -------------------------------------------------------------------------------- /docs/libs/alloy-editor/assets/fonts/alloyeditor-moono.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/libs/alloy-editor/assets/fonts/alloyeditor-moono.eot -------------------------------------------------------------------------------- /docs/libs/alloy-editor/assets/fonts/alloyeditor-moono.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/libs/alloy-editor/assets/fonts/alloyeditor-moono.ttf -------------------------------------------------------------------------------- /docs/libs/alloy-editor/assets/fonts/alloyeditor-moono.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/libs/alloy-editor/assets/fonts/alloyeditor-moono.woff -------------------------------------------------------------------------------- /docs/libs/alloy-editor/assets/fonts/alloyeditor-moono.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/libs/alloy-editor/assets/fonts/alloyeditor-moono.woff2 -------------------------------------------------------------------------------- /docs/libs/alloy-editor/assets/fonts/alloyeditor-ocean.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/libs/alloy-editor/assets/fonts/alloyeditor-ocean.eot -------------------------------------------------------------------------------- /docs/libs/alloy-editor/assets/fonts/alloyeditor-ocean.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/libs/alloy-editor/assets/fonts/alloyeditor-ocean.ttf -------------------------------------------------------------------------------- /docs/libs/alloy-editor/assets/fonts/alloyeditor-ocean.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/libs/alloy-editor/assets/fonts/alloyeditor-ocean.woff -------------------------------------------------------------------------------- /docs/libs/alloy-editor/assets/fonts/alloyeditor-ocean.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/libs/alloy-editor/assets/fonts/alloyeditor-ocean.woff2 -------------------------------------------------------------------------------- /docs/libs/alloy-editor/config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved. 3 | * For licensing, see LICENSE.md or http://ckeditor.com/license 4 | */ 5 | 6 | CKEDITOR.editorConfig = function( config ) { 7 | // Define changes to default configuration here. 8 | // For complete reference see: 9 | // http://docs.ckeditor.com/#!/api/CKEDITOR.config 10 | 11 | // The toolbar groups arrangement, optimized for a single toolbar row. 12 | config.toolbarGroups = [ 13 | { name: 'document', groups: [ 'mode', 'document', 'doctools' ] }, 14 | { name: 'clipboard', groups: [ 'clipboard', 'undo' ] }, 15 | { name: 'editing', groups: [ 'find', 'selection', 'spellchecker' ] }, 16 | { name: 'forms' }, 17 | { name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ] }, 18 | { name: 'paragraph', groups: [ 'list', 'indent', 'blocks', 'align', 'bidi' ] }, 19 | { name: 'links' }, 20 | { name: 'insert' }, 21 | { name: 'styles' }, 22 | { name: 'colors' }, 23 | { name: 'tools' }, 24 | { name: 'others' }, 25 | { name: 'about' } 26 | ]; 27 | 28 | // The default plugins included in the basic setup define some buttons that 29 | // are not needed in a basic editor. They are removed here. 30 | config.removeButtons = 'Cut,Copy,Paste,Undo,Redo,Anchor,Underline,Strike,Subscript,Superscript'; 31 | 32 | // Dialog windows are also simplified. 33 | config.removeDialogTabs = 'link:advanced'; 34 | }; 35 | -------------------------------------------------------------------------------- /docs/libs/alloy-editor/lang/alloy-editor/af.js: -------------------------------------------------------------------------------- 1 | AlloyEditor.Strings = {"alignCenter":"Middel","alignJustify":"Eweredig","alignLeft":"Links","alignRight":"Regs","bold":"Vet","bulletedlist":"Ongenommerde lys","cancel":"Kanselleer","horizontalrule":"Horisontale lyn invoeg","italic":"Skuins","numberedlist":"Genommerde lys","quote":"Sitaatblok","removeformat":"Verwyder opmaak","strike":"Deurgestreep","subscript":"Onderskrif","superscript":"Bo-skrif","underline":"Onderstreep","formatted":"Opgemaak","h1":"Opskrif 1","h2":"Opskrif 2","normal":"Normaal","blockStyles":"Blok style","inlineStyles":"Inlyn style","objectStyles":"Objek style","styles":"Styl","cell":"Sel","cellDelete":"Verwyder sel","cellInsertAfter":"Voeg sel in na","cellInsertBefore":"Voeg sel in voor","cellMerge":"Voeg selle saam","cellMergeDown":"Voeg saam ondertoe","cellMergeRight":"Voeg saam na regs","cellSplitHorizontal":"Splits sel horisontaal","cellSplitVertical":"Splits sel vertikaal","column":"Kolom","columnDelete":"Verwyder kolom","columnInsertAfter":"Voeg kolom in na","columnInsertBefore":"Voeg kolom in voor","deleteTable":"Verwyder tabel","row":"Ry","rowDelete":"Verwyder ry","rowInsertAfter":"Voeg ry in na","rowInsertBefore":"Voeg ry in voor","add":"Add","ariaUpdateNoToolbar":"No toolbars are available","ariaUpdateOneToolbar":"{toolbars} toolbar is available. Press ALT+F10 to focus.","ariaUpdateManyToolbars":"{toolbars} toolbars are available. Press ALT+F10 to focus.","camera":"Insert Image from Camera","cite":"Cite","code":"Code","clearInput":"Clear Input Field","confirm":"Confirm","editLink":"Type or paste link here","image":"Insert Image","link":"Link","removeLink":"Remove link","table":"Insert Table","twitter":"Twitter","headers":"Opskrifte","headersBoth":"Beide ","headersColumn":"Eerste kolom","headersNone":"Geen","headersRow":"Eerste ry"}; -------------------------------------------------------------------------------- /docs/libs/alloy-editor/lang/alloy-editor/ar.js: -------------------------------------------------------------------------------- 1 | AlloyEditor.Strings = {"alignCenter":"وسط","alignJustify":"ضبط","alignLeft":"يسار","alignRight":"يمين","bold":"عريض","bulletedlist":"ادخال/حذف تعداد نقطي","cancel":"إلغاء الأمر","horizontalrule":"خط فاصل","italic":"مائل","numberedlist":"ادخال/حذف تعداد رقمي","quote":"اقتباس","removeformat":"إزالة التنسيقات","strike":"يتوسطه خط","subscript":"منخفض","superscript":"مرتفع","underline":"تسطير","formatted":"منسّق","h1":"العنوان 1","h2":"العنوان 2","normal":"عادي","blockStyles":"أنماط الفقرة","inlineStyles":"أنماط مضمنة","objectStyles":"أنماط الكائن","styles":"أنماط","cell":"خلية","cellDelete":"حذف خلية","cellInsertAfter":"إدراج خلية بعد","cellInsertBefore":"إدراج خلية قبل","cellMerge":"دمج خلايا","cellMergeDown":"دمج للأسفل","cellMergeRight":"دمج لليمين","cellSplitHorizontal":"تقسيم الخلية أفقياً","cellSplitVertical":"تقسيم الخلية عمودياً","column":"عمود","columnDelete":"حذف أعمدة","columnInsertAfter":"إدراج عمود بعد","columnInsertBefore":"إدراج عمود قبل","deleteTable":"حذف الجدول","row":"صف","rowDelete":"حذف صفوف","rowInsertAfter":"إدراج صف بعد","rowInsertBefore":"إدراج صف قبل","add":"Add","ariaUpdateNoToolbar":"No toolbars are available","ariaUpdateOneToolbar":"{toolbars} toolbar is available. Press ALT+F10 to focus.","ariaUpdateManyToolbars":"{toolbars} toolbars are available. Press ALT+F10 to focus.","camera":"Insert Image from Camera","cite":"Cite","code":"Code","clearInput":"Clear Input Field","confirm":"Confirm","editLink":"Type or paste link here","image":"Insert Image","link":"Link","removeLink":"Remove link","table":"Insert Table","twitter":"Twitter","headers":"العناوين","headersBoth":"كلاهما","headersColumn":"العمود الأول","headersNone":"بدون","headersRow":"الصف الأول"}; -------------------------------------------------------------------------------- /docs/libs/alloy-editor/lang/alloy-editor/bn.js: -------------------------------------------------------------------------------- 1 | AlloyEditor.Strings = {"alignCenter":"মাঝখানে","alignJustify":"ব্লক জাস্টিফাই","alignLeft":"বামে","alignRight":"ডানে","bold":"বোল্ড","bulletedlist":"বুলেট লিস্ট লেবেল","cancel":"বাতিল","horizontalrule":"রেখা যুক্ত কর","italic":"ইটালিক","numberedlist":"সাংখ্যিক লিস্টের লেবেল","quote":"Block Quote","removeformat":"ফরমেট সরাও","strike":"স্ট্রাইক থ্রু","subscript":"অধোলেখ","superscript":"অভিলেখ","underline":"আন্ডারলাইন","formatted":"ফর্মেটেড","h1":"শীর্ষক ১","h2":"শীর্ষক ২","normal":"সাধারণ","blockStyles":"Block Styles","inlineStyles":"Inline Styles","objectStyles":"Object Styles","styles":"স্টাইল","cell":"সেল","cellDelete":"সেল মুছে দাও","cellInsertAfter":"Insert Cell After","cellInsertBefore":"Insert Cell Before","cellMerge":"সেল জোড়া দাও","cellMergeDown":"Merge Down","cellMergeRight":"Merge Right","cellSplitHorizontal":"Split Cell Horizontally","cellSplitVertical":"Split Cell Vertically","column":"কলাম","columnDelete":"কলাম মুছে দাও","columnInsertAfter":"Insert Column After","columnInsertBefore":"Insert Column Before","deleteTable":"টেবিল ডিলীট কর","row":"রো","rowDelete":"রো মুছে দাও","rowInsertAfter":"Insert Row After","rowInsertBefore":"Insert Row Before","add":"Add","ariaUpdateNoToolbar":"No toolbars are available","ariaUpdateOneToolbar":"{toolbars} toolbar is available. Press ALT+F10 to focus.","ariaUpdateManyToolbars":"{toolbars} toolbars are available. Press ALT+F10 to focus.","camera":"Insert Image from Camera","cite":"Cite","code":"Code","clearInput":"Clear Input Field","confirm":"Confirm","editLink":"Type or paste link here","image":"Insert Image","link":"Link","removeLink":"Remove link","table":"Insert Table","twitter":"Twitter","headers":"Headers","headersBoth":"Both","headersColumn":"First column","headersNone":"None","headersRow":"First Row"}; -------------------------------------------------------------------------------- /docs/libs/alloy-editor/lang/alloy-editor/bs.js: -------------------------------------------------------------------------------- 1 | AlloyEditor.Strings = {"alignCenter":"Centar","alignJustify":"Puno poravnanje","alignLeft":"Lijevo","alignRight":"Desno","bold":"Boldiraj","bulletedlist":"Lista","cancel":"Odustani","horizontalrule":"Ubaci horizontalnu liniju","italic":"Ukosi","numberedlist":"Numerisana lista","quote":"Block Quote","removeformat":"Poništi format","strike":"Precrtaj","subscript":"Subscript","superscript":"Superscript","underline":"Podvuci","formatted":"Formatted","h1":"Heading 1","h2":"Heading 2","normal":"Normal","blockStyles":"Block Styles","inlineStyles":"Inline Styles","objectStyles":"Object Styles","styles":"Stil","cell":"Cell","cellDelete":"Briši æelije","cellInsertAfter":"Insert Cell After","cellInsertBefore":"Insert Cell Before","cellMerge":"Spoji æelije","cellMergeDown":"Merge Down","cellMergeRight":"Merge Right","cellSplitHorizontal":"Split Cell Horizontally","cellSplitVertical":"Split Cell Vertically","column":"Column","columnDelete":"Briši kolone","columnInsertAfter":"Insert Column After","columnInsertBefore":"Insert Column Before","deleteTable":"Delete Table","row":"Row","rowDelete":"Briši redove","rowInsertAfter":"Insert Row After","rowInsertBefore":"Insert Row Before","add":"Add","ariaUpdateNoToolbar":"No toolbars are available","ariaUpdateOneToolbar":"{toolbars} toolbar is available. Press ALT+F10 to focus.","ariaUpdateManyToolbars":"{toolbars} toolbars are available. Press ALT+F10 to focus.","camera":"Insert Image from Camera","cite":"Cite","code":"Code","clearInput":"Clear Input Field","confirm":"Confirm","editLink":"Type or paste link here","image":"Insert Image","link":"Link","removeLink":"Remove link","table":"Insert Table","twitter":"Twitter","headers":"Headers","headersBoth":"Both","headersColumn":"First column","headersNone":"None","headersRow":"First Row"}; -------------------------------------------------------------------------------- /docs/libs/alloy-editor/lang/alloy-editor/cs.js: -------------------------------------------------------------------------------- 1 | AlloyEditor.Strings = {"alignCenter":"Na střed","alignJustify":"Zarovnat do bloku","alignLeft":"Vlevo","alignRight":"Vpravo","bold":"Tučné","bulletedlist":"Odrážky","cancel":"Zrušit","horizontalrule":"Vložit vodorovnou linku","italic":"Kurzíva","numberedlist":"Číslování","quote":"Citace","removeformat":"Odstranit formátování","strike":"Přeškrtnuté","subscript":"Dolní index","superscript":"Horní index","underline":"Podtržené","formatted":"Naformátováno","h1":"Nadpis 1","h2":"Nadpis 2","normal":"Normální","blockStyles":"Blokové styly","inlineStyles":"Řádkové styly","objectStyles":"Objektové styly","styles":"Styl","cell":"Buňka","cellDelete":"Smazat buňky","cellInsertAfter":"Vložit buňku za","cellInsertBefore":"Vložit buňku před","cellMerge":"Sloučit buňky","cellMergeDown":"Sloučit dolů","cellMergeRight":"Sloučit doprava","cellSplitHorizontal":"Rozdělit buňky vodorovně","cellSplitVertical":"Rozdělit buňky svisle","column":"Sloupec","columnDelete":"Smazat sloupec","columnInsertAfter":"Vložit sloupec za","columnInsertBefore":"Vložit sloupec před","deleteTable":"Smazat tabulku","row":"Řádek","rowDelete":"Smazat řádky","rowInsertAfter":"Vložit řádek za","rowInsertBefore":"Vložit řádek před","add":"Add","ariaUpdateNoToolbar":"No toolbars are available","ariaUpdateOneToolbar":"{toolbars} toolbar is available. Press ALT+F10 to focus.","ariaUpdateManyToolbars":"{toolbars} toolbars are available. Press ALT+F10 to focus.","camera":"Insert Image from Camera","cite":"Cite","code":"Code","clearInput":"Clear Input Field","confirm":"Confirm","editLink":"Type or paste link here","image":"Insert Image","link":"Link","removeLink":"Remove link","table":"Insert Table","twitter":"Twitter","headers":"Záhlaví","headersBoth":"Obojí","headersColumn":"První sloupec","headersNone":"Žádné","headersRow":"První řádek"}; -------------------------------------------------------------------------------- /docs/libs/alloy-editor/lang/alloy-editor/cy.js: -------------------------------------------------------------------------------- 1 | AlloyEditor.Strings = {"alignCenter":"Canol","alignJustify":"Unioni","alignLeft":"Chwith","alignRight":"Dde","bold":"Bras","bulletedlist":"Mewnosod/Tynnu Rhestr Bwled","cancel":"Diddymu","horizontalrule":"Mewnosod Llinell Lorweddol","italic":"Italig","numberedlist":"Mewnosod/Tynnu Rhestr Rhifol","quote":"Dyfyniad bloc","removeformat":"Tynnu Fformat","strike":"Llinell Trwyddo","subscript":"Is-sgript","superscript":"Uwchsgript","underline":"Tanlinellu","formatted":"Wedi'i Fformatio","h1":"Pennawd 1","h2":"Pennawd 2","normal":"Normal","blockStyles":"Arddulliau Bloc","inlineStyles":"Arddulliau Mewnol","objectStyles":"Arddulliau Gwrthrych","styles":"Arddulliau","cell":"Cell","cellDelete":"Dileu Celloedd","cellInsertAfter":"Mewnosod Cell Ar Ôl","cellInsertBefore":"Mewnosod Cell Cyn","cellMerge":"Cyfuno Celloedd","cellMergeDown":"Cyfuno i Lawr","cellMergeRight":"Cyfuno i'r Dde","cellSplitHorizontal":"Hollti'r Gell yn Lorweddol","cellSplitVertical":"Hollti'r Gell yn Fertigol","column":"Colofn","columnDelete":"Dileu Colofnau","columnInsertAfter":"Mewnosod Colofn Ar Ôl","columnInsertBefore":"Mewnosod Colofn Cyn","deleteTable":"Dileu Tabl","row":"Rhes","rowDelete":"Dileu Rhesi","rowInsertAfter":"Mewnosod Rhes Ar Ôl","rowInsertBefore":"Mewnosod Rhes Cyn","add":"Add","ariaUpdateNoToolbar":"No toolbars are available","ariaUpdateOneToolbar":"{toolbars} toolbar is available. Press ALT+F10 to focus.","ariaUpdateManyToolbars":"{toolbars} toolbars are available. Press ALT+F10 to focus.","camera":"Insert Image from Camera","cite":"Cite","code":"Code","clearInput":"Clear Input Field","confirm":"Confirm","editLink":"Type or paste link here","image":"Insert Image","link":"Link","removeLink":"Remove link","table":"Insert Table","twitter":"Twitter","headers":"Penynnau","headersBoth":"Y Ddau","headersColumn":"Colofn gyntaf","headersNone":"Dim","headersRow":"Rhes gyntaf"}; -------------------------------------------------------------------------------- /docs/libs/alloy-editor/lang/alloy-editor/da.js: -------------------------------------------------------------------------------- 1 | AlloyEditor.Strings = {"alignCenter":"Centreret","alignJustify":"Lige margener","alignLeft":"Venstre","alignRight":"Højre","bold":"Fed","bulletedlist":"Punktopstilling","cancel":"Annullér","horizontalrule":"Indsæt vandret streg","italic":"Kursiv","numberedlist":"Talopstilling","quote":"Blokcitat","removeformat":"Fjern formatering","strike":"Gennemstreget","subscript":"Sænket skrift","superscript":"Hævet skrift","underline":"Understreget","formatted":"Formateret","h1":"Overskrift 1","h2":"Overskrift 2","normal":"Normal","blockStyles":"Block typografi","inlineStyles":"Inline typografi","objectStyles":"Object typografi","styles":"Typografi","cell":"Celle","cellDelete":"Slet celle","cellInsertAfter":"Indsæt celle efter","cellInsertBefore":"Indsæt celle før","cellMerge":"Flet celler","cellMergeDown":"Flet nedad","cellMergeRight":"Flet til højre","cellSplitHorizontal":"Del celle vandret","cellSplitVertical":"Del celle lodret","column":"Kolonne","columnDelete":"Slet kolonne","columnInsertAfter":"Indsæt kolonne efter","columnInsertBefore":"Indsæt kolonne før","deleteTable":"Slet tabel","row":"Række","rowDelete":"Slet række","rowInsertAfter":"Indsæt række efter","rowInsertBefore":"Indsæt række før","add":"Add","ariaUpdateNoToolbar":"No toolbars are available","ariaUpdateOneToolbar":"{toolbars} toolbar is available. Press ALT+F10 to focus.","ariaUpdateManyToolbars":"{toolbars} toolbars are available. Press ALT+F10 to focus.","camera":"Insert Image from Camera","cite":"Cite","code":"Code","clearInput":"Clear Input Field","confirm":"Confirm","editLink":"Type or paste link here","image":"Insert Image","link":"Link","removeLink":"Remove link","table":"Insert Table","twitter":"Twitter","headers":"Hoved","headersBoth":"Begge","headersColumn":"Første kolonne","headersNone":"Ingen","headersRow":"Første række"}; -------------------------------------------------------------------------------- /docs/libs/alloy-editor/lang/alloy-editor/en-au.js: -------------------------------------------------------------------------------- 1 | AlloyEditor.Strings = {"alignCenter":"Centre","alignJustify":"Justify","alignLeft":"Left","alignRight":"Right","bold":"Bold","bulletedlist":"Insert/Remove Bulleted List","cancel":"Cancel","horizontalrule":"Insert Horizontal Line","italic":"Italic","numberedlist":"Insert/Remove Numbered List","quote":"Block Quote","removeformat":"Remove Format","strike":"Strike Through","subscript":"Subscript","superscript":"Superscript","underline":"Underline","formatted":"Formatted","h1":"Heading 1","h2":"Heading 2","normal":"Normal","blockStyles":"Block Styles","inlineStyles":"Inline Styles","objectStyles":"Object Styles","styles":"Styles","cell":"Cell","cellDelete":"Delete Cells","cellInsertAfter":"Insert Cell After","cellInsertBefore":"Insert Cell Before","cellMerge":"Merge Cells","cellMergeDown":"Merge Down","cellMergeRight":"Merge Right","cellSplitHorizontal":"Split Cell Horizontally","cellSplitVertical":"Split Cell Vertically","column":"Column","columnDelete":"Delete Columns","columnInsertAfter":"Insert Column After","columnInsertBefore":"Insert Column Before","deleteTable":"Delete Table","row":"Row","rowDelete":"Delete Rows","rowInsertAfter":"Insert Row After","rowInsertBefore":"Insert Row Before","add":"Add","ariaUpdateNoToolbar":"No toolbars are available","ariaUpdateOneToolbar":"{toolbars} toolbar is available. Press ALT+F10 to focus.","ariaUpdateManyToolbars":"{toolbars} toolbars are available. Press ALT+F10 to focus.","camera":"Insert Image from Camera","cite":"Cite","code":"Code","clearInput":"Clear Input Field","confirm":"Confirm","editLink":"Type or paste link here","image":"Insert Image","link":"Link","removeLink":"Remove link","table":"Insert Table","twitter":"Twitter","headers":"Headers","headersBoth":"Both","headersColumn":"First column","headersNone":"None","headersRow":"First Row"}; -------------------------------------------------------------------------------- /docs/libs/alloy-editor/lang/alloy-editor/en-ca.js: -------------------------------------------------------------------------------- 1 | AlloyEditor.Strings = {"alignCenter":"Centre","alignJustify":"Justify","alignLeft":"Left","alignRight":"Right","bold":"Bold","bulletedlist":"Insert/Remove Bulleted List","cancel":"Cancel","horizontalrule":"Insert Horizontal Line","italic":"Italic","numberedlist":"Insert/Remove Numbered List","quote":"Block Quote","removeformat":"Remove Format","strike":"Strike Through","subscript":"Subscript","superscript":"Superscript","underline":"Underline","formatted":"Formatted","h1":"Heading 1","h2":"Heading 2","normal":"Normal","blockStyles":"Block Styles","inlineStyles":"Inline Styles","objectStyles":"Object Styles","styles":"Styles","cell":"Cell","cellDelete":"Delete Cells","cellInsertAfter":"Insert Cell After","cellInsertBefore":"Insert Cell Before","cellMerge":"Merge Cells","cellMergeDown":"Merge Down","cellMergeRight":"Merge Right","cellSplitHorizontal":"Split Cell Horizontally","cellSplitVertical":"Split Cell Vertically","column":"Column","columnDelete":"Delete Columns","columnInsertAfter":"Insert Column After","columnInsertBefore":"Insert Column Before","deleteTable":"Delete Table","row":"Row","rowDelete":"Delete Rows","rowInsertAfter":"Insert Row After","rowInsertBefore":"Insert Row Before","add":"Add","ariaUpdateNoToolbar":"No toolbars are available","ariaUpdateOneToolbar":"{toolbars} toolbar is available. Press ALT+F10 to focus.","ariaUpdateManyToolbars":"{toolbars} toolbars are available. Press ALT+F10 to focus.","camera":"Insert Image from Camera","cite":"Cite","code":"Code","clearInput":"Clear Input Field","confirm":"Confirm","editLink":"Type or paste link here","image":"Insert Image","link":"Link","removeLink":"Remove link","table":"Insert Table","twitter":"Twitter","headers":"Headers","headersBoth":"Both","headersColumn":"First column","headersNone":"None","headersRow":"First Row"}; -------------------------------------------------------------------------------- /docs/libs/alloy-editor/lang/alloy-editor/en-gb.js: -------------------------------------------------------------------------------- 1 | AlloyEditor.Strings = {"alignCenter":"Centre","alignJustify":"Justify","alignLeft":"Left","alignRight":"Right","bold":"Bold","bulletedlist":"Insert/Remove Bulleted List","cancel":"Cancel","horizontalrule":"Insert Horizontal Line","italic":"Italic","numberedlist":"Insert/Remove Numbered List","quote":"Block Quote","removeformat":"Remove Format","strike":"Strike Through","subscript":"Subscript","superscript":"Superscript","underline":"Underline","formatted":"Formatted","h1":"Heading 1","h2":"Heading 2","normal":"Normal","blockStyles":"Block Styles","inlineStyles":"Inline Styles","objectStyles":"Object Styles","styles":"Styles","cell":"Cell","cellDelete":"Delete Cells","cellInsertAfter":"Insert Cell After","cellInsertBefore":"Insert Cell Before","cellMerge":"Merge Cells","cellMergeDown":"Merge Down","cellMergeRight":"Merge Right","cellSplitHorizontal":"Split Cell Horizontally","cellSplitVertical":"Split Cell Vertically","column":"Column","columnDelete":"Delete Columns","columnInsertAfter":"Insert Column After","columnInsertBefore":"Insert Column Before","deleteTable":"Delete Table","row":"Row","rowDelete":"Delete Rows","rowInsertAfter":"Insert Row After","rowInsertBefore":"Insert Row Before","add":"Add","ariaUpdateNoToolbar":"No toolbars are available","ariaUpdateOneToolbar":"{toolbars} toolbar is available. Press ALT+F10 to focus.","ariaUpdateManyToolbars":"{toolbars} toolbars are available. Press ALT+F10 to focus.","camera":"Insert Image from Camera","cite":"Cite","code":"Code","clearInput":"Clear Input Field","confirm":"Confirm","editLink":"Type or paste link here","image":"Insert Image","link":"Link","removeLink":"Remove link","table":"Insert Table","twitter":"Twitter","headers":"Headers","headersBoth":"Both","headersColumn":"First column","headersNone":"None","headersRow":"First Row"}; -------------------------------------------------------------------------------- /docs/libs/alloy-editor/lang/alloy-editor/en.js: -------------------------------------------------------------------------------- 1 | AlloyEditor.Strings = {"alignCenter":"Center","alignJustify":"Justify","alignLeft":"Left","alignRight":"Right","bold":"Bold","bulletedlist":"Insert/Remove Bulleted List","cancel":"Cancel","horizontalrule":"Insert Horizontal Line","italic":"Italic","numberedlist":"Insert/Remove Numbered List","quote":"Block Quote","removeformat":"Remove Format","strike":"Strikethrough","subscript":"Subscript","superscript":"Superscript","underline":"Underline","formatted":"Formatted","h1":"Heading 1","h2":"Heading 2","normal":"Normal","blockStyles":"Block Styles","inlineStyles":"Inline Styles","objectStyles":"Object Styles","styles":"Styles","cell":"Cell","cellDelete":"Delete Cells","cellInsertAfter":"Insert Cell After","cellInsertBefore":"Insert Cell Before","cellMerge":"Merge Cells","cellMergeDown":"Merge Down","cellMergeRight":"Merge Right","cellSplitHorizontal":"Split Cell Horizontally","cellSplitVertical":"Split Cell Vertically","column":"Column","columnDelete":"Delete Columns","columnInsertAfter":"Insert Column After","columnInsertBefore":"Insert Column Before","deleteTable":"Delete Table","row":"Row","rowDelete":"Delete Rows","rowInsertAfter":"Insert Row After","rowInsertBefore":"Insert Row Before","add":"Add","ariaUpdateNoToolbar":"No toolbars are available","ariaUpdateOneToolbar":"{toolbars} toolbar is available. Press ALT+F10 to focus.","ariaUpdateManyToolbars":"{toolbars} toolbars are available. Press ALT+F10 to focus.","camera":"Insert Image from Camera","cite":"Cite","code":"Code","clearInput":"Clear Input Field","confirm":"Confirm","editLink":"Type or paste link here","image":"Insert Image","link":"Link","removeLink":"Remove link","table":"Insert Table","twitter":"Twitter","headers":"Headers","headersBoth":"Both","headersColumn":"First column","headersNone":"None","headersRow":"First Row"}; -------------------------------------------------------------------------------- /docs/libs/alloy-editor/lang/alloy-editor/eo.js: -------------------------------------------------------------------------------- 1 | AlloyEditor.Strings = {"alignCenter":"Centre","alignJustify":"Ĝisrandigi Ambaŭflanke","alignLeft":"Maldekstre","alignRight":"Dekstre","bold":"Grasa","bulletedlist":"Bula Listo","cancel":"Rezigni","horizontalrule":"Enmeti Horizontalan Linion","italic":"Kursiva","numberedlist":"Numera Listo","quote":"Citaĵo","removeformat":"Forigi Formaton","strike":"Trastreko","subscript":"Suba indico","superscript":"Supra indico","underline":"Substreko","formatted":"Formatita","h1":"Titolo 1","h2":"Titolo 2","normal":"Normala","blockStyles":"Stiloj de blokoj","inlineStyles":"Enliniaj Stiloj","objectStyles":"Stiloj de objektoj","styles":"Stiloj","cell":"Ĉelo","cellDelete":"Forigi la Ĉelojn","cellInsertAfter":"Enmeti Ĉelon Post","cellInsertBefore":"Enmeti Ĉelon Antaŭ","cellMerge":"Kunfandi la Ĉelojn","cellMergeDown":"Kunfandi malsupren ","cellMergeRight":"Kunfandi dekstren","cellSplitHorizontal":"Horizontale dividi","cellSplitVertical":"Vertikale dividi","column":"Kolumno","columnDelete":"Forigi Kolumnojn","columnInsertAfter":"Enmeti kolumnon post","columnInsertBefore":"Enmeti kolumnon antaŭ","deleteTable":"Forigi Tabelon","row":"Linio","rowDelete":"Forigi Liniojn","rowInsertAfter":"Enmeti linion post","rowInsertBefore":"Enmeti linion antaŭ","add":"Add","ariaUpdateNoToolbar":"No toolbars are available","ariaUpdateOneToolbar":"{toolbars} toolbar is available. Press ALT+F10 to focus.","ariaUpdateManyToolbars":"{toolbars} toolbars are available. Press ALT+F10 to focus.","camera":"Insert Image from Camera","cite":"Cite","code":"Code","clearInput":"Clear Input Field","confirm":"Confirm","editLink":"Type or paste link here","image":"Insert Image","link":"Link","removeLink":"Remove link","table":"Insert Table","twitter":"Twitter","headers":"Supraj Paĝotitoloj","headersBoth":"Ambaŭ","headersColumn":"Unua kolumno","headersNone":"Neniu","headersRow":"Unua linio"}; -------------------------------------------------------------------------------- /docs/libs/alloy-editor/lang/alloy-editor/et.js: -------------------------------------------------------------------------------- 1 | AlloyEditor.Strings = {"alignCenter":"Kesk","alignJustify":"Rööpjoondus","alignLeft":"Vasak","alignRight":"Paremale","bold":"Paks","bulletedlist":"Punktloend","cancel":"Loobu","horizontalrule":"Horisontaaljoone sisestamine","italic":"Kursiiv","numberedlist":"Numberloend","quote":"Blokktsitaat","removeformat":"Vormingu eemaldamine","strike":"Läbijoonitud","subscript":"Allindeks","superscript":"Ülaindeks","underline":"Allajoonitud","formatted":"Vormindatud","h1":"Pealkiri 1","h2":"Pealkiri 2","normal":"Tavaline","blockStyles":"Blokkstiilid","inlineStyles":"Reasisesed stiilid","objectStyles":"Objektistiilid","styles":"Stiil","cell":"Lahter","cellDelete":"Eemalda lahtrid","cellInsertAfter":"Sisesta lahter peale","cellInsertBefore":"Sisesta lahter enne","cellMerge":"Ühenda lahtrid","cellMergeDown":"Ühenda alla","cellMergeRight":"Ühenda paremale","cellSplitHorizontal":"Poolita lahter horisontaalselt","cellSplitVertical":"Poolita lahter vertikaalselt","column":"Veerg","columnDelete":"Eemalda veerud","columnInsertAfter":"Sisesta veerg peale","columnInsertBefore":"Sisesta veerg enne","deleteTable":"Kustuta tabel","row":"Rida","rowDelete":"Eemalda read","rowInsertAfter":"Sisesta rida peale","rowInsertBefore":"Sisesta rida enne","add":"Add","ariaUpdateNoToolbar":"No toolbars are available","ariaUpdateOneToolbar":"{toolbars} toolbar is available. Press ALT+F10 to focus.","ariaUpdateManyToolbars":"{toolbars} toolbars are available. Press ALT+F10 to focus.","camera":"Insert Image from Camera","cite":"Cite","code":"Code","clearInput":"Clear Input Field","confirm":"Confirm","editLink":"Type or paste link here","image":"Insert Image","link":"Link","removeLink":"Remove link","table":"Insert Table","twitter":"Twitter","headers":"Päised","headersBoth":"Mõlemad","headersColumn":"Esimene tulp","headersNone":"Puudub","headersRow":"Esimene rida"}; -------------------------------------------------------------------------------- /docs/libs/alloy-editor/lang/alloy-editor/fa.js: -------------------------------------------------------------------------------- 1 | AlloyEditor.Strings = {"alignCenter":"وسط","alignJustify":"بلوک چین","alignLeft":"چپ","alignRight":"راست","bold":"درشت","bulletedlist":"فهرست نقطه​ای","cancel":"انصراف","horizontalrule":"گنجاندن خط افقی","italic":"خمیده","numberedlist":"فهرست شماره​دار","quote":"بلوک نقل قول","removeformat":"برداشتن فرمت","strike":"خط‌خورده","subscript":"زیرنویس","superscript":"بالانویس","underline":"زیرخط‌دار","formatted":"قالب‌دار","h1":"سرنویس ۱","h2":"سرنویس ۲","normal":"معمولی","blockStyles":"سبکهای بلوک","inlineStyles":"سبکهای درونخطی","objectStyles":"سبکهای شیء","styles":"سبک","cell":"سلول","cellDelete":"حذف سلولها","cellInsertAfter":"افزودن سلول بعد از","cellInsertBefore":"افزودن سلول قبل از","cellMerge":"ادغام سلولها","cellMergeDown":"ادغام به پایین","cellMergeRight":"ادغام به راست","cellSplitHorizontal":"جدا کردن افقی سلول","cellSplitVertical":"جدا کردن عمودی سلول","column":"ستون","columnDelete":"حذف ستونها","columnInsertAfter":"افزودن ستون بعد از","columnInsertBefore":"افزودن ستون قبل از","deleteTable":"پاک کردن جدول","row":"سطر","rowDelete":"حذف سطرها","rowInsertAfter":"افزودن سطر بعد از","rowInsertBefore":"افزودن سطر قبل از","add":"Add","ariaUpdateNoToolbar":"No toolbars are available","ariaUpdateOneToolbar":"{toolbars} toolbar is available. Press ALT+F10 to focus.","ariaUpdateManyToolbars":"{toolbars} toolbars are available. Press ALT+F10 to focus.","camera":"Insert Image from Camera","cite":"Cite","code":"Code","clearInput":"Clear Input Field","confirm":"Confirm","editLink":"Type or paste link here","image":"Insert Image","link":"Link","removeLink":"Remove link","table":"Insert Table","twitter":"Twitter","headers":"سرنویسها","headersBoth":"هردو","headersColumn":"اولین ستون","headersNone":"هیچ","headersRow":"اولین ردیف"}; -------------------------------------------------------------------------------- /docs/libs/alloy-editor/lang/alloy-editor/fo.js: -------------------------------------------------------------------------------- 1 | AlloyEditor.Strings = {"alignCenter":"Miðsett","alignJustify":"Javnir tekstkantar","alignLeft":"Vinstra","alignRight":"Høgra","bold":"Feit skrift","bulletedlist":"Punktmerktur listi","cancel":"Avlýst","horizontalrule":"Ger vatnrætta linju","italic":"Skráskrift","numberedlist":"Talmerktur listi","quote":"Blockquote","removeformat":"Strika sniðgeving","strike":"Yvirstrikað","subscript":"Lækkað skrift","superscript":"Hækkað skrift","underline":"Undirstrikað","formatted":"Sniðgivið","h1":"Yvirskrift 1","h2":"Yvirskrift 2","normal":"Vanligt","blockStyles":"Blokk stílir","inlineStyles":"Inline stílir","objectStyles":"Object stílir","styles":"Typografi","cell":"Meski","cellDelete":"Strika meskar","cellInsertAfter":"Set meska inn aftaná","cellInsertBefore":"Set meska inn áðrenn","cellMerge":"Flætta meskar","cellMergeDown":"Flætta saman","cellMergeRight":"Flætta meskar til høgru","cellSplitHorizontal":"Kloyv meska vatnrætt","cellSplitVertical":"Kloyv meska loddrætt","column":"Kolonna","columnDelete":"Strika kolonnur","columnInsertAfter":"Set kolonnu inn aftaná","columnInsertBefore":"Set kolonnu inn áðrenn","deleteTable":"Strika tabell","row":"Rað","rowDelete":"Strika røðir","rowInsertAfter":"Set rað inn aftaná","rowInsertBefore":"Set rað inn áðrenn","add":"Add","ariaUpdateNoToolbar":"No toolbars are available","ariaUpdateOneToolbar":"{toolbars} toolbar is available. Press ALT+F10 to focus.","ariaUpdateManyToolbars":"{toolbars} toolbars are available. Press ALT+F10 to focus.","camera":"Insert Image from Camera","cite":"Cite","code":"Code","clearInput":"Clear Input Field","confirm":"Confirm","editLink":"Type or paste link here","image":"Insert Image","link":"Link","removeLink":"Remove link","table":"Insert Table","twitter":"Twitter","headers":"Yvirskriftir","headersBoth":"Báðir","headersColumn":"Fyrsta kolonna","headersNone":"Eingin","headersRow":"Fyrsta rað"}; -------------------------------------------------------------------------------- /docs/libs/alloy-editor/lang/alloy-editor/he.js: -------------------------------------------------------------------------------- 1 | AlloyEditor.Strings = {"alignCenter":"מרכז","alignJustify":"יישור לשוליים","alignLeft":"לשמאל","alignRight":"לימין","bold":"מודגש","bulletedlist":"רשימת נקודות","cancel":"ביטול","horizontalrule":"הוספת קו אופקי","italic":"נטוי","numberedlist":"רשימה ממוספרת","quote":"בלוק ציטוט","removeformat":"הסרת העיצוב","strike":"כתיב מחוק","subscript":"כתיב תחתון","superscript":"כתיב עליון","underline":"קו תחתון","formatted":"קוד","h1":"כותרת","h2":"כותרת 2","normal":"נורמלי","blockStyles":"סגנונות בלוק","inlineStyles":"סגנונות רצף","objectStyles":"סגנונות אובייקט","styles":"סגנון","cell":"מאפייני תא","cellDelete":"מחיקת תאים","cellInsertAfter":"הוספת תא אחרי","cellInsertBefore":"הוספת תא לפני","cellMerge":"מיזוג תאים","cellMergeDown":"מזג למטה","cellMergeRight":"מזג ימינה","cellSplitHorizontal":"פיצול תא אופקית","cellSplitVertical":"פיצול תא אנכית","column":"עמודה","columnDelete":"מחיקת עמודות","columnInsertAfter":"הוספת עמודה אחרי","columnInsertBefore":"הוספת עמודה לפני","deleteTable":"מחק טבלה","row":"שורה","rowDelete":"מחיקת שורות","rowInsertAfter":"הוספת שורה אחרי","rowInsertBefore":"הוספת שורה לפני","add":"Add","ariaUpdateNoToolbar":"No toolbars are available","ariaUpdateOneToolbar":"{toolbars} toolbar is available. Press ALT+F10 to focus.","ariaUpdateManyToolbars":"{toolbars} toolbars are available. Press ALT+F10 to focus.","camera":"Insert Image from Camera","cite":"Cite","code":"Code","clearInput":"Clear Input Field","confirm":"Confirm","editLink":"Type or paste link here","image":"Insert Image","link":"Link","removeLink":"Remove link","table":"Insert Table","twitter":"Twitter","headers":"כותרות","headersBoth":"שניהם","headersColumn":"עמודה ראשונה","headersNone":"אין","headersRow":"שורה ראשונה"}; -------------------------------------------------------------------------------- /docs/libs/alloy-editor/lang/alloy-editor/hi.js: -------------------------------------------------------------------------------- 1 | AlloyEditor.Strings = {"alignCenter":"बीच में","alignJustify":"ब्लॉक जस्टीफ़ाई","alignLeft":"दायें","alignRight":"दायें","bold":"बोल्ड","bulletedlist":"बुलॅट सूची","cancel":"रद्द करें","horizontalrule":"हॉरिज़ॉन्टल रेखा इन्सर्ट करें","italic":"इटैलिक","numberedlist":"अंकीय सूची","quote":"ब्लॉक-कोट","removeformat":"फ़ॉर्मैट हटायें","strike":"स्ट्राइक थ्रू","subscript":"अधोलेख","superscript":"अभिलेख","underline":"रेखांकण","formatted":"फ़ॉर्मैटॅड","h1":"शीर्षक 1","h2":"शीर्षक 2","normal":"साधारण","blockStyles":"Block Styles","inlineStyles":"Inline Styles","objectStyles":"Object Styles","styles":"स्टाइल","cell":"खाना","cellDelete":"सैल डिलीट करें","cellInsertAfter":"बाद में सैल डालें","cellInsertBefore":"पहले सैल डालें","cellMerge":"सैल मिलायें","cellMergeDown":"नीचे विलय करें","cellMergeRight":"बाँया विलय","cellSplitHorizontal":"सैल को क्षैतिज स्थिति में विभाजित करें","cellSplitVertical":"सैल को लम्बाकार में विभाजित करें","column":"कालम","columnDelete":"कालम डिलीट करें","columnInsertAfter":"बाद में कालम डालें","columnInsertBefore":"पहले कालम डालें","deleteTable":"टेबल डिलीट करें","row":"पंक्ति","rowDelete":"पंक्तियाँ डिलीट करें","rowInsertAfter":"बाद में पंक्ति डालें","rowInsertBefore":"पहले पंक्ति डालें","add":"Add","ariaUpdateNoToolbar":"No toolbars are available","ariaUpdateOneToolbar":"{toolbars} toolbar is available. Press ALT+F10 to focus.","ariaUpdateManyToolbars":"{toolbars} toolbars are available. Press ALT+F10 to focus.","camera":"Insert Image from Camera","cite":"Cite","code":"Code","clearInput":"Clear Input Field","confirm":"Confirm","editLink":"Type or paste link here","image":"Insert Image","link":"Link","removeLink":"Remove link","table":"Insert Table","twitter":"Twitter","headers":"Headers","headersBoth":"Both","headersColumn":"First column","headersNone":"None","headersRow":"First Row"}; -------------------------------------------------------------------------------- /docs/libs/alloy-editor/lang/alloy-editor/hr.js: -------------------------------------------------------------------------------- 1 | AlloyEditor.Strings = {"alignCenter":"Središnje","alignJustify":"Blok poravnanje","alignLeft":"Lijevo","alignRight":"Desno","bold":"Podebljaj","bulletedlist":"Obična lista","cancel":"Poništi","horizontalrule":"Ubaci vodoravnu liniju","italic":"Ukosi","numberedlist":"Brojčana lista","quote":"Blockquote","removeformat":"Ukloni formatiranje","strike":"Precrtano","subscript":"Subscript","superscript":"Superscript","underline":"Potcrtano","formatted":"Formatirano","h1":"Heading 1","h2":"Heading 2","normal":"Normal","blockStyles":"Block stilovi","inlineStyles":"Inline stilovi","objectStyles":"Object stilovi","styles":"Stil","cell":"Ćelija","cellDelete":"Izbriši ćelije","cellInsertAfter":"Ubaci ćeliju poslije","cellInsertBefore":"Ubaci ćeliju prije","cellMerge":"Spoji ćelije","cellMergeDown":"Spoji dolje","cellMergeRight":"Spoji desno","cellSplitHorizontal":"Podijeli ćeliju vodoravno","cellSplitVertical":"Podijeli ćeliju okomito","column":"Kolona","columnDelete":"Izbriši kolone","columnInsertAfter":"Ubaci kolonu poslije","columnInsertBefore":"Ubaci kolonu prije","deleteTable":"Izbriši tablicu","row":"Red","rowDelete":"Izbriši redove","rowInsertAfter":"Ubaci red poslije","rowInsertBefore":"Ubaci red prije","add":"Add","ariaUpdateNoToolbar":"No toolbars are available","ariaUpdateOneToolbar":"{toolbars} toolbar is available. Press ALT+F10 to focus.","ariaUpdateManyToolbars":"{toolbars} toolbars are available. Press ALT+F10 to focus.","camera":"Insert Image from Camera","cite":"Cite","code":"Code","clearInput":"Clear Input Field","confirm":"Confirm","editLink":"Type or paste link here","image":"Insert Image","link":"Link","removeLink":"Remove link","table":"Insert Table","twitter":"Twitter","headers":"Zaglavlje","headersBoth":"Oba","headersColumn":"Prva kolona","headersNone":"Ništa","headersRow":"Prvi red"}; -------------------------------------------------------------------------------- /docs/libs/alloy-editor/lang/alloy-editor/hu.js: -------------------------------------------------------------------------------- 1 | AlloyEditor.Strings = {"alignCenter":"Középre","alignJustify":"Sorkizárt","alignLeft":"Bal","alignRight":"Jobbra","bold":"Félkövér","bulletedlist":"Felsorolás","cancel":"Mégsem","horizontalrule":"Elválasztóvonal beillesztése","italic":"Dőlt","numberedlist":"Számozás","quote":"Idézet blokk","removeformat":"Formázás eltávolítása","strike":"Áthúzott","subscript":"Alsó index","superscript":"Felső index","underline":"Aláhúzott","formatted":"Formázott","h1":"Fejléc 1","h2":"Fejléc 2","normal":"Normál","blockStyles":"Blokk stílusok","inlineStyles":"Inline stílusok","objectStyles":"Objektum stílusok","styles":"Stílus","cell":"Cella","cellDelete":"Cellák törlése","cellInsertAfter":"Beszúrás jobbra","cellInsertBefore":"Beszúrás balra","cellMerge":"Cellák egyesítése","cellMergeDown":"Cellák egyesítése lefelé","cellMergeRight":"Cellák egyesítése jobbra","cellSplitHorizontal":"Cellák szétválasztása vízszintesen","cellSplitVertical":"Cellák szétválasztása függőlegesen","column":"Oszlop","columnDelete":"Oszlopok törlése","columnInsertAfter":"Beszúrás jobbra","columnInsertBefore":"Beszúrás balra","deleteTable":"Táblázat törlése","row":"Sor","rowDelete":"Sorok törlése","rowInsertAfter":"Beszúrás alá","rowInsertBefore":"Beszúrás fölé","add":"Add","ariaUpdateNoToolbar":"No toolbars are available","ariaUpdateOneToolbar":"{toolbars} toolbar is available. Press ALT+F10 to focus.","ariaUpdateManyToolbars":"{toolbars} toolbars are available. Press ALT+F10 to focus.","camera":"Insert Image from Camera","cite":"Cite","code":"Code","clearInput":"Clear Input Field","confirm":"Confirm","editLink":"Type or paste link here","image":"Insert Image","link":"Link","removeLink":"Remove link","table":"Insert Table","twitter":"Twitter","headers":"Fejlécek","headersBoth":"Mindkettő","headersColumn":"Első oszlop","headersNone":"Nincsenek","headersRow":"Első sor"}; -------------------------------------------------------------------------------- /docs/libs/alloy-editor/lang/alloy-editor/id.js: -------------------------------------------------------------------------------- 1 | AlloyEditor.Strings = {"alignCenter":"Tengah","alignJustify":"Rata kiri-kanan","alignLeft":"Kiri","alignRight":"Kanan","bold":"Huruf Tebal","bulletedlist":"Sisip/Hapus Daftar Bullet","cancel":"Batal","horizontalrule":"Sisip Garis Horisontal","italic":"Huruf Miring","numberedlist":"Sisip/Hapus Daftar Bernomor","quote":"Kutipan Blok","removeformat":"Hapus Format","strike":"Strikethrough","subscript":"Subscript","superscript":"Superscript","underline":"Garis Bawah","formatted":"Membentuk","h1":"Heading 1","h2":"Heading 2","normal":"Normal","blockStyles":"Block Styles","inlineStyles":"Inline Styles","objectStyles":"Object Styles","styles":"Gaya","cell":"Sel","cellDelete":"Hapus Sel","cellInsertAfter":"Sisip Sel Setelah","cellInsertBefore":"Sisip Sel Sebelum","cellMerge":"Gabungkan Sel","cellMergeDown":"Gabungkan ke Bawah","cellMergeRight":"Gabungkan ke Kanan","cellSplitHorizontal":"Pisahkan Sel Secara Horisontal","cellSplitVertical":"Pisahkan Sel Secara Vertikal","column":"Kolom","columnDelete":"Hapus Kolom","columnInsertAfter":"Sisip Kolom Sesudah","columnInsertBefore":"Sisip Kolom Sebelum","deleteTable":"Hapus Tabel","row":"Baris","rowDelete":"Hapus Baris","rowInsertAfter":"Sisip Baris Sesudah","rowInsertBefore":"Sisip Baris Sebelum","add":"Add","ariaUpdateNoToolbar":"No toolbars are available","ariaUpdateOneToolbar":"{toolbars} toolbar is available. Press ALT+F10 to focus.","ariaUpdateManyToolbars":"{toolbars} toolbars are available. Press ALT+F10 to focus.","camera":"Insert Image from Camera","cite":"Cite","code":"Code","clearInput":"Clear Input Field","confirm":"Confirm","editLink":"Type or paste link here","image":"Insert Image","link":"Link","removeLink":"Remove link","table":"Insert Table","twitter":"Twitter","headers":"Headers","headersBoth":"Keduanya","headersColumn":"Kolom pertama","headersNone":"Tidak ada","headersRow":"Baris Pertama"}; -------------------------------------------------------------------------------- /docs/libs/alloy-editor/lang/alloy-editor/ja.js: -------------------------------------------------------------------------------- 1 | AlloyEditor.Strings = {"alignCenter":"中央","alignJustify":"両端揃え","alignLeft":"左","alignRight":"右","bold":"太字","bulletedlist":"番号無しリスト","cancel":"キャンセル","horizontalrule":"水平線","italic":"斜体","numberedlist":"番号付きリスト","quote":"ブロック引用文","removeformat":"書式を解除","strike":"打ち消し線","subscript":"下付き","superscript":"上付き","underline":"下線","formatted":"書式付き","h1":"見出し 1","h2":"見出し 2","normal":"標準","blockStyles":"ブロックスタイル","inlineStyles":"インラインスタイル","objectStyles":"オブジェクトスタイル","styles":"スタイル","cell":"セル","cellDelete":"セルを削除","cellInsertAfter":"セルを後に挿入","cellInsertBefore":"セルを前に挿入","cellMerge":"セルを結合","cellMergeDown":"下に結合","cellMergeRight":"右に結合","cellSplitHorizontal":"セルを水平方向に分割","cellSplitVertical":"セルを垂直方向に分割","column":"列","columnDelete":"列を削除","columnInsertAfter":"列を右に挿入","columnInsertBefore":"列を左に挿入","deleteTable":"表を削除","row":"行","rowDelete":"行を削除","rowInsertAfter":"行を下に挿入","rowInsertBefore":"行を上に挿入","add":"Add","ariaUpdateNoToolbar":"No toolbars are available","ariaUpdateOneToolbar":"{toolbars} toolbar is available. Press ALT+F10 to focus.","ariaUpdateManyToolbars":"{toolbars} toolbars are available. Press ALT+F10 to focus.","camera":"Insert Image from Camera","cite":"Cite","code":"Code","clearInput":"Clear Input Field","confirm":"Confirm","editLink":"Type or paste link here","image":"Insert Image","link":"Link","removeLink":"Remove link","table":"Insert Table","twitter":"Twitter","headers":"ヘッダ (th)","headersBoth":"両方","headersColumn":"最初の列のみ","headersNone":"なし","headersRow":"最初の行のみ"}; -------------------------------------------------------------------------------- /docs/libs/alloy-editor/lang/alloy-editor/ka.js: -------------------------------------------------------------------------------- 1 | AlloyEditor.Strings = {"alignCenter":"შუა","alignJustify":"両端揃え","alignLeft":"მარცხენა","alignRight":"მარჯვენა","bold":"მსხვილი","bulletedlist":"ღილიანი სია","cancel":"გაუქმება","horizontalrule":"ჰორიზონტალური ხაზის ჩასმა","italic":"დახრილი","numberedlist":"გადანომრილი სია","quote":"ციტატა","removeformat":"ფორმატირების მოხსნა","strike":"გადახაზული","subscript":"ინდექსი","superscript":"ხარისხი","underline":"გახაზული","formatted":"ფორმატირებული","h1":"სათაური 1","h2":"სათაური 2","normal":"ჩვეულებრივი","blockStyles":"არის სტილები","inlineStyles":"თანდართული სტილები","objectStyles":"ობიექტის სტილები","styles":"სტილები","cell":"უჯრა","cellDelete":"უჯრების წაშლა","cellInsertAfter":"უჯრის ჩასმა მერე","cellInsertBefore":"უჯრის ჩასმა მანამდე","cellMerge":"უჯრების შეერთება","cellMergeDown":"შეერთება ქვემოთასთან","cellMergeRight":"შეერთება მარჯვენასთან","cellSplitHorizontal":"გაყოფა ჰორიზონტალურად","cellSplitVertical":"გაყოფა ვერტიკალურად","column":"სვეტი","columnDelete":"სვეტების წაშლა","columnInsertAfter":"სვეტის ჩამატება მერე","columnInsertBefore":"სვეტის ჩამატება წინ","deleteTable":"ცხრილის წაშლა","row":"სტრიქონი","rowDelete":"სტრიქონების წაშლა","rowInsertAfter":"სტრიქონის ჩამატება მერე","rowInsertBefore":"სტრიქონის ჩამატება წინ","add":"Add","ariaUpdateNoToolbar":"No toolbars are available","ariaUpdateOneToolbar":"{toolbars} toolbar is available. Press ALT+F10 to focus.","ariaUpdateManyToolbars":"{toolbars} toolbars are available. Press ALT+F10 to focus.","camera":"Insert Image from Camera","cite":"Cite","code":"Code","clearInput":"Clear Input Field","confirm":"Confirm","editLink":"Type or paste link here","image":"Insert Image","link":"Link","removeLink":"Remove link","table":"Insert Table","twitter":"Twitter","headers":"სათაურები","headersBoth":"ორივე","headersColumn":"პირველი სვეტი","headersNone":"არაფერი","headersRow":"პირველი სტრიქონი"}; -------------------------------------------------------------------------------- /docs/libs/alloy-editor/lang/alloy-editor/ko.js: -------------------------------------------------------------------------------- 1 | AlloyEditor.Strings = {"alignCenter":"가운데","alignJustify":"양쪽 맞춤","alignLeft":"왼쪽","alignRight":"오른쪽","bold":"굵게","bulletedlist":"순서 없는 목록","cancel":"취소","horizontalrule":"가로 줄 삽입","italic":"기울임꼴","numberedlist":"순서 있는 목록","quote":"인용 단락","removeformat":"형식 지우기","strike":"취소선","subscript":"아래 첨자","superscript":"위 첨자","underline":"밑줄","formatted":"정형 문단","h1":"제목 1","h2":"제목 2","normal":"본문","blockStyles":"블록 스타일","inlineStyles":"인라인 스타일","objectStyles":"객체 스타일","styles":"스타일","cell":"셀","cellDelete":"셀 삭제","cellInsertAfter":"뒤에 셀 삽입","cellInsertBefore":"앞에 셀 삽입","cellMerge":"셀 합치기","cellMergeDown":"왼쪽 합치기","cellMergeRight":"오른쪽 합치기","cellSplitHorizontal":"수평 나누기","cellSplitVertical":"수직 나누기","column":"열","columnDelete":"열 삭제","columnInsertAfter":"오른쪽에 열 삽입","columnInsertBefore":"왼쪽에 열 삽입","deleteTable":"표 삭제","row":"행","rowDelete":"행 삭제","rowInsertAfter":"아래에 행 삽입","rowInsertBefore":"위에 행 삽입","add":"Add","ariaUpdateNoToolbar":"No toolbars are available","ariaUpdateOneToolbar":"{toolbars} toolbar is available. Press ALT+F10 to focus.","ariaUpdateManyToolbars":"{toolbars} toolbars are available. Press ALT+F10 to focus.","camera":"Insert Image from Camera","cite":"Cite","code":"Code","clearInput":"Clear Input Field","confirm":"Confirm","editLink":"Type or paste link here","image":"Insert Image","link":"Link","removeLink":"Remove link","table":"Insert Table","twitter":"Twitter","headers":"머릿칸","headersBoth":"모두","headersColumn":"첫 열","headersNone":"없음","headersRow":"첫 행"}; -------------------------------------------------------------------------------- /docs/libs/alloy-editor/lang/alloy-editor/ku.js: -------------------------------------------------------------------------------- 1 | AlloyEditor.Strings = {"alignCenter":"ناوەڕاست","alignJustify":"هاوستوونی","alignLeft":"چەپ","alignRight":"ڕاست","bold":"قەڵەو","bulletedlist":"دانان/لابردنی خاڵی لیست","cancel":"پاشگەزبوونەوە","horizontalrule":"دانانی هێلی ئاسۆیی","italic":"لار","numberedlist":"دانان/لابردنی ژمارەی لیست","quote":"بەربەستکردنی ووتەی وەرگیراو","removeformat":"لابردنی داڕشتەکە","strike":"لێدان","subscript":"ژێرنووس","superscript":"سەرنووس","underline":"ژێرهێڵ","formatted":"شێوازکراو","h1":"سەرنووسەی ١","h2":"سەرنووسەی ٢","normal":"ئاسایی","blockStyles":"شێوازی خشت","inlineStyles":"شێوازی ناوهێڵ","objectStyles":"شێوازی بەرکار","styles":"شێواز","cell":"خانه","cellDelete":"سڕینەوەی خانه","cellInsertAfter":"دانانی خانه لەپاش","cellInsertBefore":"دانانی خانه لەپێش","cellMerge":"تێکەڵکردنی خانە","cellMergeDown":"تێکەڵکردنی لەگەڵ خوارەوە","cellMergeRight":"تێکەڵکردنی لەگەڵ ڕاست","cellSplitHorizontal":"دابەشکردنی خانەی ئاسۆیی","cellSplitVertical":"دابەشکردنی خانەی ئەستونی","column":"ئەستون","columnDelete":"سڕینەوەی ئەستوون","columnInsertAfter":"دانانی ئەستوون لەپاش","columnInsertBefore":"دانانی ئەستون لەپێش","deleteTable":"سڕینەوەی خشتە","row":"ڕیز","rowDelete":"سڕینەوەی ڕیز","rowInsertAfter":"دانانی ڕیز لەپاش","rowInsertBefore":"دانانی ڕیز لەپێش","add":"Add","ariaUpdateNoToolbar":"No toolbars are available","ariaUpdateOneToolbar":"{toolbars} toolbar is available. Press ALT+F10 to focus.","ariaUpdateManyToolbars":"{toolbars} toolbars are available. Press ALT+F10 to focus.","camera":"Insert Image from Camera","cite":"Cite","code":"Code","clearInput":"Clear Input Field","confirm":"Confirm","editLink":"Type or paste link here","image":"Insert Image","link":"Link","removeLink":"Remove link","table":"Insert Table","twitter":"Twitter","headers":"سەرپەڕه","headersBoth":"هەردووك","headersColumn":"یەکەم ئەستوون","headersNone":"هیچ","headersRow":"یەکەم ڕیز"}; -------------------------------------------------------------------------------- /docs/libs/alloy-editor/lang/alloy-editor/mk.js: -------------------------------------------------------------------------------- 1 | AlloyEditor.Strings = {"alignCenter":"Center","alignJustify":"Justify","alignLeft":"Left","alignRight":"Right","bold":"Bold","bulletedlist":"Insert/Remove Bulleted List","cancel":"Cancel","horizontalrule":"Insert Horizontal Line","italic":"Italic","numberedlist":"Insert/Remove Numbered List","quote":"Block Quote","removeformat":"Remove Format","strike":"Strikethrough","subscript":"Subscript","superscript":"Superscript","underline":"Underline","formatted":"Formatted","h1":"Heading 1","h2":"Heading 2","normal":"Normal","blockStyles":"Block Styles","inlineStyles":"Inline Styles","objectStyles":"Object Styles","styles":"Styles","cell":"Cell","cellDelete":"Delete Cells","cellInsertAfter":"Insert Cell After","cellInsertBefore":"Insert Cell Before","cellMerge":"Merge Cells","cellMergeDown":"Merge Down","cellMergeRight":"Merge Right","cellSplitHorizontal":"Split Cell Horizontally","cellSplitVertical":"Split Cell Vertically","column":"Column","columnDelete":"Delete Columns","columnInsertAfter":"Insert Column After","columnInsertBefore":"Insert Column Before","deleteTable":"Delete Table","row":"Row","rowDelete":"Delete Rows","rowInsertAfter":"Insert Row After","rowInsertBefore":"Insert Row Before","add":"Add","ariaUpdateNoToolbar":"No toolbars are available","ariaUpdateOneToolbar":"{toolbars} toolbar is available. Press ALT+F10 to focus.","ariaUpdateManyToolbars":"{toolbars} toolbars are available. Press ALT+F10 to focus.","camera":"Insert Image from Camera","cite":"Cite","code":"Code","clearInput":"Clear Input Field","confirm":"Confirm","editLink":"Type or paste link here","image":"Insert Image","link":"Link","removeLink":"Remove link","table":"Insert Table","twitter":"Twitter","headers":"Headers","headersBoth":"Both","headersColumn":"First column","headersNone":"None","headersRow":"First Row"}; -------------------------------------------------------------------------------- /docs/libs/alloy-editor/lang/alloy-editor/ms.js: -------------------------------------------------------------------------------- 1 | AlloyEditor.Strings = {"alignCenter":"Tengah","alignJustify":"Jajaran Blok","alignLeft":"Kiri","alignRight":"Kanan","bold":"Bold","bulletedlist":"Senarai tidak bernombor","cancel":"Batal","horizontalrule":"Masukkan Garisan Membujur","italic":"Italic","numberedlist":"Senarai bernombor","quote":"Block Quote","removeformat":"Buang Format","strike":"Strike Through","subscript":"Subscript","superscript":"Superscript","underline":"Underline","formatted":"Telah Diformat","h1":"Heading 1","h2":"Heading 2","normal":"Normal","blockStyles":"Block Styles","inlineStyles":"Inline Styles","objectStyles":"Object Styles","styles":"Stail","cell":"Cell","cellDelete":"Buangkan Sel-sel","cellInsertAfter":"Insert Cell After","cellInsertBefore":"Insert Cell Before","cellMerge":"Cantumkan Sel-sel","cellMergeDown":"Merge Down","cellMergeRight":"Merge Right","cellSplitHorizontal":"Split Cell Horizontally","cellSplitVertical":"Split Cell Vertically","column":"Column","columnDelete":"Buangkan Lajur","columnInsertAfter":"Insert Column After","columnInsertBefore":"Insert Column Before","deleteTable":"Delete Table","row":"Row","rowDelete":"Buangkan Baris","rowInsertAfter":"Insert Row After","rowInsertBefore":"Insert Row Before","add":"Add","ariaUpdateNoToolbar":"No toolbars are available","ariaUpdateOneToolbar":"{toolbars} toolbar is available. Press ALT+F10 to focus.","ariaUpdateManyToolbars":"{toolbars} toolbars are available. Press ALT+F10 to focus.","camera":"Insert Image from Camera","cite":"Cite","code":"Code","clearInput":"Clear Input Field","confirm":"Confirm","editLink":"Type or paste link here","image":"Insert Image","link":"Link","removeLink":"Remove link","table":"Insert Table","twitter":"Twitter","headers":"Headers","headersBoth":"Both","headersColumn":"First column","headersNone":"None","headersRow":"First Row"}; -------------------------------------------------------------------------------- /docs/libs/alloy-editor/lang/alloy-editor/nl.js: -------------------------------------------------------------------------------- 1 | AlloyEditor.Strings = {"alignCenter":"Centreren","alignJustify":"Uitvullen","alignLeft":"Links","alignRight":"Rechts","bold":"Vet","bulletedlist":"Opsomming invoegen","cancel":"Annuleren","horizontalrule":"Horizontale lijn invoegen","italic":"Cursief","numberedlist":"Genummerde lijst invoegen","quote":"Citaatblok","removeformat":"Opmaak verwijderen","strike":"Doorhalen","subscript":"Subscript","superscript":"Superscript","underline":"Onderstrepen","formatted":"Met opmaak","h1":"Kop 1","h2":"Kop 2","normal":"Normaal","blockStyles":"Blok stijlen","inlineStyles":"Inline stijlen","objectStyles":"Object stijlen","styles":"Stijl","cell":"Cel","cellDelete":"Cellen verwijderen","cellInsertAfter":"Voeg cel in na","cellInsertBefore":"Voeg cel in voor","cellMerge":"Cellen samenvoegen","cellMergeDown":"Voeg samen naar beneden","cellMergeRight":"Voeg samen naar rechts","cellSplitHorizontal":"Splits cel horizontaal","cellSplitVertical":"Splits cel vertikaal","column":"Kolom","columnDelete":"Kolommen verwijderen","columnInsertAfter":"Voeg kolom in na","columnInsertBefore":"Voeg kolom in voor","deleteTable":"Tabel verwijderen","row":"Rij","rowDelete":"Rijen verwijderen","rowInsertAfter":"Voeg rij in na","rowInsertBefore":"Voeg rij in voor","add":"Add","ariaUpdateNoToolbar":"No toolbars are available","ariaUpdateOneToolbar":"{toolbars} toolbar is available. Press ALT+F10 to focus.","ariaUpdateManyToolbars":"{toolbars} toolbars are available. Press ALT+F10 to focus.","camera":"Insert Image from Camera","cite":"Cite","code":"Code","clearInput":"Clear Input Field","confirm":"Confirm","editLink":"Type or paste link here","image":"Insert Image","link":"Link","removeLink":"Remove link","table":"Insert Table","twitter":"Twitter","headers":"Koppen","headersBoth":"Beide","headersColumn":"Eerste kolom","headersNone":"Geen","headersRow":"Eerste rij"}; -------------------------------------------------------------------------------- /docs/libs/alloy-editor/lang/alloy-editor/si.js: -------------------------------------------------------------------------------- 1 | AlloyEditor.Strings = {"alignCenter":"මධ්‍ය","alignJustify":"Justify","alignLeft":"වම","alignRight":"දකුණ","bold":"තද අකුරින් ලියනලද","bulletedlist":"ඇතුලත් / ඉවත් කිරීම ලඉස්තුව","cancel":"අවලංගු කිරීම","horizontalrule":"තිරස් රේඛාවක් ඇතුලත් කරන්න","italic":"බැධීඅකුරින් ලියන ලද","numberedlist":"ඇතුලත් / ඉවත් කිරීම අන්න්කිත ලඉස්තුව","quote":"උද්ධෘත කොටස","removeformat":"සැකසීම වෙනස් කරන්න","strike":"Strikethrough","subscript":"Subscript","superscript":"Superscript","underline":"යටින් ඉරි අදින ලද","formatted":"ආකෘතියන්","h1":"ශීර්ෂය 1","h2":"ශීර්ෂය 2","normal":"සාමාන්‍ය","blockStyles":"Block Styles","inlineStyles":"Inline Styles","objectStyles":"Object Styles","styles":"විලාසය","cell":"කොටුව","cellDelete":"කොටුව මැකීම","cellInsertAfter":"පසුව කොටුවක් ඇතුලත් ","cellInsertBefore":"පෙර කොටුවක් ඇතුල්කිරිම","cellMerge":"කොටු එකට යාකිරිම","cellMergeDown":"පහලට ","cellMergeRight":"දකුණට ","cellSplitHorizontal":"තිරස්ව කොටු පැතිරීම","cellSplitVertical":"සිරස්ව කොටු පැතිරීම","column":"Column","columnDelete":"Delete Columns","columnInsertAfter":"Insert Column After","columnInsertBefore":"Insert Column Before","deleteTable":"වගුව මකන්න","row":"Row","rowDelete":"Delete Rows","rowInsertAfter":"Insert Row After","rowInsertBefore":"Insert Row Before","add":"Add","ariaUpdateNoToolbar":"No toolbars are available","ariaUpdateOneToolbar":"{toolbars} toolbar is available. Press ALT+F10 to focus.","ariaUpdateManyToolbars":"{toolbars} toolbars are available. Press ALT+F10 to focus.","camera":"Insert Image from Camera","cite":"Cite","code":"Code","clearInput":"Clear Input Field","confirm":"Confirm","editLink":"Type or paste link here","image":"Insert Image","link":"Link","removeLink":"Remove link","table":"Insert Table","twitter":"Twitter","headers":"ශීර්ෂක","headersBoth":"දෙකම","headersColumn":"පළමූ සිරස් තීරුව","headersNone":"කිසිවක්ම නොවේ","headersRow":"පළමූ පේළිය"}; -------------------------------------------------------------------------------- /docs/libs/alloy-editor/lang/alloy-editor/sl.js: -------------------------------------------------------------------------------- 1 | AlloyEditor.Strings = {"alignCenter":"Sredinsko","alignJustify":"Obojestranska poravnava","alignLeft":"Levo","alignRight":"Desno","bold":"Krepko","bulletedlist":"Označen seznam","cancel":"Prekliči","horizontalrule":"Vstavi vodoravno črto","italic":"Ležeče","numberedlist":"Oštevilčen seznam","quote":"Citat","removeformat":"Odstrani oblikovanje","strike":"Prečrtano","subscript":"Podpisano","superscript":"Nadpisano","underline":"Podčrtano","formatted":"Oblikovan","h1":"Naslov 1","h2":"Naslov 2","normal":"Navaden","blockStyles":"Slogi odstavkov","inlineStyles":"Slogi besedila","objectStyles":"Slogi objektov","styles":"Slog","cell":"Celica","cellDelete":"Izbriši celice","cellInsertAfter":"Vstavi celico za","cellInsertBefore":"Vstavi celico pred","cellMerge":"Združi celice","cellMergeDown":"Druži navzdol","cellMergeRight":"Združi desno","cellSplitHorizontal":"Razdeli celico vodoravno","cellSplitVertical":"Razdeli celico navpično","column":"Stolpec","columnDelete":"Izbriši stolpce","columnInsertAfter":"Vstavi stolpec za","columnInsertBefore":"Vstavi stolpec pred","deleteTable":"Izbriši tabelo","row":"Vrstica","rowDelete":"Izbriši vrstice","rowInsertAfter":"Vstavi vrstico za","rowInsertBefore":"Vstavi vrstico pred","add":"Add","ariaUpdateNoToolbar":"No toolbars are available","ariaUpdateOneToolbar":"{toolbars} toolbar is available. Press ALT+F10 to focus.","ariaUpdateManyToolbars":"{toolbars} toolbars are available. Press ALT+F10 to focus.","camera":"Insert Image from Camera","cite":"Cite","code":"Code","clearInput":"Clear Input Field","confirm":"Confirm","editLink":"Type or paste link here","image":"Insert Image","link":"Link","removeLink":"Remove link","table":"Insert Table","twitter":"Twitter","headers":"Glave","headersBoth":"Oboje","headersColumn":"Prvi stolpec","headersNone":"Brez","headersRow":"Prva vrstica"}; -------------------------------------------------------------------------------- /docs/libs/alloy-editor/lang/alloy-editor/sq.js: -------------------------------------------------------------------------------- 1 | AlloyEditor.Strings = {"alignCenter":"Qendër","alignJustify":"Zgjero","alignLeft":"Majtas","alignRight":"Djathtas","bold":"Trash","bulletedlist":"Vendos/Largo Listën me Pika","cancel":"Anulo","horizontalrule":"Vendos Vijë Horizontale","italic":"Pjerrët","numberedlist":"Vendos/Largo Listën me Numra","quote":"Citatet","removeformat":"Largo Formatin","strike":"Nëpërmes","subscript":"Nën-skriptë","superscript":"Super-skriptë","underline":"Nënvijëzuar","formatted":"Formatuar","h1":"Titulli 1","h2":"Titulli 2","normal":"Normal","blockStyles":"Stilet e Bllokut","inlineStyles":"Stili i Brendshëm","objectStyles":"Stilet e Objektit","styles":"Stil","cell":"Qeli","cellDelete":"Gris Qelitë","cellInsertAfter":"Shto Qeli Prapa","cellInsertBefore":"Shto Qeli Para","cellMerge":"Bashko Qelitë","cellMergeDown":"Bashko Poshtë","cellMergeRight":"Bashko Djathtas","cellSplitHorizontal":"Ndaj Qelinë Horizontalisht","cellSplitVertical":"Ndaj Qelinë Vertikalisht","column":"Kolona","columnDelete":"Gris Kolonat","columnInsertAfter":"Vendos Kolonë Pas","columnInsertBefore":"Vendos Kolonë Para","deleteTable":"Gris Tabelën","row":"Rreshti","rowDelete":"Gris Rreshtat","rowInsertAfter":"Shto Rresht Prapa","rowInsertBefore":"Shto Rresht Para","add":"Add","ariaUpdateNoToolbar":"No toolbars are available","ariaUpdateOneToolbar":"{toolbars} toolbar is available. Press ALT+F10 to focus.","ariaUpdateManyToolbars":"{toolbars} toolbars are available. Press ALT+F10 to focus.","camera":"Insert Image from Camera","cite":"Cite","code":"Code","clearInput":"Clear Input Field","confirm":"Confirm","editLink":"Type or paste link here","image":"Insert Image","link":"Link","removeLink":"Remove link","table":"Insert Table","twitter":"Twitter","headers":"Kokat","headersBoth":"Së bashku","headersColumn":"Kolona e parë","headersNone":"Asnjë","headersRow":"Rreshti i Parë"}; -------------------------------------------------------------------------------- /docs/libs/alloy-editor/lang/alloy-editor/sr-latn.js: -------------------------------------------------------------------------------- 1 | AlloyEditor.Strings = {"alignCenter":"Sredina","alignJustify":"Obostrano ravnanje","alignLeft":"Levo","alignRight":"Desno","bold":"Podebljano","bulletedlist":"Nenabrojiva lista","cancel":"Otkaži","horizontalrule":"Unesi horizontalnu liniju","italic":"Kurziv","numberedlist":"Nabrojiva lista","quote":"Block Quote","removeformat":"Ukloni formatiranje","strike":"Precrtano","subscript":"Indeks","superscript":"Stepen","underline":"Podvučeno","formatted":"Formatirano","h1":"Naslov 1","h2":"Naslov 2","normal":"Normal","blockStyles":"Block Styles","inlineStyles":"Inline Styles","objectStyles":"Object Styles","styles":"Stil","cell":"Cell","cellDelete":"Obriši ćelije","cellInsertAfter":"Insert Cell After","cellInsertBefore":"Insert Cell Before","cellMerge":"Spoj celije","cellMergeDown":"Merge Down","cellMergeRight":"Merge Right","cellSplitHorizontal":"Split Cell Horizontally","cellSplitVertical":"Split Cell Vertically","column":"Column","columnDelete":"Obriši kolone","columnInsertAfter":"Insert Column After","columnInsertBefore":"Insert Column Before","deleteTable":"Izbriši tabelu","row":"Row","rowDelete":"Obriši redove","rowInsertAfter":"Insert Row After","rowInsertBefore":"Insert Row Before","add":"Add","ariaUpdateNoToolbar":"No toolbars are available","ariaUpdateOneToolbar":"{toolbars} toolbar is available. Press ALT+F10 to focus.","ariaUpdateManyToolbars":"{toolbars} toolbars are available. Press ALT+F10 to focus.","camera":"Insert Image from Camera","cite":"Cite","code":"Code","clearInput":"Clear Input Field","confirm":"Confirm","editLink":"Type or paste link here","image":"Insert Image","link":"Link","removeLink":"Remove link","table":"Insert Table","twitter":"Twitter","headers":"Zaglavlja","headersBoth":"Oba","headersColumn":"Prva kolona","headersNone":"None","headersRow":"Prvi red"}; -------------------------------------------------------------------------------- /docs/libs/alloy-editor/lang/alloy-editor/sr.js: -------------------------------------------------------------------------------- 1 | AlloyEditor.Strings = {"alignCenter":"Средина","alignJustify":"Обострано равнање","alignLeft":"Лево","alignRight":"Десно","bold":"Подебљано","bulletedlist":"Ненабројива листа","cancel":"Oткажи","horizontalrule":"Унеси хоризонталну линију","italic":"Курзив","numberedlist":"Набројиву листу","quote":"Block Quote","removeformat":"Уклони форматирање","strike":"Прецртано","subscript":"Индекс","superscript":"Степен","underline":"Подвучено","formatted":"Formatirano","h1":"Heading 1","h2":"Heading 2","normal":"Normal","blockStyles":"Block Styles","inlineStyles":"Inline Styles","objectStyles":"Object Styles","styles":"Стил","cell":"Cell","cellDelete":"Обриши ћелије","cellInsertAfter":"Insert Cell After","cellInsertBefore":"Insert Cell Before","cellMerge":"Спој ћелије","cellMergeDown":"Merge Down","cellMergeRight":"Merge Right","cellSplitHorizontal":"Split Cell Horizontally","cellSplitVertical":"Split Cell Vertically","column":"Column","columnDelete":"Обриши колоне","columnInsertAfter":"Insert Column After","columnInsertBefore":"Insert Column Before","deleteTable":"Обриши таблу","row":"Row","rowDelete":"Обриши редове","rowInsertAfter":"Insert Row After","rowInsertBefore":"Insert Row Before","add":"Add","ariaUpdateNoToolbar":"No toolbars are available","ariaUpdateOneToolbar":"{toolbars} toolbar is available. Press ALT+F10 to focus.","ariaUpdateManyToolbars":"{toolbars} toolbars are available. Press ALT+F10 to focus.","camera":"Insert Image from Camera","cite":"Cite","code":"Code","clearInput":"Clear Input Field","confirm":"Confirm","editLink":"Type or paste link here","image":"Insert Image","link":"Link","removeLink":"Remove link","table":"Insert Table","twitter":"Twitter","headers":"Поглавља","headersBoth":"Оба","headersColumn":"Прва колона","headersNone":"None","headersRow":"Први ред"}; -------------------------------------------------------------------------------- /docs/libs/alloy-editor/lang/alloy-editor/sv.js: -------------------------------------------------------------------------------- 1 | AlloyEditor.Strings = {"alignCenter":"Centrerad","alignJustify":"Justera till marginaler","alignLeft":"Vänster","alignRight":"Höger","bold":"Fet","bulletedlist":"Punktlista","cancel":"Avbryt","horizontalrule":"Infoga horisontal linje","italic":"Kursiv","numberedlist":"Numrerad lista","quote":"Blockcitat","removeformat":"Radera formatering","strike":"Genomstruken","subscript":"Nedsänkta tecken","superscript":"Upphöjda tecken","underline":"Understruken","formatted":"Formaterad","h1":"Rubrik 1","h2":"Rubrik 2","normal":"Normal","blockStyles":"Blockstil","inlineStyles":"Inbäddad stil","objectStyles":"Objektets stil","styles":"Anpassad stil","cell":"Cell","cellDelete":"Radera celler","cellInsertAfter":"Lägg till cell efter","cellInsertBefore":"Lägg till cell före","cellMerge":"Sammanfoga celler","cellMergeDown":"Sammanfoga ner","cellMergeRight":"Sammanfoga höger","cellSplitHorizontal":"Dela cell horisontellt","cellSplitVertical":"Dela cell vertikalt","column":"Kolumn","columnDelete":"Radera kolumn","columnInsertAfter":"Lägg till kolumn efter","columnInsertBefore":"Lägg till kolumn före","deleteTable":"Radera tabell","row":"Rad","rowDelete":"Radera rad","rowInsertAfter":"Lägg till rad efter","rowInsertBefore":"Lägg till rad före","add":"Add","ariaUpdateNoToolbar":"No toolbars are available","ariaUpdateOneToolbar":"{toolbars} toolbar is available. Press ALT+F10 to focus.","ariaUpdateManyToolbars":"{toolbars} toolbars are available. Press ALT+F10 to focus.","camera":"Insert Image from Camera","cite":"Cite","code":"Code","clearInput":"Clear Input Field","confirm":"Confirm","editLink":"Type or paste link here","image":"Insert Image","link":"Link","removeLink":"Remove link","table":"Insert Table","twitter":"Twitter","headers":"Rubriker","headersBoth":"Båda","headersColumn":"Första kolumnen","headersNone":"Ingen","headersRow":"Första raden"}; -------------------------------------------------------------------------------- /docs/libs/alloy-editor/lang/alloy-editor/th.js: -------------------------------------------------------------------------------- 1 | AlloyEditor.Strings = {"alignCenter":"กึ่งกลาง","alignJustify":"நியாயப்படுத்தவும்","alignLeft":"ชิดซ้าย","alignRight":"ชิดขวา","bold":"ตัวหนา","bulletedlist":"ลำดับรายการแบบสัญลักษณ์","cancel":"ยกเลิก","horizontalrule":"แทรกเส้นคั่นบรรทัด","italic":"ตัวเอียง","numberedlist":"ลำดับรายการแบบตัวเลข","quote":"Block Quote","removeformat":"ล้างรูปแบบ","strike":"ตัวขีดเส้นทับ","subscript":"ตัวห้อย","superscript":"ตัวยก","underline":"ตัวขีดเส้นใต้","formatted":"Formatted","h1":"Heading 1","h2":"Heading 2","normal":"Normal","blockStyles":"Block Styles","inlineStyles":"Inline Styles","objectStyles":"Object Styles","styles":"ลักษณะ","cell":"ช่องตาราง","cellDelete":"ลบช่อง","cellInsertAfter":"Insert Cell After","cellInsertBefore":"Insert Cell Before","cellMerge":"ผสานช่อง","cellMergeDown":"Merge Down","cellMergeRight":"Merge Right","cellSplitHorizontal":"Split Cell Horizontally","cellSplitVertical":"Split Cell Vertically","column":"คอลัมน์","columnDelete":"ลบสดมน์","columnInsertAfter":"Insert Column After","columnInsertBefore":"Insert Column Before","deleteTable":"ลบตาราง","row":"แถว","rowDelete":"ลบแถว","rowInsertAfter":"Insert Row After","rowInsertBefore":"Insert Row Before","add":"Add","ariaUpdateNoToolbar":"No toolbars are available","ariaUpdateOneToolbar":"{toolbars} toolbar is available. Press ALT+F10 to focus.","ariaUpdateManyToolbars":"{toolbars} toolbars are available. Press ALT+F10 to focus.","camera":"Insert Image from Camera","cite":"Cite","code":"Code","clearInput":"Clear Input Field","confirm":"Confirm","editLink":"Type or paste link here","image":"Insert Image","link":"Link","removeLink":"Remove link","table":"Insert Table","twitter":"Twitter","headers":"ส่วนหัว","headersBoth":"ทั้งสองอย่าง","headersColumn":"คอลัมน์แรก","headersNone":"None","headersRow":"แถวแรก"}; -------------------------------------------------------------------------------- /docs/libs/alloy-editor/lang/alloy-editor/tr.js: -------------------------------------------------------------------------------- 1 | AlloyEditor.Strings = {"alignCenter":"Ortala","alignJustify":"İki Kenara Yaslanmış","alignLeft":"Sol","alignRight":"Sağ","bold":"Kalın","bulletedlist":"Simgeli Liste","cancel":"İptal","horizontalrule":"Yatay Satır Ekle","italic":"İtalik","numberedlist":"Numaralı Liste","quote":"Blok Oluştur","removeformat":"Biçimi Kaldır","strike":"Üstü Çizgili","subscript":"Alt Simge","superscript":"Üst Simge","underline":"Altı Çizgili","formatted":"Biçimli","h1":"Başlık 1","h2":"Başlık 2","normal":"Normal","blockStyles":"Blok Stilleri","inlineStyles":"Inline Stilleri","objectStyles":"Nesne Stilleri","styles":"Biçem","cell":"Hücre","cellDelete":"Hücre Sil","cellInsertAfter":"Hücre Ekle - Sonra","cellInsertBefore":"Hücre Ekle - Önce","cellMerge":"Hücreleri Birleştir","cellMergeDown":"Birleştir - Aşağıdaki İle ","cellMergeRight":"Birleştir - Sağdaki İle ","cellSplitHorizontal":"Hücreyi Yatay Böl","cellSplitVertical":"Hücreyi Dikey Böl","column":"Sütun","columnDelete":"Sütun Sil","columnInsertAfter":"Kolon Ekle - Sonra","columnInsertBefore":"Kolon Ekle - Önce","deleteTable":"Tabloyu Sil","row":"Satır","rowDelete":"Satır Sil","rowInsertAfter":"Satır Ekle - Sonra","rowInsertBefore":"Satır Ekle - Önce","add":"Add","ariaUpdateNoToolbar":"No toolbars are available","ariaUpdateOneToolbar":"{toolbars} toolbar is available. Press ALT+F10 to focus.","ariaUpdateManyToolbars":"{toolbars} toolbars are available. Press ALT+F10 to focus.","camera":"Insert Image from Camera","cite":"Cite","code":"Code","clearInput":"Clear Input Field","confirm":"Confirm","editLink":"Type or paste link here","image":"Insert Image","link":"Link","removeLink":"Remove link","table":"Insert Table","twitter":"Twitter","headers":"Başlıklar","headersBoth":"Her İkisi","headersColumn":"İlk Sütun","headersNone":"Yok","headersRow":"İlk Satır"}; -------------------------------------------------------------------------------- /docs/libs/alloy-editor/lang/alloy-editor/vi.js: -------------------------------------------------------------------------------- 1 | AlloyEditor.Strings = {"alignCenter":"Giữa","alignJustify":"Sắp chữ","alignLeft":"Trái","alignRight":"Phải","bold":"Đậm","bulletedlist":"Chèn/Xoá Danh sách không thứ tự","cancel":"Bỏ qua","horizontalrule":"Chèn đường phân cách ngang","italic":"Nghiêng","numberedlist":"Chèn/Xoá Danh sách có thứ tự","quote":"Khối trích dẫn","removeformat":"Xoá định dạng","strike":"Gạch xuyên ngang","subscript":"Chỉ số dưới","superscript":"Chỉ số trên","underline":"Gạch chân","formatted":"Đã thiết lập","h1":"Heading 1","h2":"Heading 2","normal":"Bình thường (P)","blockStyles":"Kiểu khối","inlineStyles":"Kiểu trực tiếp","objectStyles":"Kiểu đối tượng","styles":"Kiểu","cell":"Ô","cellDelete":"Xoá ô","cellInsertAfter":"Chèn ô Phía sau","cellInsertBefore":"Chèn ô Phía trước","cellMerge":"Kết hợp ô","cellMergeDown":"Kết hợp xuống dưới","cellMergeRight":"Kết hợp sang phải","cellSplitHorizontal":"Phân tách ô theo chiều ngang","cellSplitVertical":"Phân tách ô theo chiều dọc","column":"Cột","columnDelete":"Xoá cột","columnInsertAfter":"Chèn cột phía sau","columnInsertBefore":"Chèn cột phía trước","deleteTable":"Xóa bảng","row":"Hàng","rowDelete":"Xoá hàng","rowInsertAfter":"Chèn hàng phía sau","rowInsertBefore":"Chèn hàng phía trước","add":"Add","ariaUpdateNoToolbar":"No toolbars are available","ariaUpdateOneToolbar":"{toolbars} toolbar is available. Press ALT+F10 to focus.","ariaUpdateManyToolbars":"{toolbars} toolbars are available. Press ALT+F10 to focus.","camera":"Insert Image from Camera","cite":"Cite","code":"Code","clearInput":"Clear Input Field","confirm":"Confirm","editLink":"Type or paste link here","image":"Insert Image","link":"Link","removeLink":"Remove link","table":"Insert Table","twitter":"Twitter","headers":"Đầu đề","headersBoth":"Cả hai","headersColumn":"Cột đầu tiên","headersNone":"Không có","headersRow":"Hàng đầu tiên"}; -------------------------------------------------------------------------------- /docs/libs/alloy-editor/lang/alloy-editor/zh-cn.js: -------------------------------------------------------------------------------- 1 | AlloyEditor.Strings = {"alignCenter":"居中","alignJustify":"两端对齐","alignLeft":"左对齐","alignRight":"右对齐","bold":"加粗","bulletedlist":"项目列表","cancel":"取消","horizontalrule":"插入水平线","italic":"倾斜","numberedlist":"编号列表","quote":"块引用","removeformat":"清除格式","strike":"删除线","subscript":"下标","superscript":"上标","underline":"下划线","formatted":"已编排格式","h1":"标题 1","h2":"标题 2","normal":"普通","blockStyles":"块级元素样式","inlineStyles":"内联元素样式","objectStyles":"对象元素样式","styles":"样式","cell":"单元格","cellDelete":"删除单元格","cellInsertAfter":"在右侧插入单元格","cellInsertBefore":"在左侧插入单元格","cellMerge":"合并单元格","cellMergeDown":"向下合并单元格","cellMergeRight":"向右合并单元格","cellSplitHorizontal":"水平拆分单元格","cellSplitVertical":"垂直拆分单元格","column":"列","columnDelete":"删除列","columnInsertAfter":"在右侧插入列","columnInsertBefore":"在左侧插入列","deleteTable":"删除表格","row":"行","rowDelete":"删除行","rowInsertAfter":"在下方插入行","rowInsertBefore":"在上方插入行","add":"Add","ariaUpdateNoToolbar":"No toolbars are available","ariaUpdateOneToolbar":"{toolbars} toolbar is available. Press ALT+F10 to focus.","ariaUpdateManyToolbars":"{toolbars} toolbars are available. Press ALT+F10 to focus.","camera":"Insert Image from Camera","cite":"Cite","code":"Code","clearInput":"Clear Input Field","confirm":"Confirm","editLink":"Type or paste link here","image":"Insert Image","link":"Link","removeLink":"Remove link","table":"Insert Table","twitter":"Twitter","headers":"标题单元格","headersBoth":"第一列和第一行","headersColumn":"第一列","headersNone":"无","headersRow":"第一行"}; -------------------------------------------------------------------------------- /docs/libs/alloy-editor/lang/alloy-editor/zh.js: -------------------------------------------------------------------------------- 1 | AlloyEditor.Strings = {"alignCenter":"置中對齊","alignJustify":"左右對齊","alignLeft":"靠左對齊","alignRight":"靠右對齊","bold":"粗體","bulletedlist":"插入/移除項目符號清單","cancel":"取消","horizontalrule":"插入水平線","italic":"斜體","numberedlist":"插入/移除編號清單清單","quote":"引用段落","removeformat":"移除格式","strike":"刪除線","subscript":"下標","superscript":"上標","underline":"底線","formatted":"格式設定","h1":"標題 1","h2":"標題 2","normal":"標準","blockStyles":"區塊樣式","inlineStyles":"內嵌樣式","objectStyles":"物件樣式","styles":"樣式","cell":"儲存格","cellDelete":"刪除儲存格","cellInsertAfter":"後方插入儲存格","cellInsertBefore":"前方插入儲存格","cellMerge":"合併儲存格","cellMergeDown":"向下合併","cellMergeRight":"向右合併","cellSplitHorizontal":"水平分割儲存格","cellSplitVertical":"垂直分割儲存格","column":"行","columnDelete":"刪除行","columnInsertAfter":"右方插入行","columnInsertBefore":"左方插入行","deleteTable":"刪除表格","row":"列","rowDelete":"刪除列","rowInsertAfter":"下方插入列","rowInsertBefore":"上方插入列","add":"Add","ariaUpdateNoToolbar":"No toolbars are available","ariaUpdateOneToolbar":"{toolbars} toolbar is available. Press ALT+F10 to focus.","ariaUpdateManyToolbars":"{toolbars} toolbars are available. Press ALT+F10 to focus.","camera":"Insert Image from Camera","cite":"Cite","code":"Code","clearInput":"Clear Input Field","confirm":"Confirm","editLink":"Type or paste link here","image":"Insert Image","link":"Link","removeLink":"Remove link","table":"Insert Table","twitter":"Twitter","headers":"頁首","headersBoth":"同時","headersColumn":"第一行","headersNone":"無","headersRow":"第一列"}; -------------------------------------------------------------------------------- /docs/libs/alloy-editor/plugins/dialog/dialogDefinition.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved. 3 | For licensing, see LICENSE.md or http://ckeditor.com/license 4 | */ 5 | -------------------------------------------------------------------------------- /docs/libs/alloy-editor/plugins/icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/libs/alloy-editor/plugins/icons.png -------------------------------------------------------------------------------- /docs/libs/alloy-editor/plugins/icons_hidpi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/libs/alloy-editor/plugins/icons_hidpi.png -------------------------------------------------------------------------------- /docs/libs/alloy-editor/skins/moono/icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/libs/alloy-editor/skins/moono/icons.png -------------------------------------------------------------------------------- /docs/libs/alloy-editor/skins/moono/icons_hidpi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/libs/alloy-editor/skins/moono/icons_hidpi.png -------------------------------------------------------------------------------- /docs/libs/alloy-editor/skins/moono/images/arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/libs/alloy-editor/skins/moono/images/arrow.png -------------------------------------------------------------------------------- /docs/libs/alloy-editor/skins/moono/images/close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/libs/alloy-editor/skins/moono/images/close.png -------------------------------------------------------------------------------- /docs/libs/alloy-editor/skins/moono/images/hidpi/close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/libs/alloy-editor/skins/moono/images/hidpi/close.png -------------------------------------------------------------------------------- /docs/libs/alloy-editor/skins/moono/images/hidpi/lock-open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/libs/alloy-editor/skins/moono/images/hidpi/lock-open.png -------------------------------------------------------------------------------- /docs/libs/alloy-editor/skins/moono/images/hidpi/lock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/libs/alloy-editor/skins/moono/images/hidpi/lock.png -------------------------------------------------------------------------------- /docs/libs/alloy-editor/skins/moono/images/hidpi/refresh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/libs/alloy-editor/skins/moono/images/hidpi/refresh.png -------------------------------------------------------------------------------- /docs/libs/alloy-editor/skins/moono/images/lock-open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/libs/alloy-editor/skins/moono/images/lock-open.png -------------------------------------------------------------------------------- /docs/libs/alloy-editor/skins/moono/images/lock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/libs/alloy-editor/skins/moono/images/lock.png -------------------------------------------------------------------------------- /docs/libs/alloy-editor/skins/moono/images/refresh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/libs/alloy-editor/skins/moono/images/refresh.png -------------------------------------------------------------------------------- /docs/libs/alloy-editor/skins/moono/images/spinner.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/docs/libs/alloy-editor/skins/moono/images/spinner.gif -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "packages": ["marketplace/*"], 3 | "version": "0.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /marketplace/Readme.md: -------------------------------------------------------------------------------- 1 | # Marketplace extensions 2 | 3 | These extensions are production quality and ready to use out of the box. They used to be published to the public Contentful marketplace. 4 | 5 | ## Development 6 | 7 | We do not accept extensions for our marketplace anymore. Consider [writing an app](https://www.contentful.com/developers/docs/extensibility/app-framework/tutorial/) instead and [reach out to us](https://www.contentful.com/contact/become-partner/) to get your app in the marketplace. 8 | -------------------------------------------------------------------------------- /marketplace/gatsby-preview/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@babel/preset-env", 5 | { 6 | "useBuiltIns": false, 7 | } 8 | ], 9 | [ 10 | "@babel/preset-react", 11 | { 12 | "useBuiltIns": true 13 | } 14 | ] 15 | ], 16 | "plugins": [ 17 | [ 18 | "@babel/plugin-proposal-class-properties", 19 | { 20 | "loose": true 21 | } 22 | ], 23 | [ 24 | "@babel/plugin-transform-runtime", 25 | { 26 | "corejs": false, 27 | "helpers": false, 28 | "regenerator": true 29 | } 30 | ] 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /marketplace/gatsby-preview/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: [ 3 | require.resolve('@contentful/eslint-config-extension'), 4 | require.resolve('@contentful/eslint-config-extension/jest'), 5 | require.resolve('@contentful/eslint-config-extension/jsx-a11y'), 6 | require.resolve('@contentful/eslint-config-extension/react') 7 | ], 8 | globals: { 9 | module: true 10 | } 11 | }; 12 | -------------------------------------------------------------------------------- /marketplace/gatsby-preview/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # dotenv environment variables file 9 | .env 10 | .contentfulrc.json 11 | 12 | # parcel-bundler cache 13 | .cache 14 | 15 | # Dependency directories 16 | node_modules/ 17 | 18 | # Build 19 | build/** 20 | !/build/index.html -------------------------------------------------------------------------------- /marketplace/gatsby-preview/assets/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/marketplace/gatsby-preview/assets/demo.gif -------------------------------------------------------------------------------- /marketplace/gatsby-preview/assets/demo.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/marketplace/gatsby-preview/assets/demo.mp4 -------------------------------------------------------------------------------- /marketplace/gatsby-preview/assets/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/marketplace/gatsby-preview/assets/screenshot.png -------------------------------------------------------------------------------- /marketplace/gatsby-preview/extension.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "gatsby-preview", 3 | "name": "Gatsby Preview", 4 | "srcdoc": "./build/index.html", 5 | "parameters": { 6 | "installation": [ 7 | { 8 | "id": "previewUrl", 9 | "type": "Symbol", 10 | "name": "The URL of your Gatsby Cloud site", 11 | "required": true 12 | }, 13 | { 14 | "id": "webhookUrl", 15 | "type": "Symbol", 16 | "name": "The URL of the webhook to rebuild your Gatsby Cloud site" 17 | }, 18 | { 19 | "id": "authToken", 20 | "type": "Symbol", 21 | "name": "Optional Authentication token for private Gatsby Cloud sites" 22 | } 23 | ] 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /marketplace/gatsby-preview/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gatsby-preview", 3 | "version": "1.0.0", 4 | "private": true, 5 | "devDependencies": { 6 | "@babel/core": "7.3.4", 7 | "@babel/plugin-proposal-class-properties": "7.3.4", 8 | "@babel/plugin-transform-runtime": "7.3.4", 9 | "@babel/preset-env": "7.3.4", 10 | "@babel/preset-react": "7.0.0", 11 | "@contentful/contentful-extension-scripts": "^0.14.0", 12 | "@testing-library/react": "^8.0.7", 13 | "contentful-cli": "^0.36.0" 14 | }, 15 | "dependencies": { 16 | "@contentful/forma-36-fcss": "^0.0.27", 17 | "@contentful/forma-36-react-components": "^3.15.14", 18 | "@contentful/forma-36-tokens": "^0.4.1", 19 | "@gatsby-cloud-pkg/gatsby-cms-extension-base": "0.0.16", 20 | "contentful-ui-extensions-sdk": "^3.10.6", 21 | "emotion": "10.0.14", 22 | "prop-types": "15.7.2", 23 | "react": "16.8.6", 24 | "react-dom": "16.8.6" 25 | }, 26 | "scripts": { 27 | "start": "contentful-extension-scripts start --serve-only", 28 | "build": "contentful-extension-scripts build", 29 | "deploy": "npm run build && contentful extension update --force", 30 | "login": "contentful login", 31 | "configure": "contentful space use && contentful space environment use", 32 | "logout": "contentful logout", 33 | "help": "contentful-extension-scripts help", 34 | "test:watch": "TZ=UTC contentful-extension-scripts test --env=jsdom --watch", 35 | "test": "TZ=UTC contentful-extension-scripts test --env=jsdom" 36 | }, 37 | "browserslist": [ 38 | "last 5 Chrome version", 39 | "> 1%", 40 | "not ie <= 11" 41 | ] 42 | } 43 | -------------------------------------------------------------------------------- /marketplace/gatsby-preview/src/GatsbyIcon.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | export default function GatsbyIcon() { 4 | return ( 5 | 6 | 10 | 14 | 15 | ); 16 | } 17 | -------------------------------------------------------------------------------- /marketplace/gatsby-preview/src/index.css: -------------------------------------------------------------------------------- 1 | html, 2 | body { 3 | margin: 0; 4 | padding: 0; 5 | border: 0; 6 | font-size: 100%; 7 | font: inherit; 8 | vertical-align: baseline; 9 | } 10 | 11 | .preview-button { 12 | height: 2.5rem; 13 | padding: 0 !important; 14 | font-size: 0.875rem !important; 15 | font-weight: 400 !important; 16 | font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol!important; 17 | } 18 | .preview-button:focus { 19 | outline: 0; 20 | border: 1px solid #f1defa; 21 | } 22 | .powered-by { 23 | margin-bottom: 5%; 24 | } 25 | .powered-by p { 26 | font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol!important; 27 | margin-bottom: inherit; 28 | } 29 | .flexcontainer { 30 | display: flex; 31 | flex-direction: column; 32 | } 33 | -------------------------------------------------------------------------------- /marketplace/gatsby-preview/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /marketplace/gatsby-preview/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { render } from 'react-dom'; 3 | 4 | import { init, locations } from 'contentful-ui-extensions-sdk'; 5 | 6 | import Sidebar from './Sidebar'; 7 | import AppConfig from './AppConfig'; 8 | 9 | import '@contentful/forma-36-react-components/dist/styles.css'; 10 | import '@contentful/forma-36-fcss/dist/styles.css'; 11 | import './index.css'; 12 | 13 | init(sdk => { 14 | const root = document.getElementById('root'); 15 | 16 | if (sdk.location.is(locations.LOCATION_ENTRY_SIDEBAR)) { 17 | render(, root); 18 | } else if (sdk.location.is(locations.LOCATION_APP_CONFIG)) { 19 | render(, root); 20 | } 21 | }); 22 | -------------------------------------------------------------------------------- /marketplace/gatsby-preview/src/styles.js: -------------------------------------------------------------------------------- 1 | import { css } from 'emotion'; 2 | import tokens from '@contentful/forma-36-tokens'; 3 | 4 | export default { 5 | body: css({ 6 | height: 'auto', 7 | minHeight: '65vh', 8 | margin: '0 auto', 9 | marginTop: tokens.spacingXl, 10 | padding: `${tokens.spacingXl} ${tokens.spacing2Xl}`, 11 | maxWidth: tokens.contentWidthText, 12 | backgroundColor: tokens.colorWhite, 13 | zIndex: '2', 14 | boxShadow: '0px 0px 20px rgba(0, 0, 0, 0.1)', 15 | borderRadius: '2px' 16 | }), 17 | splitter: css({ 18 | marginTop: tokens.spacingL, 19 | marginBottom: tokens.spacingL, 20 | border: 0, 21 | height: '1px', 22 | backgroundColor: tokens.colorElementMid 23 | }), 24 | background: css({ 25 | display: 'block', 26 | position: 'absolute', 27 | zIndex: '-1', 28 | top: '0', 29 | width: '100%', 30 | height: '300px', 31 | backgroundColor: '#452475', 32 | backgroundImage: 33 | 'linear-gradient(45deg,#542c85 25%,transparent 25%,transparent 50%,#542c85 50%,#542c85 75%,transparent 75%,transparent)' 34 | }), 35 | input: css({ 36 | marginTop: tokens.spacingM 37 | }), 38 | icon: css({ 39 | display: 'flex', 40 | justifyContent: 'center', 41 | margin: `${tokens.spacingXl} 0` 42 | }), 43 | checks: css({ 44 | marginTop: tokens.spacingM 45 | }), 46 | pills: css({ 47 | margin: `0 ${tokens.spacingXs}` 48 | }) 49 | }; 50 | -------------------------------------------------------------------------------- /marketplace/sensitive-language/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "production": { 4 | "presets": ["@babel/preset-env"] 5 | }, 6 | "development": { 7 | "presets": ["@babel/preset-env"] 8 | }, 9 | "test": { 10 | "presets": ["@babel/preset-react", [ 11 | "@babel/preset-env", 12 | { 13 | "targets": { 14 | "node": 10 15 | } 16 | } 17 | ]] 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /marketplace/sensitive-language/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: [ 3 | require.resolve('@contentful/eslint-config-extension'), 4 | require.resolve('@contentful/eslint-config-extension/jest'), 5 | require.resolve('@contentful/eslint-config-extension/jsx-a11y'), 6 | require.resolve('@contentful/eslint-config-extension/react') 7 | ], 8 | globals: { 9 | module: true 10 | } 11 | }; 12 | -------------------------------------------------------------------------------- /marketplace/sensitive-language/MARKETPLACE.md: -------------------------------------------------------------------------------- 1 | An extension to check for insensitive writing. 2 | 3 | Checks all text fields for insensitive language using [Alex.js](https://alexjs.com/). Alex helps you find gender 4 | favouring, polarising, race related, religion inconsiderate, or other unequal phrasing in text. The extension is 5 | installed into the sidebar and will show violations for the following field types: 6 | 7 | - short text 8 | - long text (incl. markdown) 9 | - rich text 10 | 11 | ![](./screenshot.png) 12 | 13 | You can configure the extension to ignore specific fields and rules. 14 | -------------------------------------------------------------------------------- /marketplace/sensitive-language/README.md: -------------------------------------------------------------------------------- 1 | # Sensitive Language 2 | 3 | A UI extension to check for insensitive writing. 4 | 5 | Checks all text fields for insensitive language using [Alex.js](https://alexjs.com/). Alex helps you find gender 6 | favouring, polarising, race related, religion inconsiderate, or other unequal phrasing in text. The extension is 7 | installed into the sidebar and will show violations for the following field types: 8 | 9 | - short text 10 | - long text (incl. markdown) 11 | - rich text 12 | 13 | ![](./screenshot.png) 14 | 15 | You can configure the extension to ignore specific fields and rules. 16 | -------------------------------------------------------------------------------- /marketplace/sensitive-language/extension.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "sensitive-language", 3 | "name": "Sensitive Language", 4 | "sidebar": true, 5 | "parameters": { 6 | "installation": [ 7 | { 8 | "id": "profanitySureness", 9 | "name": "Profanity sureness", 10 | "description": "Level of likelihood for a potential profanity to be reported.", 11 | "type": "Enum", 12 | "options": [ 13 | {"0": "Unlikely"}, 14 | {"1": "Maybe"}, 15 | {"2": "Likely"} 16 | ], 17 | "default": "0" 18 | }, 19 | { 20 | "id": "ignoredRules", 21 | "name": "Ignored Rules", 22 | "description": "A comma separated list of rules to ignore. Additional rules can be specified in the content type.", 23 | "type": "Symbol", 24 | "default": "" 25 | } 26 | ], 27 | "instance": [ 28 | { 29 | "id": "ignoredFields", 30 | "name": "Ignored Fields", 31 | "description": "A comma separated list of fields to ignore", 32 | "type": "Symbol", 33 | "default": "" 34 | }, 35 | { 36 | "id": "ignoredRules", 37 | "name": "Ignored Rules", 38 | "description": "A comma separated list of additional rules to ignore. Ignored rules can also be configured globally.", 39 | "type": "Symbol", 40 | "default": "" 41 | } 42 | ] 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /marketplace/sensitive-language/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sensitive-language", 3 | "version": "1.0.0", 4 | "private": true, 5 | "devDependencies": { 6 | "@babel/core": "7.4.5", 7 | "@babel/plugin-proposal-class-properties": "7.4.4", 8 | "@babel/plugin-transform-runtime": "7.4.4", 9 | "@babel/preset-env": "7.4.5", 10 | "@babel/preset-react": "7.0.0", 11 | "@contentful/contentful-extension-scripts": "0.12.0", 12 | "contentful-cli": "^0.33.2", 13 | "react-test-renderer": "^16.8.6" 14 | }, 15 | "dependencies": { 16 | "@contentful/forma-36-fcss": "^0.0.27", 17 | "@contentful/forma-36-react-components": "^3.15.14", 18 | "@contentful/forma-36-tokens": "^0.4.1", 19 | "@contentful/rich-text-plain-text-renderer": "^13.1.0", 20 | "alex": "^7.1.0", 21 | "contentful-ui-extensions-sdk": "^3.10.6", 22 | "prop-types": "^15.7.2", 23 | "react": "^16.8.6", 24 | "react-dom": "^16.8.6" 25 | }, 26 | "scripts": { 27 | "configure": "contentful space use && contentful space environment use", 28 | "prestart": "contentful extension update --src http://localhost:1234 --force", 29 | "start": "contentful-extension-scripts start", 30 | "build": "contentful-extension-scripts build", 31 | "deploy": "npm run build && contentful extension update --force", 32 | "login": "contentful login", 33 | "logout": "contentful logout", 34 | "help": "contentful-extension-scripts help", 35 | "test:watch": "contentful-extension-scripts test --env=jsdom --watch", 36 | "test": "contentful-extension-scripts test --env=jsdom" 37 | }, 38 | "browserslist": [ 39 | "last 2 versions", 40 | "IE >= 11", 41 | "not IE 10" 42 | ] 43 | } 44 | -------------------------------------------------------------------------------- /marketplace/sensitive-language/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/marketplace/sensitive-language/screenshot.png -------------------------------------------------------------------------------- /marketplace/sensitive-language/src/app.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | import { UnsupportedLanguage } from './unsupported-language.js'; 5 | import { LanguageChecker } from './language-checker.js'; 6 | 7 | const textFieldTypes = ['Symbol', 'Text', 'RichText']; 8 | 9 | function extractParameters({ instance, installation }) { 10 | const profanitySureness = parseInt(installation.profanitySureness, 10); 11 | const ignoredFields = instance.ignoredFields 12 | .split(',') 13 | .map(id => id.trim()) 14 | .filter(id => id.length > 0); 15 | const ignoredRules = [ 16 | ...installation.ignoredRules.split(','), 17 | ...instance.ignoredRules.split(',') 18 | ] 19 | .map(id => id.trim()) 20 | .filter(id => id.length > 0); 21 | 22 | const alexConfig = { profanitySureness, allow: ignoredRules }; 23 | 24 | return { ignoredFields, alexConfig }; 25 | } 26 | 27 | export function App({ extension }) { 28 | const defaultLocale = extension.locales.default; 29 | if (!defaultLocale.startsWith('en-')) { 30 | return ( 31 | 35 | ); 36 | } 37 | 38 | const { ignoredFields, alexConfig } = extractParameters(extension.parameters); 39 | const textFields = extension.contentType.fields.filter( 40 | ({ id, type }) => textFieldTypes.includes(type) && !ignoredFields.includes(id) 41 | ); 42 | 43 | return ( 44 | 45 | ); 46 | } 47 | 48 | App.propTypes = { 49 | extension: PropTypes.object.isRequired 50 | }; 51 | -------------------------------------------------------------------------------- /marketplace/sensitive-language/src/index.css: -------------------------------------------------------------------------------- 1 | html, 2 | body, 3 | div { 4 | margin: 0; 5 | padding: 0; 6 | border: 0; 7 | font-size: 100%; 8 | font: inherit; 9 | vertical-align: baseline; 10 | } 11 | 12 | html { 13 | font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol; 14 | font-size: 16px; 15 | text-rendering: optimizeLegibility; 16 | line-height: 1.5; 17 | } 18 | 19 | .warning-list { 20 | padding: 0; 21 | margin-top: 0; 22 | list-style: none; 23 | } 24 | 25 | .warning-list__item { 26 | display: flex; 27 | margin-bottom: 0.25rem; 28 | } 29 | 30 | .warning-list__item:last-child { 31 | margin-bottom: 0; 32 | } 33 | 34 | .align-center { 35 | display: flex; 36 | align-items: center; 37 | } 38 | 39 | .bottom-margin-none { 40 | margin-bottom: 0; 41 | } 42 | -------------------------------------------------------------------------------- /marketplace/sensitive-language/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /marketplace/sensitive-language/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import '@contentful/forma-36-react-components/dist/styles.css'; 5 | import '@contentful/forma-36-fcss/dist/styles.css'; 6 | import { init } from 'contentful-ui-extensions-sdk'; 7 | 8 | import { App } from './app.js'; 9 | 10 | init(extension => { 11 | extension.window.startAutoResizer(); 12 | 13 | ReactDOM.render(, document.getElementById('root')); 14 | }); 15 | -------------------------------------------------------------------------------- /marketplace/sensitive-language/src/message.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import React from 'react'; 4 | import PropTypes from 'prop-types'; 5 | import { Icon, Paragraph } from '@contentful/forma-36-react-components'; 6 | 7 | export function Message({ message }) { 8 | return ( 9 |
  • 10 | 11 | 13 | {message.message} 14 | 15 |
  • 16 | ); 17 | } 18 | 19 | Message.propTypes = { 20 | message: PropTypes.shape({ 21 | ruleId: PropTypes.string.isRequired, 22 | message: PropTypes.string.isRequired, 23 | note: PropTypes.string 24 | }).isRequired 25 | }; 26 | -------------------------------------------------------------------------------- /marketplace/sensitive-language/src/no-issues.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import React from 'react'; 4 | 5 | import { Icon, Typography, Subheading, Paragraph } from '@contentful/forma-36-react-components'; 6 | 7 | export function NoIssues() { 8 | return ( 9 | 10 | 11 | 12 | No issues found 13 | 14 | 15 | All checked files seem to be free on insenstive language. Good job! 16 | 17 | 18 | ); 19 | } 20 | -------------------------------------------------------------------------------- /marketplace/sensitive-language/src/unsupported-language.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { Icon, Typography, Subheading, Paragraph } from '@contentful/forma-36-react-components'; 4 | 5 | export function UnsupportedLanguage({ localeCode, localeName }) { 6 | return ( 7 | 8 | 9 | 10 | Unsupported language 11 | 12 | 13 | {`The sensitive language feature only works for English text. The default locale of this space is ${localeName} (${localeCode}).`} 14 | 15 | 16 | ); 17 | } 18 | 19 | UnsupportedLanguage.propTypes = { 20 | localeCode: PropTypes.string.isRequired, 21 | localeName: PropTypes.string.isRequired 22 | }; 23 | -------------------------------------------------------------------------------- /marketplace/sensitive-language/test/__snapshots__/message.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Message: renders correctly 1`] = ` 4 |
  • 7 |
    12 |
    16 | Don't do this 17 |
    18 |
  • 19 | `; 20 | 21 | exports[`Message: shows optional note 1`] = ` 22 |
  • 25 |
    30 |
    34 | Don't do this 35 |
    36 |
  • 37 | `; 38 | -------------------------------------------------------------------------------- /marketplace/sensitive-language/test/__snapshots__/no-issues.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`NoIssues: renders correctly 1`] = ` 4 |
    7 |
    10 |
    15 | No issues found 16 |
    17 |
    20 | All checked files seem to be free on insenstive language. Good job! 21 |
    22 |
    23 | `; 24 | -------------------------------------------------------------------------------- /marketplace/sensitive-language/test/__snapshots__/unsupported-language.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`UnsupportedLanguage: renders correctly 1`] = ` 4 |
    7 |
    10 |
    15 | Unsupported language 16 |
    17 |
    20 | The sensitive language feature only works for English text. The default locale of this space is German (de-De). 21 |
    22 |
    23 | `; 24 | -------------------------------------------------------------------------------- /marketplace/sensitive-language/test/message.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const React = require('react'); 4 | const renderer = require('react-test-renderer'); 5 | 6 | const { mockComponent } = require('./mock-component.js'); 7 | 8 | jest.mock('@contentful/forma-36-react-components', () => ({ 9 | Icon: mockComponent('icon'), 10 | Paragraph: mockComponent('paragraph') 11 | })); 12 | 13 | const { Message } = require('../src/message.js'); 14 | 15 | test('Message: renders correctly', function() { 16 | const message = { 17 | message: "Don't do this", 18 | ruleId: 'simon-says' 19 | }; 20 | const tree = renderer.create().toJSON(); 21 | expect(tree).toMatchSnapshot(); 22 | }); 23 | 24 | test('Message: shows optional note', function() { 25 | const message = { 26 | message: "Don't do this", 27 | ruleId: 'simon-says', 28 | note: "you really shouldn't" 29 | }; 30 | const tree = renderer.create().toJSON(); 31 | expect(tree).toMatchSnapshot(); 32 | }); 33 | -------------------------------------------------------------------------------- /marketplace/sensitive-language/test/mock-component.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable react/display-name, react/prop-types */ 2 | 3 | 'use strict'; 4 | 5 | const React = require('react'); 6 | 7 | function mockComponent(componentClassName) { 8 | return props => { 9 | const className = props.className 10 | ? `${componentClassName} ${props.className}` 11 | : componentClassName; 12 | 13 | return ( 14 |
    15 | {props.children} 16 |
    17 | ); 18 | }; 19 | } 20 | 21 | module.exports = { mockComponent }; 22 | -------------------------------------------------------------------------------- /marketplace/sensitive-language/test/no-issues.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const React = require('react'); 4 | const renderer = require('react-test-renderer'); 5 | 6 | const { mockComponent } = require('./mock-component.js'); 7 | 8 | jest.mock('@contentful/forma-36-react-components', () => ({ 9 | Icon: mockComponent('icon'), 10 | Typography: mockComponent('typography'), 11 | Subheading: mockComponent('subheading'), 12 | Paragraph: mockComponent('paragraph') 13 | })); 14 | 15 | const { NoIssues } = require('../src/no-issues.js'); 16 | 17 | test('NoIssues: renders correctly', function() { 18 | const tree = renderer.create().toJSON(); 19 | expect(tree).toMatchSnapshot(); 20 | }); 21 | -------------------------------------------------------------------------------- /marketplace/sensitive-language/test/unsupported-language.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const React = require('react'); 4 | const renderer = require('react-test-renderer'); 5 | 6 | const { mockComponent } = require('./mock-component.js'); 7 | 8 | jest.mock('@contentful/forma-36-react-components', () => ({ 9 | Icon: mockComponent('icon'), 10 | Typography: mockComponent('typography'), 11 | Subheading: mockComponent('subheading'), 12 | Paragraph: mockComponent('paragraph') 13 | })); 14 | 15 | const { UnsupportedLanguage } = require('../src/unsupported-language.js'); 16 | 17 | test('UnsupportedLanguage: renders correctly', function() { 18 | const tree = renderer 19 | .create() 20 | .toJSON(); 21 | expect(tree).toMatchSnapshot(); 22 | }); 23 | -------------------------------------------------------------------------------- /samples/README.md: -------------------------------------------------------------------------------- 1 | # Contentful extensions samples 2 | 3 | This folder contains a set of extensions using the [UI extensions SDK](https://github.com/contentful/ui-extensions-sdk). 4 | 5 | ## Requirements 6 | 7 | All the samples require the following dependencies: 8 | 9 | ### Contentful 10 | 11 | - A space to use the widget and the space id. 12 | 13 | ### Local machine 14 | 15 | 16 | - The [contentful cli](https://github.com/contentful/contentful-cli) for uploading extensions to Contentful. 17 | - [npm](https://www.npmjs.com/) installed and configured for dependencies management. 18 | - [gulp](http://gulpjs.com/) for building some samples. 19 | 20 | ## Common preparation steps 21 | 22 | Each sample will need you to use the [Contentful CLI](https://github.com/contentful/contentful-cli): 23 | 24 | ```bash 25 | contentful login 26 | ``` 27 | 28 | ## Debugging on your local environment 29 | 30 | As the Contentful web app is served over HTTPS but your local machine is likely HTTP, you will need to enable access to insecure content. 31 | 32 | Read how to do that in [Firefox][ff-mixed] and [Chrome][chrome-mixed]. 33 | 34 | [chrome-mixed]: https://support.google.com/chrome/answer/1342714 35 | [ff-mixed]: https://support.mozilla.org/en-US/kb/mixed-content-blocking-firefox 36 | -------------------------------------------------------------------------------- /samples/ace-editor/README.md: -------------------------------------------------------------------------------- 1 | Ace editor 2 | -------------- 3 | 4 | This extension shows how to implement the powerful [Ace editor](https://ace.c9.io/) as an extension for text fields. 5 | 6 | ### Installation and usage 7 | 8 | Ensure you checked [the samples requirements listed here](../README.md). 9 | 10 | ![Screenshot of extension](https://github.com/contentful/extensions/raw/master/docs/assets/ace-editor-extension.png) 11 | 12 | Install extension for space: 13 | 14 | ```bash 15 | export SPACE= 16 | 17 | contentful extension create --space-id $SPACE 18 | ``` 19 | 20 | From this point on, you can use the [other commands](https://github.com/contentful/contentful-cli/tree/master/docs/extension) the contentful-cli provides for extensions. 21 | -------------------------------------------------------------------------------- /samples/ace-editor/extension.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "ace-editor", 3 | "name": "Ace editor", 4 | "srcdoc": "./app.html", 5 | "fieldTypes": ["Text"] 6 | } 7 | -------------------------------------------------------------------------------- /samples/alloy-editor/README.md: -------------------------------------------------------------------------------- 1 | Alloy Editor Extension 2 | ------------------- 3 | 4 | ![alloy-editor](../../docs/assets/alloy-editor.png) 5 | 6 | This extension uses the [Alloy Text Editor][alloy] to edit text fields. 7 | 8 | ## Installation and usage 9 | 10 | Ensure you checked [the samples requirements listed here](../README.md). 11 | 12 | Learn more about [Alloy editor][alloy] 13 | 14 | [alloy]: http://alloyeditor.com/ 15 | -------------------------------------------------------------------------------- /samples/alloy-editor/extension.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "alloy", 3 | "name": "Alloy Text Editor", 4 | "srcdoc": "./index.html", 5 | "fieldTypes": ["Text"] 6 | } 7 | -------------------------------------------------------------------------------- /samples/alloy-editor/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 23 | 24 | 25 |
    26 | 56 | 57 | -------------------------------------------------------------------------------- /samples/bacon-ipsum/README.md: -------------------------------------------------------------------------------- 1 | # Bacon Ipsum UI Extension 2 | 3 | ## Summary 4 | This extension hits the [BaconIpsum API](http://baconipsum.com/) and uses it to generate Bacon themed Lorem Ipsum text. 5 | 6 | ![Screenshot of extension](http://contentful.github.io/extensions/assets/bacon-ipsum.png "Screenshot of extension") 7 | 8 | ## Description 9 | 10 | This demo uses jquery to perform an ajax request for dummy data from http://baconipsum.com. It utilizes a dropdown and checkbox to pass parameter arguments to the bacon ipsum API 11 | 12 | You can install this extension into your Contentful space via the [Contentful Comand line tool](https://github.com/contentful/contentful-cli) or by utilizing the inbrowser [UI extension installer](https://www.contentful.com/developers/docs/concepts/uiextensions/). Full instructions on how to install an extension can be found in the [Contentful UI Extension Documentation](https://www.contentful.com/developers/docs/concepts/uiextensions/). 13 | -------------------------------------------------------------------------------- /samples/bacon-ipsum/extension.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "bacon_generator", 3 | "name": "bacon generator", 4 | "srcdoc": "./app.html", 5 | "fieldTypes": ["Text"] 6 | } 7 | -------------------------------------------------------------------------------- /samples/basic-approval-workflow/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@babel/preset-env", 5 | { 6 | "useBuiltIns": false, 7 | "modules": false 8 | } 9 | ], 10 | [ 11 | "@babel/preset-react", 12 | { 13 | "useBuiltIns": true 14 | } 15 | ] 16 | ], 17 | "plugins": [ 18 | [ 19 | "@babel/plugin-proposal-class-properties", 20 | { 21 | "loose": true 22 | } 23 | ], 24 | [ 25 | "@babel/plugin-transform-runtime", 26 | { 27 | "corejs": false, 28 | "helpers": false, 29 | "regenerator": true 30 | } 31 | ] 32 | ] 33 | } 34 | -------------------------------------------------------------------------------- /samples/basic-approval-workflow/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | parser: 'babel-eslint', 3 | env: { 4 | browser: true, 5 | es6: true, 6 | }, 7 | extends: 'airbnb', 8 | parserOptions: { 9 | ecmaFeatures: { 10 | jsx: true, 11 | }, 12 | ecmaVersion: 2018, 13 | sourceType: 'module', 14 | }, 15 | plugins: [ 16 | 'react', 17 | ], 18 | rules: { 19 | 'react/jsx-filename-extension': 'off' 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /samples/basic-approval-workflow/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # dotenv environment variables file 9 | .env 10 | .contentfulrc.json 11 | 12 | # parcel-bundler cache 13 | .cache 14 | 15 | # Dependency directories 16 | node_modules/ 17 | 18 | # Build 19 | build/** 20 | !/build/index.html -------------------------------------------------------------------------------- /samples/basic-approval-workflow/README.md: -------------------------------------------------------------------------------- 1 | # Basic approval workflow 2 | 3 | This UI Extension adds a basic approval workflow to the sidebar of selected content types. Users can request review from their peers and the selected reviewers can provide a positive or negative review with an optional comment. The "Publish" button is only available if there is a positive review and the entry hasn't been modified since the review was submitted. 4 | 5 | Under the hood this UI Extension uses [PubNub](https://www.pubnub.com/) for real-time sync between users and the [Storage and Playback](https://www.pubnub.com/docs/web-javascript/storage-and-history) feature for persistence. PubNub publish and subscribe key should be provided as instance parameters of the extension in the sidebar. 6 | -------------------------------------------------------------------------------- /samples/basic-approval-workflow/extension.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "basic-approval-workflow", 3 | "name": "Reviews", 4 | "srcdoc": "./build/index.html", 5 | "sidebar": true, 6 | "parameters": { 7 | "instance": [ 8 | { 9 | "id": "publishKey", 10 | "type": "Symbol", 11 | "name": "PubNub publish key", 12 | "required": true 13 | }, 14 | { 15 | "id": "subscribeKey", 16 | "type": "Symbol", 17 | "name": "PubNub subscribeKey key", 18 | "required": true 19 | }, 20 | { 21 | "id": "channelPrefix", 22 | "type": "Symbol", 23 | "name": "PubNub channel prefix", 24 | "required": true 25 | }, 26 | { 27 | "id": "webhookUrl", 28 | "type": "Symbol", 29 | "name": "URL to notify with all workflow actions" 30 | } 31 | ] 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /samples/basic-approval-workflow/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "basic-approval-workflow", 3 | "version": "0.1.0", 4 | "private": true, 5 | "devDependencies": { 6 | "@babel/core": "^7.4.0", 7 | "@babel/plugin-proposal-class-properties": "^7.3.4", 8 | "@babel/plugin-transform-runtime": "^7.3.4", 9 | "@babel/preset-env": "7.3.4", 10 | "@babel/preset-react": "^7.0.0", 11 | "@contentful/contentful-extension-scripts": "0.7.2", 12 | "babel-eslint": "^10.0.1", 13 | "contentful-cli": "0.26.2", 14 | "cssnano": "4.1.10", 15 | "eslint": "^5.16.0", 16 | "eslint-config-airbnb": "^17.1.0", 17 | "eslint-plugin-import": "^2.17.2", 18 | "eslint-plugin-jsx-a11y": "^6.2.1", 19 | "eslint-plugin-react": "^7.12.4" 20 | }, 21 | "dependencies": { 22 | "@contentful/forma-36-fcss": "^0.0.27", 23 | "@contentful/forma-36-react-components": "^3.15.14", 24 | "@contentful/forma-36-tokens": "^0.4.1", 25 | "contentful-ui-extensions-sdk": "^3.8.0", 26 | "prop-types": "^15.7.2", 27 | "react": "^16.8.6", 28 | "react-dom": "^16.8.6", 29 | "relative-date": "^1.1.3" 30 | }, 31 | "scripts": { 32 | "lint": "eslint src/*.js --fix", 33 | "prestart": "contentful extension update --src http://localhost:1234 --force", 34 | "start": "contentful-extension-scripts start", 35 | "build": "contentful-extension-scripts build", 36 | "deploy": "npm run build && contentful extension update --force", 37 | "login": "contentful login", 38 | "configure": "contentful space use && contentful space environment use", 39 | "logout": "contentful logout", 40 | "help": "contentful-extension-scripts help" 41 | }, 42 | "browserslist": [ 43 | "last 5 Chrome version", 44 | "> 1%", 45 | "not ie <= 11" 46 | ] 47 | } 48 | -------------------------------------------------------------------------------- /samples/basic-approval-workflow/src/avatar.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | import { spacingM } from '@contentful/forma-36-tokens'; 5 | 6 | const DEFAULT_AVATAR_SIZE = '50px'; 7 | const DEFAULT_SPACING = 'right'; 8 | const ALT_SPACING = 'left'; 9 | 10 | export default class Avatar extends React.Component { 11 | static propTypes = { 12 | user: PropTypes.shape({ 13 | avatarUrl: PropTypes.string.isRequired, 14 | firstName: PropTypes.string.isRequired, 15 | }).isRequired, 16 | size: PropTypes.string, 17 | spacing: PropTypes.oneOf([DEFAULT_SPACING, ALT_SPACING]), 18 | } 19 | 20 | static defaultProps = { 21 | size: DEFAULT_AVATAR_SIZE, 22 | spacing: DEFAULT_SPACING, 23 | } 24 | 25 | constructor(props) { 26 | super(props); 27 | 28 | const { size, spacing } = props; 29 | 30 | const style = { 31 | width: size, 32 | height: size, 33 | borderRadius: size, 34 | }; 35 | 36 | if (spacing === DEFAULT_SPACING) { 37 | style.marginRight = spacingM; 38 | } else if (spacing === ALT_SPACING) { 39 | style.marginLeft = spacingM; 40 | } 41 | 42 | this.state = { style }; 43 | } 44 | 45 | render() { 46 | const { user } = this.props; 47 | const { style } = this.state; 48 | 49 | return ( 50 | {user.firstName} 55 | ); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /samples/basic-approval-workflow/src/events.js: -------------------------------------------------------------------------------- 1 | export const eventTypes = { 2 | REVIEW_REQUESTED: 'REVIEW_REQUESTED', 3 | REVIEW_REQUEST_CANCELED: 'REVIEW_REQUEST_CANCELED', 4 | APPROVED: 'APPROVED', 5 | REJECTED: 'REJECTED', 6 | PUBLISHED: 'PUBLISHED', 7 | }; 8 | 9 | export const eventNames = { 10 | [eventTypes.REVIEW_REQUESTED]: 'Review requested', 11 | [eventTypes.REVIEW_REQUEST_CANCELED]: 'Review canceled', 12 | [eventTypes.APPROVED]: 'Approved', 13 | [eventTypes.REJECTED]: 'Rejected', 14 | [eventTypes.PUBLISHED]: 'Published', 15 | }; 16 | 17 | export const eventTagTypes = { 18 | [eventTypes.REVIEW_REQUESTED]: 'primary', 19 | [eventTypes.REVIEW_REQUEST_CANCELED]: 'warning', 20 | [eventTypes.APPROVED]: 'positive', 21 | [eventTypes.REJECTED]: 'negative', 22 | [eventTypes.PUBLISHED]: 'primary', 23 | }; 24 | -------------------------------------------------------------------------------- /samples/basic-approval-workflow/src/find-user.js: -------------------------------------------------------------------------------- 1 | const UNKNOWN_USER = { 2 | sys: {}, 3 | firstName: 'Unknown', 4 | lastName: 'User', 5 | avatarUrl: 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA1MTIgNTEyIj48cGF0aCBkPSJNNDM3LjAyIDMzMC45OGMtMjcuODgzLTI3Ljg4Mi02MS4wNzEtNDguNTIzLTk3LjI4MS02MS4wMThDMzc4LjUyMSAyNDMuMjUxIDQwNCAxOTguNTQ4IDQwNCAxNDggNDA0IDY2LjM5MyAzMzcuNjA3IDAgMjU2IDBTMTA4IDY2LjM5MyAxMDggMTQ4YzAgNTAuNTQ4IDI1LjQ3OSA5NS4yNTEgNjQuMjYyIDEyMS45NjItMzYuMjEgMTIuNDk1LTY5LjM5OCAzMy4xMzYtOTcuMjgxIDYxLjAxOEMyNi42MjkgMzc5LjMzMyAwIDQ0My42MiAwIDUxMmg0MGMwLTExOS4xMDMgOTYuODk3LTIxNiAyMTYtMjE2czIxNiA5Ni44OTcgMjE2IDIxNmg0MGMwLTY4LjM4LTI2LjYyOS0xMzIuNjY3LTc0Ljk4LTE4MS4wMnpNMjU2IDI1NmMtNTkuNTUxIDAtMTA4LTQ4LjQ0OC0xMDgtMTA4UzE5Ni40NDkgNDAgMjU2IDQwczEwOCA0OC40NDggMTA4IDEwOC00OC40NDkgMTA4LTEwOCAxMDh6Ii8+PC9zdmc+', 6 | }; 7 | 8 | export default function findUserById(users, id) { 9 | return users.find(current => current.sys.id === id) || UNKNOWN_USER; 10 | } 11 | -------------------------------------------------------------------------------- /samples/basic-approval-workflow/src/id.js: -------------------------------------------------------------------------------- 1 | export default function id() { 2 | const arr = new Uint32Array(4); 3 | window.crypto.getRandomValues(arr); 4 | return arr.map(x => `${x}`).join('!'); 5 | } 6 | -------------------------------------------------------------------------------- /samples/basic-approval-workflow/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
    8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /samples/basic-approval-workflow/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | 4 | import '@contentful/forma-36-react-components/dist/styles.css'; 5 | import '@contentful/forma-36-tokens/dist/css/index.css'; 6 | 7 | import { init, locations } from 'contentful-ui-extensions-sdk'; 8 | 9 | import Sidebar from './sidebar'; 10 | import Dialog from './dialog'; 11 | 12 | init((sdk) => { 13 | const root = document.getElementById('root'); 14 | 15 | if (sdk.location.is(locations.LOCATION_ENTRY_SIDEBAR)) { 16 | ReactDOM.render(, root); 17 | } else if (sdk.location.is(locations.LOCATION_DIALOG)) { 18 | ReactDOM.render(, root); 19 | } 20 | }); 21 | 22 | if (module.hot) { 23 | module.hot.accept(); 24 | } 25 | -------------------------------------------------------------------------------- /samples/basic-approval-workflow/src/pubnub-loader.js: -------------------------------------------------------------------------------- 1 | const PUBNUB_SDK_URL = 'https://cdn.pubnub.com/sdk/javascript/pubnub.4.21.7.min.js'; 2 | 3 | export default function loadPubNub() { 4 | return new Promise((resolve, reject) => { 5 | const script = document.createElement('script'); 6 | script.async = true; 7 | script.src = PUBNUB_SDK_URL; 8 | 9 | script.onerror = () => reject(new Error('Failed to load PubNub.')); 10 | script.onload = () => resolve(window.PubNub); 11 | 12 | document.getElementsByTagName('head')[0].appendChild(script); 13 | }); 14 | } 15 | -------------------------------------------------------------------------------- /samples/basic-approval-workflow/src/user-name.js: -------------------------------------------------------------------------------- 1 | export default function userName(user) { 2 | return `${user.firstName} ${user.lastName}`; 3 | } 4 | -------------------------------------------------------------------------------- /samples/basic-approval-workflow/src/vspace.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import { spacingXs } from '@contentful/forma-36-tokens'; 4 | 5 | const VSPACE = { paddingBottom: spacingXs }; 6 | 7 | export default function Vspace() { 8 | return
    ; 9 | } 10 | -------------------------------------------------------------------------------- /samples/chessboard/README.md: -------------------------------------------------------------------------------- 1 | Chessboard 2 | ========== 3 | 4 | ![Chessboard Widget in action](http://contentful.github.io/extensions/assets/chessboard.gif) 5 | 6 | This extension uses [chessboard.js][] to display a chessboard that edits a JSON 7 | field containing the position of the pieces. 8 | 9 | To use the chessboard extension in the Contentful App you need to create a content 10 | type with a `JSON Object` field. In the field settings’ `Appearance` tab you 11 | then need to select the `Chessboard` extension. 12 | 13 | [chessboard.js]: http://chessboardjs.com/ 14 | -------------------------------------------------------------------------------- /samples/chessboard/extension.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "chessboard", 3 | "name": "Chessboard", 4 | "srcdoc": "index.html", 5 | "fieldTypes": ["Object"] 6 | } 7 | -------------------------------------------------------------------------------- /samples/chessboard/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
    15 | 16 | 45 | 46 | -------------------------------------------------------------------------------- /samples/content-tree/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@babel/preset-env", 5 | { 6 | "useBuiltIns": false, 7 | "modules": false 8 | } 9 | ], 10 | [ 11 | "@babel/preset-react", 12 | { 13 | "useBuiltIns": true 14 | } 15 | ] 16 | ], 17 | "plugins": [ 18 | [ 19 | "@babel/plugin-proposal-class-properties", 20 | { 21 | "loose": true 22 | } 23 | ], 24 | [ 25 | "@babel/plugin-transform-runtime", 26 | { 27 | "corejs": false, 28 | "helpers": false, 29 | "regenerator": true 30 | } 31 | ] 32 | ] 33 | } 34 | -------------------------------------------------------------------------------- /samples/content-tree/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # dotenv environment variables file 9 | .env 10 | .contentfulrc.json 11 | 12 | # parcel-bundler cache 13 | .cache 14 | 15 | # Dependency directories 16 | node_modules/ 17 | 18 | # Build 19 | build/** 20 | !/build/index.html -------------------------------------------------------------------------------- /samples/content-tree/README.md: -------------------------------------------------------------------------------- 1 | # content-tree 2 | 3 | UI extension for browsing between sibling and child references in the entry view. 4 | 5 | ![](https://cldup.com/cxJq1ofe2o.gif) 6 | -------------------------------------------------------------------------------- /samples/content-tree/extension.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "content-tree", 3 | "name": "Content Tree", 4 | "srcdoc": "./build/index.html", 5 | "sidebar": true 6 | } 7 | -------------------------------------------------------------------------------- /samples/content-tree/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "content-tree", 3 | "version": "0.1.0", 4 | "private": true, 5 | "devDependencies": { 6 | "@babel/core": "7.3.4", 7 | "@babel/plugin-proposal-class-properties": "7.3.4", 8 | "@babel/plugin-transform-runtime": "7.3.4", 9 | "@babel/preset-env": "7.3.4", 10 | "@babel/preset-react": "7.0.0", 11 | "@contentful/contentful-extension-scripts": "0.7.2", 12 | "contentful-cli": "0.26.2" 13 | }, 14 | "dependencies": { 15 | "@contentful/forma-36-fcss": "^0.0.27", 16 | "@contentful/forma-36-react-components": "^3.15.14", 17 | "@contentful/forma-36-tokens": "^0.4.1", 18 | "contentful-ui-extensions-sdk": "3.7.2", 19 | "debounce-fn": "^1.0.0", 20 | "prop-types": "15.7.2", 21 | "react": "16.8.6", 22 | "react-dom": "16.8.6", 23 | "relative-date": "^1.1.3" 24 | }, 25 | "scripts": { 26 | "prestart": "contentful extension update --src http://localhost:1234 --force", 27 | "start": "contentful-extension-scripts start", 28 | "build": "contentful-extension-scripts build", 29 | "deploy": "npm run build && contentful extension update --force", 30 | "login": "contentful login", 31 | "configure": "contentful space use && contentful space environment use", 32 | "logout": "contentful logout", 33 | "help": "contentful-extension-scripts help" 34 | }, 35 | "browserslist": [ 36 | "last 5 Chrome version", 37 | "> 1%", 38 | "not ie <= 11" 39 | ] 40 | } 41 | -------------------------------------------------------------------------------- /samples/content-tree/src/index.css: -------------------------------------------------------------------------------- 1 | html, 2 | body { 3 | margin: 0; 4 | padding: 0; 5 | } 6 | 7 | .link { 8 | display: block; 9 | font: 1rem sans-serif; 10 | padding: 0.75rem 2rem 0.75rem 2rem; 11 | position: relative; 12 | color: #536171; 13 | cursor: pointer; 14 | overflow: hidden; 15 | text-overflow: ellipsis; 16 | white-space: nowrap; 17 | } 18 | 19 | .link::before { 20 | content: ""; 21 | display: inline-block; 22 | width: 10px; 23 | height: 10px; 24 | -moz-border-radius: 7.5px; 25 | -webkit-border-radius: 7.5px; 26 | border-radius: 7.5px; 27 | background-color: rgb(255, 225, 0); 28 | position: absolute; 29 | right: 10px; 30 | top: calc(50% - 5px); 31 | } 32 | 33 | .link.published::before { 34 | background-color: rgb(0, 155, 0); 35 | } 36 | 37 | .link:hover, 38 | .link.selected { 39 | background: #dfe5e9; 40 | } 41 | 42 | .link .left-icon { 43 | position: absolute; 44 | left: 0.5rem; 45 | fill: #000; 46 | } 47 | 48 | .section-label { 49 | margin: 0.5rem 0; 50 | color: #a2a9b1; 51 | } 52 | 53 | .child-refs { 54 | margin: 0 0 0 1.5rem; 55 | } 56 | -------------------------------------------------------------------------------- /samples/content-tree/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
    8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /samples/default-field-value/extension.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "default-field-value", 3 | "name": "Default value for a field", 4 | "srcdoc": "extension.html", 5 | "fieldTypes": ["Symbol"], 6 | "parameters": { 7 | "instance": [ 8 | { 9 | "id": "defaultColor", 10 | "name": "Default color", 11 | "description": "Set which color is the default color", 12 | "type": "Enum", 13 | "options": [{"#0000FF": "blue"}, {"#FFFF00": "yellow"}, {"#FF0000": "red"}], 14 | "labels": {"empty": "Choose a color"}, 15 | "required": true 16 | } 17 | ] 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /samples/diff/README.md: -------------------------------------------------------------------------------- 1 | # Diff UI Extensions 2 | 3 | The diff editor extension shows the diff between the draft value and the published value of a short text field. 4 | 5 | ![Screenshot of Diff extension](../../docs/assets/diff-extension.png) 6 | 7 | ## Installation and usage 8 | 9 | Check you have the [requirements](../README.md#requirements) needed to use extensions. 10 | 11 | ## Local development 12 | 13 | Start a local server, changing the port if needed: 14 | 15 | ```bash 16 | python -m SimpleHTTPServer 3030 17 | ``` 18 | 19 | Don't use the `extension.json` descriptor file but instead use 3rd party hosting from `localhost` 20 | 21 | ```bash 22 | contentful extension update --force --src 'http://localhost:3030/index.html' --id diff --name diff --field-types Symbol -field-types Text 23 | ``` 24 | 25 | The [same constraints](../README.md#debugging-on-your-local-environment) apply to loading unsafe scripts. 26 | 27 | ## Using the extension in the Contentful web app 28 | 29 | Enable the extension in the Contentful web app for a "Short text" field by opening the _Settings_ for a field and selecting the widget in the _appearance_ tab. 30 | -------------------------------------------------------------------------------- /samples/diff/extension.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "diff", 3 | "name": "Diffing draft and published values", 4 | "srcdoc": "index.html", 5 | "fieldTypes": ["Symbol", "Text"] 6 | } 7 | -------------------------------------------------------------------------------- /samples/entry-editor-extension/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@babel/preset-env", 5 | { 6 | "useBuiltIns": false, 7 | "modules": false 8 | } 9 | ], 10 | [ 11 | "@babel/preset-react", 12 | { 13 | "useBuiltIns": true 14 | } 15 | ] 16 | ], 17 | "plugins": [ 18 | [ 19 | "@babel/plugin-proposal-class-properties", 20 | { 21 | "loose": true 22 | } 23 | ], 24 | [ 25 | "@babel/plugin-transform-runtime", 26 | { 27 | "corejs": false, 28 | "helpers": false, 29 | "regenerator": true 30 | } 31 | ] 32 | ] 33 | } 34 | -------------------------------------------------------------------------------- /samples/entry-editor-extension/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # dotenv environment variables file 9 | .env 10 | .contentfulrc.json 11 | 12 | # Parcel-bundler cache 13 | .cache 14 | 15 | # Dependency directories 16 | node_modules/ 17 | 18 | # Build 19 | build/* 20 | !/build/index.html 21 | -------------------------------------------------------------------------------- /samples/entry-editor-extension/README.md: -------------------------------------------------------------------------------- 1 | # Entry editor extension 2 | 3 | This example shows how an [entry editor extension](/developers/docs/extensibility/ui-extensions/locations/#entry-extensions) is used to customize the editing experience of an entire entry by making some fields conditional. 4 | 5 | ![Screenshot of extension](./entry-extension.gif) 6 | 7 | It uses a boolean value to toggle visible of a field `abstract` so an editor can choose if this field is needed or not. 8 | 9 | ## Requirements 10 | 11 | This example depends on a specific content type: 12 | 13 | ![Screenshot of extension](./entry-extension.png) 14 | 15 | It needs to be assigned to a content type with the following fields: 16 | 17 | - `hasAbstract` of type `boolean` 18 | - `abstract` of type `text` 19 | 20 | You can find the used content type in this [json file](./sample-content-type.json). 21 | 22 | ## Usage 23 | 24 | - create the needed content type 25 | - install the dependencies of the example with `npm i` 26 | - push a development version of the example to your space `npm space use && npm run start` 27 | - assign the extension as `entry extension` in the content modelling section of the web app 28 | 29 | 30 | -------------------------------------------------------------------------------- /samples/entry-editor-extension/entry-extension.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/samples/entry-editor-extension/entry-extension.gif -------------------------------------------------------------------------------- /samples/entry-editor-extension/entry-extension.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/samples/entry-editor-extension/entry-extension.png -------------------------------------------------------------------------------- /samples/entry-editor-extension/extension.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "entry-editor-extension", 3 | "name": "entry-editor-extension", 4 | "srcdoc": "./build/index.html" 5 | } 6 | -------------------------------------------------------------------------------- /samples/entry-editor-extension/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "entry-editor-extension", 3 | "version": "0.1.0", 4 | "private": true, 5 | "devDependencies": { 6 | "@babel/core": "7.3.4", 7 | "@babel/plugin-proposal-class-properties": "7.3.4", 8 | "@babel/plugin-transform-runtime": "7.3.4", 9 | "@babel/preset-env": "7.3.4", 10 | "@babel/preset-react": "7.0.0", 11 | "@contentful/contentful-extension-scripts": "0.9.0", 12 | "cssnano": "4.1.10", 13 | "contentful-cli": "0.26.6", 14 | "@types/react": "^16.8.18", 15 | "@types/react-dom": "^16.8.4", 16 | "@types/webpack-env": "1.13.9", 17 | "typescript": "3.4.5" 18 | }, 19 | "dependencies": { 20 | "@contentful/forma-36-fcss": "^0.0.27", 21 | "@contentful/forma-36-react-components": "^3.15.14", 22 | "@contentful/forma-36-tokens": "^0.4.1", 23 | "contentful-ui-extensions-sdk": "3.8.0", 24 | "prop-types": "^15.7.2", 25 | "react": "^16.8.6", 26 | "react-dom": "^16.8.6" 27 | }, 28 | "scripts": { 29 | "prestart": "contentful extension update --src http://localhost:1234 --force", 30 | "start": "contentful-extension-scripts start", 31 | "build": "contentful-extension-scripts build", 32 | "deploy": "npm run build && contentful extension update --force", 33 | "configure": "contentful space use && contentful space environment use", 34 | "login": "contentful login", 35 | "logout": "contentful logout", 36 | "help": "contentful-extension-scripts help" 37 | }, 38 | "browserslist": [ 39 | "last 5 Chrome version", 40 | "> 1%", 41 | "not ie <= 11" 42 | ] 43 | } 44 | -------------------------------------------------------------------------------- /samples/entry-editor-extension/sample-content-type.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Article", 3 | "description": "An article with an optional abstract field.", 4 | "displayField": "title", 5 | "fields": [ 6 | { 7 | "id": "title", 8 | "name": "title", 9 | "type": "Symbol", 10 | "localized": false, 11 | "required": false, 12 | "validations": [], 13 | "disabled": false, 14 | "omitted": false 15 | }, 16 | { 17 | "id": "hasAbstract", 18 | "name": "has abstract", 19 | "type": "Boolean", 20 | "localized": false, 21 | "required": true, 22 | "validations": [], 23 | "disabled": false, 24 | "omitted": false 25 | }, 26 | { 27 | "id": "abstract", 28 | "name": "abstract", 29 | "type": "Text", 30 | "localized": false, 31 | "required": false, 32 | "validations": [], 33 | "disabled": false, 34 | "omitted": false 35 | }, 36 | { 37 | "id": "body", 38 | "name": "body", 39 | "type": "Text", 40 | "localized": false, 41 | "required": false, 42 | "validations": [], 43 | "disabled": false, 44 | "omitted": false 45 | } 46 | ], 47 | "sys": { 48 | ... 49 | } 50 | } -------------------------------------------------------------------------------- /samples/entry-editor-extension/src/index.css: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | } 4 | html, 5 | body, 6 | div { 7 | margin: 0; 8 | padding: 0; 9 | border: 0; 10 | font-size: 100%; 11 | font: inherit; 12 | vertical-align: baseline; 13 | } 14 | 15 | input, 16 | textarea { 17 | margin-bottom: 15px !important; 18 | } 19 | 20 | /* .fields > div { 21 | border: 1px dotted darkorange; 22 | margin: 2px; 23 | } */ 24 | -------------------------------------------------------------------------------- /samples/entry-editor-extension/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
    8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /samples/entry-editor-extension/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "commonjs", 5 | "strict": true, 6 | "jsx": "react", 7 | "rootDir": "./src", 8 | "experimentalDecorators": true, 9 | "lib": ["dom", "es2015"], 10 | "resolveJsonModule": true 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /samples/external-api/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@babel/preset-env", 5 | { 6 | "useBuiltIns": false, 7 | "modules": false 8 | } 9 | ], 10 | [ 11 | "@babel/preset-react", 12 | { 13 | "useBuiltIns": true 14 | } 15 | ] 16 | ], 17 | "plugins": [ 18 | [ 19 | "@babel/plugin-proposal-class-properties", 20 | { 21 | "loose": true 22 | } 23 | ], 24 | [ 25 | "@babel/plugin-transform-runtime", 26 | { 27 | "corejs": false, 28 | "helpers": false, 29 | "regenerator": true 30 | } 31 | ] 32 | ] 33 | } 34 | -------------------------------------------------------------------------------- /samples/external-api/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # dotenv environment variables file 9 | .env 10 | .contentfulrc.json 11 | 12 | # parcel-bundler cache 13 | .cache 14 | 15 | # Dependency directories 16 | node_modules/ 17 | package-lock.json 18 | 19 | # Build 20 | build/** 21 | !/build/index.html -------------------------------------------------------------------------------- /samples/external-api/README.md: -------------------------------------------------------------------------------- 1 | # External API UI Extension 2 | 3 | ## Summary 4 | 5 | This extension demonstrates accessing an external API and storing the underlying data within Contentful. 6 | 7 | The API does not need to satisfy any requirements for response format. 8 | 9 | ![Screenshot of extension](https://github.com/contentful/extensions/raw/master/docs/assets/external-api-extension.jpg) 10 | 11 | ## Description 12 | 13 | Consuming the external API is performed similar to a standalone application. This demo uses `fetch` with a [polyfill](https://www.npmjs.com/package/whatwg-fetch) to perform an AJAX request for dummy data from jsonplaceholder.typicode.com. 14 | 15 | Once the API responds, React and Forma 36 are used to build a dropdown of options. The Contentful UI Extension SDK provides access to persist data sourced from the service to the underlying data model. 16 | 17 | See the [UI Extension SDK documentation](https://github.com/contentful/ui-extensions-sdk) for a full description of its capabilities. 18 | 19 | ## Next Steps 20 | 21 | Adding additional behaviors to the extension are simple. You can add more information to the dropdown, display images, etc. by modifying or replacing the code generating the dropdown. 22 | -------------------------------------------------------------------------------- /samples/external-api/extension.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "external-api-dropdown", 3 | "name": "External API Dropdown", 4 | "srcdoc": "./build/index.html", 5 | "fieldTypes": [ 6 | "Symbol", 7 | "Text" 8 | ] 9 | } -------------------------------------------------------------------------------- /samples/external-api/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "external-api", 3 | "version": "0.1.0", 4 | "private": true, 5 | "devDependencies": { 6 | "@babel/core": "7.3.4", 7 | "@babel/plugin-proposal-class-properties": "7.3.4", 8 | "@babel/plugin-transform-runtime": "7.3.4", 9 | "@babel/preset-env": "7.3.4", 10 | "@babel/preset-react": "7.0.0", 11 | "@contentful/contentful-extension-scripts": "0.7.2", 12 | "cssnano": "4.1.10", 13 | "contentful-cli": "0.26.2" 14 | }, 15 | "dependencies": { 16 | "@contentful/forma-36-fcss": "^0.0.27", 17 | "@contentful/forma-36-react-components": "^3.15.14", 18 | "@contentful/forma-36-tokens": "^0.4.1", 19 | "contentful-ui-extensions-sdk": "3.7.2", 20 | "prop-types": "^15.7.2", 21 | "react": "^16.8.6", 22 | "react-dom": "^16.8.6", 23 | "whatwg-fetch": "3.0.0" 24 | }, 25 | "scripts": { 26 | "prestart": "contentful extension update --src http://localhost:1234 --force", 27 | "start": "contentful-extension-scripts start", 28 | "build": "contentful-extension-scripts build", 29 | "deploy": "npm run build && contentful extension update --force", 30 | "login": "contentful login", 31 | "configure": "contentful space use && contentful space environment use", 32 | "logout": "contentful logout", 33 | "help": "contentful-extension-scripts help" 34 | }, 35 | "browserslist": [ 36 | "last 5 Chrome version", 37 | "> 1%", 38 | "not ie <= 11" 39 | ] 40 | } 41 | -------------------------------------------------------------------------------- /samples/external-api/src/index.css: -------------------------------------------------------------------------------- 1 | html, 2 | body, 3 | div { 4 | margin: 0; 5 | padding: 0; 6 | border: 0; 7 | font-size: 100%; 8 | font: inherit; 9 | vertical-align: baseline; 10 | } 11 | -------------------------------------------------------------------------------- /samples/external-api/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
    8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /samples/gatsby-preview/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@babel/preset-env", 5 | { 6 | "useBuiltIns": false, 7 | "modules": false 8 | } 9 | ], 10 | [ 11 | "@babel/preset-react", 12 | { 13 | "useBuiltIns": true 14 | } 15 | ] 16 | ], 17 | "plugins": [ 18 | [ 19 | "@babel/plugin-proposal-class-properties", 20 | { 21 | "loose": true 22 | } 23 | ], 24 | [ 25 | "@babel/plugin-transform-runtime", 26 | { 27 | "corejs": false, 28 | "helpers": false, 29 | "regenerator": true 30 | } 31 | ] 32 | ] 33 | } 34 | -------------------------------------------------------------------------------- /samples/gatsby-preview/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # dotenv environment variables file 9 | .env 10 | .contentfulrc.json 11 | 12 | # parcel-bundler cache 13 | .cache 14 | 15 | # Dependency directories 16 | node_modules/ 17 | package-lock.json 18 | 19 | # Build 20 | build/** 21 | !/build/index.html -------------------------------------------------------------------------------- /samples/gatsby-preview/README.md: -------------------------------------------------------------------------------- 1 | # Gatsby Cloud 2 | 3 | Gatsby is an open-source, modern website framework based on React to create and deploy websites or web apps with ease. This UI Extension connects to [Gatsby Cloud](https://www.gatsbyjs.com/cloud/) which lets you see updates to your Gatsby site as soon as you change content in Contentful. This makes it easy for content creators to see changes they make to the website before going live. 4 | 5 | ![Demo of the extension](demo.gif) 6 | 7 | ## Overview 8 | 9 | The extension has the following features: 10 | 11 | - monitor changes on content as you type 12 | - real time site updates (de-bounced by 1000 ms) 13 | 14 | The extension has the following spec: 15 | 16 | - it is a sidebar extension used in a [custom sidebar](https://www.contentful.com/developers/docs/extensibility/custom-sidebar/) 17 | - uses the Contentful design system [Forma 36](https://f36.contentful.com/) 18 | - installation parameter to set global `projectId` 19 | - site parameters to 20 | - set an optional `slug` fragment for each content type 21 | - toggle auto-update when typing 22 | 23 | ![Screenshot of the extension](screenshot.png) 24 | 25 | ## Requirements 26 | 27 | In order to use this extension, you need: 28 | 29 | - a [Gatbsy Cloud](https://www.gatsbyjs.com/cloud/) setup to use this extension 30 | - a space and the Contentful CLI installed 31 | 32 | ## Usage 33 | 34 | After cloning, install the dependencies 35 | 36 | ```bash 37 | npm install 38 | ``` 39 | 40 | To bundle the extension 41 | 42 | ```bash 43 | npm run build 44 | ``` 45 | 46 | To host the extension for development on `http://localhost:1234` 47 | 48 | ```bash 49 | npm run start 50 | ``` 51 | 52 | To install the extension: 53 | 54 | ```bash 55 | contentful extension update --force --installation-parameters '{"projectId": "yourGatsbyPreviewId"}' 56 | ``` 57 | -------------------------------------------------------------------------------- /samples/gatsby-preview/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/samples/gatsby-preview/demo.gif -------------------------------------------------------------------------------- /samples/gatsby-preview/demo.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/samples/gatsby-preview/demo.mp4 -------------------------------------------------------------------------------- /samples/gatsby-preview/extension.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "gatsby-preview-sidebar", 3 | "name": "Gatsby Preview", 4 | "srcdoc": "./build/index.html", 5 | "sidebar": true, 6 | "parameters": { 7 | "installation": [ 8 | { 9 | "id": "previewUrl", 10 | "type": "Symbol", 11 | "name": "The url of your Gatsby Cloud site" 12 | }, 13 | { 14 | "id": "webhookUrl", 15 | "type": "Symbol", 16 | "name": "The url of the webhook to rebuild your Gatsby Cloud site" 17 | }, 18 | { 19 | "id": "authToken", 20 | "type": "Symbol", 21 | "name": "Optional Authentication token for private Gatsby Cloud sites" 22 | } 23 | ] 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /samples/gatsby-preview/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gatsby-preview", 3 | "version": "0.1.0", 4 | "private": true, 5 | "devDependencies": { 6 | "@babel/core": "7.3.4", 7 | "@babel/plugin-proposal-class-properties": "7.3.4", 8 | "@babel/plugin-transform-runtime": "7.3.4", 9 | "@babel/preset-env": "7.3.4", 10 | "@babel/preset-react": "7.0.0", 11 | "@contentful/contentful-extension-scripts": "0.7.2", 12 | "contentful-cli": "0.26.2" 13 | }, 14 | "dependencies": { 15 | "@contentful/forma-36-fcss": "^0.0.27", 16 | "@contentful/forma-36-react-components": "^3.15.14", 17 | "@contentful/forma-36-tokens": "^0.4.1", 18 | "@gatsby-cloud-pkg/gatsby-cms-extension-base": "^0.0.25", 19 | "contentful-ui-extensions-sdk": "3.7.2", 20 | "prop-types": "15.7.2", 21 | "react": "16.8.6", 22 | "react-dom": "16.8.6" 23 | }, 24 | "scripts": { 25 | "prestart": "contentful extension update --src http://localhost:1234 --force", 26 | "start": "contentful-extension-scripts start", 27 | "build": "contentful-extension-scripts build", 28 | "deploy": "npm run build && contentful extension update --force", 29 | "login": "contentful login", 30 | "configure": "contentful space use && contentful space environment use", 31 | "logout": "contentful logout", 32 | "help": "contentful-extension-scripts help" 33 | }, 34 | "browserslist": [ 35 | "last 5 Chrome version", 36 | "> 1%", 37 | "not ie <= 11" 38 | ] 39 | } 40 | -------------------------------------------------------------------------------- /samples/gatsby-preview/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/samples/gatsby-preview/screenshot.png -------------------------------------------------------------------------------- /samples/gatsby-preview/src/index.css: -------------------------------------------------------------------------------- 1 | html, 2 | body { 3 | margin: 0; 4 | padding: 0; 5 | border: 0; 6 | font-size: 100%; 7 | font: inherit; 8 | vertical-align: baseline; 9 | } 10 | 11 | .site-button { 12 | height: 2.5rem; 13 | padding: 0 !important; 14 | font-size: 0.875rem !important; 15 | font-weight: 400 !important; 16 | font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol !important; 17 | } 18 | .site-button:focus { 19 | outline: 0; 20 | border: 1px solid #f1defa; 21 | } 22 | .powered-by { 23 | margin-bottom: 5%; 24 | } 25 | .powered-by p { 26 | font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol !important; 27 | margin-bottom: inherit; 28 | } 29 | .flexcontainer { 30 | display: flex; 31 | flex-direction: column; 32 | } 33 | -------------------------------------------------------------------------------- /samples/gatsby-preview/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
    8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /samples/image-uploader/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@babel/preset-env", 5 | { 6 | "useBuiltIns": false, 7 | "modules": false 8 | } 9 | ], 10 | [ 11 | "@babel/preset-react", 12 | { 13 | "useBuiltIns": true 14 | } 15 | ] 16 | ], 17 | "plugins": [ 18 | [ 19 | "@babel/plugin-proposal-class-properties", 20 | { 21 | "loose": true 22 | } 23 | ], 24 | [ 25 | "@babel/plugin-transform-runtime", 26 | { 27 | "corejs": false, 28 | "helpers": false, 29 | "regenerator": true 30 | } 31 | ] 32 | ] 33 | } 34 | -------------------------------------------------------------------------------- /samples/image-uploader/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # dotenv environment variables file 9 | .env 10 | .contentfulrc.json 11 | 12 | # parcel-bundler cache 13 | .cache 14 | 15 | # Dependency directories 16 | node_modules/ 17 | package-lock.json 18 | 19 | # Build 20 | build/** 21 | !/build/index.html -------------------------------------------------------------------------------- /samples/image-uploader/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Image Uploader 3 | 4 | Simply upload images with drag & drop in the entry editor. This UI extension will create and publish the underlying assets for you. 5 | 6 | ![](https://raw.githubusercontent.com/contentful/extensions/master/samples/image-uploader/gifcast.gif) 7 | 8 | Once you install the extension, you can enable it by going to your content model, choosing an image field, and choosing Appearance > Image Uploader. 9 | 10 | Icon made by [Good Ware](https://www.flaticon.com/authors/good-ware) from www.flaticon.com 11 | -------------------------------------------------------------------------------- /samples/image-uploader/extension.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "image-uploader", 3 | "name": "Image Uploader", 4 | "srcdoc": "./build/index.html", 5 | "fieldTypes": [ 6 | "Asset" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /samples/image-uploader/gifcast.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/samples/image-uploader/gifcast.gif -------------------------------------------------------------------------------- /samples/image-uploader/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "image-uploader", 3 | "version": "0.1.0", 4 | "private": true, 5 | "devDependencies": { 6 | "@babel/core": "7.3.4", 7 | "@babel/plugin-proposal-class-properties": "7.3.4", 8 | "@babel/plugin-transform-runtime": "7.3.4", 9 | "@babel/preset-env": "7.3.4", 10 | "@babel/preset-react": "7.0.0", 11 | "@contentful/contentful-extension-scripts": "0.7.2", 12 | "contentful-cli": "1.2.1" 13 | }, 14 | "dependencies": { 15 | "@contentful/forma-36-fcss": "^0.0.27", 16 | "@contentful/forma-36-react-components": "^3.15.14", 17 | "@contentful/forma-36-tokens": "^0.4.1", 18 | "contentful-ui-extensions-sdk": "3.7.2", 19 | "prop-types": "15.7.2", 20 | "react": "16.8.6", 21 | "react-dom": "16.8.6" 22 | }, 23 | "scripts": { 24 | "prestart": "contentful extension update --src http://localhost:1234 --force", 25 | "start": "contentful-extension-scripts start", 26 | "build": "contentful-extension-scripts build", 27 | "deploy": "npm run build && contentful extension update --force", 28 | "login": "contentful login", 29 | "configure": "contentful space use && contentful space environment use", 30 | "logout": "contentful logout", 31 | "help": "contentful-extension-scripts help" 32 | }, 33 | "browserslist": [ 34 | "last 5 Chrome version", 35 | "> 1%", 36 | "not ie <= 11" 37 | ] 38 | } 39 | -------------------------------------------------------------------------------- /samples/image-uploader/src/components/Dropzone.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | 3 | export default class Dropzone extends React.Component { 4 | onDragOverStart = event => { 5 | prevent(event) 6 | this.props.onDragOverStart(event) 7 | } 8 | 9 | onDragOverEnd = event => { 10 | prevent(event) 11 | this.props.onDragOverEnd(event) 12 | } 13 | 14 | onDrop = event => { 15 | prevent(event) 16 | this.props.onDrop(event) 17 | this.props.onDragOverEnd(event) 18 | } 19 | 20 | render() { 21 | const eventHandlers = { 22 | onDrag: prevent, 23 | onDragStart: prevent, 24 | onDragEnd: prevent, 25 | onDragOver: prevent, 26 | onDragEnter: this.onDragOverStart, 27 | onDragLeave: this.onDragOverEnd, 28 | onDrop: this.onDrop 29 | } 30 | 31 | const className = `dropzone ${this.props.className} ${ 32 | this.props.isDraggingOver ? "dragover" : "" 33 | }` 34 | 35 | return ( 36 |
    37 | {this.props.children} 38 |
    39 | ) 40 | } 41 | } 42 | 43 | function prevent(e) { 44 | e.preventDefault() 45 | e.stopPropagation() 46 | } 47 | -------------------------------------------------------------------------------- /samples/image-uploader/src/components/FileView/fileview.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --file-icon-size: 4rem; 3 | } 4 | 5 | .file-view { 6 | display: grid; 7 | grid-template-columns: var(--file-icon-size) auto; 8 | grid-column-gap: 1rem; 9 | } 10 | 11 | .file-view.image-file { 12 | grid-template-columns: 1fr minmax(40%, 1fr); 13 | grid-column-gap: 2rem; 14 | } 15 | 16 | .file-view.image-file header { 17 | background: #f2f2f2 no-repeat center center; 18 | background-size: contain; 19 | position: relative; 20 | } 21 | 22 | .file-view.image-file header img { 23 | position: absolute; 24 | top: 50%; 25 | left: 50%; 26 | transform: translate(-50%, -50%); 27 | } 28 | 29 | .file-view.non-image-file header .file-type-icon svg { 30 | width: var(--file-icon-size); 31 | height: var(--file-icon-size); 32 | } 33 | 34 | .file-view .details .filename { 35 | margin-bottom: 0.5rem; 36 | overflow: hidden; 37 | text-overflow: ellipsis; 38 | white-space: nowrap; 39 | } 40 | 41 | .file-view .details .row { 42 | color: #555; 43 | } 44 | 45 | .file-view .details strong { 46 | font-weight: 700; 47 | } 48 | 49 | .file-view .buttonset { 50 | margin-top: 1rem; 51 | } 52 | 53 | .file-view .buttonset .button { 54 | margin-left: 0.5rem; 55 | } 56 | 57 | .file-view .buttonset .button:first-child { 58 | margin-left: 0; 59 | } 60 | 61 | .file-view img { 62 | height: 100%; 63 | } 64 | -------------------------------------------------------------------------------- /samples/image-uploader/src/components/ProgressView/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import tokens from '@contentful/forma-36-tokens'; 3 | import { Icon } from '@contentful/forma-36-react-components'; 4 | import './progress-view.css'; 5 | 6 | export default function UploadView(props) { 7 | const imageUrl = props.imageUrl || `${props.base64Prefix},${props.base64Data}`; 8 | const isSVG = imageUrl.endsWith('.svg') || imageUrl.includes('svg+xml'); 9 | 10 | const progressViewStyles = { 11 | backgroundColor: tokens.colorElementLight 12 | }; 13 | 14 | // Pass upload progress as CSS variable so we can adjust the size of progress components 15 | const uploadProgress = { 16 | '--uploadProgress': `${props.uploadProgress}%` 17 | }; 18 | 19 | return ( 20 |
    21 |
    22 | {isSVG ? ( 23 | 24 | ) : ( 25 | image being uploaded 26 | )} 27 |
    31 |
    32 | ); 33 | } 34 | -------------------------------------------------------------------------------- /samples/image-uploader/src/components/ProgressView/progress-view.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --progress-view-bar-height: 0.25rem; 3 | } 4 | 5 | .progress-view { 6 | position: relative; 7 | top: 0; 8 | left: 0; 9 | width: 100%; 10 | height: 100%; 11 | z-index: 1; 12 | background: no-repeat center center; 13 | background-size: cover; 14 | overflow-y: hidden; 15 | } 16 | 17 | .progress-view .uploaded-image { 18 | position: absolute; 19 | width: 100%; 20 | min-height: auto; 21 | z-index: 2; 22 | } 23 | 24 | .progress-view svg.uploaded-image { 25 | position: absolute; 26 | left: 50%; 27 | top: 50%; 28 | transform: translate(-50%, -50%); 29 | height: 78px; 30 | width: 78px; 31 | } 32 | 33 | .progress-view .overlay { 34 | position: absolute; 35 | top: 0; 36 | right: 0; 37 | width: calc(100% - var(--uploadProgress)); 38 | height: 100%; 39 | z-index: 3; 40 | background: rgba(255, 255, 255, 0.75); 41 | transition: width 0.3s; 42 | } 43 | 44 | .progress-view .bar { 45 | position: absolute; 46 | left: 0; 47 | bottom: 0; 48 | z-index: 4; 49 | height: var(--progress-view-bar-height); 50 | width: var(--uploadProgress); 51 | background: #007fff; 52 | transition: width 0.3s; 53 | } 54 | 55 | .progress-view .bar-placeholder { 56 | content: ''; 57 | position: absolute; 58 | bottom: 0; 59 | right: 0; 60 | width: calc(100% - var(--uploadProgress)); 61 | height: var(--progress-view-bar-height); 62 | background: #eee; 63 | transition: width 0.3s; 64 | } 65 | -------------------------------------------------------------------------------- /samples/image-uploader/src/components/UploadView/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Subheading, Button, Icon, TextLink } from '@contentful/forma-36-react-components'; 3 | import Dropzone from '../Dropzone'; 4 | import './upload-view.css'; 5 | 6 | export default function UploadView(props) { 7 | return ( 8 | 14 |
    15 | 21 | Drop an image here 22 | 23 | {!props.isDraggingOver ? ( 24 | 38 | ) : null} 39 |
    40 |
    41 | ); 42 | } 43 | -------------------------------------------------------------------------------- /samples/image-uploader/src/components/UploadView/upload-view.css: -------------------------------------------------------------------------------- 1 | .upload-view { 2 | border: 2px dashed #ccc; 3 | text-align: center; 4 | background: #fff; 5 | color: #888; 6 | } 7 | 8 | .upload-view .image-icon { 9 | width: 72px; 10 | height: 72px; 11 | } 12 | 13 | .upload-view .image-icon-label { 14 | color: #333; 15 | } 16 | 17 | .upload-view nav { 18 | margin-top: 3rem; 19 | } 20 | 21 | .upload-view .browse-button { 22 | position: relative; 23 | } 24 | 25 | .upload-view .link-existing { 26 | margin-left: 1rem; 27 | } 28 | 29 | .upload-view.dragover { 30 | border-color: #888; 31 | background: #fff; 32 | color: #111; 33 | } 34 | 35 | .upload-view .file-picker { 36 | position: absolute; 37 | margin: 0; 38 | top: 0; 39 | left: 0; 40 | width: 100%; 41 | height: 100%; 42 | z-index: 999999; 43 | opacity: 0; 44 | cursor: pointer; 45 | } 46 | -------------------------------------------------------------------------------- /samples/image-uploader/src/index.css: -------------------------------------------------------------------------------- 1 | html, 2 | body, 3 | div { 4 | margin: 0; 5 | padding: 0; 6 | border: 0; 7 | font-size: 100%; 8 | font: inherit; 9 | vertical-align: baseline; 10 | box-sizing: border-box; 11 | } 12 | 13 | * { 14 | font-weight: normal; 15 | -webkit-font-smoothing: antialiased !important; 16 | -moz-font-smoothing: antialiased !important; 17 | -moz-osx-font-smoothing: grayscale; 18 | speak: none; 19 | font-style: normal; 20 | font-weight: normal; 21 | font-variant: normal; 22 | text-transform: none; 23 | line-height: 1; 24 | -webkit-font-smoothing: antialiased; 25 | } 26 | 27 | .viewport { 28 | position: relative; 29 | height: 20rem; 30 | } 31 | 32 | .viewport.non-image-file { 33 | height: 10rem; 34 | } 35 | 36 | .centered { 37 | display: flex; 38 | align-items: center; 39 | justify-content: center; 40 | } 41 | -------------------------------------------------------------------------------- /samples/image-uploader/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
    8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /samples/json-editor/README.md: -------------------------------------------------------------------------------- 1 | # JSON Editor extension 2 | 3 | This extension provides a JSON formatter and validator for the Contentful web app based on the [Codemirror](http://codemirror.net) library. You can use this extension with `Object` field types. 4 | 5 | ![json-editor-ok](http://contentful.github.io/extensions/assets/json-editor.png) 6 | -------------------------------------------------------------------------------- /samples/json-editor/extension.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "jsonEditor", 3 | "name": "JSON Editor", 4 | "srcdoc": "./index.html", 5 | "fieldTypes": ["Object"] 6 | } 7 | -------------------------------------------------------------------------------- /samples/json-form-editor/README.md: -------------------------------------------------------------------------------- 1 | # JSON Form Editor extension 2 | 3 | This extension provides a JSON form editor (based on the [JSON Editor](https://github.com/jdorn/json-editor)) library. You can use this extension with 'Object' field types. 4 | 5 | The extension generates a form based on a [JSON Schema](https://json-schema.org/) defined in [schema.json.js](./src/schema.json.js). The generated form allows you to create JSON objects that are valid against that schema. 6 | 7 | ![json-form-editor](http://contentful.github.io/extensions/assets/json-form-editor.png) 8 | 9 | ## TODOs 10 | 11 | - Make JSON Schema configurable as a field appearance option. 12 | - Add advanced form editor styling to _json-editor-contentful-theme.js_. 13 | - Trigger auto-save while typing, not just after leaving an input field. 14 | -------------------------------------------------------------------------------- /samples/json-form-editor/extension.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "jsonFormEditor", 3 | "name": "JSON Form Editor", 4 | "srcdoc": "./index.html", 5 | "fieldTypes": ["Object"] 6 | } 7 | -------------------------------------------------------------------------------- /samples/marketo-forms/extension.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Marketo forms", 3 | "id": "marketo-forms", 4 | "srcdoc": "./app.html", 5 | "fieldTypes": ["Object"], 6 | "parameters": { 7 | "installation": [ 8 | { 9 | "id": "serviceUri", 10 | "type": "Symbol", 11 | "name": "Lambda Function URL", 12 | "required": true 13 | } 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /samples/marketo-forms/lambda-function.js: -------------------------------------------------------------------------------- 1 | const https = require("https"); 2 | 3 | const request = ({ method, hostname, path, headers }) => 4 | new Promise((resolve, reject) => { 5 | https 6 | .request({ method, hostname, path, headers }, response => { 7 | let data = ""; 8 | response.on("data", chunk => (data += chunk)); 9 | response.on("end", () => resolve(JSON.parse(data))); 10 | }) 11 | .on("error", err => reject(err)) 12 | .end(); 13 | }); 14 | 15 | exports.handler = function(event, context, callback) { 16 | request({ 17 | method: "GET", 18 | hostname: `${process.env.MKTO_MUNCHKIN_ID}.mktorest.com`, 19 | path: `/identity/oauth/token?grant_type=client_credentials&client_id=${ 20 | process.env.MKTO_CLIENT_ID 21 | }&client_secret=${process.env.MKTO_CLIENT_SECRET}` 22 | }) 23 | .then(res => res.access_token) 24 | .then(bearer => 25 | request({ 26 | method: "GET", 27 | hostname: `${process.env.MKTO_MUNCHKIN_ID}.mktorest.com`, 28 | path: `/rest/asset/v1/forms.json`, 29 | headers: { 30 | Authorization: `Bearer ${bearer}` 31 | } 32 | }) 33 | .then(res => 34 | callback(null, { 35 | statusCode: 200, 36 | headers: { 37 | "Access-Control-Allow-Origin": "*", 38 | "Content-Type": "application/json" 39 | }, 40 | body: JSON.stringify(res.result) 41 | }) 42 | ) 43 | .catch(err => { 44 | console.log(err); 45 | callback(err); 46 | }) 47 | ) 48 | .catch(err => { 49 | callback(err); 50 | }); 51 | }; 52 | -------------------------------------------------------------------------------- /samples/page-extension-react-router/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@babel/preset-env", 5 | { 6 | "useBuiltIns": false, 7 | "modules": false 8 | } 9 | ], 10 | [ 11 | "@babel/preset-react", 12 | { 13 | "useBuiltIns": true 14 | } 15 | ] 16 | ], 17 | "plugins": [ 18 | [ 19 | "@babel/plugin-proposal-class-properties", 20 | { 21 | "loose": true 22 | } 23 | ], 24 | [ 25 | "@babel/plugin-transform-runtime", 26 | { 27 | "corejs": false, 28 | "helpers": false, 29 | "regenerator": true 30 | } 31 | ] 32 | ] 33 | } 34 | -------------------------------------------------------------------------------- /samples/page-extension-react-router/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: [ 3 | require.resolve('@contentful/eslint-config-extension'), 4 | require.resolve('@contentful/eslint-config-extension/jest'), 5 | require.resolve('@contentful/eslint-config-extension/jsx-a11y'), 6 | require.resolve('@contentful/eslint-config-extension/react'), 7 | ], 8 | }; 9 | -------------------------------------------------------------------------------- /samples/page-extension-react-router/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # dotenv environment variables file 9 | .env 10 | .contentfulrc.json 11 | 12 | # Parcel-bundler cache 13 | .cache 14 | 15 | # Dependency directories 16 | node_modules/ 17 | 18 | # Build 19 | build/** 20 | !/build/index.html 21 | -------------------------------------------------------------------------------- /samples/page-extension-react-router/README.md: -------------------------------------------------------------------------------- 1 | # Page Extension React Router 2 | This UI Extension serves as an example of how to set up a simple React application using React Router for navigation within a page extension. 3 | 4 | ![](../../docs/assets/router-page-extension.gif) 5 | 6 | ## Further Information 7 | 8 | This example uses React Router, a popular routing solution for SPAs. 9 | Documentation for [React Router](https://reacttraining.com/react-router/web/guides/quick-start). 10 | 11 | It also uses the [history](https://github.com/ReactTraining/history) object to be able to listen to 12 | location changes. This is important for keeping the state of your application intact during a page reload. -------------------------------------------------------------------------------- /samples/page-extension-react-router/extension.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "page-extension-react-router", 3 | "name": "Page extension with React Router", 4 | "srcdoc": "./build/index.html", 5 | "sidebar": true 6 | } 7 | -------------------------------------------------------------------------------- /samples/page-extension-react-router/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "page-extension-react-router", 3 | "version": "0.1.0", 4 | "private": true, 5 | "devDependencies": { 6 | "@babel/core": "7.3.4", 7 | "@babel/plugin-proposal-class-properties": "7.3.4", 8 | "@babel/plugin-transform-runtime": "7.3.4", 9 | "@babel/preset-env": "7.3.4", 10 | "@babel/preset-react": "7.0.0", 11 | "@contentful/contentful-extension-scripts": "0.10.0", 12 | "cssnano": "4.1.10", 13 | "contentful-cli": "0.28.0", 14 | "@types/react": "^16.8.22", 15 | "@types/react-dom": "^16.8.4", 16 | "@types/webpack-env": "1.13.9" 17 | }, 18 | "dependencies": { 19 | "@contentful/forma-36-fcss": "^0.0.27", 20 | "@contentful/forma-36-react-components": "^3.15.14", 21 | "@contentful/forma-36-tokens": "^0.4.1", 22 | "contentful-ui-extensions-sdk": "3.9.0", 23 | "history": "4.9.0", 24 | "prop-types": "15.7.2", 25 | "react": "16.8.6", 26 | "react-dom": "16.8.6", 27 | "react-motion": "^0.5.2", 28 | "react-router": "5.0.1", 29 | "react-router-dom": "5.0.1" 30 | }, 31 | "scripts": { 32 | "start": "contentful-extension-scripts start", 33 | "build": "contentful-extension-scripts build", 34 | "deploy": "npm run build && contentful extension update --force", 35 | "configure": "contentful space use && contentful space environment use", 36 | "login": "contentful login", 37 | "logout": "contentful logout", 38 | "help": "contentful-extension-scripts help" 39 | }, 40 | "browserslist": [ 41 | "last 5 Chrome version", 42 | "> 1%", 43 | "not ie <= 11" 44 | ] 45 | } 46 | -------------------------------------------------------------------------------- /samples/page-extension-react-router/src/index.css: -------------------------------------------------------------------------------- 1 | html, 2 | body, 3 | div { 4 | margin: 0; 5 | padding: 0; 6 | border: 0; 7 | font-size: 100%; 8 | font: inherit; 9 | vertical-align: baseline; 10 | } 11 | -------------------------------------------------------------------------------- /samples/page-extension-react-router/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
    8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /samples/publish-confirm/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@babel/preset-env", 5 | { 6 | "useBuiltIns": false, 7 | "modules": false 8 | } 9 | ], 10 | [ 11 | "@babel/preset-react", 12 | { 13 | "useBuiltIns": true 14 | } 15 | ] 16 | ], 17 | "plugins": [ 18 | [ 19 | "@babel/plugin-proposal-class-properties", 20 | { 21 | "loose": true 22 | } 23 | ], 24 | [ 25 | "@babel/plugin-transform-runtime", 26 | { 27 | "corejs": false, 28 | "helpers": false, 29 | "regenerator": true 30 | } 31 | ] 32 | ] 33 | } 34 | -------------------------------------------------------------------------------- /samples/publish-confirm/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # dotenv environment variables file 9 | .env 10 | .contentfulrc.json 11 | 12 | # parcel-bundler cache 13 | .cache 14 | 15 | # Dependency directories 16 | node_modules/ 17 | package-lock.json 18 | 19 | # Build 20 | build/** 21 | !/build/index.html -------------------------------------------------------------------------------- /samples/publish-confirm/README.md: -------------------------------------------------------------------------------- 1 | # Publish Confirmation UI Extension 2 | 3 | This is a sidebar UI extension which shows the entry status and a publish button. It also has a link to unpublish the entry and shows when the entry was last saved. 4 | 5 | ![image](./publish_button_with_confirmation_screenshot1.png) 6 | 7 | When the publish button is clicked, a small popup is shown to confirm the user's desire to publish the entry. It also checks for unpublished child references and provides a warning if any are found. 8 | 9 | Here's the normal confirmation where no unpublished references have been found: 10 | ![image](./publish_button_with_confirmation_screenshot2.png) 11 | 12 | And here's the warning when a child reference has been found: 13 | ![image](./publish_button_with_confirmation_screenshot3.png) 14 | -------------------------------------------------------------------------------- /samples/publish-confirm/extension.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "publish-with-confirmation", 3 | "name": "Publish button with confirmation", 4 | "srcdoc": "./build/index.html", 5 | "sidebar": true 6 | } 7 | -------------------------------------------------------------------------------- /samples/publish-confirm/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "publish-with-confirmation", 3 | "version": "0.1.0", 4 | "private": true, 5 | "devDependencies": { 6 | "@babel/core": "7.3.4", 7 | "@babel/plugin-proposal-class-properties": "7.3.4", 8 | "@babel/plugin-transform-runtime": "7.3.4", 9 | "@babel/preset-env": "7.3.4", 10 | "@babel/preset-react": "7.0.0", 11 | "@contentful/contentful-extension-scripts": "0.7.2", 12 | "contentful-cli": "0.26.2" 13 | }, 14 | "dependencies": { 15 | "@contentful/forma-36-fcss": "^0.0.27", 16 | "@contentful/forma-36-react-components": "^3.15.14", 17 | "@contentful/forma-36-tokens": "^0.4.1", 18 | "contentful-ui-extensions-sdk": "3.7.2", 19 | "prop-types": "15.7.2", 20 | "react": "16.8.6", 21 | "react-dom": "16.8.6", 22 | "relative-date": "^1.1.3" 23 | }, 24 | "scripts": { 25 | "prestart": "contentful extension update --src http://localhost:1234 --force", 26 | "start": "contentful-extension-scripts start", 27 | "build": "contentful-extension-scripts build", 28 | "deploy": "npm run build && contentful extension update --force", 29 | "login": "contentful login", 30 | "configure": "contentful space use && contentful space environment use", 31 | "logout": "contentful logout", 32 | "help": "contentful-extension-scripts help" 33 | }, 34 | "browserslist": [ 35 | "last 5 Chrome version", 36 | "> 1%", 37 | "not ie <= 11" 38 | ] 39 | } 40 | -------------------------------------------------------------------------------- /samples/publish-confirm/publish_button_with_confirmation_screenshot1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/samples/publish-confirm/publish_button_with_confirmation_screenshot1.png -------------------------------------------------------------------------------- /samples/publish-confirm/publish_button_with_confirmation_screenshot2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/samples/publish-confirm/publish_button_with_confirmation_screenshot2.png -------------------------------------------------------------------------------- /samples/publish-confirm/publish_button_with_confirmation_screenshot3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/samples/publish-confirm/publish_button_with_confirmation_screenshot3.png -------------------------------------------------------------------------------- /samples/publish-confirm/src/index.css: -------------------------------------------------------------------------------- 1 | html, 2 | body, 3 | div { 4 | margin: 0; 5 | padding: 0; 6 | border: 0; 7 | font-size: 100%; 8 | font: inherit; 9 | vertical-align: baseline; 10 | } 11 | -------------------------------------------------------------------------------- /samples/publish-confirm/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
    8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /samples/rating-dropdown/extension.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "number-dropdown", 3 | "name": "Rating Dropdown", 4 | "srcdoc": "./app.html", 5 | "fieldTypes": ["Integer", "Number"] 6 | } 7 | -------------------------------------------------------------------------------- /samples/slug/README.md: -------------------------------------------------------------------------------- 1 | Slug Generator 2 | -------------- 3 | 4 | ![slug-widget](http://contentful.github.io/extensions/assets/slug-widget.png) 5 | 6 | This extension enables to generate a slug using the title of the entry. 7 | It also checks whether or not any duplicates across the other entries of the 8 | same content type exist to warn users before publishing. 9 | 10 | **Note**: In order to prevent publication whenever another entry has the same 11 | value for the field, it is advised to use the "Uniqueness" validation constraint. 12 | It can be combined with this extension. 13 | 14 | ### Installation steps 15 | 16 | Ensure you checked [the samples requirements listed here](../README.md). 17 | 18 | Install dependencies if not done already through `npm install`. 19 | 20 | You then need to update the [Makefile](./Makefile), uncomment and update the 21 | following line: 22 | ```Makefile 23 | export SPACE= 24 | ``` 25 | 26 | Then do the following: 27 | ```bash 28 | make create 29 | ``` 30 | 31 | ### Updating the extension 32 | If you make any changes to the code of the extension, you may push these updates 33 | to Contentful by calling: 34 | ```bash 35 | make update 36 | ``` 37 | 38 | ### Debugging in local environment 39 | If you wish to run the extension from your local environment for debugging 40 | purposes, you may use the following commands: 41 | ```bash 42 | make update-dev 43 | make serve 44 | ``` 45 | -------------------------------------------------------------------------------- /samples/slug/extension.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "slug", 3 | "name": "Slug Generator", 4 | "srcdoc": "./index.html", 5 | "fieldTypes": ["Symbol"] 6 | } 7 | -------------------------------------------------------------------------------- /samples/template-vanilla/README.md: -------------------------------------------------------------------------------- 1 | ## Vanilla HTML5 UI Extension template 2 | 3 | Vanilla HTML5 UI Extension template implementing the basic lifecycle methods to better understand the concept. 4 | 5 | ![Screenshot of template](../../docs/assets/uiextensions-vanilla-extension.png) 6 | The UI Extension in the Contentful web app 7 | 8 | ![Screenshot of params](../../docs/assets/uiextensions-vanilla-extension-params.png) 9 | Assigning the UI Extension to a content type and setting the instance parameter 10 | 11 | The template includes: 12 | - the [UI Extensions SDK][extensions-sdk] library 13 | - a Contentful look-and-feel by loading our CSS library 14 | - basic handling of user-generated events (here: keyboard input) 15 | - basic handling of externally generated events (here: changes introduced by other authors) 16 | - cleanup of event listeners 17 | - example usage of [installation and instance parameters](https://www.contentful.com/developers/docs/references/content-management-api/#/reference/ui-extensions/configuration-parameters) 18 | 19 | ## Usage 20 | 21 | To install the UI Extension: 22 | ```bash 23 | contentful extension create --installation-parameters '{"exampleParameter": "I am an installation parameter value."}' 24 | ``` 25 | To update the UI Extension: 26 | ```bash 27 | contentful extension update --force --installation-parameters '{"exampleParameter": "I am an updated installation parameter value."}' 28 | ``` 29 | 30 | 31 | [extensions-sdk]: https://github.com/contentful/ui-extensions-sdk/blob/master/docs/ui-extensions-sdk-frontend.md 32 | -------------------------------------------------------------------------------- /samples/template-vanilla/extension.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "template-vanilla", 3 | "name": "Vanilla UI Extension template", 4 | "srcdoc": "index.html", 5 | "fieldTypes": ["Symbol", "Text"], 6 | "parameters": { 7 | "instance": [ 8 | { 9 | "id": "exampleParameter", 10 | "type": "Symbol", 11 | "name": "An example instance parameter" 12 | } 13 | ], 14 | "installation": [ 15 | { 16 | "id": "exampleParameter", 17 | "type": "Symbol", 18 | "name": "An example installation parameter" 19 | } 20 | ] 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /samples/translate/README.md: -------------------------------------------------------------------------------- 1 | # Translation extension 2 | 3 | This extension translates text from the default locale to other locales in a space using the [Yandex](https://translate.yandex.com/) translation API. 4 | 5 | ![translate-widget](../../docs/assets/translate-widget.png) 6 | 7 | ## Installation and usage 8 | 9 | [Check you have the requirements needed](../README.md#extensions-samples) to use our extensions. 10 | -------------------------------------------------------------------------------- /samples/translate/extension.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "translate", 3 | "name": "Translate Widget", 4 | "srcdoc": "index.html", 5 | "fieldTypes": ["Symbol", "Text"] 6 | } 7 | -------------------------------------------------------------------------------- /samples/wistia-videos/README.md: -------------------------------------------------------------------------------- 1 | # Wistia videos 2 | 3 | This UI extension allows your editors to see a nice dropdown of all the videos in your Wistia account sorted by Projects. Your developers can then use this data to construct landing pages from the data. 4 | 5 | ![](./screenshot.png) 6 | 7 | ## Requirements 8 | 9 | - A Wistia account and access to an admin account 10 | - A Wistia API Key with permissions: _read all project and video data._ 11 | - Ability to host a lambda function (AWS, Google Cloud Functions, etc...) 12 | 13 | ## Usage 14 | 15 | ### 1. Get your Wistia key 16 | 17 | Go to your _Account > Settings_ in Wistia. On the sidebar click on **API Access** under the **Advanced** header. 18 | 19 | Create an API key with the permissions _Read all project and video data_. 20 | 21 | ![](../../docs/assets/wistia-create-api-key.png) 22 | 23 | Once you've created your API Token click _Copy_ and save it for the next step. 24 | 25 | ![](../../docs/assets/wistia-api-key-password.png) 26 | 27 | ### 2. Deploy the Lambda function 28 | 29 | Now that you have these credentials you can deploy your Lambda function to your desired platform. 30 | 31 | [Here is the code for the lambda function](./lambda-function.js) that you will be deploying. 32 | 33 | Copy the API_KEY you have from step 1 into the Environment Variables section of your lambda hosting platform. Here is the names of the variable you will be adding to that section. **Make sure the key name is added exactly as below otherwise your lambda function won't work**. 34 | 35 | ``` 36 | WISTIA_API_KEY= 37 | ``` 38 | -------------------------------------------------------------------------------- /samples/wistia-videos/extension.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Wistia Videos", 3 | "id": "wistia-videos", 4 | "srcdoc": "./app.html", 5 | "fieldTypes": ["Object"], 6 | "parameters": { 7 | "installation": [ 8 | { 9 | "id": "serviceUri", 10 | "type": "Symbol", 11 | "name": "Lambda Function URL", 12 | "required": true 13 | } 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /samples/wistia-videos/lambda-function.js: -------------------------------------------------------------------------------- 1 | const https = require("https"); 2 | 3 | const request = ({ method, hostname, path, headers }) => 4 | new Promise((resolve, reject) => { 5 | https 6 | .request({ method, hostname, path, headers }, response => { 7 | let data = ""; 8 | response.on("data", chunk => (data += chunk)); 9 | response.on("end", () => resolve(JSON.parse(data))); 10 | }) 11 | .on("error", err => reject(err)) 12 | .end(); 13 | }); 14 | 15 | const cleanup = res => 16 | res.map(video => { 17 | [ 18 | "embedCode", 19 | "progress", 20 | "status", 21 | "assets", 22 | "type", 23 | "created", 24 | "updated" 25 | ].forEach(e => delete video[e]); 26 | 27 | return { 28 | ...video, 29 | thumbnail: video.thumbnail.url.replace(/\?image_crop_resized.*/, "") 30 | }; 31 | }); 32 | 33 | exports.handler = function(event, context, callback) { 34 | request({ 35 | method: "GET", 36 | hostname: `api.wistia.com`, 37 | path: `/v1/medias.json?api_password=${process.env.WISTIA_API_KEY}` 38 | }) 39 | .then(cleanup) 40 | .then(res => 41 | callback(null, { 42 | statusCode: 200, 43 | headers: { 44 | "Access-Control-Allow-Origin": "*", 45 | "Content-Type": "application/json" 46 | }, 47 | body: JSON.stringify(res) 48 | }) 49 | ) 50 | .catch(err => { 51 | console.log(err); 52 | callback(err); 53 | }); 54 | }; 55 | -------------------------------------------------------------------------------- /samples/wistia-videos/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentful/extensions/33bc7678394b6eeb09d450b1680b71a8e2111187/samples/wistia-videos/screenshot.png -------------------------------------------------------------------------------- /samples/youtube-id/README.md: -------------------------------------------------------------------------------- 1 | YouTube ID 2 | -------------- 3 | 4 | ![youtube-id](http://contentful.github.io/extensions/assets/youtube-id.png) 5 | 6 | This extension extracts the video ID from a YouTube URI. 7 | 8 | ### Installation and usage 9 | 10 | Ensure you checked [the samples requirements listed here](../README.md). 11 | 12 | Install extension for space: 13 | 14 | ```bash 15 | export SPACE= 16 | 17 | contentful extension create --space-id $SPACE 18 | ``` 19 | 20 | From this point on, you can use the [other commands](https://github.com/contentful/contentful-cli/tree/master/docs/extension) the contentful-cli provides for extensions. 21 | -------------------------------------------------------------------------------- /samples/youtube-id/extension.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "youtube-id", 3 | "fieldTypes":["Symbol"], 4 | "name":"Youtube ID", 5 | "srcdoc":"index.html" 6 | } 7 | -------------------------------------------------------------------------------- /samples/youtube-id/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 11 |

    12 | Video ID 13 |

    14 | 15 | 16 | 41 | -------------------------------------------------------------------------------- /scripts/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "node": true 4 | }, 5 | "extends": [ 6 | "../.eslintrc.js", 7 | "plugin:node/recommended" 8 | ], 9 | "plugins": ["node"], 10 | "rules": { 11 | "no-console": "off", 12 | "node/no-unpublished-require": "off" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /scripts/utils.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { readdir, readdirSync, readFile, writeFile } = require('fs-extra'); 4 | 5 | async function dirs(directory) { 6 | const dirs = []; 7 | for (const file of await readdir(directory, { withFileTypes: true })) { 8 | if (file.isDirectory()) { 9 | dirs.push(file.name); 10 | } 11 | } 12 | return dirs; 13 | } 14 | 15 | function dirsSync(directory) { 16 | const files = readdirSync(directory, { withFileTypes: true }); 17 | 18 | return files.filter(file => file.isDirectory()).map(file => file.name); 19 | } 20 | 21 | async function readJsonFile(filePath) { 22 | return JSON.parse(await readFile(filePath, 'utf8')); 23 | } 24 | 25 | async function writeJsonFile(filePath, data) { 26 | return await writeFile(filePath, JSON.stringify(data), 'utf8'); 27 | } 28 | 29 | module.exports = { dirs, dirsSync, readJsonFile, writeJsonFile }; 30 | -------------------------------------------------------------------------------- /test/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "node": true 4 | }, 5 | "extends": [ 6 | "../.eslintrc.js", 7 | "plugin:jest/recommended", 8 | "plugin:jest/style", 9 | "plugin:node/recommended" 10 | ], 11 | "plugins": ["node"], 12 | "rules": { 13 | "no-console": "off", 14 | "node/no-unpublished-require": "off" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/dist-file-structure.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | const { dirsSync } = require('../scripts/utils.js'); 5 | 6 | const BASE_DIR = path.join(__dirname, '..', 'dist'); 7 | const extensions = dirsSync(BASE_DIR); 8 | 9 | describe('Dist file structure', function() { 10 | describe.each(extensions)('%s', function(extension) { 11 | test('has extension.json', function() { 12 | expect(path.join(BASE_DIR, extension, 'extension.json')).toBeExistingFile(); 13 | }); 14 | 15 | test('has _headers', function() { 16 | expect(path.join(BASE_DIR, extension, '_headers')).toBeExistingFile(); 17 | }); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /test/matchers/filesystem.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | const { existsSync } = require('fs'); 5 | const { matcherHint } = require('jest-matcher-utils'); 6 | 7 | expect.extend({ 8 | toBeExistingFile(received) { 9 | const pass = existsSync(received); 10 | 11 | let fileName = ''; 12 | if (typeof received === 'string') { 13 | const parts = received.split(path.sep); 14 | fileName = parts[parts.length - 1]; 15 | } 16 | 17 | const message = pass 18 | ? () => 19 | `${matcherHint( 20 | '.not.toBeExistingFile', 21 | received, 22 | '' 23 | )}\n\nExpected ${fileName} not to exist` 24 | : () => `${matcherHint('.toBeExistingFile', received, '')}\n\nExpected ${fileName} to exist`; 25 | 26 | return { 27 | actual: received, 28 | name: 'toBeExistingFile', 29 | message, 30 | pass 31 | }; 32 | } 33 | }); 34 | -------------------------------------------------------------------------------- /test/setup.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | require('./matchers/filesystem.js'); 4 | const { matchers } = require('jest-json-schema'); 5 | 6 | const jestExpect = global.expect; 7 | if (jestExpect !== undefined) { 8 | jestExpect.extend(matchers); 9 | } else { 10 | // eslint-disable-next-line no-console 11 | console.error("Unable to find Jest's global expect."); 12 | } 13 | -------------------------------------------------------------------------------- /test/source-file-structure.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | const { dirsSync, readJsonFile } = require('../scripts/utils.js'); 5 | 6 | const BASE_DIR = path.join(__dirname, '..', 'marketplace'); 7 | const extensions = dirsSync(BASE_DIR); 8 | 9 | describe.each(extensions)('Source file structure for %s', function(extension) { 10 | test('has package.json', function() { 11 | expect(path.join(BASE_DIR, extension, 'package.json')).toBeExistingFile(); 12 | }); 13 | 14 | test('has extension.json', function() { 15 | expect(path.join(BASE_DIR, extension, 'extension.json')).toBeExistingFile(); 16 | }); 17 | 18 | test('folder name matches extension ID', async function() { 19 | const { id } = await readJsonFile(path.join(BASE_DIR, extension, 'extension.json')); 20 | 21 | expect(extension).toBe(id); 22 | }); 23 | 24 | test('has a non-zero major version', async function() { 25 | const { version } = await readJsonFile(path.join(BASE_DIR, extension, 'package.json')); 26 | expect(Number(version.split('.')[0])).toBeGreaterThanOrEqual(1); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "commonjs", 5 | "strict": true, 6 | "jsx": "react" 7 | } 8 | } 9 | --------------------------------------------------------------------------------