Changeset 2896421
- Timestamp:
- 04/10/2023 06:35:03 AM (3 years ago)
- Location:
- qalam/trunk
- Files:
-
- 8 added
- 4 edited
-
assets/css/qalamExtension.css (modified) (2 diffs)
-
assets/fonts (added)
-
assets/fonts/Tajawal-Bold.woff (added)
-
assets/fonts/Tajawal-ExtraBold.woff (added)
-
assets/fonts/Tajawal-Light.woff (added)
-
assets/fonts/Tajawal-Regular.woff (added)
-
assets/images/add.svg (added)
-
assets/images/more.png (added)
-
assets/images/wrong-suggestion.svg (added)
-
assets/js/main.js (modified) (1 diff)
-
qalam.php (modified) (1 diff)
-
readme.txt (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
qalam/trunk/assets/css/qalamExtension.css
r2594341 r2896421 1 1 @font-face { 2 font-family: "Cairo-Regular"; 3 src: URL("chrome-extension://__MSG_@@extension_id__/fonts/Cairo-Regular.e793edb5.ttf") 4 format("truetype"); 5 } 2 font-family: 'Tajawal'; 3 font-style: normal; 4 font-weight: 400; 5 src: URL('../fonts/Tajawal-Regular.woff') format('woff'); 6 } 7 8 @font-face { 9 font-family: 'Tajawal'; 10 font-style: normal; 11 font-weight: 300; 12 src: URL('../fonts/Tajawal-Light.woff') format('woff'); 13 } 14 15 @font-face { 16 font-family: 'Tajawal'; 17 font-style: normal; 18 font-weight: 700; 19 src: URL('../fonts/Tajawal-Bold.woff') format('woff'); 20 } 21 22 @font-face { 23 font-family: 'Tajawal'; 24 font-style: normal; 25 font-weight: 900; 26 src: URL('../fonts/Tajawal-ExtraBold.woff') format('woff'); 27 } 28 6 29 qalam-wrapper { 7 position: absolute;8 top: 0px;9 left: 0px;30 position: absolute; 31 top: 0px; 32 left: 0px; 10 33 } 11 34 qalam-extension { 12 position: absolute;13 pointer-events: none;14 direction: ltr;15 z-index: 2147483647;35 position: absolute; 36 pointer-events: none; 37 direction: ltr; 38 z-index: 998; 16 39 } 17 40 qalam-extension qalam-extension-cont { 18 position: absolute;19 width: 100%;20 height: 100%;21 top: 0px;22 left: 0px;23 direction: ltr;24 overflow: hidden;41 position: absolute; 42 width: 100%; 43 height: 100%; 44 top: 0px; 45 left: 0px; 46 direction: ltr; 47 overflow: hidden; 25 48 } 26 49 qalam-extension qalam-extension-cont .qalam-highlights-cont { 27 width: 100%;28 height: 100%;29 position: relative;50 width: 100%; 51 height: 100%; 52 position: relative; 30 53 } 31 54 qalam-extension qalam-extension-cont .qalam-highlights-cont qalam-label { 32 position: absolute;33 cursor: pointer;34 pointer-events: all;35 overflow: hidden;55 position: absolute; 56 cursor: pointer; 57 pointer-events: all; 58 overflow: hidden; 36 59 } 37 60 qalam-extension qalam-extension-cont .qalam-highlights-cont qalam-label.active { 38 pointer-events: none;39 background-color: #ff000014;61 pointer-events: none; 62 background-color: #ff000014; 40 63 } 41 64 qalam-extension 42 qalam-extension-cont43 .qalam-highlights-cont44 qalam-label45 label-border {46 position: absolute;47 height: 1.5px;48 background-color: #ec2240;49 transition: all 0.5s ease-in;50 bottom: 0;65 qalam-extension-cont 66 .qalam-highlights-cont 67 qalam-label 68 label-border { 69 position: absolute; 70 height: 1.5px; 71 background-color: #ec2240; 72 transition: all 0.5s ease-in; 73 bottom: 0; 51 74 } 52 75 qalam-tashkeel-blk, 53 76 qalam-quraan-blk { 54 cursor: pointer !important;55 pointer-events: all !important;56 display: flex;57 position: absolute !important;58 flex-direction: row !important;59 align-items: center !important;60 justify-content: space-around !important;61 bottom: 7px !important;62 left: 60px;63 border-radius: 20px !important;64 width: 25px !important;65 height: 25px !important;66 background: #d9d2d2 !important;77 cursor: pointer !important; 78 pointer-events: all !important; 79 display: flex; 80 position: absolute !important; 81 flex-direction: row !important; 82 align-items: center !important; 83 justify-content: space-around !important; 84 bottom: 7px !important; 85 left: 60px; 86 border-radius: 20px !important; 87 width: 25px !important; 88 height: 25px !important; 89 background: #d9d2d2 !important; 67 90 } 68 91 qalam-quraan-blk { 69 left: 90px;92 left: 90px; 70 93 } 71 94 qalam-tashkeel-blk:hover { 72 background: #d9d2d2;95 background: #d9d2d2; 73 96 } 74 97 .qalam-tashkeel-icon { 75 width: 25px !important;76 height: 25px !important;77 margin: 0 !important;78 padding: 0 !important;79 border-radius: 20px !important;80 background: rgb(217, 210, 210) !important;81 cursor: pointer !important;98 width: 25px !important; 99 height: 25px !important; 100 margin: 0 !important; 101 padding: 0 !important; 102 border-radius: 20px !important; 103 background: rgb(217, 210, 210) !important; 104 cursor: pointer !important; 82 105 } 83 106 .qalam-quraan-icon { 84 width: 17px !important; 85 height: 17px !important; 86 margin: 0 !important; 87 padding: 0 !important; 88 border-radius: 20px !important; 89 background: rgb(217, 210, 210) !important; 90 cursor: pointer !important; 107 width: 17px !important; 108 height: 17px !important; 109 margin: 0 !important; 110 padding: 0 !important; 111 border-radius: 20px !important; 112 background: rgb(217, 210, 210) !important; 113 cursor: pointer !important; 114 } 115 116 .qalam-icons-loader { 117 border: 3px solid #f3f3f3; /* Light grey */ 118 border-top: 3px solid #008677; /* Blue */ 119 border-radius: 50%; 120 width: 100%; 121 height: 100%; 122 animation: spin 2s linear infinite; 123 position: absolute; 124 } 125 126 .disabled-tashkeel-tawtheeq { 127 cursor: not-allowed !important; 128 opacity: 0.6 !important; 129 pointer-events: none !important; 91 130 } 92 131 qalam-wrapper qalam-button-cont { 93 height: 26px !important;94 direction: ltr;95 position: absolute;96 cursor: pointer;97 pointer-events: all;98 display: flex;99 flex-direction: row;100 align-items: center;101 justify-content: space-around;102 box-sizing: border-box;132 height: 26px !important; 133 direction: ltr; 134 position: absolute; 135 cursor: pointer; 136 pointer-events: all; 137 display: flex; 138 flex-direction: row; 139 align-items: center; 140 justify-content: space-around; 141 box-sizing: border-box; 103 142 } 104 143 qalam-wrapper qalam-button-cont:hover, 105 144 qalam-wrapper qalam-button-cont.active { 106 height: 26px !important;107 width: 70px !important;108 border-radius: 16px;109 background-color: #fff;110 box-shadow: 0 1px 8px 0 rgba(0, 0, 0, 0.1);145 height: 26px !important; 146 width: 70px !important; 147 border-radius: 16px; 148 background-color: #fff; 149 box-shadow: 0 1px 8px 0 rgba(0, 0, 0, 0.1); 111 150 } 112 151 qalam-wrapper qalam-button-cont:hover .separator, … … 114 153 qalam-wrapper qalam-button-cont.active .separator, 115 154 qalam-wrapper qalam-button-cont.active .disable-icon { 116 display: block;155 display: block; 117 156 } 118 157 qalam-wrapper qalam-button-cont .qalam-button { 119 width: 24px;120 height: 24px;121 background-size: 100%;122 margin-left: 3px;123 border-radius: 20px;124 background-color: #30827e;125 display: flex;126 align-items: center;158 width: 24px; 159 height: 24px; 160 background-size: 100%; 161 margin-left: 3px; 162 border-radius: 20px; 163 background-color: #30827e; 164 display: flex; 165 align-items: center; 127 166 } 128 167 qalam-wrapper qalam-button-cont .qalam-button .errors { 129 color: #ffffff;130 font-size: 15px;131 font-weight: bold;132 letter-spacing: 0;133 text-align: center;134 display: none;135 width: 24px;136 height: 24px;137 line-height: 24px;138 margin: 0;139 padding: 0;140 font-family:sans-serif !important;168 color: #ffffff; 169 font-size: 15px; 170 font-weight: bold; 171 letter-spacing: 0; 172 text-align: center; 173 display: none; 174 width: 24px; 175 height: 24px; 176 line-height: 24px; 177 margin: 0; 178 padding: 0; 179 font-family: Tajawal, sans-serif !important; 141 180 } 142 181 qalam-wrapper qalam-button-cont:hover .qalam-button, 143 182 qalam-wrapper qalam-button-cont.active .qalam-button { 144 margin-left: 0;183 margin-left: 0; 145 184 } 146 185 qalam-wrapper qalam-button-cont .separator { 147 height: 20px;148 width: 1px;149 border: 1px solid #000;150 opacity: 0.4;151 display: none;152 box-sizing: border-box;186 height: 20px; 187 width: 1px; 188 border: 1px solid #000; 189 opacity: 0.4; 190 display: none; 191 box-sizing: border-box; 153 192 } 154 193 qalam-wrapper qalam-button-cont .disable-icon { 155 display: none;194 display: none; 156 195 } 157 196 qalam-notification { 158 position: fixed;159 top: 16px;160 right: -450px;161 -webkit-transition: all 750ms ease-in-out;162 -moz-transition: all 750ms ease-in-out;163 -o-transition: all 750ms ease-in-out;164 -ms-transition: all 750ms ease-in-out;165 transition: all 750ms ease-in-out;166 width: 412px;167 border-radius: 4px;168 background-color: #fff;169 box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.2);170 z-index: 2147483647;171 padding: 24px 32px;172 font-family: Cairo-Regular, sans-serif !important;197 position: fixed; 198 top: 16px; 199 right: -450px; 200 -webkit-transition: all 750ms ease-in-out; 201 -moz-transition: all 750ms ease-in-out; 202 -o-transition: all 750ms ease-in-out; 203 -ms-transition: all 750ms ease-in-out; 204 transition: all 750ms ease-in-out; 205 width: 412px; 206 border-radius: 4px; 207 background-color: #fff; 208 box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.2); 209 z-index: 2147483647; 210 padding: 24px 32px; 211 font-family: Tajawal, sans-serif !important; 173 212 } 174 213 qalam-notification .notification-inner-cont { 175 display: flex;176 flex-direction: row;177 align-items: end;178 direction: rtl;179 justify-content: space-between;214 display: flex; 215 flex-direction: row; 216 align-items: end; 217 direction: rtl; 218 justify-content: space-between; 180 219 } 181 220 qalam-notification .notification-inner-cont .notification-close { 182 position: absolute;183 cursor: pointer;184 top: 8px;185 right: 8px;221 position: absolute; 222 cursor: pointer; 223 top: 8px; 224 right: 8px; 186 225 } 187 226 qalam-notification .notification-inner-cont .notification-rightside { 188 max-width: 260px;227 max-width: 260px; 189 228 } 190 229 qalam-notification .notification-inner-cont .notification-logo { 191 width: 62px;192 height: 62px;230 width: 62px; 231 height: 62px; 193 232 } 194 233 qalam-notification 195 .notification-inner-cont196 .notification-rightside197 .notification-title {198 color: #000;199 font-size: 18px;200 letter-spacing: 0;201 line-height: 36px;202 text-align: right;203 margin: 0 0 6px 0;204 font-family: Cairo-Regular, sans-serif !important;234 .notification-inner-cont 235 .notification-rightside 236 .notification-title { 237 color: #000; 238 font-size: 18px; 239 letter-spacing: 0; 240 line-height: 36px; 241 text-align: right; 242 margin: 0 0 6px 0; 243 font-family: Tajawal, sans-serif !important; 205 244 } 206 245 qalam-notification 207 .notification-inner-cont208 .notification-rightside209 .notification-desc {210 opacity: 0.6;211 color: #000;212 font-size: 14px;213 letter-spacing: 0;214 line-height: 28px;215 text-align: right;216 margin: 0;217 font-family: Cairo-Regular, sans-serif !important;246 .notification-inner-cont 247 .notification-rightside 248 .notification-desc { 249 opacity: 0.6; 250 color: #000; 251 font-size: 14px; 252 letter-spacing: 0; 253 line-height: 28px; 254 text-align: right; 255 margin: 0; 256 font-family: Tajawal, sans-serif !important; 218 257 } 219 258 qalam-notification .notification-inner-cont .notification-rightside button { 220 float: right;221 width: 66px;259 float: right; 260 width: 66px; 222 261 } 223 262 .qalam-btn { 224 width: 100%;225 height: 32px;226 font-size: 14px;227 font-weight: 600;228 border-radius: 4px;229 margin: 16px 0 0 0;230 padding: 0;231 outline: none;232 border-style: solid;233 cursor: pointer;234 font-family: Cairo-Regular, sans-serif !important;263 width: 100%; 264 height: 32px; 265 font-size: 14px; 266 font-weight: 600; 267 border-radius: 4px; 268 margin: 16px 0 0 0; 269 padding: 0; 270 outline: none; 271 border-style: solid; 272 cursor: pointer; 273 font-family: Tajawal, sans-serif !important; 235 274 } 236 275 .qalam-btn.secondary-btn { 237 border: 1px solid #30827e;238 color: #30827e;239 background-color: #fff;276 border: 1px solid #30827e; 277 color: #30827e; 278 background-color: #fff; 240 279 } 241 280 .qalam-btn.primary-btn { 242 background-color: #30827e;243 color: #fff;244 border-color: #30827e;281 background-color: #30827e; 282 color: #fff; 283 border-color: #30827e; 245 284 } 246 285 247 286 qalam-container { 248 display: block !important; 249 } 287 display: block !important; 288 } 289 290 @keyframes spin { 291 0% { 292 transform: rotate(0deg); 293 } 294 100% { 295 transform: rotate(360deg); 296 } 297 } -
qalam/trunk/assets/js/main.js
r2594341 r2896421 1 const baseLink = "https://api.app.qalam.ai/"; 2 let doneCallback = null, API_LINK = "", TOKEN = "", shadowRoot = null, qalamDisablePrompt = null, isTextArea = null, 3 triggerFlag = !0, SCServiceActive = null, qalamExtension = null, qalamExtensionCont = null, 4 qalamHighlightsCont = null, qalamMirror = null, qalamSuggestions = null, element = null, withoutScrollDiff = 0, 5 elementParent = null, typingStallCounter = 0, secondsCounter = null, resizeHoldCounter = null, 6 currentTextSuggestions = [], ignoredSet = new Set, removeSuggestionsTimeout = null, selectedText = "", 7 isTashkeelActive = null, isTawtheeqActive = null, isWriterAllowedToAddToDic = !1, activeFrameId = null, 8 editorId = "", PATH_MODE = "PATH_MODE", QUERY_MODE = "QUERY_MODE"; 9 var cssId = "myCss", INTERSECTION_THRESHOLD = .7, REMOVE_SUGGESTION_DELAY = 300, TYPING_STALL = 1, 10 ANIMATION_DELAY = 1e3, DUMMY_STRING = "@⻆@", 11 STYLES_BLOCKING = new Set(["block", "flex", "flow-root", "grid", "list-item", "table", "table-caption", "table-cell", "table-footer-group", "table-header-group", "table-row", "table-row-group"]), 12 example = "\nقلم للأعمال\nمساعد الكتابة الذكي للغة العربية\nعن قلم:\nقال تعالى: نون والقلم وما يسطرون\nوقال تعالى: إن الله وملائكته يصلون على النبي يا أيها الذين آمنوا صلوا عليه وسلموا تسليما\nقلم واحدة من شركات مجموعة موضوع. كوم (المجموعة)، وهي الراءدة في تطبيقات الذكاء الاصطناعي باللغة العربية داخل المجموعة . وبعد نجاح إستخدام هذه التطبيقات داخلياً ولدى بعض عملاءنا المقربون ، قررنا مشاركة التجربة مع الشركات، و المؤسسات، والوزارات الأخرى محليا داخل الأردنوخارجها.\nيعمل على تطوير قلم نخبة من الأخصائيون والخبراء في اللغة العربيه وحوسبتها، وفي علم البيانات والذكاء الاصطناعي، اضافه إلى مهندسو البرمجيات والحاسوب. جميعهم يعملون معاً لصناعة منتج ذكي، يخدم الكتابة بلغة الصاد.\nلماذا قلم؟\nنعلم أن كتابة المحتوي، وتدقيقه، والمحافظة على أسلوب الكتابة والنسق المتبع في شركتكم مهمة ليست بالهلة، خاصة حين يكون بصيغ مختلفة، وفي حجماً كبير، مثل:\nالتقارير بشتى أنواعها\nالأبحاث والنشر\nالعروض الفنية و المالية\nالمراسلاة والخطابات\nالرسائل الإلكترونية\nوغيرها\nومن هنا جاءت المهمه التي اضطلع بها قلم للأعمال أن يكون عوناً لكم في التخفيف من عبئ تدقيق المحتوى بشتى أنواعه، ومساعدة الكتّاب/الموظفين حتى ينتجو محتوى سليماً من الأخطائ الإملائية واللغوية والقواعدية، وتحسين الصياغة في اللغة العربية، بالإضافة إلى مساعدتهم في اتباع النسق وأسلوب الكتابة الخاص بالشركة.", 13 STYLES_HIDDEN = new Set(["none", "table-column", "table-column-group"]), 14 STYLES_WRAP = new Set(["pre", "pre-wrap", "pre-line"]), BUTTON_NORMAL_COLOR = "#30827E", 15 BUTTON_ERROR_COLOR = "#EC2240", QALAM_TOOLBAR_STYLE = "", 16 MIRROR_SHADOW_STYLE = "\nqalam-mirror {\n border: 0px transparent;\n text-shadow: none;\n text-indent: 0px;\n word-break: normal;\n overflow-wrap: break-word;\n word-spacing: 0px;\n writing-mode: horizontal-tb;\n white-space: pre-wrap;\n vertical-align: baseline;\n clear: both;\n box-sizing: content-box;\n position: fixed;\n top: 0px;\n left: 0px;\n background: transparent;\n pointer-events: none;\n overflow: hidden;\n color: transparent;\n z-index: 1;\n visibility: hidden;\n}\nqalam-disable-prompt {\n position: fixed;\n padding: 24px 32px;\n border-radius: 4px;\n background-color: #fff;\n box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.2);\n pointer-events: all;\n width: 228px;\n height: fit-content;\n font-family: Tajawal-Regular, sans-serif !important;\n box-sizing: border-box;\n z-index: 2147483647;\n}\nqalam-disable-prompt .prompt-title {\n color: #000;\n font-size: 18px;\n letter-spacing: 0;\n line-height: 36px;\n text-align: right;\n margin: 0 0 8px 0;\n padding: 0;\n display: inline-block;\n font-family: Tajawal-Regular, sans-serif !important;\n width: 100%;\n}\n.qalam-btn {\n width: 100%;\n height: 32px;\n font-size: 14px;\n font-weight: 600;\n border-radius: 4px;\n margin: 16px 0 0 0;\n padding: 0;\n outline: none;\n border-style: solid;\n cursor: pointer;\n font-family: Tajawal-Regular, sans-serif !important;\n}\n.qalam-btn.secondary-btn {\n border: 1px solid #30827e;\n color: #30827e;\n background-color: #fff;\n}\n.qalam-btn.primary-btn {\n background-color: #30827e;\n color: #fff;\n border-color: #30827e;\n}\nqalam-suggestions {\n width: 175px;\n border-radius: 4px;\n background-color: #ffffff;\n box-shadow: 0 1px 8px 0 rgba(0, 0, 0, 0.2);\n position: fixed;\n display: none;\n cursor: pointer;\n z-index: 2147483647;\n pointer-events: all;\n}\nqalam-suggestions suggestions-cont > div:nth-of-type(1) {\n border-top-right-radius: 4px;\n border-top-left-radius: 4px;\n}\nqalam-suggestions suggestions-cont suggestion-item {\n padding: 16px;\n background-color: #fff;\n width: 100%;\n height: 56px;\n display: flex;\n align-items: center;\n box-sizing: border-box;\n}\nqalam-suggestions suggestions-cont suggestion-item suggestion-text {\n color: #108426;\n font-family: Tajawal-Regular, sans-serif !important;\n font-size: 20px;\n font-weight: 600;\n text-align: right;\n width: 100%;\n height: fit-content;\n margin: -2px 0 0 0;\n padding: 0;\n direction: rtl;\n display: inline-block;\n text-overflow: ellipsis;\n overflow: hidden;\n white-space: nowrap;\n}\nqalam-suggestions suggestions-cont suggestion-item:hover {\n background-color: #108426;\n}\nqalam-suggestions suggestions-cont suggestion-item:hover suggestion-text {\n color: #fff;\n}\nqalam-suggestions .ignore-cont,qalam-suggestions .add-to-dic-cont {\n direction: rtl;\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n padding: 16px;\n background-color: #fff;\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n align-items: center;\n width: 100%;\n height: 46px;\n box-sizing: border-box;\n}\nqalam-suggestions .ignore-cont .ignore-icon, qalam-suggestions .add-to-dic-cont .add-to-dic-icon {\n width: 15px;\n height: 15px;\n}\nqalam-suggestions .ignore-cont .ignore-text, qalam-suggestions .add-to-dic-cont .add-to-dic-text{\n opacity: 0.55;\n color: #000;\n font-family: Tajawal-Regular, sans-serif !important;\n font-size: 14px;\n margin: -2px 0 0 0;\n padding: 0;\n display: inline-block;\n}\nqalam-suggestions .ignore-cont:hover,qalam-suggestions .add-to-dic-cont:hover {\n background-color: #e7e7e7;\n}\nqalam-suggestions .ignore-cont:hover .ignore-text,qalam-suggestions .add-to-dic-cont:hover .add-to-dic-text{\n opacity: 0.7;\n}\n.d-none{\n display:none;\n}\nqalam-container{\n display:block !important;\n}\n", 17 FLAT_RED = "#EC2240", FLAT_YELLOW = "#ffc940", FLAT_BLUE = "#1873D3", FLAT_GREEN = "#1DBC60", 18 FLAT_BLUE_GREY = "#263238", FLAT_PURPLE = "#4a148c", FLAT_ORANGE = "#263238", 19 TRANSPARENT_RED = "rgba(255, 0, 0, 0.08)", TRANSPARENT_YELLOW = "rgba(255, 201, 64, 0.27)", 20 TRANSPARENT_BLUE = "rgba(0, 255, 255, 0.08)", TRANSPARENT_GREEN = "rgba(0, 255, 0, 0.08)", 21 TRANSPARENT_FLAT_BLUE_GREY = "rgba(38, 50, 56, 0.08)", TRANSPARENT_FLAT_PURPLE = "rgba(74, 20, 140, 0.08)", 22 TRANSPARENT_FLAT_ORANGE = "rgba(38, 50, 56, 0.08)", SC_LINE_COLOR = FLAT_RED, SC_LABEL_COLOR = TRANSPARENT_RED, 23 NUM_LINE_COLOR = FLAT_YELLOW, NUM_LABEL_COLOR = TRANSPARENT_YELLOW, GRAMMAR_LINE_COLOR = FLAT_BLUE, 24 GRAMMAR_LABEL_COLOR = TRANSPARENT_BLUE, T_LINE_COLOR = FLAT_GREEN, T_LABEL_COLOR = TRANSPARENT_GREEN, 25 PHRASING_LINE_COLOR = FLAT_YELLOW, PHRASING_LABEL_COLOR = TRANSPARENT_YELLOW, TERM_LINE_COLOR = FLAT_PURPLE, 26 TERM_LABEL_COLOR = TRANSPARENT_FLAT_PURPLE, TAFQEET_LINE_COLOR = FLAT_ORANGE, 27 TAFQEET_LABEL_COLOR = TRANSPARENT_FLAT_ORANGE, $ = jQuery.noConflict(), scr = document.createElement("script"), 28 head = document.head || document.getElementsByTagName("head")[0]; 1 const baseLink = 'https://api.qalam.ai/'; 2 let originalText = null, 3 qalamAgent = 'Wordpress', 4 type = null, 5 doneCallback = null, 6 API_LINK = '', 7 TOKEN = '', 8 shadowRoot = null, 9 qalamDisablePrompt = null, 10 isTextArea = null, 11 triggerFlag = !0, 12 SCServiceActive = null, 13 qalamExtension = null, 14 qalamExtensionCont = null, 15 qalamHighlightsCont = null, 16 qalamMirror = null, 17 qalamSuggestions = null, 18 wrongSuggestionItem = null, 19 element = null, 20 withoutScrollDiff = 0, 21 elementParent = null, 22 typingStallCounter = 0, 23 secondsCounter = null, 24 resizeHoldCounter = null, 25 currentTextSuggestions = [], 26 ignoredSet = new Set(), 27 removeSuggestionsTimeout = null, 28 selectedText = '', 29 isTashkeelActive = null, 30 isTawtheeqActive = null, 31 isWriterAllowedToAddToDic = !1, 32 activeFrameId = null, 33 offset_indices = null, 34 editorId = '', 35 PATH_MODE = 'PATH_MODE', 36 QUERY_MODE = 'QUERY_MODE'; 37 var cssId = 'myCss', 38 INTERSECTION_THRESHOLD = 0.7, 39 REMOVE_SUGGESTION_DELAY = 300, 40 TYPING_STALL = 1, 41 ANIMATION_DELAY = 1e3, 42 STYLES_BLOCKING = new Set([ 43 'block', 44 'flex', 45 'flow-root', 46 'grid', 47 'list-item', 48 'table', 49 'table-caption', 50 'table-cell', 51 'table-footer-group', 52 'table-header-group', 53 'table-row', 54 'table-row-group', 55 ]), 56 example = 57 '\nقلم للأعمال\nمساعد الكتابة الذكي للغة العربية\nعن قلم:\nقال تعالى: نون والقلم وما يسطرون\nوقال تعالى: إن الله وملائكته يصلون على النبي يا أيها الذين آمنوا صلوا عليه وسلموا تسليما\nقلم واحدة من شركات مجموعة موضوع. كوم (المجموعة)، وهي الراءدة في تطبيقات الذكاء الاصطناعي باللغة العربية داخل المجموعة . وبعد نجاح إستخدام هذه التطبيقات داخلياً ولدى بعض عملاءنا المقربون ، قررنا مشاركة التجربة مع الشركات، و المؤسسات، والوزارات الأخرى محليا داخل الأردنوخارجها.\nيعمل على تطوير قلم نخبة من الأخصائيون والخبراء في اللغة العربيه وحوسبتها، وفي علم البيانات والذكاء الاصطناعي، اضافه إلى مهندسو البرمجيات والحاسوب. جميعهم يعملون معاً لصناعة منتج ذكي، يخدم الكتابة بلغة الصاد.\nلماذا قلم؟\nنعلم أن كتابة المحتوي، وتدقيقه، والمحافظة على أسلوب الكتابة والنسق المتبع في شركتكم مهمة ليست بالهلة، خاصة حين يكون بصيغ مختلفة، وفي حجماً كبير، مثل:\nالتقارير بشتى أنواعها\nالأبحاث والنشر\nالعروض الفنية و المالية\nالمراسلاة والخطابات\nالرسائل الإلكترونية\nوغيرها\nومن هنا جاءت المهمه التي اضطلع بها قلم للأعمال أن يكون عوناً لكم في التخفيف من عبئ تدقيق المحتوى بشتى أنواعه، ومساعدة الكتّاب/الموظفين حتى ينتجو محتوى سليماً من الأخطائ الإملائية واللغوية والقواعدية، وتحسين الصياغة في اللغة العربية، بالإضافة إلى مساعدتهم في اتباع النسق وأسلوب الكتابة الخاص بالشركة.', 58 STYLES_HIDDEN = new Set(['none', 'table-column', 'table-column-group']), 59 STYLES_WRAP = new Set(['pre', 'pre-wrap', 'pre-line']), 60 BUTTON_NORMAL_COLOR = '#008677', 61 BUTTON_ERROR_COLOR = '#EC2240', 62 QALAM_TOOLBAR_STYLE = '', 63 MIRROR_SHADOW_STYLE = 64 '\nqalam-mirror {\n border: 0px transparent;\n text-shadow: none;\n text-indent: 0px;\n word-break: normal;\n overflow-wrap: break-word;\n word-spacing: 0px;\n writing-mode: horizontal-tb;\n white-space: pre-wrap;\n vertical-align: baseline;\n clear: both;\n box-sizing: content-box;\n position: fixed;\n top: 0px;\n left: 0px;\n background: transparent;\n pointer-events: none;\n overflow: hidden;\n color: transparent;\n z-index: 1;\n visibility: hidden;\n}\nqalam-disable-prompt {\n position: fixed;\n padding: 24px 32px;\n border-radius: 4px;\n background-color: #fff;\n box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.2);\n pointer-events: all;\n width: 228px;\n height: fit-content;\n font-family: Tajawal, sans-serif !important;\n box-sizing: border-box;\n z-index: 2147483647;\n}\nqalam-disable-prompt .prompt-title {\n color: #000;\n font-size: 18px;\n letter-spacing: 0;\n line-height: 36px;\n text-align: right;\n margin: 0 0 8px 0;\n padding: 0;\n display: inline-block;\n font-family: Tajawal, sans-serif !important;\n width: 100%;\n}\n.qalam-btn {\n width: 100%;\n height: 32px;\n font-size: 14px;\n font-weight: 600;\n border-radius: 4px;\n margin: 16px 0 0 0;\n padding: 0;\n outline: none;\n border-style: solid;\n cursor: pointer;\n font-family: Tajawal, sans-serif !important;\n}\n.qalam-btn.secondary-btn {\n border: 1px solid #008677;\n color: #008677;\n background-color: #fff;\n}\n.qalam-btn.primary-btn {\n background-color: #008677;\n color: #fff;\n border-color: #008677;\n}\nqalam-suggestions {\n width: 175px;\n border-radius: 4px;\n background-color: #ffffff;\n box-shadow: 0 1px 8px 0 rgba(0, 0, 0, 0.2);\n position: fixed;\n display: none;\n cursor: pointer;\n z-index: 2147483647;\n pointer-events: all;\n}\nqalam-suggestions suggestions-cont > div:nth-of-type(1) {\n border-top-right-radius: 4px;\n border-top-left-radius: 4px;\n}\nqalam-suggestions suggestions-cont suggestion-item {\n padding: 16px;\n background-color: #fff;\n width: 100%;\n height: 56px;\n display: flex;\n align-items: center;\n box-sizing: border-box;\n}\nqalam-suggestions suggestions-cont suggestion-item suggestion-text {\n color: #008677;\n font-family: Tajawal, sans-serif !important;\n font-size: 20px;\n font-weight: 600;\n text-align: right;\n width: 100%;\n height: fit-content;\n margin: -2px 0 0 0;\n padding: 0;\n direction: rtl;\n display: inline-block;\n text-overflow: ellipsis;\n overflow: hidden;\n white-space: nowrap;\n}\nqalam-suggestions suggestions-cont suggestion-item:hover {\n background-color: #008677;\n}\nqalam-suggestions suggestions-cont suggestion-item:hover suggestion-text {\n color: #fff;\n}\nqalam-suggestions .ignore-cont{\n position: relative;\n}\nqalam-suggestions .ignore-cont,qalam-suggestions .add-to-dic-cont, qalam-suggestions .wrong-suggestion-cont {\n direction: rtl;\n display: flex;\n flex-direction: row;\n justify-content: start;\n padding: 12px;\n background-color: #fff;\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n align-items: center;\n width: 100%;\n height: 46px;\n box-sizing: border-box;\n}\nqalam-suggestions .ignore-cont .ignore-icon, qalam-suggestions .add-to-dic-cont .add-to-dic-icon, qalam-suggestions .wrong-suggestion-cont .wrong-suggestion-icon {\n width: 15px;\n height: 15px;\n margin-left: 10px;\n}\nqalam-suggestions .ignore-cont .ignore-text, qalam-suggestions .add-to-dic-cont .add-to-dic-text, qalam-suggestions .wrong-suggestion-cont .wrong-suggestion-text{\n opacity: 0.55;\n color: #000;\n font-family: Tajawal, sans-serif !important;\n font-size: 14px;\n margin: -2px 0 0 0;\n padding: 0;\n display: inline-block;\n}\nqalam-suggestions .ignore-cont:hover,qalam-suggestions .add-to-dic-cont:hover, qalam-suggestions .wrong-suggestion-cont:hover {\n background-color: #e7e7e7;\n}\nqalam-suggestions .ignore-cont:hover .ignore-text,qalam-suggestions .add-to-dic-cont:hover .add-to-dic-text, qalam-suggestions .wrong-suggestion-cont:hover .wrong-suggestion-text{\n opacity: 0.7;\n}\n\nqalam-suggestions .wrong-suggestion-more-icon {\n\tposition: absolute;\n\tright: 85%;\n\tpadding: 4px;\n\tborder-radius: 10px\n }\n qalam-suggestions .wrong-suggestion-more-icon:hover {\n\tbackground-color: #9F9898;\n }\n \n qalam-suggestions .wrong-suggestion-cont{\n\tposition: absolute;\n\tright: 100%;\n\ttop: 0;\n\tbox-shadow: 0 1px 8px 0 rgba(0, 0, 0, 0.2);\n\tborder-radius: 10px;\n }\n.d-none{\n display:none;\n}\nqalam-container{\n display:block !important;\n}\n'; 65 const FLAT_RED = '#EC2240', 66 FLAT_YELLOW = '#ffc940', 67 FLAT_BLUE = '#1873D3', 68 FLAT_GREEN = '#1DBC60', 69 FLAT_BLUE_GREY = '#263238', 70 FLAT_PURPLE = '#4a148c', 71 FLAT_ORANGE = '#263238', 72 FLAT_GREY = '#7393B3', 73 TRANSPARENT_RED = 'rgba(255, 0, 0, 0.08)', 74 TRANSPARENT_YELLOW = 'rgba(255, 201, 64, 0.27)', 75 TRANSPARENT_BLUE = 'rgba(0, 255, 255, 0.08)', 76 TRANSPARENT_GREEN = 'rgba(0, 255, 0, 0.08)', 77 TRANSPARENT_FLAT_BLUE_GREY = 'rgba(38, 50, 56, 0.08)', 78 TRANSPARENT_FLAT_PURPLE = 'rgba(74, 20, 140, 0.08)', 79 TRANSPARENT_FLAT_ORANGE = 'rgba(38, 50, 56, 0.08)', 80 TRANSPARENT_GREY = '#b1b1b114', 81 SC_LINE_COLOR = FLAT_RED, 82 SC_LABEL_COLOR = TRANSPARENT_RED, 83 OS_LINE_COLOR = '#7393B3', 84 OS_LABEL_COLOR = '#b1b1b114', 85 NUM_LINE_COLOR = '#ffc940', 86 NUM_LABEL_COLOR = TRANSPARENT_YELLOW, 87 GRAMMAR_LINE_COLOR = FLAT_BLUE, 88 GRAMMAR_LABEL_COLOR = TRANSPARENT_BLUE, 89 T_LINE_COLOR = FLAT_GREEN, 90 T_LABEL_COLOR = TRANSPARENT_GREEN, 91 PHRASING_LINE_COLOR = FLAT_YELLOW, 92 PHRASING_LABEL_COLOR = TRANSPARENT_YELLOW, 93 TERM_LINE_COLOR = FLAT_PURPLE, 94 TERM_LABEL_COLOR = TRANSPARENT_FLAT_PURPLE, 95 TAFQEET_LINE_COLOR = FLAT_ORANGE, 96 TAFQEET_LABEL_COLOR = TRANSPARENT_FLAT_ORANGE, 97 $ = jQuery.noConflict(), 98 scr = document.createElement('script'), 99 head = document.head || document.getElementsByTagName('head')[0]; 29 100 30 101 function setParams(e, t, n, a) { 31 this.clientId = e, this.documentId = t, this.mode = n, this.modeValue = a 32 } 33 102 (this.clientId = e), 103 (this.documentId = t), 104 (this.mode = n), 105 (this.modeValue = a); 106 } 34 107 function activate(e, t) { 35 SCServiceActive = !0, API_LINK = e, TOKEN = t, getConfig(), getTermsConfig(), init() 36 } 37 108 (SCServiceActive = !0), 109 (API_LINK = e), 110 (TOKEN = t), 111 getConfig(), 112 getTermsConfig(), 113 setSDKVersion(), 114 setInterval(function () { 115 setSDKVersion(); 116 }, 1 * 1000 * 60 * 60 * 24), 117 init(); 118 } 119 function setSDKVersion() { 120 $.ajax({ 121 dataType: 'json', 122 url: baseLink + 'sdk/version', 123 method: 'PUT', 124 timeout: 0, 125 headers: { 126 'Content-Type': 'application/json', 127 Authorization: `${clientId}`, 128 'Qalam-Agent': qalamAgent, 129 'sdk-version': '1.1.0-wp', 130 }, 131 success: function () {}, 132 error: function () {}, 133 }); 134 } 38 135 function checkFocusedElement() { 39 if ($(element).next().fadeOut(700), assignEditorIds(), SCServiceActive) { 40 let e = $(document.activeElement); 41 e.hasClass("gramm_editor") && e.attr("data-gramm_editor", "false"), e.hasClass("qalam_editor") && e.attr("data-qalam_editor", "false"), (e.is("textarea") || "true" == e.attr("contenteditable")) && listenerTriggered(document.activeElement) 136 if ((assignEditorIds(), SCServiceActive)) { 137 let e = $(document.activeElement); 138 e.hasClass('gramm_editor') && e.attr('data-gramm_editor', 'false'), 139 e.hasClass('qalam_editor') && e.attr('data-qalam_editor', 'false'), 140 (e.is('textarea') || 'true' == e.attr('contenteditable')) && 141 listenerTriggered(document.activeElement); 142 } 143 clearInterval(resizeHoldCounter), (resizeHoldCounter = null); 144 } 145 function init() { 146 function e(e, t) { 147 var n = 0; 148 return function () { 149 var a = this, 150 o = arguments; 151 clearTimeout(n), 152 (n = setTimeout(function () { 153 e.apply(a, o); 154 }, t || 0)); 155 }; 156 } 157 158 getCookie('qalam_user_id') || setCookie(), 159 checkFocusedElement(), 160 document.addEventListener('focus', checkFocusedElement, !0); 161 let t = 0, 162 n = 0, 163 a = 0; 164 var o = setInterval(function () { 165 let l = document.querySelectorAll('iframe'); 166 if (0 != l.length) { 167 for (var i = 0; i < l.length; ) { 168 let s = l[i]; 169 if ((assignIframeEditorIds(s, i), s)) { 170 let o = 171 s.contentDocument && s.contentDocument.body 172 ? s.contentDocument.body.parentElement.querySelector( 173 '[contenteditable]' 174 ) || s.contentDocument.body.parentElement 175 : null; 176 if (o) { 177 let l = s; 178 s = s.contentDocument.querySelector('[contenteditable]'); 179 let i = o; 180 $(i).on('click', function (e) { 181 let t = tagIframe(l); 182 activeFrameId !== t && 183 ((activeFrameId = t), 184 setTimeout(function () { 185 listenerTriggered($(l)[0]); 186 }, 10)); 187 }), 188 $(i).on('mousemove', function (e) { 189 if (isEventInsideElement(e, qalamSuggestions)) 190 stopRemoveSuggestionsTimeout(); 191 else { 192 let t = $('qalam-label.active'); 193 if (t.length) { 194 isInLabel = !1; 195 for (let n = 0; n < t.length; n++) 196 if (isEventInsideElement(e, t[n])) { 197 isInLabel = !0; 198 break; 199 } 200 isInLabel 201 ? stopRemoveSuggestionsTimeout() 202 : setRemoveSuggestionsTimeout(); 203 } 204 } 205 }), 206 $(i).unbind('keyup'), 207 $(i).keyup( 208 e(function (e) { 209 clearLabels(), 210 8 == e.keyCode 211 ? (clearTimeout(t), 212 SCServiceActive && 213 (t = setTimeout(listenerTriggered($(l)[0]), 800))) 214 : (clearTimeout(n), 215 SCServiceActive && 216 91 != e.keyCode && 217 81 != e.keyCode && 218 17 != e.keyCode && 219 (n = setTimeout(listenerTriggered($(l)[0]), 600))); 220 }, 1e3) 221 ), 222 i && 223 (i.onpaste = () => { 224 SCServiceActive && 225 (clearTimeout(a), 226 (a = setTimeout(listenerTriggered($(l)[0]), 600))); 227 let e = 1; 228 e && 229 setTimeout(() => { 230 spellCheckText(!0), (e = 0); 231 }, 1e3); 232 }); 233 } 234 } 235 setTimeout(() => { 236 clearInterval(o); 237 }, 5e3), 238 i++; 239 } 240 clearInterval(o); 42 241 } 43 clearInterval(resizeHoldCounter), resizeHoldCounter = null 44 } 45 46 function init() { 47 function e(e, t) { 48 var n = 0; 49 return function () { 50 var a = this, o = arguments; 51 clearTimeout(n), n = setTimeout(function () { 52 e.apply(a, o) 53 }, t || 0) 242 }, 5e3); 243 $(document).on('click', function (e) { 244 $(e.target).closest('qalam-button-cont').length || 245 isEventInsideElement(e, qalamDisablePrompt) || 246 removeDisablePrompt(), 247 isEventInsideElement(e, qalamSuggestions) || removeQalamSuggestions(), 248 clearInterval(resizeHoldCounter), 249 (resizeHoldCounter = null); 250 }), 251 mobileCheck && 252 document.addEventListener( 253 'touchstart', 254 function (e) { 255 'QALAM-LABEL' == e.target.tagName && 256 (e.target.classList.add('active'), renderQalamSuggestions(e)), 257 'QALAM-LABEL' != e.target.tagName && 258 'QALAM-SUGGESTIONS' != e.target.tagName && 259 'SUGGESTION-ITEM' != e.target.tagName && 260 'SUGGESTION-TEXT' != e.target.tagName && 261 'QALAM-MIRROR-SHADOW' != e.target.tagName && 262 ($(qalamSuggestions).remove(), 263 $( 264 'qalam-extension .qalam-highlights-cont qalam-label' 265 ).removeClass('active')); 266 }, 267 !1 268 ), 269 $(document).on('mousemove', function (e) { 270 if ( 271 isEventInsideElement(e, qalamSuggestions) || 272 isEventInsideElement(e, wrongSuggestionItem) 273 ) 274 stopRemoveSuggestionsTimeout(); 275 else { 276 let t = $('qalam-label.active'); 277 if (t.length) { 278 isInLabel = !1; 279 for (let n = 0; n < t.length; n++) 280 if (isEventInsideElement(e, t[n])) { 281 isInLabel = !0; 282 break; 283 } 284 isInLabel 285 ? stopRemoveSuggestionsTimeout() 286 : setRemoveSuggestionsTimeout(); 54 287 } 288 } 289 }); 290 } 291 292 function tagIframe(e) { 293 if (e.getAttribute('data-qtag')) return e.getAttribute('data-qtag'); 294 const t = Math.random().toString(36).substring(5); 295 return e.setAttribute('data-qtag', t), t; 296 } 297 298 function isEventInsideElement(e, t) { 299 if (null == t) return !1; 300 let n = t.getBoundingClientRect(); 301 return ( 302 e.clientX >= n.left && 303 e.clientX <= n.right && 304 e.clientY >= n.top && 305 e.clientY <= n.bottom 306 ); 307 } 308 309 function setRemoveSuggestionsTimeout() { 310 null === removeSuggestionsTimeout && 311 (removeSuggestionsTimeout = setTimeout(function () { 312 removeQalamSuggestions(), (removeSuggestionsTimeout = null); 313 }, REMOVE_SUGGESTION_DELAY)); 314 } 315 function stopRemoveSuggestionsTimeout() { 316 null !== removeSuggestionsTimeout && 317 (clearTimeout(removeSuggestionsTimeout), (removeSuggestionsTimeout = null)); 318 } 319 320 function getText() { 321 offset_indices = new Set(); 322 if (!element) { 323 return ''; 324 } 325 //IFRAME 326 if (element.tagName == 'IFRAME') { 327 let body = element.contentDocument.querySelector('[contenteditable]'); 328 let text = ''; 329 let stack = [{ element: body, parent: null }]; 330 editorId = element.getAttribute('data-qid'); 331 while (stack.length) { 332 let currentNode = stack.pop(); 333 let parentNode = currentNode.parent; 334 currentNode = currentNode.element; 335 if (!currentNode) { 336 continue; 337 } 338 if (currentNode.tagName == 'BR') { 339 // Add a dummy newline 340 if (text.length > 0 && !offset_indices.has(text.length - 1)) { 341 offset_indices.add(text.length); 342 text += '\n'; 343 } 344 } else if (currentNode.nodeType == 3) { 345 // TEXT NODE, GET TEXT CONTENT 346 347 let currentText = currentNode.textContent; 348 // REPLACE NEWLINES WITH SPACES IF PARENT `WHITE-SPACE` STYLE DOESN'T RENDER NEWLINES 349 if ( 350 !STYLES_WRAP.has(window.getComputedStyle(parentNode, null).whiteSpace) 351 ) 352 currentText = currentText.replace(/\n/g, ' '); 353 354 text += currentText; 355 } else { 356 let displayStyle = 357 typeof currentNode == Element 358 ? window.getComputedStyle(currentNode, null).display 359 : ''; 360 361 // HIDDEN ELEMENT, SKIP 362 if (STYLES_HIDDEN.has(displayStyle)) continue; 363 364 // Block element, to add a dummy newline after all child nodes 365 if (STYLES_BLOCKING.has(displayStyle)) 366 stack.push({ 367 element: document.createElement('br'), 368 parent: currentNode, 369 }); 370 371 // Push child nodes to stack 372 let list = []; 373 Array.from(currentNode.childNodes) 374 .reverse() 375 .forEach((childNode) => { 376 list.push({ element: childNode, parent: currentNode }); 377 }); 378 stack.push(...list); 379 380 // Block element, to add a dummy newline before all child nodes 381 if (STYLES_BLOCKING.has(displayStyle)) 382 stack.push({ 383 element: document.createElement('br'), 384 parent: currentNode, 385 }); 386 } 55 387 } 56 57 getCookie("qalam_user_id") || setCookie(), checkFocusedElement(), document.addEventListener("focus", checkFocusedElement, !0); 58 let t = 0, n = 0, a = 0; 59 var o = setInterval(function () { 60 let l = document.querySelectorAll("iframe"); 61 if (0 != l.length) { 62 for (var i = 0; i < l.length;) { 63 let s = l[i]; 64 if (assignIframeEditorIds(s, i), s) { 65 let o = s.contentDocument && s.contentDocument.body ? s.contentDocument.body.parentElement.querySelector("[contenteditable]") || s.contentDocument.body.parentElement : null; 66 if (o) { 67 let l = s; 68 s = s.contentDocument.querySelector("[contenteditable]"); 69 let i = o; 70 $(i).on("click", function (e) { 71 let t = tagIframe(l); 72 activeFrameId !== t && (activeFrameId = t, setTimeout(function () { 73 listenerTriggered($(l)[0]) 74 }, 10)) 75 }), $(i).on("mousemove", function (e) { 76 if (isEventInsideElement(e, qalamSuggestions)) stopRemoveSuggestionsTimeout(); else { 77 let t = $("qalam-label.active"); 78 if (t.length) { 79 isInLabel = !1; 80 for (let n = 0; n < t.length; n++) if (isEventInsideElement(e, t[n])) { 81 isInLabel = !0; 82 break 83 } 84 isInLabel ? stopRemoveSuggestionsTimeout() : setRemoveSuggestionsTimeout() 85 } 86 } 87 }), $(i).unbind("keyup"), $(i).keyup(e(function (e) { 88 clearLabels(), 8 == e.keyCode ? (clearTimeout(t), SCServiceActive && (t = setTimeout(listenerTriggered($(l)[0]), 800))) : (clearTimeout(n), SCServiceActive && 91 != e.keyCode && 81 != e.keyCode && 17 != e.keyCode && (n = setTimeout(listenerTriggered($(l)[0]), 600))) 89 }, 1e3)), i && (i.onpaste = (() => { 90 SCServiceActive && (clearTimeout(a), a = setTimeout(listenerTriggered($(l)[0]), 600)); 91 let e = 1; 92 e && setTimeout(() => { 93 spellCheckText(!0), e = 0 94 }, 1e3) 95 })) 96 } 97 } 98 setTimeout(() => { 99 clearInterval(o) 100 }, 5e3), i++ 101 } 102 clearInterval(o) 388 return text; 389 } 390 391 //TEXTAREA 392 if (isTextArea) { 393 editorId = element.getAttribute('data-qid'); 394 return $(element).val() || $(element).text(); 395 } 396 397 // TRAVERSE THROUGH TREE OF DIV (DFS) 398 let text = ''; 399 let stack = [{ element: element, parent: null }]; 400 401 while (stack.length) { 402 let currentNode = stack.pop(); 403 let parentNode = currentNode.parent; 404 currentNode = currentNode.element; 405 406 if (currentNode.tagName == 'BR') { 407 // Add a dummy newline 408 if (text.length > 0 && !offset_indices.has(text.length - 1)) { 409 offset_indices.add(text.length); 410 text += '\n'; 411 } 412 } else if (currentNode.nodeType == 3) { 413 // Text node, get text content 414 415 let currentText = currentNode.textContent; 416 // Replace newlines with spaces if parent `white-space` style doesn't render newlines 417 let displayStyle = 418 typeof currentNode == Element 419 ? window.getComputedStyle(currentNode, null).whiteSpace 420 : ''; 421 if (!STYLES_WRAP.has(displayStyle)) 422 currentText = currentText.replace(/\n/g, ' '); 423 424 text += currentText; 425 } else { 426 let displayStyle = 427 typeof currentNode == Element 428 ? window.getComputedStyle(currentNode, null).display 429 : ''; 430 // Hidden element, skip 431 if (STYLES_HIDDEN.has(displayStyle)) continue; 432 433 // Block element, to add a dummy newline after all child nodes 434 if (STYLES_BLOCKING.has(displayStyle)) 435 stack.push({ 436 element: document.createElement('br'), 437 parent: currentNode, 438 }); 439 440 // Push child nodes to stack 441 let list = []; 442 Array.from(currentNode.childNodes) 443 .reverse() 444 .forEach((childNode) => { 445 list.push({ element: childNode, parent: currentNode }); 446 }); 447 stack.push(...list); 448 449 // Block element, to add a dummy newline before all child nodes 450 if (STYLES_BLOCKING.has(displayStyle)) 451 stack.push({ 452 element: document.createElement('br'), 453 parent: currentNode, 454 }); 455 } 456 } 457 editorId = element.getAttribute('data-qid'); 458 return text; 459 } 460 461 function listenerTriggered(e) { 462 if ((assignEditorIds(), element != e || 'IFRAME' == e.tagName)) { 463 if ( 464 (unmountQalamComponent(), 465 (isTextArea = 466 'TEXTAREA' == (element = e).tagName || 'IFRAME' == element.tagName)) 467 ) { 468 let e = getText(); 469 $(element).val(''); 470 let t = parseFloat($(element).css('border-left-width').replace('px', '')), 471 n = parseFloat($(element).css('border-right-width').replace('px', '')); 472 (withoutScrollDiff = element.offsetWidth - element.clientWidth - t - n), 473 $(element).val(e); 474 } 475 if ( 476 ($(element).attr('spellcheck', !1), 477 (elementParent = element.parentNode), 478 '0px' == $(elementParent).css('width') && 479 '0px' == $(elementParent).css('height') && 480 $(elementParent).css('position', 'unset'), 481 renderQalamMirror(), 482 renderQalamComponent(), 483 'IFRAME' != element.tagName) 484 ) 485 $(element).on('scroll', function () { 486 handleReposition(!1); 487 }), 488 $(window).on('scroll', function () { 489 handleReposition(!1); 490 }), 491 $(window).on('resize', function () { 492 handleReposition(!0); 493 }); 494 else { 495 let e, 496 t = $(element).contents(); 497 $(t).on('scroll', function () { 498 !(function () { 499 let e = $('qalam-extension .qalam-highlights-cont qalam-label'); 500 for (let t = 0; t < e.length; t++) { 501 const n = e[t]; 502 n.style.display = 'none'; 503 } 504 })(), 505 clearTimeout(e), 506 (e = setTimeout(function () { 507 handleReposition(!0); 508 }, 200)); 509 }); 510 } 511 new ResizeObserver(function () { 512 handleReposition(!0); 513 }).observe(element), 514 '' != getText().trim() && (languageChecker(), spellCheckText()); 515 } 516 } 517 518 function handleReposition(e) { 519 removeQalamSuggestions(), 520 removeDisablePrompt(), 521 repositionQalamButton(), 522 $(qalamExtensionCont).scrollTop($(element).scrollTop()), 523 $(qalamExtensionCont).scrollLeft($(element).scrollLeft()), 524 e && SCServiceActive && drawLabels(!0); 525 } 526 527 function repositionQalamButton() { 528 let e = $('qalam-button-cont'); 529 if ( 530 (e.css('position', 'absolute'), 531 (qalamExtensionCont ? qalamExtensionCont.getBoundingClientRect() : '') 532 .height > 30) 533 ) { 534 let t = 0; 535 if ('rtl' == $(element).css('direction')) { 536 let e = parseFloat($(element).css('border-left-width').replace('px', '')), 537 n = parseFloat($(element).css('border-right-width').replace('px', '')); 538 t = element.offsetWidth - element.clientWidth - e - n; 539 } 540 e.css('left', 6 + t), e.css('bottom', 6), e.css('padding', 4); 541 } else e.css('left', 6), e.css('bottom', 6), e.css('padding', 0); 542 } 543 544 function renderQalamComponent() { 545 if ((drawLabels(!0), !$(elementParent).find('qalam-container').length)) { 546 let e = document.createElement('qalam-container'); 547 $(elementParent).append(e); 548 let t = document.createElement('qalam-wrapper'); 549 (qalamExtension = document.createElement('qalam-extension')), 550 (qalamExtensionCont = document.createElement('qalam-extension-cont')), 551 ((qalamHighlightsCont = document.createElement('div')).className = 552 'qalam-highlights-cont'); 553 let n = document.createElement('qalam-button-cont'), 554 a = document.createElement('div'); 555 a.className = 'qalam-button'; 556 let o = document.createElement('p'); 557 (o.className = 'errors'), 558 $(a).css('backgroundImage', `url(${settings.assetsPath}/images/128.png)`), 559 isUrlDisabled() 560 ? $(a).css('background-image', 'url(../images/disabled.png)') 561 : $(a).css( 562 'backgroundImage', 563 `url(${settings.assetsPath}/images/128.png)` 564 ); 565 let l = document.createElement('div'); 566 l.className = 'separator'; 567 let i = document.createElement('img'); 568 (i.className = 'disable-icon'), 569 (i.src = `${settings.assetsPath}/images/disable.svg`), 570 (i.title = 'تعطيل عمل قلم'), 571 $(i).on('click', function (e) { 572 showDisablePrompt(); 573 }), 574 resizeQalamExtension(); 575 let s = document.createElement('qalam-tashkeel-blk'); 576 (s.className = 'qalam-tashkeel'), (s.style.display = 'none'); 577 let r = document.createElement('qalam-quraan-blk'); 578 (r.className = 'qalam-quraan'), (r.style.display = 'none'); 579 let c = document.createElement('img'); 580 (c.className = 'qalam-quraan-icon'), 581 (c.src = `${settings.assetsPath}/images/quran_3.svg`); 582 let m = document.createElement('img'); 583 if ( 584 ((m.className = 'qalam-tashkeel-icon'), 585 (m.src = `${settings.assetsPath}/images/tashkeel.svg`), 586 (qalamExtensionCont.style.width = '100%'), 587 (qalamExtensionCont.style.height = '100%'), 588 a.appendChild(o), 589 n.appendChild(a), 590 n.appendChild(l), 591 n.appendChild(i), 592 qalamExtensionCont.appendChild(qalamHighlightsCont), 593 qalamExtension.appendChild(qalamExtensionCont), 594 isTashkeelActive && 595 (s.appendChild(m), 596 s.appendChild(document.createElement('div')), 597 qalamExtension.appendChild(s)), 598 isTawtheeqActive && 599 (r.appendChild(c), 600 r.appendChild(document.createElement('div')), 601 qalamExtension.appendChild(r)), 602 'IFRAME' == element.tagName) 603 ) { 604 let e = 605 element.contentDocument && element.contentDocument.body 606 ? element.contentDocument.body.parentElement.querySelector( 607 '[contenteditable]' 608 ) || element.contentDocument.body.parentElement 609 : null, 610 t = element.contentWindow || element.contentDocument; 611 $(e).mouseup(function () { 612 (selectedText = getSelectedText(t)), 613 showTashkeelAndTawtheeq(selectedText, s, r); 614 }); 615 } else 616 $(element).mouseup(function () { 617 (selectedText = getSelectedText(window)), 618 showTashkeelAndTawtheeq(selectedText, s, r); 619 }); 620 $(s).on('mousedown', function (e) { 621 $(this).prop('disabled') || controlSelection(e); 622 }), 623 $(r).on('mousedown', function (e) { 624 $(this).prop('disabled') || controlSelection(e); 625 }), 626 $(element).on( 627 isTextArea ? 'input propertychange' : 'DOMSubtreeModified', 628 function () { 629 triggerFlag && 630 ('IFRAME' != element.tagName && 631 $('qalam-tashkeel-blk') && 632 $('qalam-quraan-blk'), 633 clearButton(), 634 clearLabels(), 635 resizeQalamExtension(), 636 typedIn()); 103 637 } 104 }, 5e3); 105 $(document).on("click", function (e) { 106 $(e.target).closest("qalam-button-cont").length || isEventInsideElement(e, qalamDisablePrompt) || removeDisablePrompt(), isEventInsideElement(e, qalamSuggestions) || removeQalamSuggestions(), clearInterval(resizeHoldCounter), resizeHoldCounter = null 107 }), mobileCheck && document.addEventListener("touchstart", function (e) { 108 "QALAM-LABEL" == e.target.tagName && (e.target.classList.add("active"), renderQalamSuggestions(e)), "QALAM-LABEL" != e.target.tagName && "QALAM-SUGGESTIONS" != e.target.tagName && "SUGGESTION-ITEM" != e.target.tagName && "SUGGESTION-TEXT" != e.target.tagName && "QALAM-MIRROR-SHADOW" != e.target.tagName && ($(qalamSuggestions).remove(), $("qalam-extension .qalam-highlights-cont qalam-label").removeClass("active")) 109 }, !1), $(document).on("mousemove", function (e) { 110 if (isEventInsideElement(e, qalamSuggestions)) stopRemoveSuggestionsTimeout(); else { 111 let t = $("qalam-label.active"); 112 if (t.length) { 113 isInLabel = !1; 114 for (let n = 0; n < t.length; n++) if (isEventInsideElement(e, t[n])) { 115 isInLabel = !0; 116 break 117 } 118 isInLabel ? stopRemoveSuggestionsTimeout() : setRemoveSuggestionsTimeout() 119 } 120 } 121 }) 122 } 123 124 function tagIframe(e) { 125 if (e.getAttribute("data-qtag")) return e.getAttribute("data-qtag"); 126 const t = Math.random().toString(36).substring(5); 127 return e.setAttribute("data-qtag", t), t 128 } 129 130 function isEventInsideElement(e, t) { 131 if (null == t) return !1; 132 let n = t.getBoundingClientRect(); 133 return e.clientX >= n.left && e.clientX <= n.right && e.clientY >= n.top && e.clientY <= n.bottom 134 } 135 136 function setRemoveSuggestionsTimeout() { 137 null === removeSuggestionsTimeout && (removeSuggestionsTimeout = setTimeout(function () { 138 removeQalamSuggestions(), removeSuggestionsTimeout = null 139 }, REMOVE_SUGGESTION_DELAY)) 140 } 141 142 function stopRemoveSuggestionsTimeout() { 143 null !== removeSuggestionsTimeout && (clearTimeout(removeSuggestionsTimeout), removeSuggestionsTimeout = null) 144 } 145 146 function getText() { 147 if ("IFRAME" == element.tagName) { 148 let e = element.contentDocument.querySelector("[contenteditable]"); 149 editorId = e.getAttribute("data-qid"); 150 let t = "", n = [{element: e, parent: null}]; 151 for (; n.length;) { 152 let e = n.pop(), a = e.parent; 153 if ("BR" == (e = e.element).tagName) t += `\n${DUMMY_STRING}\n`; else if (3 == e.nodeType) { 154 let n = e.textContent; 155 STYLES_WRAP.has(window.getComputedStyle(a, null).whiteSpace) || (n = n.replace(/\n/g, " ")), t += n 156 } else { 157 let t = window.getComputedStyle(e, null).display; 158 if (STYLES_HIDDEN.has(t)) continue; 159 STYLES_BLOCKING.has(t) && n.push({element: document.createElement("br"), parent: e}); 160 let a = []; 161 Array.from(e.childNodes).reverse().forEach(t => { 162 a.push({element: t, parent: e}) 163 }), n.push(...a), STYLES_BLOCKING.has(t) && n.push({element: document.createElement("br"), parent: e}) 164 } 165 } 166 return t 638 ), 639 t.append(qalamExtension), 640 qalamExtension.appendChild(n), 641 e.append(t); 642 } 643 } 644 function getConfig() { 645 $.ajax({ 646 url: baseLink + 'test/config', 647 method: 'GET', 648 timeout: 0, 649 headers: { 650 'Content-Type': 'application/json', 651 Authorization: `${clientId}`, 652 'Qalam-Agent': qalamAgent, 653 }, 654 success: function (e) { 655 let t = e.categories.filter((e) => 'tashkeel' == e.id), 656 n = e.categories.filter((e) => 'tawtheeq' == e.id); 657 'true' == t[0].value || $('.qalam-tashkeel').remove(), 658 (isTashkeelActive = 'true' == t[0].value), 659 (isTawtheeqActive = 'true' == n[0].value); 660 }, 661 error: function () {}, 662 }); 663 } 664 665 function getTermsConfig() { 666 $.ajax({ 667 dataType: 'json', 668 url: baseLink + 'dictionaries/words?fields=config', 669 type: 'GET', 670 headers: { 671 'Content-Type': 'application/json', 672 Authorization: `${clientId}`, 673 'Qalam-Agent': qalamAgent, 674 }, 675 success: function (e) { 676 isWriterAllowedToAddToDic = 677 'true' == e.dictionaryConfig.writerAllowedToAddDictionary; 678 }, 679 error: function () {}, 680 }); 681 } 682 683 function controlSelection(e) { 684 e.preventDefault(), e.stopPropagation(); 685 let t = e.currentTarget, 686 n = ''; 687 if ( 688 ((n = 689 'qalam-tashkeel' == e.currentTarget.classList.value 690 ? 'SC_service_tashkeel' 691 : 'SC_service_tawtheeq'), 692 'IFRAME' == element.tagName) 693 ) { 694 let e = element.contentWindow || element.contentDocument; 695 selectedText = getSelectedText(e); 696 } else selectedText = getSelectedText(window); 697 if (!selectedText || isEmpty(selectedText)) 698 return void hideTashkeelAndTawtheeq(); 699 $('qalam-tashkeel-blk').prop('disabled', !0), 700 $('qalam-quraan-blk').prop('disabled', !0), 701 $(t).find('div').addClass('qalam-icons-loader'); 702 let a = getUuid(), 703 o = { text: selectedText, docId: a }; 704 'SC_service_tashkeel' == n && 705 $.ajax({ 706 dataType: 'json', 707 url: baseLink + 'qalam/tashkeel', 708 type: 'POST', 709 headers: { 710 'Content-Type': 'application/json', 711 Authorization: `${clientId}`, 712 'Qalam-Agent': qalamAgent, 713 }, 714 data: JSON.stringify(o), 715 success: function (e) { 716 var n = e && e.text ? e.text : ''; 717 'IFRAME' == element.tagName 718 ? (element.contentDocument.execCommand('insertText', !1, n), 719 spellCheckText(!0)) 720 : isTextArea 721 ? document.execCommand('insertText', !1, n) 722 : document.execCommand('insertHTML', !1, n), 723 $('qalam-tashkeel-blk,qalam-quraan-blk').removeClass('disabled'), 724 $('qalam-tashkeel-blk').prop('disabled', !1), 725 $('qalam-quraan-blk').prop('disabled', !1), 726 $(t).find('div').removeClass('qalam-icons-loader'), 727 (selectedText = null); 728 }, 729 error: function () {}, 730 }), 731 'SC_service_tawtheeq' == n && 732 $.ajax({ 733 dataType: 'json', 734 url: baseLink + 'quran/tawtheeq', 735 type: 'POST', 736 headers: { 737 'Content-Type': 'application/json', 738 Authorization: `${clientId}`, 739 'Qalam-Agent': qalamAgent, 740 }, 741 data: JSON.stringify(o), 742 success: function (e) { 743 isEmpty(e) || (enter = '\n'); 744 var n = 745 e && e.suggestions 746 ? e.suggestions[0].matchedTextAyaModern + enter 747 : ''; 748 n && 749 '\n' != n && 750 ('IFRAME' == element.tagName 751 ? (element.contentDocument.execCommand('insertText', !1, n), 752 spellCheckText(!0)) 753 : isTextArea 754 ? document.execCommand('insertText', !1, n) 755 : document.execCommand('insertHTML', !1, n)), 756 $('qalam-tashkeel-blk,qalam-quraan-blk').removeClass('disabled'), 757 $('qalam-tashkeel-blk').prop('disabled', !1), 758 $('qalam-quraan-blk').prop('disabled', !1), 759 $(t).find('div').removeClass('qalam-icons-loader'), 760 (selectedText = null); 761 }, 762 error: function () {}, 763 }); 764 } 765 function getSelectedText(e) { 766 if (e.getSelection && e.getSelection().toString()) 767 return e.getSelection().toString(); 768 if (document.selection) return document.selection.createRange().text; 769 { 770 let e = $(element).get(0); 771 return e && e.value && e.selectionStart 772 ? e.value.substring(e.selectionStart, e.selectionEnd) 773 : ''; 774 } 775 } 776 function showTashkeelAndTawtheeq(e, t, n) { 777 e 778 ? ((t.style.display = 'flex'), (n.style.display = 'flex')) 779 : ((t.style.display = 'none'), (n.style.display = 'none')); 780 } 781 782 function hideTashkeelAndTawtheeq() { 783 $('qalam-quraan-blk').css('display', 'none'), 784 $('qalam-tashkeel-blk').css('display', 'none'); 785 } 786 787 function renderQalamMirror() { 788 if (!$('html').find('qalam-mirror-shadow').length) { 789 let e = document.createElement('qalam-mirror-shadow'); 790 $('html').append(e), (shadowRoot = e.attachShadow({ mode: 'open' })); 791 let t = document.createElement('style'); 792 (t.textContent = MIRROR_SHADOW_STYLE), 793 shadowRoot.appendChild(t), 794 isTextArea && 795 ((qalamMirror = document.createElement('qalam-mirror')), 796 $(qalamMirror).css('padding', $(element).css('padding')), 797 languageChecker(), 798 setFontSpecsForQalamMirror(), 799 resetQalamMirror(), 800 shadowRoot.append(qalamMirror)); 801 } 802 } 803 804 function setFontSpecsForQalamMirror() { 805 let e = 806 $(element).css('font-weight') + 807 ' ' + 808 $(element).css('font-size') + 809 ' / ' + 810 $(element).css('line-height') + 811 ' ' + 812 $(element).css('font-family'); 813 $(qalamMirror).css('font', e), 814 $(qalamMirror).css('letter-spacing', $(element).css('letter-spacing')); 815 } 816 817 function reflectToQalamMirror() { 818 isTextArea && element && (resetQalamMirror(), $(qalamMirror).html(getText())); 819 } 820 821 function resetQalamMirror() { 822 setFontSpecsForQalamMirror(); 823 let e = parseFloat($(element).css('padding-left').replace('px', '')), 824 t = parseFloat($(element).css('padding-right').replace('px', '')), 825 n = parseFloat($(element).css('border-left-width').replace('px', '')), 826 a = parseFloat($(element).css('border-right-width').replace('px', '')), 827 o = element.offsetWidth - element.clientWidth - n - a; 828 (o -= withoutScrollDiff), $(qalamMirror).css('left', o); 829 let l = e + t + o + n + a; 830 $(qalamMirror).css('width', element.getBoundingClientRect().width - l), 831 $(qalamMirror).css('height', 'auto'); 832 } 833 834 function resizeQalamExtension() { 835 let e = parseFloat($(element).css('border-top-width').replace('px', '')), 836 t = parseFloat($(element).css('border-bottom-width').replace('px', '')), 837 n = parseFloat($(element).css('border-left-width').replace('px', '')), 838 a = parseFloat($(element).css('border-right-width').replace('px', '')), 839 o = element.getBoundingClientRect(); 840 $(qalamExtension).css('height', o.height - e - t), 841 $(qalamExtension).css('top', $(element).position().top + e), 842 $(qalamExtension).css('margin', $(element).css('margin')), 843 $(qalamExtension).css('width', o.width - n - a), 844 $(qalamExtension).css('left', $(element).position().left + n), 845 $(qalamExtension).css('position', 'absolute'), 846 $('.qalam-highlights-cont').css('height', element.scrollHeight); 847 } 848 849 function getUrlWithoutParams() { 850 return [location.protocol, '//', location.host, location.pathname].join(''); 851 } 852 853 function disableUrl() { 854 if (isUrlDisabled()) return; 855 let e = JSON.parse(localStorage.getItem('urlsDisabled')) || []; 856 e.push(getUrlWithoutParams()), 857 localStorage.setItem('urlsDisabled', JSON.stringify(e)); 858 } 859 860 function enableUrl() { 861 let e = JSON.parse(localStorage.getItem('urlsDisabled')) || []; 862 (urlDisabledIndex = e.findIndex((e) => e === getUrlWithoutParams())), 863 urlDisabledIndex > -1 && 864 (e.splice(urlDisabledIndex, 1), 865 localStorage.setItem('urlsDisabled', JSON.stringify(e))); 866 } 867 868 function isUrlDisabled() { 869 let e = JSON.parse(localStorage.getItem('urlsDisabled')) || []; 870 return ( 871 (urlsDisabledIndex = e.find((e) => e === getUrlWithoutParams())), 872 !!urlsDisabledIndex 873 ); 874 } 875 876 function showDisablePrompt() { 877 if (!$(shadowRoot).find('qalam-disable-prompt').length) { 878 qalamDisablePrompt = document.createElement('qalam-disable-prompt'); 879 let e = document.createElement('p'); 880 (e.innerHTML = 'تعطيل عمل “قلم”؟'), (e.className = 'prompt-title'); 881 let t = document.createElement('button'); 882 (t.innerHTML = 'تعطيل عمل قلم'), 883 (t.className = 'qalam-btn secondary-btn'), 884 $(t).attr('type', 'button'), 885 $(t).on('click', function (e) { 886 disableUrl(), 887 drawLabels(!1), 888 $('.qalam-highlights-cont qalam-label').remove(), 889 $(element).next().addClass('d-none'), 890 $('qalam-button-cont .qalam-button .errors').css('display', 'none'), 891 $('qalam-button-cont .qalam-button').css( 892 'background-image', 893 `url(${settings.assetsPath}/images/disabled.png)` 894 ); 895 }); 896 let n = document.createElement('button'); 897 (n.innerHTML = 'إبقاء قلم فعّالاً'), 898 (n.className = 'qalam-btn primary-btn'), 899 $(n).attr('type', 'button'), 900 $(n).on('click', function () { 901 enableUrl(), 902 removeDisablePrompt(), 903 spellCheckText(!0), 904 $(element).next().removeClass('d-none'), 905 $('qalam-button-cont .qalam-button').css('background-image', 'none'); 906 }), 907 qalamDisablePrompt.appendChild(e), 908 qalamDisablePrompt.appendChild(t), 909 qalamDisablePrompt.appendChild(n), 910 $(shadowRoot).append(qalamDisablePrompt); 911 let a = $('qalam-button-cont')[0].getBoundingClientRect(), 912 o = qalamDisablePrompt.getBoundingClientRect(), 913 l = [ 914 { top: a.top + a.height - o.height, left: a.left + a.width }, 915 { 916 top: a.top, 917 left: a.left + a.width, 918 }, 919 { top: a.top + a.height - o.height, left: a.left - o.width }, 920 { top: a.top, left: a.left - o.width }, 921 ]; 922 for ( 923 let e = 0; 924 e < l.length && 925 ($(qalamDisablePrompt).css('top', l[e].top), 926 $(qalamDisablePrompt).css('left', l[e].left), 927 !isElementInViewport(qalamDisablePrompt)); 928 e++ 929 ); 930 $('qalam-button-cont').addClass('active'); 931 } 932 } 933 934 function removeDisablePrompt() { 935 $('qalam-button-cont').removeClass('active'), $(qalamDisablePrompt).remove(); 936 } 937 938 function mobileCheck() { 939 let e = !1; 940 var t; 941 return ( 942 (t = navigator.userAgent || navigator.vendor || window.opera), 943 (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test( 944 t 945 ) || 946 /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test( 947 t.substr(0, 4) 948 )) && 949 (e = !0), 950 e 951 ); 952 } 953 954 function removeQalamSuggestions() { 955 mobileCheck() || 956 ($(qalamSuggestions).remove(), 957 $('qalam-extension .qalam-highlights-cont qalam-label').removeClass( 958 'active' 959 )); 960 } 961 962 function removeNotification() { 963 $('qalam-notification').css('right', '-450px'), 964 setTimeout(function () { 965 $('qalam-notification').remove(); 966 }, 750); 967 } 968 969 function typedIn() { 970 (typingStallCounter = 0), 971 languageChecker(), 972 secondsCounter || 973 (secondsCounter = setInterval(function () { 974 typingStallCounter >= TYPING_STALL && 975 ('' != getText().trim() 976 ? spellCheckText() 977 : (clearButton(), clearLabels()), 978 clearInterval(secondsCounter), 979 (typingStallCounter = 0), 980 (secondsCounter = null)), 981 typingStallCounter++; 982 }, 500)); 983 } 984 985 function clearButton() { 986 $('qalam-button-cont .qalam-button .errors').css('display', 'none'), 987 isUrlDisabled() 988 ? $('qalam-button-cont .qalam-button').css( 989 'background-image', 990 `url(${settings.assetsPath}/images/disabled.png)` 991 ) 992 : $('qalam-button-cont .qalam-button').css( 993 'background-image', 994 `url(${settings.assetsPath}/images/128.png)` 995 ), 996 $('qalam-button-cont .qalam-button').css( 997 'background-color', 998 BUTTON_NORMAL_COLOR 999 ), 1000 clearLabels(); 1001 } 1002 1003 function languageChecker() { 1004 isTextArea && 1005 (/[\u0600-\u06FF]/.test(getText()) 1006 ? $(element).css('direction', 'rtl') 1007 : $(element).css('direction', 'ltr')); 1008 let e = $(element).css('direction'), 1009 t = 'rtl' == e ? 'right' : 'left'; 1010 $(qalamMirror).css('direction', e), 1011 $(qalamMirror).css('text-align', t), 1012 $(element).css('text-align', t); 1013 } 1014 1015 function spellCheckText(e) { 1016 let t = ANIMATION_DELAY; 1017 e 1018 ? (t = 0) 1019 : (isUrlDisabled() 1020 ? $('.qalam-button').css( 1021 'background-image', 1022 `url(${settings.assetsPath}/images/disabled.png)` 1023 ) 1024 : $('qalam-button-cont .qalam-button').css( 1025 'background-image', 1026 `url(${settings.assetsPath}/images/logo.gif)` 1027 ), 1028 $('qalam-button-cont .qalam-button').css( 1029 'background-image', 1030 `url(${settings.assetsPath}/images/logo.gif)` 1031 ), 1032 $('qalam-button-cont .qalam-button .errors').css('display', 'none')); 1033 let n = getText(); 1034 isUrlDisabled() || callService(n, t, e); 1035 } 1036 1037 function fetchErrors(e, t) { 1038 (currentTextSuggestions = e), drawLabels(t); 1039 } 1040 1041 function drawLabels(e) { 1042 reflectToQalamMirror(), 1043 resizeQalamExtension(), 1044 $('.qalam-highlights-cont qalam-label').remove(); 1045 let t = currentTextSuggestions.length; 1046 t > 0 1047 ? ($.each(currentTextSuggestions, function () { 1048 let t = this.original; 1049 type = this.type; 1050 let n = this.from, 1051 a = this.to, 1052 o = this.lang, 1053 l = this.replacement, 1054 i = this.lineColor, 1055 r = this.labelColor, 1056 s = getRangeSpecs(n, a); 1057 s && 1058 ($.each(s, function () { 1059 labelCreator(o, t, type, n, a, l, i, r, this, e); 1060 }), 1061 handleReposition()); 1062 }), 1063 setErrorsTotal(t)) 1064 : clearButton(); 1065 } 1066 1067 function detectBrowser() { 1068 return -1 != 1069 (navigator.userAgent.indexOf('Opera') || navigator.userAgent.indexOf('OPR')) 1070 ? 'Opera' 1071 : -1 != navigator.userAgent.indexOf('Chrome') 1072 ? 'Chrome' 1073 : -1 != navigator.userAgent.indexOf('Safari') 1074 ? 'Safari' 1075 : -1 != navigator.userAgent.indexOf('Firefox') 1076 ? 'Firefox' 1077 : -1 != navigator.userAgent.indexOf('MSIE') || 1 == !!document.documentMode 1078 ? 'IE' 1079 : 'Unknown'; 1080 } 1081 1082 function detectBrowser() { 1083 return -1 != 1084 (navigator.userAgent.indexOf('Opera') || navigator.userAgent.indexOf('OPR')) 1085 ? 'Opera' 1086 : -1 != navigator.userAgent.indexOf('Chrome') 1087 ? 'Chrome' 1088 : -1 != navigator.userAgent.indexOf('Safari') 1089 ? 'Safari' 1090 : -1 != navigator.userAgent.indexOf('Firefox') 1091 ? 'Firefox' 1092 : -1 != navigator.userAgent.indexOf('MSIE') || 1 == !!document.documentMode 1093 ? 'IE' 1094 : 'Unknown'; 1095 } 1096 function labelCreator(e, t, n, a, o, l, i, r, s, u) { 1097 let c = document.createElement('qalam-label'); 1098 (s.width = s.right - s.left), 1099 (s.height = s.bottom - s.top), 1100 $(c).css('width', s.width), 1101 $(c).css('height', 1.05 * s.height), 1102 'Firefox' == detectBrowser() 1103 ? ($(c).css('top', s.top + 6 - 0.025 * s.height), 1104 $(c).css('left', s.left + 12)) 1105 : ($(c).css('top', s.top - 0.025 * s.height), $(c).css('left', s.left)), 1106 $(c).css('background-color', r), 1107 $(c).on('mouseenter', function (e) { 1108 renderQalamSuggestions(e, t, n), $(c).addClass('active'); 1109 }); 1110 let m = JSON.stringify(l); 1111 $(c).attr('data-suggestions', m), 1112 $(c).attr('data-start-index', a), 1113 $(c).attr('data-end-index', o), 1114 $(c).attr('data-lang', e); 1115 let d = document.createElement('label-border'); 1116 $(d).css('left', s.left), 1117 $(d).css('width', s.width), 1118 $(d).css('background-color', i), 1119 c.appendChild(d), 1120 qalamHighlightsCont.appendChild(c), 1121 u 1122 ? $(d).css('left', '0') 1123 : setTimeout(function () { 1124 $(d).css('left', '0'); 1125 }, 10); 1126 } 1127 function getRangeInfo(e, t) { 1128 let n = {}; 1129 if ('IFRAME' == element.tagName) { 1130 let a = [element.contentDocument.activeElement], 1131 o = 0; 1132 for (; a.length; ) { 1133 let l = a.pop(); 1134 if (3 == l.nodeType) { 1135 for (let a = 0; a < l.textContent.length; a++) 1136 e <= o + a && 1137 o + a <= t && 1138 (n[o + a] = { 1139 node: l, 1140 index: a, 1141 }); 1142 if ((o += l.textContent.length) > t) break; 1143 } else { 1144 let displayStyle = 1145 typeof currentNode == Element 1146 ? window.getComputedStyle(l, null).display 1147 : ''; 1148 if (STYLES_HIDDEN.has(displayStyle)) continue; 1149 a.push(...Array.from(l.childNodes).reverse()); 1150 } 167 1151 } 168 if (isTextArea) return editorId = element.getAttribute("data-qid"), $(element).val() || $(element).text(); 169 let e = "", t = [{element: element, parent: null}]; 170 for (; t.length;) { 171 let n = t.pop(), a = n.parent; 172 if ("BR" == (n = n.element).tagName) e += `\n${DUMMY_STRING}\n`; else if (3 == n.nodeType) { 173 let t = n.textContent; 174 STYLES_WRAP.has(window.getComputedStyle(a, null).whiteSpace) || (t = t.replace(/\n/g, " ")), e += t 175 } else { 176 let e = window.getComputedStyle(n, null).display; 177 if (STYLES_HIDDEN.has(e)) continue; 178 STYLES_BLOCKING.has(e) && t.push({element: document.createElement("br"), parent: n}); 179 let a = []; 180 Array.from(n.childNodes).reverse().forEach(e => { 181 a.push({element: e, parent: n}) 182 }), t.push(...a), STYLES_BLOCKING.has(e) && t.push({element: document.createElement("br"), parent: n}) 183 } 1152 return n; 1153 } 1154 if (isTextArea) { 1155 let a = qalamMirror.childNodes[0]; 1156 for (let o = e; o <= t; o++) n[o] = { node: a, index: o }; 1157 return n; 1158 } 1159 let a = [element], 1160 o = 0; 1161 for (; a.length; ) { 1162 let l = a.pop(); 1163 if (3 == l.nodeType) { 1164 for (let a = 0; a < l.textContent.length; a++) 1165 e <= o + a && o + a <= t && (n[o + a] = { node: l, index: a }); 1166 if ((o += l.textContent.length) > t) break; 1167 } else { 1168 let displayStyle = 1169 typeof l == Element ? window.getComputedStyle(l, null).display : ''; 1170 if (STYLES_HIDDEN.has(displayStyle)) continue; 1171 a.push(...Array.from(l.childNodes).reverse()); 184 1172 } 185 return editorId = element.getAttribute("data-qid"), e 186 } 187 188 function listenerTriggered(e) { 189 if (assignEditorIds(), element != e || "IFRAME" == e.tagName) { 190 if (unmountQalamComponent(), isTextArea = "TEXTAREA" == (element = e).tagName || "IFRAME" == element.tagName) { 191 let e = getText(); 192 $(element).val(""); 193 let t = parseFloat($(element).css("border-left-width").replace("px", "")), 194 n = parseFloat($(element).css("border-right-width").replace("px", "")); 195 withoutScrollDiff = element.offsetWidth - element.clientWidth - t - n, $(element).val(e) 196 } 197 if ($(element).attr("spellcheck", !1), elementParent = element.parentNode, "0px" == $(elementParent).css("width") && "0px" == $(elementParent).css("height") && $(elementParent).css("position", "unset"), renderQalamMirror(), renderQalamComponent(), "IFRAME" != element.tagName) $(element).on("scroll", function () { 198 handleReposition(!1) 199 }), $(window).on("scroll", function () { 200 handleReposition(!1) 201 }), $(window).on("resize", function () { 202 handleReposition(!0) 203 }); else { 204 let e, t = $(element).contents(); 205 $(t).on("scroll", function () { 206 !function () { 207 let e = $("qalam-extension .qalam-highlights-cont qalam-label"); 208 for (let t = 0; t < e.length; t++) { 209 const n = e[t]; 210 n.style.display = "none" 211 } 212 }(), clearTimeout(e), e = setTimeout(function () { 213 handleReposition(!0) 214 }, 200) 215 }) 216 } 217 new ResizeObserver(function () { 218 handleReposition(!0) 219 }).observe(element), "" != getText().trim() && (languageChecker(), spellCheckText()) 1173 } 1174 return n; 1175 } 1176 1177 function getRangeSpecs(e, t) { 1178 let n = getRangeInfo(e, t), 1179 a = document.createRange(), 1180 o = [], 1181 l = 0, 1182 i = 0, 1183 s = element.getBoundingClientRect(); 1184 for (let r = e; r <= t; r++) { 1185 try { 1186 a.setStart(n[r].node, n[r].index), a.setEnd(n[r].node, n[r].index + 1); 1187 } catch (e) {} 1188 let e = a.getBoundingClientRect(); 1189 if (0 == e.width || 0 == e.height) continue; 1190 let t = e.top - !isTextArea * (s.top - $(element).scrollTop()), 1191 c = e.bottom - !isTextArea * (s.top - $(element).scrollTop()), 1192 m = e.left - !isTextArea * s.left, 1193 d = e.right - !isTextArea * s.left, 1194 u = Math.min(c - t, i - l), 1195 g = Math.min(i, c) - Math.max(l, t); 1196 0 == o.length || g / u < INTERSECTION_THRESHOLD 1197 ? o.push({ 1198 right: d, 1199 left: m, 1200 bottom: c, 1201 top: t, 1202 }) 1203 : ((o[o.length - 1].left = Math.min(o[o.length - 1].left, m)), 1204 (o[o.length - 1].right = Math.max(o[o.length - 1].right, d)), 1205 (o[o.length - 1].top = Math.min(o[o.length - 1].top, t)), 1206 (o[o.length - 1].bottom = Math.max(o[o.length - 1].bottom, c))), 1207 (l = t), 1208 (i = c); 1209 } 1210 return o; 1211 } 1212 1213 function clearLabels() { 1214 (currentTextSuggestions = []), 1215 $('.qalam-highlights-cont qalam-label').remove(); 1216 } 1217 1218 function setErrorsTotal(e) { 1219 $('qalam-button-cont .qalam-button').css( 1220 'background-color', 1221 BUTTON_ERROR_COLOR 1222 ), 1223 $('qalam-button-cont .qalam-button').css('background-image', 'unset'), 1224 $('qalam-button-cont .qalam-button .errors').css('display', 'block'), 1225 $('qalam-button-cont .qalam-button .errors').text(e), 1226 e > 99 1227 ? $('qalam-button-cont .qalam-button .errors').css('font-size', '12px') 1228 : $('qalam-button-cont .qalam-button .errors').css('font-size', '15px'); 1229 } 1230 1231 function decreaseTotalErrorsCount() { 1232 let e = parseInt($('qalam-button-cont .qalam-button .errors').text()); 1233 e > 1 1234 ? $('qalam-button-cont .qalam-button .errors').text(e - 1) 1235 : clearButton(); 1236 } 1237 1238 function renderQalamSuggestions(e, t, n) { 1239 removeQalamSuggestions(); 1240 let a = $(e.target).closest('qalam-label'), 1241 o = JSON.parse($(a).attr('data-suggestions')), 1242 l = $(a).attr('data-start-index'), 1243 i = $(a).attr('data-end-index'), 1244 r = $(a).attr('data-lang'); 1245 if (!$(shadowRoot).find('qalam-suggestions').length) { 1246 qalamSuggestions = document.createElement('qalam-suggestions'); 1247 let e = document.createElement('suggestions-cont'); 1248 $.each(o, function () { 1249 let t = this, 1250 n = document.createElement('suggestion-item'); 1251 $(n).on('click', function () { 1252 let e = $(element).scrollTop(), 1253 n = $(window).scrollTop(); 1254 $(`qalam-label[data-start-index="${l}"]`).remove(), 1255 removeQalamSuggestions(), 1256 decreaseTotalErrorsCount(), 1257 replaceOriginalText(t, l, i), 1258 spellCheckText(!0), 1259 $(element).scrollTop(e), 1260 $(window).scrollTop(n), 1261 mobileCheck() && 1262 ($(qalamSuggestions).remove(), 1263 $('qalam-extension .qalam-highlights-cont qalam-label').removeClass( 1264 'active' 1265 )); 1266 }); 1267 let a = document.createElement('suggestion-text'); 1268 'en' === r && ((a.style.direction = 'ltr'), (a.style.textAlign = 'left')), 1269 '' === t.trim() 1270 ? (a.innerHTML = '<i style="font-size:12px;"><مسافة زائدة><i>') 1271 : (a.innerHTML = t), 1272 n.appendChild(a), 1273 e.appendChild(n); 1274 }); 1275 let s = document.createElement('div'); 1276 (s.className = 'ignore-cont'), 1277 $(s).on('click', function () { 1278 wordGetter(l, i); 1279 onDismissCallback([t], getContext(t, l, i)), 1280 $(`qalam-label[data-start-index='${l}']`).remove(), 1281 removeQalamSuggestions(), 1282 spellCheckText(!0); 1283 }); 1284 let u = document.createElement('img'); 1285 (u.className = 'ignore-icon'), 1286 (u.src = `${settings.assetsPath}/images/ignore.svg`); 1287 let c, 1288 m = document.createElement('p'); 1289 if ( 1290 ((m.className = 'ignore-text'), 1291 (m.innerHTML = 'تجاهل هذا التصحيح'), 1292 s.appendChild(u), 1293 s.appendChild(m), 1294 isWriterAllowedToAddToDic && 'terms' != n) 1295 ) { 1296 (c = document.createElement('div')), 1297 (c.className = 'add-to-dic-cont'), 1298 $(c).on('click', function () { 1299 onAddToDictionaryCallback([t], getContext(t, l, i)), 1300 $(`qalam-label[data-start-index="${l}"]`).remove(), 1301 removeQalamSuggestions(), 1302 spellCheckText(!0); 1303 }); 1304 let e = document.createElement('img'); 1305 (e.className = 'add-to-dic-icon'), 1306 (e.src = `${settings.assetsPath}/images/add.svg`); 1307 let n = document.createElement('p'); 1308 (n.className = 'add-to-dic-text'), 1309 (n.innerHTML = 'إضافة إلى القاموس'), 1310 c.appendChild(e), 1311 c.appendChild(n); 220 1312 } 221 } 222 223 function handleReposition(e) { 224 removeQalamSuggestions(), removeDisablePrompt(), repositionQalamButton(), $(qalamExtensionCont).scrollTop($(element).scrollTop()), $(qalamExtensionCont).scrollLeft($(element).scrollLeft()), e && SCServiceActive && drawLabels(!0) 225 } 226 227 function repositionQalamButton() { 228 let e = $("qalam-button-cont"); 229 if (e.css("position", "absolute"), (qalamExtensionCont ? qalamExtensionCont.getBoundingClientRect() : "").height > 30) { 1313 let d = document.createElement('img'); 1314 if ( 1315 ((d.className = 'wrong-suggestion-more-icon'), 1316 (d.src = `${settings.assetsPath}/images/more.png`), 1317 (d.width = '15'), 1318 (d.height = '15'), 1319 $(d).on('click', function (e) { 1320 e.preventDefault(), 1321 e.stopPropagation(), 1322 (wrongSuggestionItem = document.createElement('div')), 1323 (wrongSuggestionItem.className = 'wrong-suggestion-cont'); 1324 let n = document.createElement('img'); 1325 (n.className = 'wrong-suggestion-icon'), 1326 (n.src = `${settings.assetsPath}/images/wrong-suggestion.svg`); 1327 let a = document.createElement('p'); 1328 (a.className = 'wrong-suggestion-text'), 1329 (a.innerHTML = 'هذا اقتراح خاطئ'), 1330 wrongSuggestionItem.appendChild(n), 1331 wrongSuggestionItem.appendChild(a), 1332 $(wrongSuggestionItem).on('click', function () { 1333 onWrongSuggestionCallback(t, getContext(t, l, i)), 1334 $(`qalam-label[data-start-index="${l}"]`).remove(), 1335 removeQalamSuggestions(); 1336 }), 1337 s.appendChild(wrongSuggestionItem); 1338 }), 1339 qalamSuggestions.appendChild(e), 1340 qalamSuggestions.appendChild(s), 1341 'terms' != n && s.appendChild(d), 1342 isWriterAllowedToAddToDic && 1343 'terms' != n && 1344 qalamSuggestions.appendChild(c), 1345 $(shadowRoot).append(qalamSuggestions), 1346 o.length > 0) 1347 ) { 1348 (labelBoundingBox = a[0].getBoundingClientRect()), 1349 $(qalamSuggestions).css('display', 'block'), 1350 (suggestionBoundingBox = qalamSuggestions.getBoundingClientRect()); 1351 let e = [ 1352 { 1353 top: labelBoundingBox.top + labelBoundingBox.height, 1354 left: 1355 labelBoundingBox.left + 1356 labelBoundingBox.width - 1357 suggestionBoundingBox.width, 1358 }, 1359 { 1360 top: labelBoundingBox.top + labelBoundingBox.height, 1361 left: labelBoundingBox.left, 1362 }, 1363 { 1364 top: labelBoundingBox.top - suggestionBoundingBox.height, 1365 left: 1366 labelBoundingBox.left + 1367 labelBoundingBox.width - 1368 suggestionBoundingBox.width, 1369 }, 1370 { 1371 top: labelBoundingBox.top - suggestionBoundingBox.height, 1372 left: labelBoundingBox.left, 1373 }, 1374 ]; 1375 for ( 230 1376 let t = 0; 231 if ("rtl" == $(element).css("direction")) { 232 let e = parseFloat($(element).css("border-left-width").replace("px", "")), 233 n = parseFloat($(element).css("border-right-width").replace("px", "")); 234 t = element.offsetWidth - element.clientWidth - e - n 235 } 236 e.css("left", 6 + t), e.css("bottom", 6), e.css("padding", 4) 237 } else e.css("left", 6), e.css("bottom", 6), e.css("padding", 0) 238 } 239 240 function renderQalamComponent() { 241 if (drawLabels(!0), !$(elementParent).find("qalam-container").length) { 242 let e = document.createElement("qalam-container"); 243 $(elementParent).append(e); 244 let t = document.createElement("qalam-wrapper"); 245 qalamExtension = document.createElement("qalam-extension"), qalamExtensionCont = document.createElement("qalam-extension-cont"), (qalamHighlightsCont = document.createElement("div")).className = "qalam-highlights-cont"; 246 let n = document.createElement("qalam-button-cont"), a = document.createElement("div"); 247 a.className = "qalam-button"; 248 let o = document.createElement("p"); 249 o.className = "errors", $(a).css("backgroundImage", `url(${settings.assetsPath}/images/128.png)`), isUrlDisabled() ? $(a).css("background-image", "url(../images/disabled.png)") : $(a).css("backgroundImage", `url(${settings.assetsPath}/images/128.png)`); 250 let l = document.createElement("div"); 251 l.className = "separator"; 252 let i = document.createElement("img"); 253 i.className = "disable-icon", i.src = `${settings.assetsPath}/images/disable.svg`, i.title = "تعطيل عمل قلم", $(i).on("click", function (e) { 254 showDisablePrompt() 255 }), resizeQalamExtension(); 256 let s = document.createElement("qalam-tashkeel-blk"); 257 s.className = "qalam-tashkeel", s.style.display = "none"; 258 let r = document.createElement("qalam-quraan-blk"); 259 r.className = "qalam-quraan", r.style.display = "none"; 260 let c = document.createElement("img"); 261 c.className = "qalam-quraan-icon", c.src = `${settings.assetsPath}/images/quran_3.svg`; 262 let m = document.createElement("img"); 263 if (m.className = "qalam-tashkeel-icon", m.src = `${settings.assetsPath}/images/tashkeel.svg`, qalamExtensionCont.style.width = "100%", qalamExtensionCont.style.height = "100%", a.appendChild(o), n.appendChild(a), n.appendChild(l), n.appendChild(i), qalamExtensionCont.appendChild(qalamHighlightsCont), qalamExtension.appendChild(qalamExtensionCont), isTashkeelActive && (s.appendChild(m), qalamExtension.appendChild(s)), isTawtheeqActive && (r.appendChild(c), qalamExtension.appendChild(r)), "IFRAME" == element.tagName) { 264 let e = element.contentDocument && element.contentDocument.body ? element.contentDocument.body.parentElement.querySelector("[contenteditable]") || element.contentDocument.body.parentElement : null, 265 t = element.contentWindow || element.contentDocument; 266 $(e).mouseup(function () { 267 showTashkeelAndTawtheeq(selectedText = getSelectedText(t), s, r) 268 }) 269 } else $(element).mouseup(function () { 270 showTashkeelAndTawtheeq(selectedText = getSelectedText(window), s, r) 1377 t < e.length && 1378 ($(qalamSuggestions).css('top', e[t].top), 1379 $(qalamSuggestions).css('left', e[t].left), 1380 !isElementInViewport(qalamSuggestions)); 1381 t++ 1382 ); 1383 } 1384 } 1385 resizeQalamExtension(); 1386 } 1387 function onAddToDictionaryCallback(e, t) { 1388 $.ajax({ 1389 dataType: 'json', 1390 url: baseLink + 'dictionaries/words', 1391 type: 'POST', 1392 headers: { 1393 'Content-Type': 'application/json', 1394 Authorization: `${clientId}`, 1395 'Qalam-Agent': qalamAgent, 1396 }, 1397 data: JSON.stringify({ words: e, context: t }), 1398 success: function (e) {}, 1399 error: function () {}, 1400 }); 1401 } 1402 function onWrongSuggestionCallback(e, t) { 1403 $.ajax({ 1404 dataType: 'json', 1405 url: `${baseLink}documents/${uuidV3Hash}/wrong/suggestions`, 1406 type: 'POST', 1407 headers: { 1408 'Content-Type': 'application/json', 1409 Authorization: `${clientId}`, 1410 'Qalam-Agent': qalamAgent, 1411 }, 1412 data: JSON.stringify({ words: e, context: t }), 1413 success: function (e) {}, 1414 error: function () {}, 1415 }); 1416 } 1417 function onDismissCallback(e, t) { 1418 $.ajax({ 1419 dataType: 'json', 1420 url: baseLink + 'documents/' + uuidV3Hash + '/dismissals', 1421 method: 'POST', 1422 timeout: 0, 1423 headers: { 1424 'Content-Type': 'application/json', 1425 Authorization: `${clientId}`, 1426 'Qalam-Agent': qalamAgent, 1427 }, 1428 data: JSON.stringify({ words: e, context: t }), 1429 success: function (e) {}, 1430 error: function () {}, 1431 }); 1432 } 1433 1434 function isElementInViewport(e) { 1435 let t = e.getBoundingClientRect(); 1436 return ( 1437 t.top >= 0 && 1438 t.left >= 0 && 1439 t.bottom <= (window.innerHeight || document.documentElement.clientHeight) && 1440 t.right <= (window.innerWidth || document.documentElement.clientWidth) 1441 ); 1442 } 1443 1444 function wordGetter(e, t) { 1445 return $(element) 1446 .val() 1447 .substr(e, parseInt(t) - e + 1); 1448 } 1449 1450 function replaceOriginalText(e, t, n) { 1451 let a = getText().length; 1452 if (isTextArea) 1453 if ('IFRAME' == element.tagName) { 1454 element.contentWindow.focus(); 1455 let e = getRangeInfo(t, n); 1456 (range = element.contentDocument.createRange()), 1457 range.setStart(e[t].node, e[t].index), 1458 range.setEnd(e[n].node, e[n].index + 1), 1459 (sel = element.contentDocument.getSelection()), 1460 sel.removeAllRanges(), 1461 sel.addRange(range); 1462 } else 1463 $(element).trigger('focus'), 1464 ($(element)[0].selectionStart = t), 1465 ($(element)[0].selectionEnd = parseInt(n) + 1); 1466 else { 1467 $(element).trigger('focus'); 1468 let e = getRangeInfo(t, n); 1469 (range = document.createRange()), 1470 range.setStart(e[t].node, e[t].index), 1471 range.setEnd(e[n].node, e[n].index + 1), 1472 (sel = window.getSelection()), 1473 sel.removeAllRanges(), 1474 sel.addRange(range); 1475 } 1476 (triggerFlag = !1), 1477 'IFRAME' == element.tagName 1478 ? element.contentDocument.execCommand('insertText', !1, e) 1479 : document.execCommand('insertText', !1, e), 1480 setTimeout(function () { 1481 triggerFlag = !0; 1482 }, 5); 1483 let o = a - getText().length, 1484 l = -1; 1485 $.each(currentTextSuggestions, function (e, n) { 1486 n.from == t 1487 ? (l = e) 1488 : n.from > t && 1489 ((currentTextSuggestions[e].from -= o), 1490 (currentTextSuggestions[e].to -= o)); 1491 }), 1492 -1 != l && currentTextSuggestions.splice(l, 1), 1493 drawLabels(!0); 1494 } 1495 1496 function unmountQalamComponent() { 1497 $('qalam-container').remove(), 1498 $('qalam-mirror-shadow').remove(), 1499 null != qalamMirror && $(qalamMirror).remove(), 1500 removeQalamSuggestions(), 1501 (ignoredSet = new Set()), 1502 (currentTextSuggestions = []); 1503 } 1504 1505 function resetGlobalVariables() { 1506 (shadowRoot = null), 1507 (qalamDisablePrompt = null), 1508 (isTextArea = null), 1509 (triggerFlag = !0), 1510 (SCServiceActive = null), 1511 (qalamExtension = null), 1512 (qalamExtensionCont = null), 1513 (qalamHighlightsCont = null), 1514 (qalamMirror = null), 1515 removeDisablePrompt(), 1516 removeQalamSuggestions(), 1517 (qalamSuggestions = null), 1518 $(element).off(), 1519 (element = null), 1520 (withoutScrollDiff = 0), 1521 (elementParent = null), 1522 (typingStallCounter = 0), 1523 (secondsCounter = null), 1524 (resizeHoldCounter = null), 1525 (currentTextSuggestions = []), 1526 clearInterval(secondsCounter), 1527 clearInterval(resizeHoldCounter); 1528 } 1529 1530 function turnOnSC() { 1531 (SCServiceActive = !0), init(); 1532 } 1533 1534 function turnOffSC() { 1535 (SCServiceActive = !1), unmountQalamComponent(), resetGlobalVariables(); 1536 } 1537 1538 function setCookie() { 1539 let e = generateId(8); 1540 document.cookie = 'qalam_user_id=' + e + '; path=/'; 1541 } 1542 1543 function getCookie(e) { 1544 for ( 1545 var t = e + '=', n = document.cookie.split(';'), a = 0; 1546 a < n.length; 1547 a++ 1548 ) { 1549 for (var o = n[a]; ' ' == o.charAt(0); ) o = o.substring(1, o.length); 1550 if (0 == o.indexOf(t)) return o.substring(t.length, o.length); 1551 } 1552 return null; 1553 } 1554 1555 function generateId(e) { 1556 for ( 1557 var t = '', 1558 n = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789', 1559 a = n.length, 1560 o = 0; 1561 o < e; 1562 o++ 1563 ) 1564 t += n.charAt(Math.floor(Math.random() * a)); 1565 return t; 1566 } 1567 1568 function getUuid() { 1569 let elementQalamId = $(element).attr('qalam-id'); 1570 if (elementQalamId) { 1571 uuidV3Hash = uuidv5(elementQalamId, clientId); 1572 } else if (documentId) 1573 uuidV3Hash = uuid.v5(documentId + ':' + editorId, clientId); 1574 else if (mode == PATH_MODE) { 1575 var a = extractPathParamAt(modeValue); 1576 a || (documentId = a = uuid.v4()), 1577 (uuidV3Hash = uuid.v5(a + ':' + editorId, clientId)); 1578 } else if (mode == QUERY_MODE) { 1579 var o = extractQueryParam(modeValue); 1580 o || (documentId = o = uuid.v4()), 1581 (uuidV3Hash = uuid.v5(o + ':' + editorId, clientId)); 1582 } else 1583 (documentId = uuid.v4()), 1584 (uuidV3Hash = uuid.v5(documentId + ':' + editorId, clientId)); 1585 1586 return uuidV3Hash; 1587 } 1588 1589 function callService(e, t, n) { 1590 uuidV3Hash = getUuid(); 1591 var l = { 1592 url: API_LINK, 1593 method: 'POST', 1594 timeout: 0, 1595 headers: { 1596 'Content-Type': 'application/json', 1597 Authorization: `${clientId}`, 1598 'Qalam-Agent': qalamAgent, 1599 }, 1600 success: function () {}, 1601 error: function (e, t, n) { 1602 e.status; 1603 }, 1604 data: JSON.stringify({ text: e, docId: uuidV3Hash }), 1605 }; 1606 setTimeout(function () { 1607 $.ajax(l).done(function (t) { 1608 let a = []; 1609 extend( 1610 a, 1611 extractRest( 1612 t.termSuggestions, 1613 TERM_LINE_COLOR, 1614 TERM_LABEL_COLOR, 1615 'terms' 1616 ) 1617 ), 1618 extend( 1619 a, 1620 extractRest( 1621 t.tafqeetSuggestions, 1622 TAFQEET_LINE_COLOR, 1623 TAFQEET_LABEL_COLOR, 1624 'tafqeet' 1625 ) 1626 ), 1627 extend( 1628 a, 1629 extractResponse( 1630 t.grammarResponse, 1631 GRAMMAR_LINE_COLOR, 1632 GRAMMAR_LABEL_COLOR, 1633 'grammar' 1634 ) 1635 ), 1636 extend( 1637 a, 1638 extractResponse( 1639 t.phrasingResponse, 1640 PHRASING_LINE_COLOR, 1641 PHRASING_LABEL_COLOR, 1642 'phrasing' 1643 ) 1644 ), 1645 extend( 1646 a, 1647 extractResponse( 1648 t.otherSuggestions, 1649 OS_LINE_COLOR, 1650 OS_LABEL_COLOR, 1651 'otherSuggestions' 1652 ) 1653 ), 1654 extend( 1655 a, 1656 extractResponse( 1657 t.spellCheckResponse, 1658 SC_LINE_COLOR, 1659 SC_LABEL_COLOR, 1660 'spellChecker' 1661 ) 1662 ), 1663 $.each(t.numDate, function () { 1664 extend(a, extractRest(this, NUM_LINE_COLOR, NUM_LABEL_COLOR)); 1665 }), 1666 $.each(t.tashkeel, function () { 1667 extend(a, extractRest(this, T_LINE_COLOR, T_LABEL_COLOR)); 1668 }), 1669 $.each(t.punctuation, function () { 1670 extend(a, extractRest(this, PUNC_LINE_COLOR, PUNC_LABEL_COLOR)); 271 1671 }); 272 $(r).on("click", function (e) { 273 controlSelection(e) 274 }), $(s).on("click", function (e) { 275 controlSelection(e) 276 }), $(element).on(isTextArea ? "input propertychange" : "DOMSubtreeModified", function () { 277 triggerFlag && ("IFRAME" != element.tagName && $("qalam-tashkeel-blk") && $("qalam-quraan-blk"), clearButton(), clearLabels(), resizeQalamExtension(), typedIn()) 278 }), t.append(qalamExtension), qalamExtension.appendChild(n), e.append(t) 279 } 280 } 281 282 function getConfig() { 283 $.ajax({ 284 dataType: "json", url: baseLink + "test/config", type: "GET", beforeSend: function (e) { 285 e.setRequestHeader("Authorization", `${clientId}`), e.setRequestHeader("Content-Type", "application/json") 286 }, success: function (e) { 287 let t = e.categories.filter(e => "tashkeel" == e.id), n = e.categories.filter(e => "tawtheeq" == e.id); 288 "true" == t[0].value || $(".qalam-tashkeel").remove(), isTashkeelActive = "true" == t[0].value, isTawtheeqActive = "true" == n[0].value 289 }, error: function () { 290 } 291 }) 292 } 293 294 function getTermsConfig() { 295 $.ajax({ 296 dataType: "json", 297 url: baseLink + "dictionaries/words?fields=config", 298 type: "GET", 299 beforeSend: function (e) { 300 e.setRequestHeader("Authorization", `${clientId}`), e.setRequestHeader("Content-Type", "application/json") 301 }, 302 success: function (e) { 303 isWriterAllowedToAddToDic = "true" == e.dictionaryConfig.writerAllowedToAddDictionary 304 }, 305 error: function () { 306 } 307 }) 308 } 309 310 function controlSelection(e) { 311 hideTashkeelAndTawtheeq(); 312 let t = ""; 313 t = "qalam-tashkeel" == e.currentTarget.classList.value ? "SC_service_tashkeel" : "SC_service_tawtheeq"; 314 let n = uuid.v5(documentId, clientId), a = {text: selectedText, docId: n}; 315 "SC_service_tashkeel" == t && $.ajax({ 316 dataType: "json", 317 url: baseLink + "qalam/tashkeel", 318 type: "POST", 319 beforeSend: function (e) { 320 e.setRequestHeader("Authorization", `${clientId}`), e.setRequestHeader("Content-Type", "application/json") 321 }, 322 data: JSON.stringify(a), 323 success: function (e) { 324 var t = e.text; 325 "IFRAME" == element.tagName ? (element.contentDocument.execCommand("insertText", !1, t), spellCheckText(!0)) : document.execCommand("insertHTML", !1, t), selectedText = null 326 }, 327 error: function () { 328 } 329 }), "SC_service_tawtheeq" == t && $.ajax({ 330 dataType: "json", 331 url: baseLink + "quran/tawtheeq", 332 type: "POST", 333 beforeSend: function (e) { 334 e.setRequestHeader("Authorization", `${clientId}`), e.setRequestHeader("Content-Type", "application/json") 335 }, 336 data: JSON.stringify(a), 337 success: function (e) { 338 isEmpty(e) || (enter = "\n"); 339 var t = e.suggestions[0].matchedTextAyaModern + enter; 340 "IFRAME" == element.tagName ? (element.contentDocument.execCommand("insertText", !1, t), spellCheckText(!0)) : document.execCommand("insertText", !1, t), selectedText = null 341 }, 342 error: function () { 343 } 344 }) 345 } 346 347 function getSelectedText(e) { 348 return e.getSelection ? e.getSelection().toString() : document.selection ? document.selection.createRange().text : "" 349 } 350 351 function showTashkeelAndTawtheeq(e, t, n) { 352 e ? (t.style.display = "flex", n.style.display = "flex") : (t.style.display = "none", n.style.display = "none") 353 } 354 355 function hideTashkeelAndTawtheeq() { 356 $("qalam-quraan-blk").css("display", "none"), $("qalam-tashkeel-blk").css("display", "none") 357 } 358 359 function renderQalamMirror() { 360 if (!$("html").find("qalam-mirror-shadow").length) { 361 let e = document.createElement("qalam-mirror-shadow"); 362 $("html").append(e), shadowRoot = e.attachShadow({mode: "open"}); 363 let t = document.createElement("style"); 364 t.textContent = MIRROR_SHADOW_STYLE, shadowRoot.appendChild(t), isTextArea && (qalamMirror = document.createElement("qalam-mirror"), $(qalamMirror).css("padding", $(element).css("padding")), languageChecker(), setFontSpecsForQalamMirror(), resetQalamMirror(), shadowRoot.append(qalamMirror)) 365 } 366 } 367 368 function setFontSpecsForQalamMirror() { 369 let e = $(element).css("font-weight") + " " + $(element).css("font-size") + " / " + $(element).css("line-height") + " " + $(element).css("font-family"); 370 $(qalamMirror).css("font", e), $(qalamMirror).css("letter-spacing", $(element).css("letter-spacing")) 371 } 372 373 function reflectToQalamMirror() { 374 isTextArea && element && (resetQalamMirror(), $(qalamMirror).html(getText())) 375 } 376 377 function resetQalamMirror() { 378 setFontSpecsForQalamMirror(); 379 let e = parseFloat($(element).css("padding-left").replace("px", "")), 380 t = parseFloat($(element).css("padding-right").replace("px", "")), 381 n = parseFloat($(element).css("border-left-width").replace("px", "")), 382 a = parseFloat($(element).css("border-right-width").replace("px", "")), 383 o = element.offsetWidth - element.clientWidth - n - a; 384 o -= withoutScrollDiff, $(qalamMirror).css("left", o); 385 let l = e + t + o + n + a; 386 $(qalamMirror).css("width", element.getBoundingClientRect().width - l), $(qalamMirror).css("height", "auto") 387 } 388 389 function resizeQalamExtension() { 390 let e = parseFloat($(element).css("border-top-width").replace("px", "")), 391 t = parseFloat($(element).css("border-bottom-width").replace("px", "")), 392 n = parseFloat($(element).css("border-left-width").replace("px", "")), 393 a = parseFloat($(element).css("border-right-width").replace("px", "")), o = element.getBoundingClientRect(); 394 $(qalamExtension).css("height", o.height - e - t), $(qalamExtension).css("top", $(element).position().top + e), $(qalamExtension).css("margin", $(element).css("margin")), $(qalamExtension).css("width", o.width - n - a), $(qalamExtension).css("left", $(element).position().left + n), $(qalamExtension).css("position", "absolute"), $(".qalam-highlights-cont").css("height", element.scrollHeight) 395 } 396 397 function getUrlWithoutParams() { 398 return [location.protocol, "//", location.host, location.pathname].join("") 399 } 400 401 function disableUrl() { 402 if (isUrlDisabled()) return; 403 let e = JSON.parse(localStorage.getItem("urlsDisabled")) || []; 404 e.push(getUrlWithoutParams()), localStorage.setItem("urlsDisabled", JSON.stringify(e)) 405 } 406 407 function enableUrl() { 408 let e = JSON.parse(localStorage.getItem("urlsDisabled")) || []; 409 urlDisabledIndex = e.findIndex(e => e === getUrlWithoutParams()), urlDisabledIndex > -1 && (e.splice(urlDisabledIndex, 1), localStorage.setItem("urlsDisabled", JSON.stringify(e))) 410 } 411 412 function isUrlDisabled() { 413 let e = JSON.parse(localStorage.getItem("urlsDisabled")) || []; 414 return urlsDisabledIndex = e.find(e => e === getUrlWithoutParams()), !!urlsDisabledIndex 415 } 416 417 function showDisablePrompt() { 418 if (!$(shadowRoot).find("qalam-disable-prompt").length) { 419 qalamDisablePrompt = document.createElement("qalam-disable-prompt"); 420 let e = document.createElement("p"); 421 e.innerHTML = "تعطيل عمل “قلم”؟", e.className = "prompt-title"; 422 let t = document.createElement("button"); 423 t.innerHTML = "تعطيل عمل قلم", t.className = "qalam-btn secondary-btn", $(t).attr("type", "button"), $(t).on("click", function (e) { 424 disableUrl(), drawLabels(!1), $(".qalam-highlights-cont qalam-label").remove(), $(element).next().addClass("d-none"), $("qalam-button-cont .qalam-button .errors").css("display", "none"), $("qalam-button-cont .qalam-button").css("background-image", `url(${settings.assetsPath}/images/disabled.png)`) 425 }); 426 let n = document.createElement("button"); 427 n.innerHTML = "إبقاء قلم فعّالاً", n.className = "qalam-btn primary-btn", $(n).attr("type", "button"), $(n).on("click", function () { 428 enableUrl(), removeDisablePrompt(), drawLabels(!0), $(element).next().removeClass("d-none"), $("qalam-button-cont .qalam-button").css("background-image", "none") 429 }), qalamDisablePrompt.appendChild(e), qalamDisablePrompt.appendChild(t), qalamDisablePrompt.appendChild(n), $(shadowRoot).append(qalamDisablePrompt); 430 let a = $("qalam-button-cont")[0].getBoundingClientRect(), o = qalamDisablePrompt.getBoundingClientRect(), 431 l = [{top: a.top + a.height - o.height, left: a.left + a.width}, { 432 top: a.top, 433 left: a.left + a.width 434 }, {top: a.top + a.height - o.height, left: a.left - o.width}, {top: a.top, left: a.left - o.width}]; 435 for (let e = 0; e < l.length && ($(qalamDisablePrompt).css("top", l[e].top), $(qalamDisablePrompt).css("left", l[e].left), !isElementInViewport(qalamDisablePrompt)); e++) ; 436 $("qalam-button-cont").addClass("active") 437 } 438 } 439 440 function removeDisablePrompt() { 441 $("qalam-button-cont").removeClass("active"), $(qalamDisablePrompt).remove() 442 } 443 444 function mobileCheck() { 445 let e = !1; 446 var t; 447 return t = navigator.userAgent || navigator.vendor || window.opera, (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(t) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(t.substr(0, 4))) && (e = !0), e 448 } 449 450 function removeQalamSuggestions() { 451 mobileCheck() || ($(qalamSuggestions).remove(), $("qalam-extension .qalam-highlights-cont qalam-label").removeClass("active")) 452 } 453 454 function removeNotification() { 455 $("qalam-notification").css("right", "-450px"), setTimeout(function () { 456 $("qalam-notification").remove() 457 }, 750) 458 } 459 460 function typedIn() { 461 typingStallCounter = 0, languageChecker(), secondsCounter || (secondsCounter = setInterval(function () { 462 typingStallCounter >= TYPING_STALL && ("" != getText().trim() ? spellCheckText() : (clearButton(), clearLabels()), clearInterval(secondsCounter), typingStallCounter = 0, secondsCounter = null), typingStallCounter++ 463 }, 500)) 464 } 465 466 function clearButton() { 467 $("qalam-button-cont .qalam-button .errors").css("display", "none"), isUrlDisabled() ? $("qalam-button-cont .qalam-button").css("background-image", `url(${settings.assetsPath}/images/disabled.png)`) : $("qalam-button-cont .qalam-button").css("background-image", `url(${settings.assetsPath}/images/128.png)`), $("qalam-button-cont .qalam-button").css("background-color", BUTTON_NORMAL_COLOR), clearLabels() 468 } 469 470 function languageChecker() { 471 isTextArea && (/[\u0600-\u06FF]/.test(getText()) ? $(element).css("direction", "rtl") : $(element).css("direction", "ltr")); 472 let e = $(element).css("direction"), t = "rtl" == e ? "right" : "left"; 473 $(qalamMirror).css("direction", e), $(qalamMirror).css("text-align", t), $(element).css("text-align", t) 474 } 475 476 function spellCheckText(e) { 477 let t = ANIMATION_DELAY; 478 e ? t = 0 : (isUrlDisabled() ? $(".qalam-button").css("background-image", `url(${settings.assetsPath}/images/disabled.png)`) : $("qalam-button-cont .qalam-button").css("background-image", `url(${settings.assetsPath}/images/logo.gif)`), $("qalam-button-cont .qalam-button").css("background-image", `url(${settings.assetsPath}/images/logo.gif)`), $("qalam-button-cont .qalam-button .errors").css("display", "none")); 479 let n = getText(); 480 isUrlDisabled() || callService(n, t, e) 481 } 482 483 function fetchErrors(e, t) { 484 currentTextSuggestions = e, drawLabels(t) 485 } 486 487 function drawLabels(e) { 488 reflectToQalamMirror(), resizeQalamExtension(), $(".qalam-highlights-cont qalam-label").remove(); 489 let t = currentTextSuggestions.length; 490 t > 0 ? ($.each(currentTextSuggestions, function () { 491 let t = this.original, n = this.from, a = this.to, o = this.replacement, l = this.lineColor, 492 i = this.labelColor, s = getRangeSpecs(n, a); 493 s && ($.each(s, function () { 494 labelCreator(t, n, a, o, l, i, this, e) 495 }), handleReposition()) 496 }), setErrorsTotal(t)) : clearButton() 497 } 498 499 function detectBrowser() { 500 return -1 != (navigator.userAgent.indexOf("Opera") || navigator.userAgent.indexOf("OPR")) ? "Opera" : -1 != navigator.userAgent.indexOf("Chrome") ? "Chrome" : -1 != navigator.userAgent.indexOf("Safari") ? "Safari" : -1 != navigator.userAgent.indexOf("Firefox") ? "Firefox" : -1 != navigator.userAgent.indexOf("MSIE") || 1 == !!document.documentMode ? "IE" : "Unknown" 501 } 502 503 function detectBrowser() { 504 return -1 != (navigator.userAgent.indexOf("Opera") || navigator.userAgent.indexOf("OPR")) ? "Opera" : -1 != navigator.userAgent.indexOf("Chrome") ? "Chrome" : -1 != navigator.userAgent.indexOf("Safari") ? "Safari" : -1 != navigator.userAgent.indexOf("Firefox") ? "Firefox" : -1 != navigator.userAgent.indexOf("MSIE") || 1 == !!document.documentMode ? "IE" : "Unknown" 505 } 506 507 function labelCreator(e, t, n, a, o, l, i, s) { 508 let r = document.createElement("qalam-label"); 509 i.width = i.right - i.left, i.height = i.bottom - i.top, $(r).css("width", i.width), $(r).css("height", 1.05 * i.height), "Firefox" == detectBrowser() ? ($(r).css("top", i.top + 6 - .025 * i.height), $(r).css("left", i.left + 12)) : ($(r).css("top", i.top - .025 * i.height), $(r).css("left", i.left)), $(r).css("background-color", l), $(r).on("mouseenter", function (t) { 510 renderQalamSuggestions(t, e), $(r).addClass("active") 1672 let o = [], 1673 l = 0; 1674 for (let t = 0; t < e.length; ++t) 1675 offset_indices.has(t) && (l += 1), o.push(l); 1676 for (let e = 0; e < a.length; ++e) 1677 (a[e].from -= o[a[e].from]), (a[e].to -= o[a[e].to]); 1678 e == getText() && 1679 ((flagged_tokens = []), 1680 $.each(a, function () { 1681 let e = JSON.stringify({ 1682 word: wordGetter(this.from, this.to), 1683 suggestions: this.replacement, 1684 }); 1685 ignoredSet.has(e) || flagged_tokens.push(this); 1686 }), 1687 0 == flagged_tokens.length 1688 ? clearButton() 1689 : fetchErrors(flagged_tokens, n)); 511 1690 }); 512 let c = JSON.stringify(a); 513 $(r).attr("data-suggestions", c), $(r).attr("data-start-index", t), $(r).attr("data-end-index", n); 514 let m = document.createElement("label-border"); 515 $(m).css("left", i.left), $(m).css("width", i.width), $(m).css("background-color", o), r.appendChild(m), qalamHighlightsCont.appendChild(r), s ? $(m).css("left", "0") : setTimeout(function () { 516 $(m).css("left", "0") 517 }, 10) 518 } 519 520 function getRangeInfo(e, t) { 521 let n = {}; 522 if ("IFRAME" == element.tagName) { 523 let a = [element.contentDocument.activeElement], o = 0; 524 for (; a.length;) { 525 let l = a.pop(); 526 if (3 == l.nodeType) { 527 for (let a = 0; a < l.textContent.length; a++) e <= o + a && o + a <= t && (n[o + a] = { 528 node: l, 529 index: a 530 }); 531 if ((o += l.textContent.length) > t) break 532 } else { 533 if (STYLES_HIDDEN.has(window.getComputedStyle(l, null).display)) continue; 534 a.push(...Array.from(l.childNodes).reverse()) 535 } 536 } 537 return n 538 } 539 if (isTextArea) { 540 let a = qalamMirror.childNodes[0]; 541 for (let o = e; o <= t; o++) n[o] = {node: a, index: o}; 542 return n 543 } 544 let a = [element], o = 0; 545 for (; a.length;) { 546 let l = a.pop(); 547 if (3 == l.nodeType) { 548 for (let a = 0; a < l.textContent.length; a++) e <= o + a && o + a <= t && (n[o + a] = {node: l, index: a}); 549 if ((o += l.textContent.length) > t) break 550 } else { 551 if (STYLES_HIDDEN.has(window.getComputedStyle(l, null).display)) continue; 552 a.push(...Array.from(l.childNodes).reverse()) 553 } 554 } 555 return n 556 } 557 558 function getRangeSpecs(e, t) { 559 let n = getRangeInfo(e, t), a = document.createRange(), o = [], l = 0, i = 0, s = element.getBoundingClientRect(); 560 for (let r = e; r <= t; r++) { 561 try { 562 a.setStart(n[r].node, n[r].index), a.setEnd(n[r].node, n[r].index + 1) 563 } catch (e) { 564 } 565 let e = a.getBoundingClientRect(); 566 if (0 == e.width || 0 == e.height) continue; 567 let t = e.top - !isTextArea * (s.top - $(element).scrollTop()), 568 c = e.bottom - !isTextArea * (s.top - $(element).scrollTop()), m = e.left - !isTextArea * s.left, 569 d = e.right - !isTextArea * s.left, u = Math.min(c - t, i - l), g = Math.min(i, c) - Math.max(l, t); 570 0 == o.length || g / u < INTERSECTION_THRESHOLD ? o.push({ 571 right: d, 572 left: m, 573 bottom: c, 574 top: t 575 }) : (o[o.length - 1].left = Math.min(o[o.length - 1].left, m), o[o.length - 1].right = Math.max(o[o.length - 1].right, d), o[o.length - 1].top = Math.min(o[o.length - 1].top, t), o[o.length - 1].bottom = Math.max(o[o.length - 1].bottom, c)), l = t, i = c 576 } 577 return o 578 } 579 580 function clearLabels() { 581 currentTextSuggestions = [], $(".qalam-highlights-cont qalam-label").remove() 582 } 583 584 function setErrorsTotal(e) { 585 $("qalam-button-cont .qalam-button").css("background-color", BUTTON_ERROR_COLOR), $("qalam-button-cont .qalam-button").css("background-image", "unset"), $("qalam-button-cont .qalam-button .errors").css("display", "block"), $("qalam-button-cont .qalam-button .errors").text(e), e > 99 ? $("qalam-button-cont .qalam-button .errors").css("font-size", "12px") : $("qalam-button-cont .qalam-button .errors").css("font-size", "15px") 586 } 587 588 function decreaseTotalErrorsCount() { 589 let e = parseInt($("qalam-button-cont .qalam-button .errors").text()); 590 e > 1 ? $("qalam-button-cont .qalam-button .errors").text(e - 1) : clearButton() 591 } 592 593 function renderQalamSuggestions(e, t) { 594 removeQalamSuggestions(); 595 let n = $(e.target).closest("qalam-label"), a = JSON.parse($(n).attr("data-suggestions")), 596 o = $(n).attr("data-start-index"), l = $(n).attr("data-end-index"); 597 if (!$(shadowRoot).find("qalam-suggestions").length) { 598 qalamSuggestions = document.createElement("qalam-suggestions"); 599 let e = document.createElement("suggestions-cont"); 600 $.each(a, function () { 601 let t = this, n = document.createElement("suggestion-item"); 602 $(n).on("click", function () { 603 let e = $(element).scrollTop(), n = $(window).scrollTop(); 604 $(`qalam-label[data-start-index='${o}']`).remove(), removeQalamSuggestions(), decreaseTotalErrorsCount(), replaceOriginalText(t, o, l), spellCheckText(!0), $(element).scrollTop(e), $(window).scrollTop(n), mobileCheck() && ($(qalamSuggestions).remove(), $("qalam-extension .qalam-highlights-cont qalam-label").removeClass("active")) 605 }); 606 let a = document.createElement("suggestion-text"); 607 "" === t.trim() ? a.innerHTML = '<i style="font-size:12px;"><مسافة زائدة><i>' : a.innerHTML = t, n.appendChild(a), e.appendChild(n) 608 }); 609 let i = document.createElement("div"); 610 i.className = "ignore-cont", $(i).on("click", function () { 611 wordGetter(o, l); 612 onDismissCallback([t]), $(`qalam-label[data-start-index='${o}']`).remove(), removeQalamSuggestions(), spellCheckText(!0) 613 }); 614 let s = document.createElement("img"); 615 s.className = "ignore-icon", s.src = `${settings.assetsPath}/images/ignore.svg`; 616 let r = document.createElement("p"); 617 if (r.className = "ignore-text", r.innerHTML = "تجاهل هذا التصحيح", i.appendChild(s), i.appendChild(r), isWriterAllowedToAddToDic) { 618 addToDictionaryItem = document.createElement("div"), addToDictionaryItem.className = "add-to-dic-cont", $(addToDictionaryItem).on("click", function () { 619 onAddToDictionaryCallback([t]), $(`qalam-label[data-start-index='${o}']`).remove(), removeQalamSuggestions(), spellCheckText(!0) 620 }); 621 let e = document.createElement("img"); 622 e.className = "add-to-dic-icon", e.src = `${settings.assetsPath}/images/add.svg`; 623 let n = document.createElement("p"); 624 n.className = "add-to-dic-text", n.innerHTML = "إضافة إلى القاموس", addToDictionaryItem.appendChild(e), addToDictionaryItem.appendChild(n) 625 } 626 if (qalamSuggestions.appendChild(e), qalamSuggestions.appendChild(i), isWriterAllowedToAddToDic && qalamSuggestions.appendChild(addToDictionaryItem), $(shadowRoot).append(qalamSuggestions), a.length > 0) { 627 labelBoundingBox = n[0].getBoundingClientRect(), $(qalamSuggestions).css("display", "block"), suggestionBoundingBox = qalamSuggestions.getBoundingClientRect(); 628 let e = [{ 629 top: labelBoundingBox.top + labelBoundingBox.height, 630 left: labelBoundingBox.left + labelBoundingBox.width - suggestionBoundingBox.width 631 }, { 632 top: labelBoundingBox.top + labelBoundingBox.height, 633 left: labelBoundingBox.left 634 }, { 635 top: labelBoundingBox.top - suggestionBoundingBox.height, 636 left: labelBoundingBox.left + labelBoundingBox.width - suggestionBoundingBox.width 637 }, {top: labelBoundingBox.top - suggestionBoundingBox.height, left: labelBoundingBox.left}]; 638 for (let t = 0; t < e.length && ($(qalamSuggestions).css("top", e[t].top), $(qalamSuggestions).css("left", e[t].left), !isElementInViewport(qalamSuggestions)); t++) ; 639 } 640 } 641 resizeQalamExtension() 642 } 643 644 function onAddToDictionaryCallback(e) { 645 $.ajax({ 646 dataType: "json", url: baseLink + "dictionaries/words", type: "POST", beforeSend: function (e) { 647 e.setRequestHeader("Authorization", `${clientId}`), e.setRequestHeader("Content-Type", "application/json") 648 }, data: JSON.stringify({words: e}), success: function (e) { 649 }, error: function () { 650 } 651 }) 652 } 653 654 function onDismissCallback(e) { 655 $.ajax({ 656 dataType: "json", 657 url: baseLink + "documents/" + uuidV3Hash + "/dismissals", 658 type: "POST", 659 beforeSend: function (e) { 660 e.setRequestHeader("Authorization", `${clientId}`), e.setRequestHeader("Content-Type", "application/json") 661 }, 662 data: JSON.stringify({words: e}), 663 success: function (e) { 664 }, 665 error: function () { 666 } 667 }) 668 } 669 670 function isElementInViewport(e) { 671 let t = e.getBoundingClientRect(); 672 return t.top >= 0 && t.left >= 0 && t.bottom <= (window.innerHeight || document.documentElement.clientHeight) && t.right <= (window.innerWidth || document.documentElement.clientWidth) 673 } 674 675 function wordGetter(e, t) { 676 return $(element).val().substr(e, parseInt(t) - e + 1) 677 } 678 679 function replaceOriginalText(e, t, n) { 680 let a = getText().length; 681 if (isTextArea) if ("IFRAME" == element.tagName) { 682 element.contentWindow.focus(); 683 let e = getRangeInfo(t, n); 684 range = element.contentDocument.createRange(), range.setStart(e[t].node, e[t].index), range.setEnd(e[n].node, e[n].index + 1), sel = element.contentDocument.getSelection(), sel.removeAllRanges(), sel.addRange(range) 685 } else $(element).trigger("focus"), $(element)[0].selectionStart = t, $(element)[0].selectionEnd = parseInt(n) + 1; else { 686 $(element).trigger("focus"); 687 let e = getRangeInfo(t, n); 688 range = document.createRange(), range.setStart(e[t].node, e[t].index), range.setEnd(e[n].node, e[n].index + 1), sel = window.getSelection(), sel.removeAllRanges(), sel.addRange(range) 689 } 690 triggerFlag = !1, "IFRAME" == element.tagName ? element.contentDocument.execCommand("insertText", !1, e) : document.execCommand("insertText", !1, e), setTimeout(function () { 691 triggerFlag = !0 692 }, 5); 693 let o = a - getText().length, l = -1; 694 $.each(currentTextSuggestions, function (e, n) { 695 n.from == t ? l = e : n.from > t && (currentTextSuggestions[e].from -= o, currentTextSuggestions[e].to -= o) 696 }), -1 != l && currentTextSuggestions.splice(l, 1), drawLabels(!0) 697 } 698 699 function unmountQalamComponent() { 700 $("qalam-container").remove(), $("qalam-mirror-shadow").remove(), null != qalamMirror && $(qalamMirror).remove(), removeQalamSuggestions(), ignoredSet = new Set, currentTextSuggestions = [] 701 } 702 703 function resetGlobalVariables() { 704 shadowRoot = null, qalamDisablePrompt = null, isTextArea = null, triggerFlag = !0, SCServiceActive = null, qalamExtension = null, qalamExtensionCont = null, qalamHighlightsCont = null, qalamMirror = null, removeDisablePrompt(), removeQalamSuggestions(), qalamSuggestions = null, $(element).off(), element = null, withoutScrollDiff = 0, elementParent = null, typingStallCounter = 0, secondsCounter = null, resizeHoldCounter = null, currentTextSuggestions = [], clearInterval(secondsCounter), clearInterval(resizeHoldCounter) 705 } 706 707 function turnOnSC() { 708 SCServiceActive = !0, init() 709 } 710 711 function turnOffSC() { 712 SCServiceActive = !1, unmountQalamComponent(), resetGlobalVariables() 713 } 714 715 function setCookie() { 716 let e = generateId(8); 717 document.cookie = "qalam_user_id=" + e + "; path=/" 718 } 719 720 function getCookie(e) { 721 for (var t = e + "=", n = document.cookie.split(";"), a = 0; a < n.length; a++) { 722 for (var o = n[a]; " " == o.charAt(0);) o = o.substring(1, o.length); 723 if (0 == o.indexOf(t)) return o.substring(t.length, o.length) 724 } 725 return null 726 } 727 728 function generateId(e) { 729 for (var t = "", n = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", a = n.length, o = 0; o < e; o++) t += n.charAt(Math.floor(Math.random() * a)); 730 return t 731 } 732 733 function callService(e, t, n) { 734 if (documentId) uuidV3Hash = uuid.v5(documentId + ":" + editorId, clientId); else if (mode == PATH_MODE) { 735 var a = extractPathParamAt(modeValue); 736 a || (documentId = a = uuid.v4()), uuidV3Hash = uuid.v5(a + ":" + editorId, clientId) 737 } else if (mode == QUERY_MODE) { 738 var o = extractQueryParam(modeValue); 739 o || (documentId = o = uuid.v4()), uuidV3Hash = uuid.v5(o + ":" + editorId, clientId) 740 } else documentId = uuid.v4(), uuidV3Hash = uuid.v5(documentId + ":" + editorId, clientId); 741 var l = { 742 url: API_LINK, 743 method: "POST", 744 timeout: 0, 745 headers: {"Content-Type": "application/json", Authorization: `${clientId}`}, 746 success: function () { 747 }, 748 error: function (e, t, n) { 749 e.status 750 }, 751 data: JSON.stringify({text: e, docId: uuidV3Hash}) 752 }; 753 setTimeout(function () { 754 $.ajax(l).done(function (t) { 755 let a = []; 756 extend(a, extractRest(t.termSuggestions, TERM_LINE_COLOR, TERM_LABEL_COLOR)), extend(a, extractRest(t.tafqeetSuggestions, TAFQEET_LINE_COLOR, TAFQEET_LABEL_COLOR)), extend(a, extractResponse(t.grammarResponse, GRAMMAR_LINE_COLOR, GRAMMAR_LABEL_COLOR)), extend(a, extractResponse(t.phrasingResponse, PHRASING_LINE_COLOR, PHRASING_LABEL_COLOR)), extend(a, extractResponse(t.spellCheckResponse, SC_LINE_COLOR, SC_LABEL_COLOR)), $.each(t.numDate, function () { 757 extend(a, extractRest(this, NUM_LINE_COLOR, NUM_LABEL_COLOR)) 758 }), $.each(t.tashkeel, function () { 759 extend(a, extractRest(this, T_LINE_COLOR, T_LABEL_COLOR)) 760 }), $.each(t.punctuation, function () { 761 extend(a, extractRest(this, PUNC_LINE_COLOR, PUNC_LABEL_COLOR)) 762 }); 763 let o = [], l = 0; 764 for (let t = 0; t < e.length; ++t) { 765 let n = t + DUMMY_STRING.length + 2; 766 n <= e.length && e.slice(t, n) == `\n${DUMMY_STRING}\n` && (l += DUMMY_STRING.length + 2), o.push(l) 767 } 768 for (let e = 0; e < a.length; ++e) a[e].from -= o[a[e].from], a[e].to -= o[a[e].to]; 769 e == getText() && (flagged_tokens = [], $.each(a, function () { 770 let e = JSON.stringify({word: wordGetter(this.from, this.to), suggestions: this.replacement}); 771 ignoredSet.has(e) || flagged_tokens.push(this) 772 }), 0 == flagged_tokens.length ? clearButton() : fetchErrors(flagged_tokens, n)) 773 }) 774 }, t) 775 } 776 777 function extractResponse(e, t, n) { 778 if (null == e || jQuery.isEmptyObject(e)) return []; 779 if (SCSuggestions = e.results.flagged_tokens, null == SCSuggestions) return []; 780 let a = []; 781 for (let e = 0; e < SCSuggestions.length; e++) token = SCSuggestions[e], a.push({ 1691 }, t); 1692 } 1693 1694 function extractResponse(e, t, n, x) { 1695 if (null == e || jQuery.isEmptyObject(e)) return []; 1696 if (((SCSuggestions = e.results.flagged_tokens), null == SCSuggestions)) 1697 return []; 1698 let a = []; 1699 for (let e = 0; e < SCSuggestions.length; e++) 1700 (token = SCSuggestions[e]), 1701 a.push({ 1702 type: x, 782 1703 lineColor: t, 783 1704 labelColor: n, 784 1705 from: token.start_index, 785 1706 to: token.end_index, 1707 lang: token.lang ? token.lang : 'ar', 786 1708 original: token.original_word, 787 replacement: function (e) { 788 let t = []; 789 for (let n = 0; n < e.length; n++) t.push(e[n].text); 790 return t 791 }(token.suggestions) 1709 replacement: (function (e) { 1710 let t = []; 1711 for (let n = 0; n < e.length; n++) t.push(e[n].text); 1712 return t; 1713 })(token.suggestions), 1714 }); 1715 return a; 1716 } 1717 1718 function extractRest(e, t, n, x) { 1719 if (null == e) return []; 1720 for (let a = 0; a < e.length; a++) 1721 (e[a].type = x), 1722 (e[a].replacement = [e[a].replacement]), 1723 (e[a].to -= 1), 1724 (e[a].lineColor = t), 1725 (e[a].labelColor = n); 1726 return e; 1727 } 1728 1729 function isOverlapping(e, t, n, a) { 1730 return n <= t && a >= e; 1731 } 1732 1733 function extend(e, t) { 1734 for (let n = 0; n < t.length; n++) { 1735 let a = !0; 1736 for (let o = 0; o < e.length; o++) 1737 if (isOverlapping(t[n].from, t[n].to, e[o].from, e[o].to)) { 1738 a = !1; 1739 break; 1740 } 1741 a && e.push(t[n]); 1742 } 1743 } 1744 1745 async function shakel() { 1746 selectedText = window.getSelection().toString(); 1747 } 1748 1749 function unshakel(e) { 1750 return e && (selectedText = e.replace(/([\u064b-\u0653\u0670])/g, '')), e; 1751 } 1752 1753 function isEmpty(e) { 1754 return 0 === Object.keys(e).length; 1755 } 1756 1757 function extractQueryParam(e) { 1758 return new URLSearchParams(window.location.search).get(e); 1759 } 1760 1761 function extractPathParamAt(e) { 1762 if (0 != e) return window.location.pathname.split('/')[e]; 1763 console.error('Index should start from 1'); 1764 } 1765 1766 function assignEditorIds() { 1767 document.querySelectorAll('[contenteditable]').forEach((e, t) => { 1768 e.setAttribute('data-qid', 'ce:' + t); 1769 }), 1770 document.querySelectorAll('textarea').forEach((e, t) => { 1771 e.setAttribute('data-qid', 'te:' + t); 792 1772 }); 793 return a 794 } 795 796 function extractRest(e, t, n) { 797 if (null == e) return []; 798 for (let a = 0; a < e.length; a++) e[a].replacement = [e[a].replacement], e[a].to -= 1, e[a].lineColor = t, e[a].labelColor = n; 799 return e 800 } 801 802 function isOverlapping(e, t, n, a) { 803 return n <= t && a >= e 804 } 805 806 function extend(e, t) { 807 for (let n = 0; n < t.length; n++) { 808 let a = !0; 809 for (let o = 0; o < e.length; o++) if (isOverlapping(t[n].from, t[n].to, e[o].from, e[o].to)) { 810 a = !1; 811 break 812 } 813 a && e.push(t[n]) 1773 } 1774 1775 function assignIframeEditorIds(e, t) { 1776 e.contentDocument.querySelectorAll('[contenteditable]').forEach((e, n) => { 1777 e.setAttribute('data-qid', `fce:${t}:${n}`); 1778 }), 1779 e.contentDocument.querySelectorAll('textarea').forEach((e, n) => { 1780 e.setAttribute('data-qid', `fte:${t}:${n}`); 1781 }); 1782 } 1783 1784 function getContext(e, t, n) { 1785 let a = getText(), 1786 o = a 1787 .replace(/\n/g, '') 1788 .substring(0, t) 1789 .split(' ') 1790 .filter((e) => '' != e && ' ' != e), 1791 l = a 1792 .replace(/\n/g, '') 1793 .substring(parseInt(n) + 1) 1794 .split(' ') 1795 .filter((e) => '' != e && ' ' != e); 1796 return `\n\t\t\t${o.slice(o.length - 6).join(' ')} ${e} ${l 1797 .slice(0, 5) 1798 .join(' ')}`; 1799 } 1800 window.x || (x = {}), 1801 (x.Selector = {}), 1802 (x.Selector.getSelected = function () { 1803 var e = ''; 1804 return ( 1805 window.getSelection 1806 ? (e = window.getSelection()) 1807 : document.getSelection 1808 ? (e = document.getSelection()) 1809 : document.selection && (e = document.selection.createRange().text), 1810 e 1811 ); 1812 }), 1813 $(document).ready(function () { 1814 (scr.src = `${settings.assetsPath}/js/uuid.js`), 1815 (scr.async = !1), 1816 head.insertBefore(scr, head.firstChild); 1817 let e = document.querySelectorAll('textarea'); 1818 for (let a = 0; a < e.length; a++) { 1819 const o = e[a]; 1820 var t = o.parentNode, 1821 n = document.createElement('div'); 1822 n.classList.add('textarea-blk'), t.replaceChild(n, o), n.appendChild(o); 814 1823 } 815 } 816 817 async function shakel() { 818 selectedText = window.getSelection().toString() 819 } 820 821 function unshakel(e) { 822 return e && (selectedText = e.replace(/([\u064b-\u0653\u0670])/g, "")), e 823 } 824 825 function isEmpty(e) { 826 return 0 === Object.keys(e).length 827 } 828 829 function extractQueryParam(e) { 830 return new URLSearchParams(window.location.search).get(e) 831 } 832 833 function extractPathParamAt(e) { 834 if (0 != e) return window.location.pathname.split("/")[e]; 835 console.error("Index should start from 1") 836 } 837 838 function assignEditorIds() { 839 document.querySelectorAll("[contenteditable]").forEach((e, t) => { 840 e.setAttribute("data-qid", "ce:" + t) 841 }), document.querySelectorAll("textarea").forEach((e, t) => { 842 e.setAttribute("data-qid", "te:" + t) 843 }) 844 } 845 846 function assignIframeEditorIds(e, t) { 847 e.contentDocument.querySelectorAll("[contenteditable]").forEach((e, n) => { 848 e.setAttribute("data-qid", `fce:${t}:${n}`) 849 }), e.contentDocument.querySelectorAll("textarea").forEach((e, n) => { 850 e.setAttribute("data-qid", `fte:${t}:${n}`) 851 }) 852 } 853 854 window.x || (x = {}), x.Selector = {}, x.Selector.getSelected = function () { 855 var e = ""; 856 return window.getSelection ? e = window.getSelection() : document.getSelection ? e = document.getSelection() : document.selection && (e = document.selection.createRange().text), e 857 }, $(document).ready(function () { 858 scr.src = `${settings.assetsPath}/js/uuid.js`, scr.async = !1, head.insertBefore(scr, head.firstChild); 859 let e = document.querySelectorAll("textarea"); 860 for (let a = 0; a < e.length; a++) { 861 const o = e[a]; 862 var t = o.parentNode, n = document.createElement("div"); 863 n.classList.add("textarea-blk"), t.replaceChild(n, o), n.appendChild(o) 1824 if ( 1825 (activate(baseLink + 'test/go', clientId), 1826 !document.getElementById(cssId)) 1827 ) { 1828 var a = document.getElementsByTagName('head')[0], 1829 o = document.createElement('link'); 1830 (o.id = cssId), 1831 (o.rel = 'stylesheet'), 1832 (o.type = 'text/css'), 1833 (o.href = `${settings.assetsPath}/css/qalamExtension.css`), 1834 (o.media = 'all'), 1835 a.appendChild(o); 864 1836 } 865 if (activate(baseLink + "test/go", clientId), !document.getElementById(cssId)) { 866 var a = document.getElementsByTagName("head")[0], o = document.createElement("link"); 867 o.id = cssId, o.rel = "stylesheet", o.type = "text/css", o.href = `${settings.assetsPath}/css/qalamExtension.css`, o.media = "all", a.appendChild(o) 868 } 869 }); 1837 }); -
qalam/trunk/qalam.php
r2599982 r2896421 3 3 * Plugin Name: Qalam 4 4 * Description: Qalam helps you to write clear, effective texts that are free from spelling and grammatical errors, using the latest artificial intelligence technologies and Arabic language processing. 5 * Version: 1.0. 05 * Version: 1.0.1 6 6 * Requires at least: 5.2 7 7 * Requires PHP: 7.2 -
qalam/trunk/readme.txt
r2594341 r2896421 4 4 Donate link: https://www.qalam.ai/ 5 5 Requires at least: 5.2 6 Tested up to: 5.87 Stable tag: 1.0. 06 Tested up to: 6.2 7 Stable tag: 1.0.1 8 8 License: GPL v2 9 9 Requires PHP: 7.2
Note: See TracChangeset
for help on using the changeset viewer.