diff --git a/.github/scripts/manage-deploy.js b/.github/scripts/manage-deploy.js new file mode 100644 index 000000000..9e34a19e5 --- /dev/null +++ b/.github/scripts/manage-deploy.js @@ -0,0 +1,65 @@ +require("dotenv").config(); +const { Octokit } = require("@octokit/rest"); + +const octokit = new Octokit({ + auth: process.env.GITHUB_TOKEN, +}); + +async function closeIssuesForMilestone() { + const owner = "jihong88"; + const repo = "suneditor"; + const versionName = process.env.VERSION_NAME; + + if (!versionName) { + console.log("No version name provided"); + return; + } + + try { + const milestones = await octokit.rest.issues.listMilestones({ + owner, + repo, + state: "open", + }); + + const milestone = milestones.data.find((m) => m.title === versionName); + if (!milestone) { + console.log("No matching milestone found"); + return; + } + + const issues = await octokit.issues.listForRepo({ + owner, + repo, + state: "open", + milestone: milestone.number, + }); + + issues.data.forEach(async (issue) => { + const comment = { + owner, + repo, + issue_number: issue.number, + body: + "Thank you for your engagement with the project.\n" + + "This issue has been resolved for version " + + versionName + + ".\n" + + "If the problem persists or if you believe this issue is still relevant,\n" + + "please reopen it with additional comments.", + }; + await octokit.issues.createComment(comment); + + await octokit.issues.update({ + owner, + repo, + issue_number: issue.number, + state: "closed", + }); + }); + } catch (error) { + console.error(`Error while processing issues for milestone: ${error}`); + } +} + +closeIssuesForMilestone(); diff --git a/.github/scripts/manage-issues.js b/.github/scripts/manage-issues.js new file mode 100644 index 000000000..3fd10ca8f --- /dev/null +++ b/.github/scripts/manage-issues.js @@ -0,0 +1,52 @@ +require("dotenv").config(); +const { Octokit } = require("@octokit/rest"); + +const octokit = new Octokit({ + auth: process.env.GITHUB_TOKEN, +}); + +async function closeOldIssues() { + try { + const owner = "jihong88"; + const repo = "suneditor"; + const issues = await octokit.issues.listForRepo({ + owner, + repo, + state: "open", + }); + + const sixWeeksAgo = new Date(); + sixWeeksAgo.setDate(sixWeeksAgo.getDate() - 42); // 6 weeks + + for (const issue of issues.data) { + const lastUpdated = new Date(issue.updated_at); + if (lastUpdated < sixWeeksAgo) { + const comment = { + owner, + repo, + issue_number: issue.number, + body: + "Thank you for your engagement with the project.\n" + + "Due to a lack of activity for over 6 weeks, this issue has been automatically closed." + + "\nThis is part of the process to keep the project up-to-date.\n\n" + + "If a new version has been released recently, please test your scenario with that version to see if the issue persists.\n" + + "If the problem still exists or if you believe this issue is still relevant, \n" + + "feel free to reopen it and provide additional comments.\n\n" + + "I truly appreciate your continuous interest and support for the project. Your feedback is crucial in improving its quality.", + }; + await octokit.issues.createComment(comment); + + await octokit.issues.update({ + owner, + repo, + issue_number: issue.number, + state: "closed", + }); + } + } + } catch (error) { + console.error(`Error while closing issues: ${error}`); + } +} + +closeOldIssues(); diff --git a/.github/workflows/deploy-manager.yml b/.github/workflows/deploy-manager.yml new file mode 100644 index 000000000..76b1fb732 --- /dev/null +++ b/.github/workflows/deploy-manager.yml @@ -0,0 +1,49 @@ +name: Deploy Management Action + +on: + push: + branches: + - release + +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Setup Node.js + uses: actions/setup-node@v2 + with: + node-version: "12" + registry-url: "https://registry.npmjs.org/" + + - name: Check if version has been updated + id: check-version + run: | + PACKAGE_VERSION=$(node -p "require('./package.json').version") + LAST_GIT_TAG=$(git describe --tags --abbrev=0) + if [ "v$PACKAGE_VERSION" == "$LAST_GIT_TAG" ]; then + echo "Package version ($PACKAGE_VERSION) has not been updated since the last tag ($LAST_GIT_TAG)." + exit 1 + else + echo "Package version has been updated to $PACKAGE_VERSION." + fi + + - name: Install dependencies + run: npm install && npm audit fix + + - name: Build + run: npm run build + + - name: Deploy + run: npm publish + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + + - name: Execute script for milestone + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + VERSION_NAME: ${{ steps.check-version.outputs.package_version }} + run: node .github/scripts/manage-deploy.js $VERSION_NAME + diff --git a/.github/workflows/issue-manager.yml b/.github/workflows/issue-manager.yml new file mode 100644 index 000000000..518eece84 --- /dev/null +++ b/.github/workflows/issue-manager.yml @@ -0,0 +1,14 @@ +name: Issue Management Action + +on: + schedule: + - cron: '0 0 * * *' + +jobs: + manage-issues: + runs-on: ubuntu-latest + steps: + - name: Run script to manage issues + run: node .github/scripts/manage-issues.js + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index 1fc7bafc2..a825daaf0 100644 --- a/.gitignore +++ b/.gitignore @@ -14,4 +14,5 @@ bower_components/** #dev .git/** -package-lock.json \ No newline at end of file +package-lock.json +/.vs diff --git a/README.md b/README.md index 8dd3c3e16..e7dae9d34 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # SunEditor Vanilla javascript based WYSIWYG web editor, with no dependencies. SunEditor supports IE11 and all modern browsers with no dependencies and polyfill. +Coded based on ES5 in supported by IE11. #### Demo : suneditor.com @@ -390,6 +391,7 @@ plugins: [ // * {custom_plugin, ...plugins} // Values +strictMode : Option to disable clean mode, which checks the styles, classes, etc. of the editor content. default : false {Boolean} lang : language object. default : en {Object} defaultTag : Specifies default tag name of the editor. default: 'p' {String} textTags : You can change the tag of the default text button. default: { bold: 'STRONG', underline: 'U', italic: 'EM', strike: 'DEL' } diff --git a/dist/suneditor.min.js b/dist/suneditor.min.js index 008804974..508633832 100644 --- a/dist/suneditor.min.js +++ b/dist/suneditor.min.js @@ -1,2 +1,2 @@ -!function(e){var t={};function n(i){if(t[i])return t[i].exports;var l=t[i]={i:i,l:!1,exports:{}};return e[i].call(l.exports,l,l.exports,n),l.l=!0,l.exports}n.m=e,n.c=t,n.d=function(e,t,i){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var l in e)n.d(i,l,function(t){return e[t]}.bind(null,l));return i},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s="XJR1")}({"1kvd":function(e,t,n){"use strict";var i,l;i="undefined"!=typeof window?window:this,l=function(e,t){const n={name:"dialog",add:function(e){const t=e.context;t.dialog={kind:"",updateModal:!1,_closeSignal:!1};let n=e.util.createElement("DIV");n.className="se-dialog sun-editor-common";let i=e.util.createElement("DIV");i.className="se-dialog-back",i.style.display="none";let l=e.util.createElement("DIV");l.className="se-dialog-inner",l.style.display="none",n.appendChild(i),n.appendChild(l),t.dialog.modalArea=n,t.dialog.back=i,t.dialog.modal=l,t.dialog.modal.addEventListener("mousedown",this._onMouseDown_dialog.bind(e)),t.dialog.modal.addEventListener("click",this._onClick_dialog.bind(e)),t.element.relative.appendChild(n),n=null,i=null,l=null},_onMouseDown_dialog:function(e){/se-dialog-inner/.test(e.target.className)?this.context.dialog._closeSignal=!0:this.context.dialog._closeSignal=!1},_onClick_dialog:function(e){(/close/.test(e.target.getAttribute("data-command"))||this.context.dialog._closeSignal)&&this.plugins.dialog.close.call(this)},open:function(e,t){if(this.modalForm)return!1;this.plugins.dialog._bindClose&&(this._d.removeEventListener("keydown",this.plugins.dialog._bindClose),this.plugins.dialog._bindClose=null),this.plugins.dialog._bindClose=function(e){/27/.test(e.keyCode)&&this.plugins.dialog.close.call(this)}.bind(this),this._d.addEventListener("keydown",this.plugins.dialog._bindClose),this.context.dialog.updateModal=t,"full"===this.options.popupDisplay?this.context.dialog.modalArea.style.position="fixed":this.context.dialog.modalArea.style.position="absolute",this.context.dialog.kind=e,this.modalForm=this.context[e].modal;const n=this.context[e].focusElement;"function"==typeof this.plugins[e].on&&this.plugins[e].on.call(this,t),this.context.dialog.modalArea.style.display="block",this.context.dialog.back.style.display="block",this.context.dialog.modal.style.display="block",this.modalForm.style.display="block",n&&n.focus()},_bindClose:null,close:function(){this.plugins.dialog._bindClose&&(this._d.removeEventListener("keydown",this.plugins.dialog._bindClose),this.plugins.dialog._bindClose=null);const e=this.context.dialog.kind;this.modalForm.style.display="none",this.context.dialog.back.style.display="none",this.context.dialog.modalArea.style.display="none",this.context.dialog.updateModal=!1,"function"==typeof this.plugins[e].init&&this.plugins[e].init.call(this),this.context.dialog.kind="",this.modalForm=null,this.focus()}};return void 0===t&&(e.SUNEDITOR_MODULES||Object.defineProperty(e,"SUNEDITOR_MODULES",{enumerable:!0,writable:!1,configurable:!1,value:{}}),Object.defineProperty(e.SUNEDITOR_MODULES,"dialog",{enumerable:!0,writable:!1,configurable:!1,value:n})),n},"object"==typeof e.exports?e.exports=i.document?l(i,!0):function(e){if(!e.document)throw new Error("SUNEDITOR_MODULES a window with a document");return l(e)}:l(i)},"3FqI":function(e,t,n){},JhlZ:function(e,t,n){"use strict";var i,l;i="undefined"!=typeof window?window:this,l=function(e,t){const n={name:"fileBrowser",_xmlHttp:null,_loading:null,add:function(e){const t=e.context;t.fileBrowser={_closeSignal:!1,area:null,header:null,tagArea:null,body:null,list:null,tagElements:null,items:[],selectedTags:[],selectorHandler:null,contextPlugin:"",columnSize:4};let n=e.util.createElement("DIV");n.className="se-file-browser sun-editor-common";let i=e.util.createElement("DIV");i.className="se-file-browser-back";let l=e.util.createElement("DIV");l.className="se-file-browser-inner",l.innerHTML=this.set_browser(e),n.appendChild(i),n.appendChild(l),this._loading=n.querySelector(".se-loading-box"),t.fileBrowser.area=n,t.fileBrowser.header=l.querySelector(".se-file-browser-header"),t.fileBrowser.titleArea=l.querySelector(".se-file-browser-title"),t.fileBrowser.tagArea=l.querySelector(".se-file-browser-tags"),t.fileBrowser.body=l.querySelector(".se-file-browser-body"),t.fileBrowser.list=l.querySelector(".se-file-browser-list"),t.fileBrowser.tagArea.addEventListener("click",this.onClickTag.bind(e)),t.fileBrowser.list.addEventListener("click",this.onClickFile.bind(e)),l.addEventListener("mousedown",this._onMouseDown_browser.bind(e)),l.addEventListener("click",this._onClick_browser.bind(e)),t.element.relative.appendChild(n),n=null,i=null,l=null},set_browser:function(e){const t=e.lang;return'
0)&&t,n=!!(n&&n.length>0)&&n;const s=!e,o=s&&!n&&!t;let c=l.startContainer,d=l.startOffset,u=l.endContainer,h=l.endOffset;if(o&&l.collapsed&&r.isFormatElement(c.parentNode)||c===u&&1===c.nodeType&&r.isNonEditable(c)){const e=c.parentNode;if(!r.isListCell(e)||!r.getValues(e.style).some(function(e){return this._listKebab.indexOf(e)>-1}.bind(this)))return}if(l.collapsed&&!o&&1===c.nodeType&&!r.isBreak(c)&&!r.isComponent(c)){let e=null;const t=c.childNodes[d];t&&(e=t.nextSibling?r.isBreak(t)?t:t.nextSibling:null);const n=r.createTextNode(r.zeroWidthSpace);c.insertBefore(n,e),this.setRange(n,1,n,1),l=this.getRange(),c=l.startContainer,d=l.startOffset,u=l.endContainer,h=l.endOffset}r.isFormatElement(c)&&(c=c.childNodes[d]||c.firstChild,d=0),r.isFormatElement(u)&&(u=u.childNodes[h]||u.lastChild,h=u.textContent.length),s&&(e=r.createElement("DIV"));const g=a.RegExp,p=e.nodeName;if(!o&&c===u&&!n&&e){let t=c,n=0;const i=[],l=e.style;for(let e=0,t=l.length;e
"+l.defaultTag+">"},_setEditorDataToCodeView:function(){const t=this.convertHTMLForCodeView(e.element.wysiwyg,!1);let n="";if(l.fullPage){const e=r.getAttributesToString(this._wd.body,null);n="\n\n"+this._wd.head.outerHTML.replace(/>(?!\n)/g,">\n")+"\n"+t+"\n"}else n=t;e.element.code.style.display="block",e.element.wysiwygFrame.style.display="none",this._setCodeView(n)},toggleFullScreen:function(t){const n=e.element.topArea,i=e.element.toolbar,s=e.element.editorArea,d=e.element.wysiwygFrame,g=e.element.code,p=this._variable;this.controllersOff();const m="none"===i.style.display||this._isInline&&!this._inlineToolbarAttr.isShow;p.isFullScreen?(p.isFullScreen=!1,d.style.cssText=p._wysiwygOriginCssText,g.style.cssText=p._codeOriginCssText,i.style.cssText="",s.style.cssText=p._editorAreaOriginCssText,n.style.cssText=p._originCssText,o.body.style.overflow=p._bodyOverflow,"auto"!==l.height||l.codeMirrorEditor||u._codeViewAutoHeight(),l.toolbarContainer&&l.toolbarContainer.appendChild(i),l.stickyToolbar>-1&&r.removeClass(i,"se-toolbar-sticky"),p._fullScreenAttrs.sticky&&!l.toolbarContainer&&(p._fullScreenAttrs.sticky=!1,e.element._stickyDummy.style.display="block",r.addClass(i,"se-toolbar-sticky")),this._isInline=p._fullScreenAttrs.inline,this._isBalloon=p._fullScreenAttrs.balloon,this._isInline&&u._showToolbarInline(),l.toolbarContainer&&r.removeClass(i,"se-toolbar-balloon"),u.onScroll_window(),t&&r.changeElement(t.firstElementChild,c.expansion),e.element.topArea.style.marginTop="",r.removeClass(this._styleCommandMap.fullScreen,"active")):(p.isFullScreen=!0,p._fullScreenAttrs.inline=this._isInline,p._fullScreenAttrs.balloon=this._isBalloon,(this._isInline||this._isBalloon)&&(this._isInline=!1,this._isBalloon=!1),l.toolbarContainer&&e.element.relative.insertBefore(i,s),n.style.position="fixed",n.style.top="0",n.style.left="0",n.style.width="100%",n.style.maxWidth="100%",n.style.height="100%",n.style.zIndex="2147483647",""!==e.element._stickyDummy.style.display&&(p._fullScreenAttrs.sticky=!0,e.element._stickyDummy.style.display="none",r.removeClass(i,"se-toolbar-sticky")),p._bodyOverflow=o.body.style.overflow,o.body.style.overflow="hidden",p._editorAreaOriginCssText=s.style.cssText,p._wysiwygOriginCssText=d.style.cssText,p._codeOriginCssText=g.style.cssText,s.style.cssText=i.style.cssText="",d.style.cssText=(d.style.cssText.match(/\s?display(\s+)?:(\s+)?[a-zA-Z]+;/)||[""])[0]+l._editorStyles.editor,g.style.cssText=(g.style.cssText.match(/\s?display(\s+)?:(\s+)?[a-zA-Z]+;/)||[""])[0],i.style.width=d.style.height=g.style.height="100%",i.style.position="relative",i.style.display="block",p.innerHeight_fullScreen=a.innerHeight-i.offsetHeight,s.style.height=p.innerHeight_fullScreen-l.fullScreenOffset+"px",t&&r.changeElement(t.firstElementChild,c.reduction),l.iframe&&"auto"===l.height&&(s.style.overflow="auto",this._iframeAutoHeight()),e.element.topArea.style.marginTop=l.fullScreenOffset+"px",r.addClass(this._styleCommandMap.fullScreen,"active")),m&&h.toolbar.hide(),"function"==typeof h.toggleFullScreen&&h.toggleFullScreen(this._variable.isFullScreen,this)},print:function(){const e=r.createElement("IFRAME");e.style.display="none",o.body.appendChild(e);const t=l.printTemplate?l.printTemplate.replace(/\{\{\s*contents\s*\}\}/i,this.getContents(!0)):this.getContents(!0),n=r.getIframeDocument(e),i=this._wd;if(l.iframe){const e=null!==l._printClass?'class="'+l._printClass+'"':l.fullPage?r.getAttributesToString(i.body,["contenteditable"]):'class="'+l._editableClass+'"';n.write(""+i.head.innerHTML+""+t+"")}else{const e=o.head.getElementsByTagName("link"),i=o.head.getElementsByTagName("style");let s="";for(let t=0,n=e.length;t0&&(l+="<"+n+">"+r._HTMLConvertor(e)+""+n+">");return l}return 8===e.nodeType&&this._allowHTMLComments?"\x3c!--"+e.textContent.trim()+"--\x3e":""},_tagConvertor:function(e){if(!this._disallowedTextTagsRegExp)return e;const t=l._textTagsMap;return e.replace(this._disallowedTextTagsRegExp,(function(e,n,i,l){return n+("string"==typeof t[i]?t[i]:i)+(l?" "+l:"")}))},_deleteDisallowedTags:function(e){return e=e.replace(this.__disallowedTagsRegExp,"").replace(/<[a-z0-9]+\:[a-z0-9]+[^>^\/]*>[^>]*<\/[a-z0-9]+\:[a-z0-9]+>/gi,""),/\bfont\b/i.test(this.options._editorTagsWhitelist)||(e=e.replace(/(<\/?)font(\s?)/gi,"$1span$2")),e.replace(this.editorTagsWhitelistRegExp,"").replace(this.editorTagsBlacklistRegExp,"")},_convertFontSize:function(e,t){const n=this._w.Math,i=t.match(/(\d+(?:\.\d+)?)(.+)/),l=i?1*i[1]:r.fontValueMap[t],s=i?i[2]:"rem";let o=l;switch(/em/.test(s)?o=n.round(l/.0625):"pt"===s?o=n.round(1.333*l):"%"===s&&(o=l/100),e){case"em":case"rem":case"%":return(.0625*o).toFixed(2)+e;case"pt":return n.floor(o/1.333)+e;default:return o+e}},_cleanStyle:function(e,t,n){let i=(e.match(/style\s*=\s*(?:"|')[^"']*(?:"|')/)||[])[0];if(/span/i.test(n)&&!i&&(e.match(/0&&t.push('style="'+n.join(";")+'"')}}return t},_cleanTags:function(e,t,n){if(/^<[a-z0-9]+\:[a-z0-9]+/i.test(t))return t;let i=null;const l=n.match(/(?!<)[a-zA-Z0-9\-]+/)[0].toLowerCase(),s=this._attributesTagsBlacklist[l];t=t.replace(/\s(?:on[a-z]+)\s*=\s*(")[^"]*\1/gi,""),t=s?t.replace(s,""):t.replace(this._attributesBlacklistRegExp,"");const o=this._attributesTagsWhitelist[l];if(i=o?t.match(o):t.match(e?this._attributesWhitelistRegExp:this._attributesWhitelistRegExp_all_data),e||"span"===l)if("a"===l){const e=t.match(/(?:(?:id|name)\s*=\s*(?:"|')[^"']*(?:"|'))/g);e&&(i||(i=[]),i.push(e[0]))}else i&&/style=/i.test(i.toString())||("span"===l?i=this._cleanStyle(t,i,"span"):/^(P|DIV|H[1-6]|PRE)$/i.test(l)&&(i=this._cleanStyle(t,i,"format")));else{const e=t.match(/style\s*=\s*(?:"|')[^"']*(?:"|')/);e&&!i?i=[e[0]]:e&&!i.some((function(e){return/^style/.test(e.trim())}))&&i.push(e[0])}if(r.isFigures(l)){const e=t.match(/style\s*=\s*(?:"|')[^"']*(?:"|')/);i||(i=[]),e&&i.push(e[0])}if(i)for(let e,t=0,l=i.length;t
")+"":r.isRangeFormatElement(n)&&!r.isTable(n)?t+=this._convertListCell(n):t+="
")+"
$/i,"");const i=o.createRange().createContextualFragment(e);try{r._consistencyCheckOfHTML(i,this._htmlCheckWhitelistRegExp,this._htmlCheckBlacklistRegExp,this._classNameFilter)}catch(e){console.warn("[SUNEDITOR.cleanHTML.consistencyCheck.fail] "+e)}if(this.managedTagsInfo&&this.managedTagsInfo.query){const e=i.querySelectorAll(this.managedTagsInfo.query);for(let t,n,i=0,l=e.length;i
"+l.defaultTag+">":(i=r.htmlRemoveWhiteSpace(i),this._tagConvertor(i))},convertHTMLForCodeView:function(e,t){let n="";const i=a.RegExp,l=new i("^(BLOCKQUOTE|PRE|TABLE|THEAD|TBODY|TR|TH|TD|OL|UL|IMG|IFRAME|VIDEO|AUDIO|FIGURE|FIGCAPTION|HR|BR|CANVAS|SELECT)$","i"),s="string"==typeof e?o.createRange().createContextualFragment(e):e,c=function(e){return this.isFormatElement(e)||this.isComponent(e)}.bind(r),d=t?"":"\n";let u=t?0:1*this._variable.codeIndent;return u=u>0?new a.Array(u+1).join(" "):"",function e(t,s){const o=t.childNodes,h=l.test(t.nodeName),g=h?s:"";for(let p,m,f,_,b,v,y=0,C=o.length;y